2 * Greybus audio commands
4 * Copyright 2015 Google Inc.
5 * Copyright 2015 Linaro Ltd.
7 * Released under the GPLv2 only.
10 #include <linux/kernel.h>
15 /***********************************
16 * GB I2S helper functions
17 ***********************************/
18 int gb_i2s_mgmt_activate_cport(struct gb_connection *connection,
21 struct gb_i2s_mgmt_activate_cport_request request;
23 memset(&request, 0, sizeof(request));
24 request.cport = cpu_to_le16(cport);
26 return gb_operation_sync(connection, GB_I2S_MGMT_TYPE_ACTIVATE_CPORT,
27 &request, sizeof(request), NULL, 0);
30 int gb_i2s_mgmt_deactivate_cport(struct gb_connection *connection,
33 struct gb_i2s_mgmt_deactivate_cport_request request;
35 memset(&request, 0, sizeof(request));
36 request.cport = cpu_to_le16(cport);
38 return gb_operation_sync(connection, GB_I2S_MGMT_TYPE_DEACTIVATE_CPORT,
39 &request, sizeof(request), NULL, 0);
42 int gb_i2s_mgmt_get_supported_configurations(
43 struct gb_connection *connection,
44 struct gb_i2s_mgmt_get_supported_configurations_response *get_cfg,
47 return gb_operation_sync(connection,
48 GB_I2S_MGMT_TYPE_GET_SUPPORTED_CONFIGURATIONS,
49 NULL, 0, get_cfg, size);
52 int gb_i2s_mgmt_set_configuration(struct gb_connection *connection,
53 struct gb_i2s_mgmt_set_configuration_request *set_cfg)
55 return gb_operation_sync(connection, GB_I2S_MGMT_TYPE_SET_CONFIGURATION,
56 set_cfg, sizeof(*set_cfg), NULL, 0);
59 int gb_i2s_mgmt_set_samples_per_message(
60 struct gb_connection *connection,
61 uint16_t samples_per_message)
63 struct gb_i2s_mgmt_set_samples_per_message_request request;
65 memset(&request, 0, sizeof(request));
66 request.samples_per_message = cpu_to_le16(samples_per_message);
68 return gb_operation_sync(connection,
69 GB_I2S_MGMT_TYPE_SET_SAMPLES_PER_MESSAGE,
70 &request, sizeof(request), NULL, 0);
73 int gb_i2s_mgmt_get_cfgs(struct gb_snd *snd_dev,
74 struct gb_connection *connection)
76 struct gb_i2s_mgmt_get_supported_configurations_response *get_cfg;
80 size = sizeof(*get_cfg) +
81 (CONFIG_COUNT_MAX * sizeof(get_cfg->config[0]));
83 get_cfg = kzalloc(size, GFP_KERNEL);
87 ret = gb_i2s_mgmt_get_supported_configurations(connection, get_cfg,
90 pr_err("get_supported_config failed: %d\n", ret);
91 goto err_free_get_cfg;
94 snd_dev->i2s_configs = get_cfg;
103 void gb_i2s_mgmt_free_cfgs(struct gb_snd *snd_dev)
105 kfree(snd_dev->i2s_configs);
106 snd_dev->i2s_configs = NULL;
109 int gb_i2s_mgmt_set_cfg(struct gb_snd *snd_dev, int rate, int chans,
110 int bytes_per_chan, int is_le)
112 struct gb_i2s_mgmt_set_configuration_request set_cfg;
113 struct gb_i2s_mgmt_configuration *cfg;
115 u8 byte_order = GB_I2S_MGMT_BYTE_ORDER_NA;
117 if (bytes_per_chan > 1) {
119 byte_order = GB_I2S_MGMT_BYTE_ORDER_LE;
121 byte_order = GB_I2S_MGMT_BYTE_ORDER_BE;
124 for (i = 0, cfg = snd_dev->i2s_configs->config;
125 i < CONFIG_COUNT_MAX;
127 if ((cfg->sample_frequency == cpu_to_le32(rate)) &&
128 (cfg->num_channels == chans) &&
129 (cfg->bytes_per_channel == bytes_per_chan) &&
130 (cfg->byte_order & byte_order) &&
132 cpu_to_le32(GB_I2S_MGMT_PROTOCOL_I2S)) &&
133 (cfg->ll_mclk_role & GB_I2S_MGMT_ROLE_MASTER) &&
134 (cfg->ll_bclk_role & GB_I2S_MGMT_ROLE_MASTER) &&
135 (cfg->ll_wclk_role & GB_I2S_MGMT_ROLE_MASTER) &&
136 (cfg->ll_wclk_polarity & GB_I2S_MGMT_POLARITY_NORMAL) &&
137 (cfg->ll_wclk_change_edge & GB_I2S_MGMT_EDGE_FALLING) &&
138 (cfg->ll_wclk_tx_edge & GB_I2S_MGMT_EDGE_RISING) &&
139 (cfg->ll_wclk_rx_edge & GB_I2S_MGMT_EDGE_FALLING) &&
140 (cfg->ll_data_offset == 1))
144 if (i >= CONFIG_COUNT_MAX) {
145 pr_err("No valid configuration\n");
149 memcpy(&set_cfg, cfg, sizeof(set_cfg));
150 set_cfg.config.byte_order = byte_order;
151 set_cfg.config.ll_protocol = cpu_to_le32(GB_I2S_MGMT_PROTOCOL_I2S);
152 set_cfg.config.ll_mclk_role = GB_I2S_MGMT_ROLE_MASTER;
153 set_cfg.config.ll_bclk_role = GB_I2S_MGMT_ROLE_MASTER;
154 set_cfg.config.ll_wclk_role = GB_I2S_MGMT_ROLE_MASTER;
155 set_cfg.config.ll_wclk_polarity = GB_I2S_MGMT_POLARITY_NORMAL;
156 set_cfg.config.ll_wclk_change_edge = GB_I2S_MGMT_EDGE_FALLING;
157 set_cfg.config.ll_wclk_tx_edge = GB_I2S_MGMT_EDGE_RISING;
158 set_cfg.config.ll_wclk_rx_edge = GB_I2S_MGMT_EDGE_FALLING;
160 ret = gb_i2s_mgmt_set_configuration(snd_dev->mgmt_connection, &set_cfg);
162 pr_err("set_configuration failed: %d\n", ret);
167 int gb_i2s_send_data(struct gb_connection *connection,
168 void *req_buf, void *source_addr,
169 size_t len, int sample_num)
171 struct gb_i2s_send_data_request *gb_req;
175 gb_req->sample_number = cpu_to_le32(sample_num);
177 memcpy((void *)&gb_req->data[0], source_addr, len);
179 if (len < MAX_SEND_DATA_LEN)
180 for (; len < MAX_SEND_DATA_LEN; len++)
181 gb_req->data[len] = gb_req->data[len - SAMPLE_SIZE];
183 gb_req->size = cpu_to_le32(len);
185 ret = gb_operation_sync(connection, GB_I2S_DATA_TYPE_SEND_DATA,
186 (void *) gb_req, SEND_DATA_BUF_LEN, NULL, 0);