blob: ebb8effb5f723ebd7deb2ce957d761339b7380cc [file] [log] [blame]
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12#include <linux/slab.h>
13#include <linux/debugfs.h>
14#include <linux/kernel.h>
15#include <linux/kthread.h>
16#include <linux/uaccess.h>
17#include <linux/wait.h>
18#include <linux/wakelock.h>
19#include <linux/jiffies.h>
20#include <linux/sched.h>
21#include <linux/msm_audio_ion.h>
22#include <linux/delay.h>
23#include <sound/apr_audio-v2.h>
24#include <sound/q6afe-v2.h>
25#include <sound/q6audio-v2.h>
26#include "msm-pcm-routing-v2.h"
27#include <sound/audio_cal_utils.h>
28#include <sound/adsp_err.h>
29#include <linux/qdsp6v2/apr_tal.h>
30
31#define WAKELOCK_TIMEOUT 5000
32enum {
33 AFE_COMMON_RX_CAL = 0,
34 AFE_COMMON_TX_CAL,
35 AFE_AANC_CAL,
36 AFE_FB_SPKR_PROT_CAL,
37 AFE_HW_DELAY_CAL,
38 AFE_SIDETONE_CAL,
Siena Richardd83d83f2016-12-15 13:49:41 -080039 AFE_SIDETONE_IIR_CAL,
Banajit Goswami0530e2f2016-12-09 21:34:37 -080040 AFE_TOPOLOGY_CAL,
41 AFE_CUST_TOPOLOGY_CAL,
42 AFE_FB_SPKR_PROT_TH_VI_CAL,
43 AFE_FB_SPKR_PROT_EX_VI_CAL,
44 MAX_AFE_CAL_TYPES
45};
46
47enum fbsp_state {
48 FBSP_INCORRECT_OP_MODE,
49 FBSP_INACTIVE,
50 FBSP_WARMUP,
51 FBSP_IN_PROGRESS,
52 FBSP_SUCCESS,
53 FBSP_FAILED,
54 MAX_FBSP_STATE
55};
56
57static char fbsp_state[MAX_FBSP_STATE][50] = {
58 [FBSP_INCORRECT_OP_MODE] = "incorrect operation mode",
59 [FBSP_INACTIVE] = "port not started",
60 [FBSP_WARMUP] = "waiting for warmup",
61 [FBSP_IN_PROGRESS] = "in progress state",
62 [FBSP_SUCCESS] = "success",
63 [FBSP_FAILED] = "failed"
64};
65
66enum {
67 USE_CALIBRATED_R0TO,
68 USE_SAFE_R0TO
69};
70
71enum {
72 QUICK_CALIB_DISABLE,
73 QUICK_CALIB_ENABLE
74};
75
76enum {
77 Q6AFE_MSM_SPKR_PROCESSING = 0,
78 Q6AFE_MSM_SPKR_CALIBRATION,
79 Q6AFE_MSM_SPKR_FTM_MODE
80};
81
82struct wlock {
83 struct wakeup_source ws;
84};
85
86static struct wlock wl;
87
88struct afe_ctl {
89 void *apr;
90 atomic_t state;
91 atomic_t status;
92 wait_queue_head_t wait[AFE_MAX_PORTS];
93 struct task_struct *task;
94 void (*tx_cb)(uint32_t opcode,
95 uint32_t token, uint32_t *payload, void *priv);
96 void (*rx_cb)(uint32_t opcode,
97 uint32_t token, uint32_t *payload, void *priv);
98 void *tx_private_data;
99 void *rx_private_data;
100 uint32_t mmap_handle;
101
102 int topology[AFE_MAX_PORTS];
103 struct cal_type_data *cal_data[MAX_AFE_CAL_TYPES];
104
105 atomic_t mem_map_cal_handles[MAX_AFE_CAL_TYPES];
106 atomic_t mem_map_cal_index;
107 u32 afe_cal_mode[AFE_MAX_PORTS];
108
109 u16 dtmf_gen_rx_portid;
110 struct audio_cal_info_spk_prot_cfg prot_cfg;
111 struct afe_spkr_prot_calib_get_resp calib_data;
112 struct audio_cal_info_sp_th_vi_ftm_cfg th_ftm_cfg;
113 struct audio_cal_info_sp_ex_vi_ftm_cfg ex_ftm_cfg;
114 struct afe_sp_th_vi_get_param_resp th_vi_resp;
115 struct afe_sp_ex_vi_get_param_resp ex_vi_resp;
Manish Dewangan1903ffb2016-12-20 12:56:24 +0530116 struct afe_av_dev_drift_get_param_resp av_dev_drift_resp;
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800117 int vi_tx_port;
118 int vi_rx_port;
119 uint32_t afe_sample_rates[AFE_MAX_PORTS];
120 struct aanc_data aanc_info;
121 struct mutex afe_cmd_lock;
122 int set_custom_topology;
Siena Richard23364c92017-01-11 16:20:55 -0800123 int dev_acdb_id[AFE_MAX_PORTS];
124 routing_cb rt_cb;
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800125};
126
127static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX];
128static unsigned long afe_configured_cmd;
129
130static struct afe_ctl this_afe;
131
132#define TIMEOUT_MS 1000
133#define Q6AFE_MAX_VOLUME 0x3FFF
134
135static int pcm_afe_instance[2];
136static int proxy_afe_instance[2];
137bool afe_close_done[2] = {true, true};
138
139#define SIZEOF_CFG_CMD(y) \
140 (sizeof(struct apr_hdr) + sizeof(u16) + (sizeof(struct y)))
141
142static int afe_get_cal_hw_delay(int32_t path,
143 struct audio_cal_hw_delay_entry *entry);
144static int remap_cal_data(struct cal_block_data *cal_block, int cal_index);
145
146int afe_get_topology(int port_id)
147{
148 int topology;
149 int port_index = afe_get_port_index(port_id);
150
Xiaoyu Ye38ae2252017-01-26 18:20:06 -0800151 if ((port_index < 0) || (port_index >= AFE_MAX_PORTS)) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800152 pr_err("%s: Invalid port index %d\n", __func__, port_index);
153 topology = -EINVAL;
154 goto done;
155 }
156
157 topology = this_afe.topology[port_index];
158done:
159 return topology;
160}
161
162void afe_set_aanc_info(struct aanc_data *q6_aanc_info)
163{
164 this_afe.aanc_info.aanc_active = q6_aanc_info->aanc_active;
165 this_afe.aanc_info.aanc_rx_port = q6_aanc_info->aanc_rx_port;
166 this_afe.aanc_info.aanc_tx_port = q6_aanc_info->aanc_tx_port;
167
168 pr_debug("%s: aanc active is %d rx port is 0x%x, tx port is 0x%x\n",
169 __func__,
170 this_afe.aanc_info.aanc_active,
171 this_afe.aanc_info.aanc_rx_port,
172 this_afe.aanc_info.aanc_tx_port);
173}
174
175static void afe_callback_debug_print(struct apr_client_data *data)
176{
177 uint32_t *payload;
178
179 payload = data->payload;
180
181 if (data->payload_size >= 8)
182 pr_debug("%s: code = 0x%x PL#0[0x%x], PL#1[0x%x], size = %d\n",
183 __func__, data->opcode, payload[0], payload[1],
184 data->payload_size);
185 else if (data->payload_size >= 4)
186 pr_debug("%s: code = 0x%x PL#0[0x%x], size = %d\n",
187 __func__, data->opcode, payload[0],
188 data->payload_size);
189 else
190 pr_debug("%s: code = 0x%x, size = %d\n",
191 __func__, data->opcode, data->payload_size);
192}
193
Manish Dewangan1903ffb2016-12-20 12:56:24 +0530194static void av_dev_drift_afe_cb_handler(uint32_t *payload,
195 uint32_t payload_size)
196{
197 u32 param_id;
198 struct afe_av_dev_drift_get_param_resp *resp =
199 (struct afe_av_dev_drift_get_param_resp *) payload;
200
201 if (!(&(resp->pdata))) {
202 pr_err("%s: Error: resp pdata is NULL\n", __func__);
203 return;
204 }
205
206 param_id = resp->pdata.param_id;
207 if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) {
208 if (payload_size < sizeof(this_afe.av_dev_drift_resp)) {
209 pr_err("%s: Error: received size %d, resp size %zu\n",
210 __func__, payload_size,
211 sizeof(this_afe.av_dev_drift_resp));
212 return;
213 }
214 memcpy(&this_afe.av_dev_drift_resp, payload,
215 sizeof(this_afe.av_dev_drift_resp));
216 if (!this_afe.av_dev_drift_resp.status) {
217 atomic_set(&this_afe.state, 0);
218 } else {
219 pr_debug("%s: av_dev_drift_resp status: %d", __func__,
220 this_afe.av_dev_drift_resp.status);
221 atomic_set(&this_afe.state, -1);
222 }
223 }
224}
225
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800226static int32_t sp_make_afe_callback(uint32_t *payload, uint32_t payload_size)
227{
228 u32 param_id;
229 struct afe_spkr_prot_calib_get_resp *resp =
230 (struct afe_spkr_prot_calib_get_resp *) payload;
231
232 if (!(&(resp->pdata))) {
233 pr_err("%s: Error: resp pdata is NULL\n", __func__);
234 return -EINVAL;
235 }
236
237 param_id = resp->pdata.param_id;
238 if (param_id == AFE_PARAM_ID_CALIB_RES_CFG_V2) {
239 if (payload_size < sizeof(this_afe.calib_data)) {
240 pr_err("%s: Error: received size %d, calib_data size %zu\n",
241 __func__, payload_size,
242 sizeof(this_afe.calib_data));
243 return -EINVAL;
244 }
245 memcpy(&this_afe.calib_data, payload,
246 sizeof(this_afe.calib_data));
247 if (!this_afe.calib_data.status) {
248 atomic_set(&this_afe.state, 0);
249 } else {
250 pr_debug("%s: calib resp status: %d", __func__,
251 this_afe.calib_data.status);
252 atomic_set(&this_afe.state, -1);
253 }
254 }
255 if (param_id == AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS) {
256 if (payload_size < sizeof(this_afe.th_vi_resp)) {
257 pr_err("%s: Error: received size %d, th_vi_resp size %zu\n",
258 __func__, payload_size,
259 sizeof(this_afe.th_vi_resp));
260 return -EINVAL;
261 }
262 memcpy(&this_afe.th_vi_resp, payload,
263 sizeof(this_afe.th_vi_resp));
264 if (!this_afe.th_vi_resp.status) {
265 atomic_set(&this_afe.state, 0);
266 } else {
267 pr_debug("%s: th vi resp status: %d", __func__,
268 this_afe.th_vi_resp.status);
269 atomic_set(&this_afe.state, -1);
270 }
271 }
272 if (param_id == AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS) {
273 if (payload_size < sizeof(this_afe.ex_vi_resp)) {
274 pr_err("%s: Error: received size %d, ex_vi_resp size %zu\n",
275 __func__, payload_size,
276 sizeof(this_afe.ex_vi_resp));
277 return -EINVAL;
278 }
279 memcpy(&this_afe.ex_vi_resp, payload,
280 sizeof(this_afe.ex_vi_resp));
281 if (!this_afe.ex_vi_resp.status) {
282 atomic_set(&this_afe.state, 0);
283 } else {
284 pr_debug("%s: ex vi resp status: %d", __func__,
285 this_afe.ex_vi_resp.status);
286 atomic_set(&this_afe.state, -1);
287 }
288 }
289
290 return 0;
291}
292
293static int32_t afe_callback(struct apr_client_data *data, void *priv)
294{
295 if (!data) {
296 pr_err("%s: Invalid param data\n", __func__);
297 return -EINVAL;
298 }
299 if (data->opcode == RESET_EVENTS) {
300 pr_debug("%s: reset event = %d %d apr[%pK]\n",
301 __func__,
302 data->reset_event, data->reset_proc, this_afe.apr);
303
304 cal_utils_clear_cal_block_q6maps(MAX_AFE_CAL_TYPES,
305 this_afe.cal_data);
306
307 /* Reset the custom topology mode: to resend again to AFE. */
308 mutex_lock(&this_afe.cal_data[AFE_CUST_TOPOLOGY_CAL]->lock);
309 this_afe.set_custom_topology = 1;
310 mutex_unlock(&this_afe.cal_data[AFE_CUST_TOPOLOGY_CAL]->lock);
Vidyakumar Athota3cf42302017-02-06 13:53:10 -0800311 rtac_clear_mapping(AFE_RTAC_CAL);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800312
313 if (this_afe.apr) {
314 apr_reset(this_afe.apr);
315 atomic_set(&this_afe.state, 0);
316 this_afe.apr = NULL;
317 rtac_set_afe_handle(this_afe.apr);
318 }
319 /* send info to user */
320 if (this_afe.task == NULL)
321 this_afe.task = current;
322 pr_debug("%s: task_name = %s pid = %d\n",
323 __func__,
324 this_afe.task->comm, this_afe.task->pid);
325
326 /*
327 * Pass reset events to proxy driver, if cb is registered
328 */
329 if (this_afe.tx_cb) {
330 this_afe.tx_cb(data->opcode, data->token,
331 data->payload,
332 this_afe.tx_private_data);
333 this_afe.tx_cb = NULL;
334 }
335 if (this_afe.rx_cb) {
336 this_afe.rx_cb(data->opcode, data->token,
337 data->payload,
338 this_afe.rx_private_data);
339 this_afe.rx_cb = NULL;
340 }
341
342 return 0;
343 }
344 afe_callback_debug_print(data);
345 if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V2) {
Manish Dewangan1903ffb2016-12-20 12:56:24 +0530346 uint32_t *payload = data->payload;
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800347
348 if (!payload || (data->token >= AFE_MAX_PORTS)) {
349 pr_err("%s: Error: size %d payload %pK token %d\n",
350 __func__, data->payload_size,
351 payload, data->token);
352 return -EINVAL;
353 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800354
Manish Dewangan1903ffb2016-12-20 12:56:24 +0530355 if (payload[2] == AFE_PARAM_ID_DEV_TIMING_STATS) {
356 av_dev_drift_afe_cb_handler(data->payload,
357 data->payload_size);
358 } else {
359 if (rtac_make_afe_callback(data->payload,
360 data->payload_size))
361 return 0;
362
363 if (sp_make_afe_callback(data->payload,
364 data->payload_size))
365 return -EINVAL;
366 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800367 wake_up(&this_afe.wait[data->token]);
368 } else if (data->payload_size) {
369 uint32_t *payload;
370 uint16_t port_id = 0;
371
372 payload = data->payload;
373 if (data->opcode == APR_BASIC_RSP_RESULT) {
374 pr_debug("%s:opcode = 0x%x cmd = 0x%x status = 0x%x token=%d\n",
375 __func__, data->opcode,
376 payload[0], payload[1], data->token);
377 /* payload[1] contains the error status for response */
378 if (payload[1] != 0) {
379 atomic_set(&this_afe.status, payload[1]);
380 pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
381 __func__, payload[0], payload[1]);
382 }
383 switch (payload[0]) {
384 case AFE_PORT_CMD_SET_PARAM_V2:
385 if (rtac_make_afe_callback(payload,
386 data->payload_size))
387 return 0;
388 case AFE_PORT_CMD_DEVICE_STOP:
389 case AFE_PORT_CMD_DEVICE_START:
390 case AFE_PSEUDOPORT_CMD_START:
391 case AFE_PSEUDOPORT_CMD_STOP:
392 case AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS:
393 case AFE_SERVICE_CMD_SHARED_MEM_UNMAP_REGIONS:
394 case AFE_SERVICE_CMD_UNREGISTER_RT_PORT_DRIVER:
395 case AFE_PORTS_CMD_DTMF_CTL:
396 case AFE_SVC_CMD_SET_PARAM:
397 atomic_set(&this_afe.state, 0);
398 wake_up(&this_afe.wait[data->token]);
399 break;
400 case AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER:
401 break;
402 case AFE_PORT_DATA_CMD_RT_PROXY_PORT_WRITE_V2:
403 port_id = RT_PROXY_PORT_001_TX;
404 break;
405 case AFE_PORT_DATA_CMD_RT_PROXY_PORT_READ_V2:
406 port_id = RT_PROXY_PORT_001_RX;
407 break;
408 case AFE_CMD_ADD_TOPOLOGIES:
409 atomic_set(&this_afe.state, 0);
410 wake_up(&this_afe.wait[data->token]);
411 pr_debug("%s: AFE_CMD_ADD_TOPOLOGIES cmd 0x%x\n",
412 __func__, payload[1]);
413 break;
414 default:
415 pr_err("%s: Unknown cmd 0x%x\n", __func__,
416 payload[0]);
417 break;
418 }
419 } else if (data->opcode ==
420 AFE_SERVICE_CMDRSP_SHARED_MEM_MAP_REGIONS) {
421 pr_debug("%s: mmap_handle: 0x%x, cal index %d\n",
422 __func__, payload[0],
423 atomic_read(&this_afe.mem_map_cal_index));
424 if (atomic_read(&this_afe.mem_map_cal_index) != -1)
425 atomic_set(&this_afe.mem_map_cal_handles[
426 atomic_read(
427 &this_afe.mem_map_cal_index)],
428 (uint32_t)payload[0]);
429 else
430 this_afe.mmap_handle = payload[0];
431 atomic_set(&this_afe.state, 0);
432 wake_up(&this_afe.wait[data->token]);
433 } else if (data->opcode == AFE_EVENT_RT_PROXY_PORT_STATUS) {
434 port_id = (uint16_t)(0x0000FFFF & payload[0]);
435 }
436 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
437 switch (port_id) {
438 case RT_PROXY_PORT_001_TX: {
439 if (this_afe.tx_cb) {
440 this_afe.tx_cb(data->opcode, data->token,
441 data->payload,
442 this_afe.tx_private_data);
443 }
444 break;
445 }
446 case RT_PROXY_PORT_001_RX: {
447 if (this_afe.rx_cb) {
448 this_afe.rx_cb(data->opcode, data->token,
449 data->payload,
450 this_afe.rx_private_data);
451 }
452 break;
453 }
454 default:
455 pr_debug("%s: default case 0x%x\n", __func__, port_id);
456 break;
457 }
458 }
459 return 0;
460}
461
462int afe_get_port_type(u16 port_id)
463{
464 int ret;
465
466 switch (port_id) {
467 case PRIMARY_I2S_RX:
468 case SECONDARY_I2S_RX:
469 case MI2S_RX:
470 case HDMI_RX:
471 case DISPLAY_PORT_RX:
472 case AFE_PORT_ID_SPDIF_RX:
473 case SLIMBUS_0_RX:
474 case SLIMBUS_1_RX:
475 case SLIMBUS_2_RX:
476 case SLIMBUS_3_RX:
477 case SLIMBUS_4_RX:
478 case SLIMBUS_5_RX:
479 case SLIMBUS_6_RX:
480 case SLIMBUS_7_RX:
481 case SLIMBUS_8_RX:
482 case INT_BT_SCO_RX:
483 case INT_BT_A2DP_RX:
484 case INT_FM_RX:
485 case VOICE_PLAYBACK_TX:
486 case VOICE2_PLAYBACK_TX:
487 case RT_PROXY_PORT_001_RX:
488 case AUDIO_PORT_ID_I2S_RX:
489 case AFE_PORT_ID_PRIMARY_MI2S_RX:
490 case AFE_PORT_ID_SECONDARY_MI2S_RX:
491 case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1:
492 case AFE_PORT_ID_TERTIARY_MI2S_RX:
493 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
494 case AFE_PORT_ID_QUINARY_MI2S_RX:
495 case AFE_PORT_ID_PRIMARY_PCM_RX:
496 case AFE_PORT_ID_SECONDARY_PCM_RX:
497 case AFE_PORT_ID_TERTIARY_PCM_RX:
498 case AFE_PORT_ID_QUATERNARY_PCM_RX:
499 case AFE_PORT_ID_PRIMARY_TDM_RX:
500 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
501 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
502 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
503 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
504 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
505 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
506 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
507 case AFE_PORT_ID_SECONDARY_TDM_RX:
508 case AFE_PORT_ID_SECONDARY_TDM_RX_1:
509 case AFE_PORT_ID_SECONDARY_TDM_RX_2:
510 case AFE_PORT_ID_SECONDARY_TDM_RX_3:
511 case AFE_PORT_ID_SECONDARY_TDM_RX_4:
512 case AFE_PORT_ID_SECONDARY_TDM_RX_5:
513 case AFE_PORT_ID_SECONDARY_TDM_RX_6:
514 case AFE_PORT_ID_SECONDARY_TDM_RX_7:
515 case AFE_PORT_ID_TERTIARY_TDM_RX:
516 case AFE_PORT_ID_TERTIARY_TDM_RX_1:
517 case AFE_PORT_ID_TERTIARY_TDM_RX_2:
518 case AFE_PORT_ID_TERTIARY_TDM_RX_3:
519 case AFE_PORT_ID_TERTIARY_TDM_RX_4:
520 case AFE_PORT_ID_TERTIARY_TDM_RX_5:
521 case AFE_PORT_ID_TERTIARY_TDM_RX_6:
522 case AFE_PORT_ID_TERTIARY_TDM_RX_7:
523 case AFE_PORT_ID_QUATERNARY_TDM_RX:
524 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
525 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
526 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
527 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
528 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
529 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
530 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
531 case AFE_PORT_ID_USB_RX:
532 case AFE_PORT_ID_INT0_MI2S_RX:
533 case AFE_PORT_ID_INT1_MI2S_RX:
534 case AFE_PORT_ID_INT2_MI2S_RX:
535 case AFE_PORT_ID_INT3_MI2S_RX:
536 case AFE_PORT_ID_INT4_MI2S_RX:
537 case AFE_PORT_ID_INT5_MI2S_RX:
538 case AFE_PORT_ID_INT6_MI2S_RX:
539 ret = MSM_AFE_PORT_TYPE_RX;
540 break;
541
542 case PRIMARY_I2S_TX:
543 case SECONDARY_I2S_TX:
544 case MI2S_TX:
545 case DIGI_MIC_TX:
546 case VOICE_RECORD_TX:
547 case SLIMBUS_0_TX:
548 case SLIMBUS_1_TX:
549 case SLIMBUS_2_TX:
550 case SLIMBUS_3_TX:
551 case SLIMBUS_4_TX:
552 case SLIMBUS_5_TX:
553 case SLIMBUS_6_TX:
554 case SLIMBUS_7_TX:
555 case SLIMBUS_8_TX:
556 case INT_FM_TX:
557 case VOICE_RECORD_RX:
558 case INT_BT_SCO_TX:
559 case RT_PROXY_PORT_001_TX:
560 case AFE_PORT_ID_PRIMARY_MI2S_TX:
561 case AFE_PORT_ID_SECONDARY_MI2S_TX:
562 case AFE_PORT_ID_TERTIARY_MI2S_TX:
563 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
564 case AFE_PORT_ID_QUINARY_MI2S_TX:
565 case AFE_PORT_ID_SENARY_MI2S_TX:
566 case AFE_PORT_ID_PRIMARY_PCM_TX:
567 case AFE_PORT_ID_SECONDARY_PCM_TX:
568 case AFE_PORT_ID_TERTIARY_PCM_TX:
569 case AFE_PORT_ID_QUATERNARY_PCM_TX:
570 case AFE_PORT_ID_PRIMARY_TDM_TX:
571 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
572 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
573 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
574 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
575 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
576 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
577 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
578 case AFE_PORT_ID_SECONDARY_TDM_TX:
579 case AFE_PORT_ID_SECONDARY_TDM_TX_1:
580 case AFE_PORT_ID_SECONDARY_TDM_TX_2:
581 case AFE_PORT_ID_SECONDARY_TDM_TX_3:
582 case AFE_PORT_ID_SECONDARY_TDM_TX_4:
583 case AFE_PORT_ID_SECONDARY_TDM_TX_5:
584 case AFE_PORT_ID_SECONDARY_TDM_TX_6:
585 case AFE_PORT_ID_SECONDARY_TDM_TX_7:
586 case AFE_PORT_ID_TERTIARY_TDM_TX:
587 case AFE_PORT_ID_TERTIARY_TDM_TX_1:
588 case AFE_PORT_ID_TERTIARY_TDM_TX_2:
589 case AFE_PORT_ID_TERTIARY_TDM_TX_3:
590 case AFE_PORT_ID_TERTIARY_TDM_TX_4:
591 case AFE_PORT_ID_TERTIARY_TDM_TX_5:
592 case AFE_PORT_ID_TERTIARY_TDM_TX_6:
593 case AFE_PORT_ID_TERTIARY_TDM_TX_7:
594 case AFE_PORT_ID_QUATERNARY_TDM_TX:
595 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
596 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
597 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
598 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
599 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
600 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
601 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
602 case AFE_PORT_ID_USB_TX:
603 case AFE_PORT_ID_INT0_MI2S_TX:
604 case AFE_PORT_ID_INT1_MI2S_TX:
605 case AFE_PORT_ID_INT2_MI2S_TX:
606 case AFE_PORT_ID_INT3_MI2S_TX:
607 case AFE_PORT_ID_INT4_MI2S_TX:
608 case AFE_PORT_ID_INT5_MI2S_TX:
609 case AFE_PORT_ID_INT6_MI2S_TX:
610 ret = MSM_AFE_PORT_TYPE_TX;
611 break;
612
613 default:
614 WARN_ON(1);
615 pr_err("%s: Invalid port id = 0x%x\n",
616 __func__, port_id);
617 ret = -EINVAL;
618 }
619
620 return ret;
621}
622
623int afe_sizeof_cfg_cmd(u16 port_id)
624{
625 int ret_size;
626
627 switch (port_id) {
628 case PRIMARY_I2S_RX:
629 case PRIMARY_I2S_TX:
630 case SECONDARY_I2S_RX:
631 case SECONDARY_I2S_TX:
632 case MI2S_RX:
633 case MI2S_TX:
634 case AFE_PORT_ID_PRIMARY_MI2S_RX:
635 case AFE_PORT_ID_PRIMARY_MI2S_TX:
636 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
637 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
638 case AFE_PORT_ID_QUINARY_MI2S_RX:
639 case AFE_PORT_ID_QUINARY_MI2S_TX:
640 ret_size = SIZEOF_CFG_CMD(afe_param_id_i2s_cfg);
641 break;
642 case HDMI_RX:
643 case DISPLAY_PORT_RX:
644 ret_size =
645 SIZEOF_CFG_CMD(afe_param_id_hdmi_multi_chan_audio_cfg);
646 break;
647 case SLIMBUS_0_RX:
648 case SLIMBUS_0_TX:
649 case SLIMBUS_1_RX:
650 case SLIMBUS_1_TX:
651 case SLIMBUS_2_RX:
652 case SLIMBUS_2_TX:
653 case SLIMBUS_3_RX:
654 case SLIMBUS_3_TX:
655 case SLIMBUS_4_RX:
656 case SLIMBUS_4_TX:
657 case SLIMBUS_5_RX:
658 case SLIMBUS_5_TX:
659 case SLIMBUS_6_RX:
660 case SLIMBUS_6_TX:
661 case SLIMBUS_7_RX:
662 case SLIMBUS_7_TX:
663 case SLIMBUS_8_RX:
664 case SLIMBUS_8_TX:
665 ret_size = SIZEOF_CFG_CMD(afe_param_id_slimbus_cfg);
666 break;
667 case VOICE_PLAYBACK_TX:
668 case VOICE2_PLAYBACK_TX:
669 case VOICE_RECORD_RX:
670 case VOICE_RECORD_TX:
671 ret_size = SIZEOF_CFG_CMD(afe_param_id_pseudo_port_cfg);
672 break;
673 case RT_PROXY_PORT_001_RX:
674 case RT_PROXY_PORT_001_TX:
675 ret_size = SIZEOF_CFG_CMD(afe_param_id_rt_proxy_port_cfg);
676 break;
677 case AFE_PORT_ID_USB_RX:
678 case AFE_PORT_ID_USB_TX:
679 ret_size = SIZEOF_CFG_CMD(afe_param_id_usb_audio_cfg);
680 break;
681 case AFE_PORT_ID_PRIMARY_PCM_RX:
682 case AFE_PORT_ID_PRIMARY_PCM_TX:
683 case AFE_PORT_ID_SECONDARY_PCM_RX:
684 case AFE_PORT_ID_SECONDARY_PCM_TX:
685 case AFE_PORT_ID_TERTIARY_PCM_RX:
686 case AFE_PORT_ID_TERTIARY_PCM_TX:
687 case AFE_PORT_ID_QUATERNARY_PCM_RX:
688 case AFE_PORT_ID_QUATERNARY_PCM_TX:
689 default:
690 pr_debug("%s: default case 0x%x\n", __func__, port_id);
691 ret_size = SIZEOF_CFG_CMD(afe_param_id_pcm_cfg);
692 break;
693 }
694 return ret_size;
695}
696
697int afe_q6_interface_prepare(void)
698{
699 int ret = 0;
700
701 pr_debug("%s:\n", __func__);
702
703 if (this_afe.apr == NULL) {
704 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
705 0xFFFFFFFF, &this_afe);
706 if (this_afe.apr == NULL) {
707 pr_err("%s: Unable to register AFE\n", __func__);
708 ret = -ENODEV;
709 }
710 rtac_set_afe_handle(this_afe.apr);
711 }
712 return ret;
713}
714
715/*
716 * afe_apr_send_pkt : returns 0 on success, negative otherwise.
717 */
718static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait)
719{
720 int ret;
721
722 if (wait)
723 atomic_set(&this_afe.state, 1);
724 atomic_set(&this_afe.status, 0);
725 ret = apr_send_pkt(this_afe.apr, data);
726 if (ret > 0) {
727 if (wait) {
728 ret = wait_event_timeout(*wait,
729 (atomic_read(&this_afe.state) == 0),
730 msecs_to_jiffies(TIMEOUT_MS));
731 if (!ret) {
732 ret = -ETIMEDOUT;
733 } else if (atomic_read(&this_afe.status) > 0) {
734 pr_err("%s: DSP returned error[%s]\n", __func__,
735 adsp_err_get_err_str(atomic_read(
736 &this_afe.status)));
737 ret = adsp_err_get_lnx_err_code(
738 atomic_read(&this_afe.status));
739 } else {
740 ret = 0;
741 }
742 } else {
743 ret = 0;
744 }
745 } else if (ret == 0) {
746 pr_err("%s: packet not transmitted\n", __func__);
747 /* apr_send_pkt can return 0 when nothing is transmitted */
748 ret = -EINVAL;
749 }
750
751 pr_debug("%s: leave %d\n", __func__, ret);
752 return ret;
753}
754
755static int afe_send_cal_block(u16 port_id, struct cal_block_data *cal_block)
756{
757 int result = 0;
758 int index = 0;
759 struct afe_audioif_config_command_no_payload afe_cal;
760
761 if (!cal_block) {
762 pr_debug("%s: No AFE cal to send!\n", __func__);
763 result = -EINVAL;
764 goto done;
765 }
766 if (cal_block->cal_data.size <= 0) {
767 pr_debug("%s: AFE cal has invalid size!\n", __func__);
768 result = -EINVAL;
769 goto done;
770 }
771
772 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -0800773 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800774 pr_err("%s: AFE port index[%d] invalid!\n",
775 __func__, index);
776 result = -EINVAL;
777 goto done;
778 }
779
780 afe_cal.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
781 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
782 afe_cal.hdr.pkt_size = sizeof(afe_cal);
783 afe_cal.hdr.src_port = 0;
784 afe_cal.hdr.dest_port = 0;
785 afe_cal.hdr.token = index;
786 afe_cal.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
787 afe_cal.param.port_id = port_id;
788 afe_cal.param.payload_size = cal_block->cal_data.size;
789 afe_cal.param.payload_address_lsw =
790 lower_32_bits(cal_block->cal_data.paddr);
791 afe_cal.param.payload_address_msw =
792 msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
793 afe_cal.param.mem_map_handle = cal_block->map_data.q6map_handle;
794
795 pr_debug("%s: AFE cal sent for device port = 0x%x, cal size = %zd, cal addr = 0x%pK\n",
796 __func__, port_id,
797 cal_block->cal_data.size, &cal_block->cal_data.paddr);
798
799 result = afe_apr_send_pkt(&afe_cal, &this_afe.wait[index]);
800 if (result)
801 pr_err("%s: AFE cal for port 0x%x failed %d\n",
802 __func__, port_id, result);
803
804done:
805 return result;
806}
807
808
809static int afe_send_custom_topology_block(struct cal_block_data *cal_block)
810{
811 int result = 0;
812 int index = 0;
813 struct cmd_set_topologies afe_cal;
814
815 if (!cal_block) {
816 pr_err("%s: No AFE SVC cal to send!\n", __func__);
817 return -EINVAL;
818 }
819 if (cal_block->cal_data.size <= 0) {
820 pr_err("%s: AFE SVC cal has invalid size: %zd!\n",
821 __func__, cal_block->cal_data.size);
822 return -EINVAL;
823 }
824
825 afe_cal.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
826 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
827 afe_cal.hdr.pkt_size = sizeof(afe_cal);
828 afe_cal.hdr.src_port = 0;
829 afe_cal.hdr.dest_port = 0;
830 afe_cal.hdr.token = index;
831 afe_cal.hdr.opcode = AFE_CMD_ADD_TOPOLOGIES;
832
833 afe_cal.payload_size = cal_block->cal_data.size;
834 afe_cal.payload_addr_lsw =
835 lower_32_bits(cal_block->cal_data.paddr);
836 afe_cal.payload_addr_msw =
837 msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
838 afe_cal.mem_map_handle = cal_block->map_data.q6map_handle;
839
840 pr_debug("%s:cmd_id:0x%x calsize:%zd memmap_hdl:0x%x caladdr:0x%pK",
841 __func__, AFE_CMD_ADD_TOPOLOGIES, cal_block->cal_data.size,
842 afe_cal.mem_map_handle, &cal_block->cal_data.paddr);
843
844 result = afe_apr_send_pkt(&afe_cal, &this_afe.wait[index]);
845 if (result)
846 pr_err("%s: AFE send topology for command 0x%x failed %d\n",
847 __func__, AFE_CMD_ADD_TOPOLOGIES, result);
848
849 return result;
850}
851
852static void afe_send_custom_topology(void)
853{
854 struct cal_block_data *cal_block = NULL;
855 int cal_index = AFE_CUST_TOPOLOGY_CAL;
856 int ret;
857
858 if (this_afe.cal_data[cal_index] == NULL) {
859 pr_err("%s: cal_index %d not allocated!\n",
860 __func__, cal_index);
861 return;
862 }
863 mutex_lock(&this_afe.cal_data[cal_index]->lock);
864
865 if (!this_afe.set_custom_topology)
866 goto unlock;
867 this_afe.set_custom_topology = 0;
868 cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]);
869 if (cal_block == NULL) {
870 pr_err("%s cal_block not found!!\n", __func__);
871 goto unlock;
872 }
873
874 pr_debug("%s: Sending cal_index cal %d\n", __func__, cal_index);
875
876 ret = remap_cal_data(cal_block, cal_index);
877 if (ret) {
878 pr_err("%s: Remap_cal_data failed for cal %d!\n",
879 __func__, cal_index);
880 goto unlock;
881 }
882 ret = afe_send_custom_topology_block(cal_block);
883 if (ret < 0) {
884 pr_err("%s: No cal sent for cal_index %d! ret %d\n",
885 __func__, cal_index, ret);
886 goto unlock;
887 }
888 pr_debug("%s:sent custom topology for AFE\n", __func__);
889unlock:
890 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
891}
892
893static int afe_spk_ramp_dn_cfg(int port)
894{
895 int ret = -EINVAL;
896 int index = 0;
897 struct afe_spkr_prot_config_command config;
898
899 if (afe_get_port_type(port) != MSM_AFE_PORT_TYPE_RX) {
900 pr_debug("%s: port doesn't match 0x%x\n", __func__, port);
901 return 0;
902 }
903 if (this_afe.prot_cfg.mode == MSM_SPKR_PROT_DISABLED ||
904 (this_afe.vi_rx_port != port)) {
905 pr_debug("%s: spkr protection disabled port 0x%x %d 0x%x\n",
906 __func__, port, ret, this_afe.vi_rx_port);
907 return 0;
908 }
909 memset(&config, 0, sizeof(config));
910 ret = q6audio_validate_port(port);
911 if (ret < 0) {
912 pr_err("%s: Invalid port 0x%x ret %d", __func__, port, ret);
913 ret = -EINVAL;
914 goto fail_cmd;
915 }
916 index = q6audio_get_port_index(port);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -0800917 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800918 pr_err("%s: AFE port index[%d] invalid!\n",
919 __func__, index);
920 ret = -EINVAL;
921 goto fail_cmd;
922 }
923 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
924 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
925 config.hdr.pkt_size = sizeof(config);
926 config.hdr.src_port = 0;
927 config.hdr.dest_port = 0;
928 config.hdr.token = index;
929
930 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
931 config.param.port_id = q6audio_get_port_id(port);
932 config.param.payload_size =
933 sizeof(config) - sizeof(config.hdr) - sizeof(config.param)
934 - sizeof(config.prot_config);
935 config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX;
936 config.pdata.param_id = AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG;
937 config.pdata.param_size = 0;
938 atomic_set(&this_afe.state, 1);
939 atomic_set(&this_afe.status, 0);
940 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config);
941 if (ret < 0) {
942 pr_err("%s: port = 0x%x param = 0x%x failed %d\n",
943 __func__, port, config.pdata.param_id, ret);
944 goto fail_cmd;
945 }
946 ret = wait_event_timeout(this_afe.wait[index],
947 (atomic_read(&this_afe.state) == 0),
948 msecs_to_jiffies(TIMEOUT_MS));
949 if (!ret) {
950 pr_err("%s: wait_event timeout\n", __func__);
951 ret = -EINVAL;
952 goto fail_cmd;
953 }
954 if (atomic_read(&this_afe.status) > 0) {
955 pr_err("%s: config cmd failed [%s]\n",
956 __func__, adsp_err_get_err_str(
957 atomic_read(&this_afe.status)));
958 ret = adsp_err_get_lnx_err_code(
959 atomic_read(&this_afe.status));
960 goto fail_cmd;
961 }
962 /* dsp needs atleast 15ms to ramp down pilot tone*/
963 usleep_range(15000, 15010);
964 ret = 0;
965fail_cmd:
966 pr_debug("%s: config.pdata.param_id 0x%x status %d\n",
967 __func__, config.pdata.param_id, ret);
968return ret;
969}
970
971static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id,
972 union afe_spkr_prot_config *prot_config)
973{
974 int ret = -EINVAL;
975 int index = 0;
976 struct afe_spkr_prot_config_command config;
977
978 memset(&config, 0, sizeof(config));
979 if (!prot_config) {
980 pr_err("%s: Invalid params\n", __func__);
981 goto fail_cmd;
982 }
983 ret = q6audio_validate_port(src_port);
984 if (ret < 0) {
985 pr_err("%s: Invalid src port 0x%x ret %d",
986 __func__, src_port, ret);
987 ret = -EINVAL;
988 goto fail_cmd;
989 }
990 ret = q6audio_validate_port(dst_port);
991 if (ret < 0) {
992 pr_err("%s: Invalid dst port 0x%x ret %d", __func__,
993 dst_port, ret);
994 ret = -EINVAL;
995 goto fail_cmd;
996 }
997 index = q6audio_get_port_index(src_port);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -0800998 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800999 pr_err("%s: AFE port index[%d] invalid!\n",
1000 __func__, index);
1001 ret = -EINVAL;
1002 goto fail_cmd;
1003 }
1004 switch (param_id) {
1005 case AFE_PARAM_ID_FBSP_MODE_RX_CFG:
1006 config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX;
1007 break;
1008 case AFE_PARAM_ID_FEEDBACK_PATH_CFG:
1009 this_afe.vi_tx_port = src_port;
1010 this_afe.vi_rx_port = dst_port;
1011 config.pdata.module_id = AFE_MODULE_FEEDBACK;
1012 break;
1013 /*
1014 * AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2 is same as
1015 * AFE_PARAM_ID_SP_V2_TH_VI_MODE_CFG
1016 */
1017 case AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2:
1018 case AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG:
1019 config.pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI;
1020 break;
1021 case AFE_PARAM_ID_SP_V2_EX_VI_MODE_CFG:
1022 case AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG:
1023 config.pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI;
1024 break;
1025 default:
1026 pr_err("%s: default case 0x%x\n", __func__, param_id);
1027 goto fail_cmd;
1028 }
1029
1030 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1031 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1032 config.hdr.pkt_size = sizeof(config);
1033 config.hdr.src_port = 0;
1034 config.hdr.dest_port = 0;
1035 config.hdr.token = index;
1036
1037 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
1038 config.param.port_id = q6audio_get_port_id(src_port);
1039 config.param.payload_size = sizeof(config) - sizeof(config.hdr)
1040 - sizeof(config.param);
1041 config.pdata.param_id = param_id;
1042 config.pdata.param_size = sizeof(config.prot_config);
1043 config.prot_config = *prot_config;
1044 atomic_set(&this_afe.state, 1);
1045 atomic_set(&this_afe.status, 0);
1046 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config);
1047 if (ret < 0) {
1048 pr_err("%s: port = 0x%x param = 0x%x failed %d\n",
1049 __func__, src_port, param_id, ret);
1050 goto fail_cmd;
1051 }
1052 ret = wait_event_timeout(this_afe.wait[index],
1053 (atomic_read(&this_afe.state) == 0),
1054 msecs_to_jiffies(TIMEOUT_MS));
1055 if (!ret) {
1056 pr_err("%s: wait_event timeout\n", __func__);
1057 ret = -EINVAL;
1058 goto fail_cmd;
1059 }
1060 if (atomic_read(&this_afe.status) > 0) {
1061 pr_err("%s: config cmd failed [%s]\n",
1062 __func__, adsp_err_get_err_str(
1063 atomic_read(&this_afe.status)));
1064 ret = adsp_err_get_lnx_err_code(
1065 atomic_read(&this_afe.status));
1066 goto fail_cmd;
1067 }
1068 ret = 0;
1069fail_cmd:
1070 pr_debug("%s: config.pdata.param_id 0x%x status %d 0x%x\n",
1071 __func__, config.pdata.param_id, ret, src_port);
1072 return ret;
1073}
1074
1075static void afe_send_cal_spkr_prot_tx(int port_id)
1076{
1077 union afe_spkr_prot_config afe_spk_config;
1078
1079 if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL ||
1080 this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL ||
1081 this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL)
1082 return;
1083
1084 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
1085 if ((this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED) &&
1086 (this_afe.vi_tx_port == port_id)) {
1087 if (this_afe.prot_cfg.mode ==
1088 MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) {
1089 afe_spk_config.vi_proc_cfg.operation_mode =
1090 Q6AFE_MSM_SPKR_CALIBRATION;
1091 afe_spk_config.vi_proc_cfg.quick_calib_flag =
1092 this_afe.prot_cfg.quick_calib_flag;
1093 } else {
1094 afe_spk_config.vi_proc_cfg.operation_mode =
1095 Q6AFE_MSM_SPKR_PROCESSING;
1096 }
1097
1098 if (this_afe.th_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE)
1099 afe_spk_config.vi_proc_cfg.operation_mode =
1100 Q6AFE_MSM_SPKR_FTM_MODE;
1101 afe_spk_config.vi_proc_cfg.minor_version = 1;
1102 afe_spk_config.vi_proc_cfg.r0_cali_q24[SP_V2_SPKR_1] =
1103 (uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_1];
1104 afe_spk_config.vi_proc_cfg.r0_cali_q24[SP_V2_SPKR_2] =
1105 (uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_2];
1106 afe_spk_config.vi_proc_cfg.t0_cali_q6[SP_V2_SPKR_1] =
1107 (uint32_t) this_afe.prot_cfg.t0[SP_V2_SPKR_1];
1108 afe_spk_config.vi_proc_cfg.t0_cali_q6[SP_V2_SPKR_2] =
1109 (uint32_t) this_afe.prot_cfg.t0[SP_V2_SPKR_2];
1110 if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_NOT_CALIBRATED) {
1111 struct asm_spkr_calib_vi_proc_cfg *vi_proc_cfg;
1112
1113 vi_proc_cfg = &afe_spk_config.vi_proc_cfg;
1114 vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_1] =
1115 USE_CALIBRATED_R0TO;
1116 vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_2] =
1117 USE_CALIBRATED_R0TO;
1118 } else {
1119 struct asm_spkr_calib_vi_proc_cfg *vi_proc_cfg;
1120
1121 vi_proc_cfg = &afe_spk_config.vi_proc_cfg;
1122 vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_1] =
1123 USE_SAFE_R0TO;
1124 vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_2] =
1125 USE_SAFE_R0TO;
1126 }
1127 if (afe_spk_prot_prepare(port_id, 0,
1128 AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2,
1129 &afe_spk_config))
1130 pr_err("%s: SPKR_CALIB_VI_PROC_CFG failed\n",
1131 __func__);
1132 }
1133 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
1134
1135 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
1136 if ((this_afe.th_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) &&
1137 (this_afe.vi_tx_port == port_id)) {
1138 afe_spk_config.th_vi_ftm_cfg.minor_version = 1;
1139 afe_spk_config.th_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_1] =
1140 this_afe.th_ftm_cfg.wait_time[SP_V2_SPKR_1];
1141 afe_spk_config.th_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_2] =
1142 this_afe.th_ftm_cfg.wait_time[SP_V2_SPKR_2];
1143 afe_spk_config.th_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_1] =
1144 this_afe.th_ftm_cfg.ftm_time[SP_V2_SPKR_1];
1145 afe_spk_config.th_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_2] =
1146 this_afe.th_ftm_cfg.ftm_time[SP_V2_SPKR_2];
1147
1148 if (afe_spk_prot_prepare(port_id, 0,
1149 AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG,
1150 &afe_spk_config))
1151 pr_err("%s: th vi ftm cfg failed\n", __func__);
1152 this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED;
1153 }
1154 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
1155
1156 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
1157 if ((this_afe.ex_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) &&
1158 (this_afe.vi_tx_port == port_id)) {
1159 afe_spk_config.ex_vi_mode_cfg.minor_version = 1;
1160 afe_spk_config.ex_vi_mode_cfg.operation_mode =
1161 Q6AFE_MSM_SPKR_FTM_MODE;
1162 if (afe_spk_prot_prepare(port_id, 0,
1163 AFE_PARAM_ID_SP_V2_EX_VI_MODE_CFG,
1164 &afe_spk_config))
1165 pr_err("%s: ex vi mode cfg failed\n", __func__);
1166
1167 afe_spk_config.ex_vi_ftm_cfg.minor_version = 1;
1168 afe_spk_config.ex_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_1] =
1169 this_afe.ex_ftm_cfg.wait_time[SP_V2_SPKR_1];
1170 afe_spk_config.ex_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_2] =
1171 this_afe.ex_ftm_cfg.wait_time[SP_V2_SPKR_2];
1172 afe_spk_config.ex_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_1] =
1173 this_afe.ex_ftm_cfg.ftm_time[SP_V2_SPKR_1];
1174 afe_spk_config.ex_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_2] =
1175 this_afe.ex_ftm_cfg.ftm_time[SP_V2_SPKR_2];
1176
1177 if (afe_spk_prot_prepare(port_id, 0,
1178 AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG,
1179 &afe_spk_config))
1180 pr_err("%s: ex vi ftm cfg failed\n", __func__);
1181 this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED;
1182 }
1183 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
1184
1185}
1186
1187static void afe_send_cal_spkr_prot_rx(int port_id)
1188{
1189 union afe_spkr_prot_config afe_spk_config;
1190
1191 if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL)
1192 goto done;
1193
1194 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
1195
1196 if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED &&
1197 (this_afe.vi_rx_port == port_id)) {
1198 if (this_afe.prot_cfg.mode ==
1199 MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS)
1200 afe_spk_config.mode_rx_cfg.mode =
1201 Q6AFE_MSM_SPKR_CALIBRATION;
1202 else
1203 afe_spk_config.mode_rx_cfg.mode =
1204 Q6AFE_MSM_SPKR_PROCESSING;
1205 afe_spk_config.mode_rx_cfg.minor_version = 1;
1206 if (afe_spk_prot_prepare(port_id, 0,
1207 AFE_PARAM_ID_FBSP_MODE_RX_CFG,
1208 &afe_spk_config))
1209 pr_err("%s: RX MODE_VI_PROC_CFG failed\n",
1210 __func__);
1211 }
1212 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
1213done:
1214 return;
1215}
1216
1217static int afe_send_hw_delay(u16 port_id, u32 rate)
1218{
1219 struct audio_cal_hw_delay_entry delay_entry;
1220 struct afe_audioif_config_command config;
1221 int index = 0;
1222 int ret = -EINVAL;
1223
1224 pr_debug("%s:\n", __func__);
1225
Xiaoyu Yed3650382017-02-02 12:58:01 -08001226 memset(&delay_entry, 0, sizeof(delay_entry));
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001227 delay_entry.sample_rate = rate;
1228 if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX)
1229 ret = afe_get_cal_hw_delay(TX_DEVICE, &delay_entry);
1230 else if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX)
1231 ret = afe_get_cal_hw_delay(RX_DEVICE, &delay_entry);
1232
1233 /*
1234 * HW delay is only used for IMS calls to sync audio with video
1235 * It is only needed for devices & sample rates used for IMS video
1236 * calls. Values are received from ACDB calbration files
1237 */
1238 if (ret != 0) {
1239 pr_debug("%s: debug: HW delay info not available %d\n",
1240 __func__, ret);
1241 goto fail_cmd;
1242 }
1243
1244 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08001245 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001246 pr_err("%s: AFE port index[%d] invalid!\n",
1247 __func__, index);
1248 ret = -EINVAL;
1249 goto fail_cmd;
1250 }
1251
1252 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1253 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1254 config.hdr.pkt_size = sizeof(config);
1255 config.hdr.src_port = 0;
1256 config.hdr.dest_port = 0;
1257 config.hdr.token = index;
1258
1259 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
1260 config.param.port_id = q6audio_get_port_id(port_id);
1261 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
1262 sizeof(config.param);
1263 config.param.payload_address_lsw = 0x00;
1264 config.param.payload_address_msw = 0x00;
1265 config.param.mem_map_handle = 0x00;
1266 config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
1267 config.pdata.param_id = AFE_PARAM_ID_DEVICE_HW_DELAY;
1268 config.pdata.param_size = sizeof(config.port);
1269
1270 config.port.hw_delay.delay_in_us = delay_entry.delay_usec;
1271 config.port.hw_delay.device_hw_delay_minor_version =
1272 AFE_API_VERSION_DEVICE_HW_DELAY;
1273
1274 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
1275 if (ret) {
1276 pr_err("%s: AFE hw delay for port 0x%x failed %d\n",
1277 __func__, port_id, ret);
1278 goto fail_cmd;
1279 }
1280
1281fail_cmd:
1282 pr_debug("%s: port_id 0x%x rate %u delay_usec %d status %d\n",
1283 __func__, port_id, rate, delay_entry.delay_usec, ret);
1284 return ret;
1285}
1286
1287static struct cal_block_data *afe_find_cal_topo_id_by_port(
1288 struct cal_type_data *cal_type, u16 port_id)
1289{
1290 struct list_head *ptr, *next;
1291 struct cal_block_data *cal_block = NULL;
1292 int32_t path;
1293 struct audio_cal_info_afe_top *afe_top;
Siena Richard23364c92017-01-11 16:20:55 -08001294 int afe_port_index = q6audio_get_port_index(port_id);
1295
1296 if (afe_port_index < 0)
1297 goto err_exit;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001298
1299 list_for_each_safe(ptr, next,
1300 &cal_type->cal_blocks) {
1301 cal_block = list_entry(ptr,
1302 struct cal_block_data, list);
1303
1304 path = ((afe_get_port_type(port_id) ==
1305 MSM_AFE_PORT_TYPE_TX)?(TX_DEVICE):(RX_DEVICE));
1306 afe_top =
1307 (struct audio_cal_info_afe_top *)cal_block->cal_info;
Vidyakumar Athota6ca5f292017-02-13 17:02:58 -08001308 if (afe_top->path == path) {
1309 if (this_afe.dev_acdb_id[afe_port_index] > 0) {
1310 if (afe_top->acdb_id ==
1311 this_afe.dev_acdb_id[afe_port_index]) {
1312 pr_debug("%s: top_id:%x acdb_id:%d afe_port_id:%d\n",
1313 __func__, afe_top->topology,
1314 afe_top->acdb_id,
1315 q6audio_get_port_id(port_id));
1316 return cal_block;
1317 }
1318 } else {
1319 pr_debug("%s: top_id:%x acdb_id:%d afe_port:%d\n",
Siena Richard23364c92017-01-11 16:20:55 -08001320 __func__, afe_top->topology, afe_top->acdb_id,
1321 q6audio_get_port_id(port_id));
Vidyakumar Athota6ca5f292017-02-13 17:02:58 -08001322 return cal_block;
1323 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001324 }
1325 }
Siena Richard23364c92017-01-11 16:20:55 -08001326
1327err_exit:
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001328 return NULL;
1329}
1330
1331static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id)
1332{
1333 int ret = 0;
1334
1335 struct cal_block_data *cal_block = NULL;
1336 struct audio_cal_info_afe_top *afe_top_info = NULL;
1337
1338 if (this_afe.cal_data[AFE_TOPOLOGY_CAL] == NULL) {
1339 pr_err("%s: [AFE_TOPOLOGY_CAL] not initialized\n", __func__);
1340 return -EINVAL;
1341 }
1342 if (topology_id == NULL) {
1343 pr_err("%s: topology_id is NULL\n", __func__);
1344 return -EINVAL;
1345 }
1346 *topology_id = 0;
1347
1348 mutex_lock(&this_afe.cal_data[AFE_TOPOLOGY_CAL]->lock);
1349 cal_block = afe_find_cal_topo_id_by_port(
1350 this_afe.cal_data[AFE_TOPOLOGY_CAL], port_id);
1351 if (cal_block == NULL) {
1352 pr_err("%s: [AFE_TOPOLOGY_CAL] not initialized for this port %d\n",
1353 __func__, port_id);
1354 ret = -EINVAL;
1355 goto unlock;
1356 }
1357
1358 afe_top_info = ((struct audio_cal_info_afe_top *)
1359 cal_block->cal_info);
1360 if (!afe_top_info->topology) {
1361 pr_err("%s: invalid topology id : [%d, %d]\n",
1362 __func__, afe_top_info->acdb_id, afe_top_info->topology);
1363 ret = -EINVAL;
1364 goto unlock;
1365 }
1366 *topology_id = (u32)afe_top_info->topology;
1367
1368 pr_debug("%s: port_id = %u acdb_id = %d topology_id = %u ret=%d\n",
1369 __func__, port_id, afe_top_info->acdb_id,
1370 afe_top_info->topology, ret);
1371unlock:
1372 mutex_unlock(&this_afe.cal_data[AFE_TOPOLOGY_CAL]->lock);
1373 return ret;
1374}
1375
1376static int afe_send_port_topology_id(u16 port_id)
1377{
1378 struct afe_audioif_config_command config;
1379 int index = 0;
1380 int ret = 0;
1381 u32 topology_id = 0;
1382
1383 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08001384 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001385 pr_err("%s: AFE port index[%d] invalid!\n",
1386 __func__, index);
1387 return -EINVAL;
1388 }
1389
1390 ret = afe_get_cal_topology_id(port_id, &topology_id);
1391 if (ret || !topology_id) {
1392 pr_debug("%s: AFE port[%d] get_cal_topology[%d] invalid!\n",
1393 __func__, port_id, topology_id);
1394 goto done;
1395 }
1396
1397 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1398 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1399 config.hdr.pkt_size = sizeof(config);
1400 config.hdr.src_port = 0;
1401 config.hdr.dest_port = 0;
1402 config.hdr.token = index;
1403
1404 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
1405 config.param.port_id = q6audio_get_port_id(port_id);
1406 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
1407 sizeof(config.param);
1408 config.param.payload_address_lsw = 0x00;
1409 config.param.payload_address_msw = 0x00;
1410 config.param.mem_map_handle = 0x00;
1411 config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
1412 config.pdata.param_id = AFE_PARAM_ID_SET_TOPOLOGY;
1413 config.pdata.param_size = sizeof(config.port);
1414 config.port.topology.minor_version = AFE_API_VERSION_TOPOLOGY_V1;
1415 config.port.topology.topology_id = topology_id;
1416
1417 pr_debug("%s: param PL size=%d iparam_size[%d][%zd %zd %zd %zd] param_id[0x%x]\n",
1418 __func__, config.param.payload_size, config.pdata.param_size,
1419 sizeof(config), sizeof(config.param), sizeof(config.port),
1420 sizeof(struct apr_hdr), config.pdata.param_id);
1421
1422 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
1423 if (ret) {
1424 pr_err("%s: AFE set topology id enable for port 0x%x failed %d\n",
1425 __func__, port_id, ret);
1426 goto done;
1427 }
1428
1429 this_afe.topology[index] = topology_id;
Vidyakumar Athota69ece6b2017-02-02 17:29:19 -08001430 rtac_update_afe_topology(port_id);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001431done:
1432 pr_debug("%s: AFE set topology id 0x%x enable for port 0x%x ret %d\n",
1433 __func__, topology_id, port_id, ret);
1434 return ret;
1435
1436}
1437
1438static int remap_cal_data(struct cal_block_data *cal_block, int cal_index)
1439{
1440 int ret = 0;
1441
1442 if (cal_block->map_data.ion_client == NULL) {
1443 pr_err("%s: No ION allocation for cal index %d!\n",
1444 __func__, cal_index);
1445 ret = -EINVAL;
1446 goto done;
1447 }
1448
1449 if ((cal_block->map_data.map_size > 0) &&
1450 (cal_block->map_data.q6map_handle == 0)) {
1451 atomic_set(&this_afe.mem_map_cal_index, cal_index);
1452 ret = afe_cmd_memory_map(cal_block->cal_data.paddr,
1453 cal_block->map_data.map_size);
1454 atomic_set(&this_afe.mem_map_cal_index, -1);
1455 if (ret < 0) {
1456 pr_err("%s: mmap did not work! size = %zd ret %d\n",
1457 __func__,
1458 cal_block->map_data.map_size, ret);
1459 pr_debug("%s: mmap did not work! addr = 0x%pK, size = %zd\n",
1460 __func__,
1461 &cal_block->cal_data.paddr,
1462 cal_block->map_data.map_size);
1463 goto done;
1464 }
1465 cal_block->map_data.q6map_handle = atomic_read(&this_afe.
1466 mem_map_cal_handles[cal_index]);
1467 }
1468done:
1469 return ret;
1470}
1471
Siena Richard23364c92017-01-11 16:20:55 -08001472static struct cal_block_data *afe_find_cal(int cal_index, int port_id)
1473{
1474 struct list_head *ptr, *next;
1475 struct cal_block_data *cal_block = NULL;
1476 struct audio_cal_info_afe *afe_cal_info = NULL;
1477 int afe_port_index = q6audio_get_port_index(port_id);
1478
1479 pr_debug("%s: cal_index %d port_id %d port_index %d\n", __func__,
1480 cal_index, port_id, afe_port_index);
1481 if (afe_port_index < 0) {
1482 pr_err("%s: Error getting AFE port index %d\n",
1483 __func__, afe_port_index);
1484 goto exit;
1485 }
1486
1487 list_for_each_safe(ptr, next,
1488 &this_afe.cal_data[cal_index]->cal_blocks) {
1489 cal_block = list_entry(ptr, struct cal_block_data, list);
1490 afe_cal_info = cal_block->cal_info;
1491 if ((afe_cal_info->acdb_id ==
1492 this_afe.dev_acdb_id[afe_port_index]) &&
1493 (afe_cal_info->sample_rate ==
1494 this_afe.afe_sample_rates[afe_port_index])) {
1495 pr_debug("%s: cal block is a match, size is %zd\n",
1496 __func__, cal_block->cal_data.size);
1497 goto exit;
1498 }
1499 }
1500 pr_err("%s: no matching cal_block found\n", __func__);
1501 cal_block = NULL;
1502
1503exit:
1504 return cal_block;
1505}
1506
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001507static void send_afe_cal_type(int cal_index, int port_id)
1508{
1509 struct cal_block_data *cal_block = NULL;
1510 int ret;
Vidyakumar Athota6ca5f292017-02-13 17:02:58 -08001511 int afe_port_index = q6audio_get_port_index(port_id);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001512
1513 pr_debug("%s:\n", __func__);
1514
1515 if (this_afe.cal_data[cal_index] == NULL) {
1516 pr_warn("%s: cal_index %d not allocated!\n",
1517 __func__, cal_index);
1518 goto done;
1519 }
1520
Vidyakumar Athota6ca5f292017-02-13 17:02:58 -08001521 if (afe_port_index < 0) {
1522 pr_err("%s: Error getting AFE port index %d\n",
1523 __func__, afe_port_index);
1524 goto done;
1525 }
1526
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001527 mutex_lock(&this_afe.cal_data[cal_index]->lock);
Siena Richard23364c92017-01-11 16:20:55 -08001528
Vidyakumar Athota6ca5f292017-02-13 17:02:58 -08001529 if (((cal_index == AFE_COMMON_RX_CAL) ||
1530 (cal_index == AFE_COMMON_TX_CAL)) &&
1531 (this_afe.dev_acdb_id[afe_port_index] > 0))
Siena Richard23364c92017-01-11 16:20:55 -08001532 cal_block = afe_find_cal(cal_index, port_id);
1533 else
1534 cal_block = cal_utils_get_only_cal_block(
1535 this_afe.cal_data[cal_index]);
1536
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001537 if (cal_block == NULL) {
1538 pr_err("%s cal_block not found!!\n", __func__);
1539 goto unlock;
1540 }
1541
1542 pr_debug("%s: Sending cal_index cal %d\n", __func__, cal_index);
1543
1544 ret = remap_cal_data(cal_block, cal_index);
1545 if (ret) {
1546 pr_err("%s: Remap_cal_data failed for cal %d!\n",
1547 __func__, cal_index);
1548 goto unlock;
1549 }
1550 ret = afe_send_cal_block(port_id, cal_block);
1551 if (ret < 0)
1552 pr_debug("%s: No cal sent for cal_index %d, port_id = 0x%x! ret %d\n",
1553 __func__, cal_index, port_id, ret);
1554unlock:
1555 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
1556done:
1557 return;
1558}
1559
1560void afe_send_cal(u16 port_id)
1561{
1562 pr_debug("%s: port_id=0x%x\n", __func__, port_id);
1563
1564 if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX) {
1565 afe_send_cal_spkr_prot_tx(port_id);
1566 send_afe_cal_type(AFE_COMMON_TX_CAL, port_id);
1567 } else if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) {
1568 afe_send_cal_spkr_prot_rx(port_id);
1569 send_afe_cal_type(AFE_COMMON_RX_CAL, port_id);
1570 }
1571}
1572
1573int afe_turn_onoff_hw_mad(u16 mad_type, u16 enable)
1574{
1575 int ret;
1576 struct afe_cmd_hw_mad_ctrl config;
1577
1578 pr_debug("%s: enter\n", __func__);
1579 memset(&config, 0, sizeof(config));
1580 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1581 APR_HDR_LEN(APR_HDR_SIZE),
1582 APR_PKT_VER);
1583 config.hdr.pkt_size = sizeof(config);
1584 config.hdr.src_port = 0;
1585 config.hdr.dest_port = 0;
1586 config.hdr.token = IDX_GLOBAL_CFG;
1587 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
1588 config.param.port_id = SLIMBUS_5_TX;
1589 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
1590 sizeof(config.param);
1591 config.param.payload_address_lsw = 0x00;
1592 config.param.payload_address_msw = 0x00;
1593 config.param.mem_map_handle = 0x00;
1594 config.pdata.module_id = AFE_MODULE_HW_MAD;
1595 config.pdata.param_id = AFE_PARAM_ID_HW_MAD_CTRL;
1596 config.pdata.param_size = sizeof(config.payload);
1597 config.payload.minor_version = 1;
1598 config.payload.mad_type = mad_type;
1599 config.payload.mad_enable = enable;
1600
1601 ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
1602 if (ret)
1603 pr_err("%s: AFE_PARAM_ID_HW_MAD_CTRL failed %d\n", __func__,
1604 ret);
1605 return ret;
1606}
1607
1608static int afe_send_slimbus_slave_cfg(
1609 struct afe_param_cdc_slimbus_slave_cfg *sb_slave_cfg)
1610{
1611 int ret;
1612 struct afe_svc_cmd_sb_slave_cfg config;
1613
1614 pr_debug("%s: enter\n", __func__);
1615
1616 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1617 APR_HDR_LEN(APR_HDR_SIZE),
1618 APR_PKT_VER);
1619 config.hdr.pkt_size = sizeof(config);
1620 config.hdr.src_port = 0;
1621 config.hdr.dest_port = 0;
1622 config.hdr.token = IDX_GLOBAL_CFG;
1623 config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
1624 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
1625 sizeof(config.param);
1626 config.param.payload_address_lsw = 0x00;
1627 config.param.payload_address_msw = 0x00;
1628 config.param.mem_map_handle = 0x00;
1629 config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG;
1630 config.pdata.param_id = AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG;
1631 config.pdata.param_size =
1632 sizeof(struct afe_param_cdc_slimbus_slave_cfg);
1633 config.sb_slave_cfg = *sb_slave_cfg;
1634
1635 ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
1636 if (ret)
1637 pr_err("%s: AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG failed %d\n",
1638 __func__, ret);
1639
1640 pr_debug("%s: leave %d\n", __func__, ret);
1641 return ret;
1642}
1643
1644static int afe_send_codec_reg_page_config(
1645 struct afe_param_cdc_reg_page_cfg *cdc_reg_page_cfg)
1646{
1647 struct afe_svc_cmd_cdc_reg_page_cfg config;
1648 int ret;
1649
1650 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1651 APR_HDR_LEN(APR_HDR_SIZE),
1652 APR_PKT_VER);
1653 config.hdr.pkt_size = sizeof(config);
1654 config.hdr.src_port = 0;
1655 config.hdr.dest_port = 0;
1656 config.hdr.token = IDX_GLOBAL_CFG;
1657 config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
1658 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
1659 sizeof(config.param);
1660 config.param.payload_address_lsw = 0x00;
1661 config.param.payload_address_msw = 0x00;
1662 config.param.mem_map_handle = 0x00;
1663 config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG;
1664 config.pdata.param_id = AFE_PARAM_ID_CDC_REG_PAGE_CFG;
1665 config.pdata.param_size =
1666 sizeof(struct afe_param_cdc_reg_page_cfg);
1667 config.cdc_reg_page_cfg = *cdc_reg_page_cfg;
1668
1669 ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
1670 if (ret)
1671 pr_err("%s: AFE_PARAM_ID_CDC_REG_PAGE_CFG failed %d\n",
1672 __func__, ret);
1673
1674 return ret;
1675}
1676
1677static int afe_send_codec_reg_config(
1678 struct afe_param_cdc_reg_cfg_data *cdc_reg_cfg)
1679{
1680 int i, j, ret = -EINVAL;
1681 int pkt_size, payload_size, reg_per_pkt, num_pkts, num_regs;
1682 struct afe_svc_cmd_cdc_reg_cfg *config;
1683 struct afe_svc_cmd_set_param *param;
1684
1685 reg_per_pkt = (APR_MAX_BUF - sizeof(*config)) /
1686 sizeof(struct afe_param_cdc_reg_cfg_payload);
1687 if (reg_per_pkt > 0) {
1688 num_pkts = (cdc_reg_cfg->num_registers / reg_per_pkt) +
1689 (cdc_reg_cfg->num_registers % reg_per_pkt == 0 ? 0 : 1);
1690 } else {
1691 pr_err("%s: Failed to build codec reg config APR packet\n",
1692 __func__);
1693 return -EINVAL;
1694 }
1695
1696 for (j = 0; j < num_pkts; ++j) {
1697 /*
1698 * num_regs is set to reg_per_pkt on each pass through the loop
1699 * except the last, when it is set to the number of registers
1700 * remaining from the total
1701 */
1702 num_regs = (j < (num_pkts - 1) ? reg_per_pkt :
1703 cdc_reg_cfg->num_registers - (reg_per_pkt * j));
1704 payload_size = sizeof(struct afe_param_cdc_reg_cfg_payload) *
1705 num_regs;
1706 pkt_size = sizeof(*config) + payload_size;
1707 pr_debug("%s: pkt_size %d, payload_size %d\n", __func__,
1708 pkt_size, payload_size);
1709 config = kzalloc(pkt_size, GFP_KERNEL);
1710 if (!config)
1711 return -ENOMEM;
1712
1713 config->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1714 APR_HDR_LEN(APR_HDR_SIZE),
1715 APR_PKT_VER);
1716 config->hdr.pkt_size = pkt_size;
1717 config->hdr.src_port = 0;
1718 config->hdr.dest_port = 0;
1719 config->hdr.token = IDX_GLOBAL_CFG;
1720 config->hdr.opcode = AFE_SVC_CMD_SET_PARAM;
1721
1722 param = &config->param;
1723 param->payload_size = payload_size;
1724 param->payload_address_lsw = 0x00;
1725 param->payload_address_msw = 0x00;
1726 param->mem_map_handle = 0x00;
1727
1728 for (i = 0; i < num_regs; i++) {
1729 config->reg_data[i].common.module_id =
1730 AFE_MODULE_CDC_DEV_CFG;
1731 config->reg_data[i].common.param_id =
1732 AFE_PARAM_ID_CDC_REG_CFG;
1733 config->reg_data[i].common.param_size =
1734 sizeof(config->reg_data[i].reg_cfg);
1735 config->reg_data[i].reg_cfg =
1736 cdc_reg_cfg->reg_data[i + (j * reg_per_pkt)];
1737 }
1738
1739 ret = afe_apr_send_pkt(config, &this_afe.wait[IDX_GLOBAL_CFG]);
1740 if (ret) {
1741 pr_err("%s: AFE_PARAM_ID_CDC_REG_CFG failed %d\n",
1742 __func__, ret);
1743 kfree(config);
1744 break;
1745 }
1746 kfree(config);
1747 }
1748
1749 return ret;
1750}
1751
1752static int afe_init_cdc_reg_config(void)
1753{
1754 int ret;
1755 struct afe_svc_cmd_init_cdc_reg_cfg config;
1756
1757 pr_debug("%s: enter\n", __func__);
1758 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1759 APR_HDR_LEN(APR_HDR_SIZE),
1760 APR_PKT_VER);
1761 config.hdr.pkt_size = sizeof(config);
1762 config.hdr.src_port = 0;
1763 config.hdr.dest_port = 0;
1764 config.hdr.token = IDX_GLOBAL_CFG;
1765 config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
1766
1767 config.param.payload_size = sizeof(struct afe_port_param_data_v2);
1768 config.param.payload_address_lsw = 0x00;
1769 config.param.payload_address_msw = 0x00;
1770 config.param.mem_map_handle = 0x00;
1771
1772 config.init.module_id = AFE_MODULE_CDC_DEV_CFG;
1773 config.init.param_id = AFE_PARAM_ID_CDC_REG_CFG_INIT;
1774 config.init.param_size = 0;
1775
1776 ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
1777 if (ret) {
1778 pr_err("%s: AFE_PARAM_ID_CDC_INIT_REG_CFG failed %d\n",
1779 __func__, ret);
1780 }
1781
1782 return ret;
1783}
1784
1785static int afe_send_slimbus_slave_port_cfg(
1786 struct afe_param_slimbus_slave_port_cfg *port_config, u16 port_id)
1787{
1788 int ret, index;
1789 struct afe_cmd_hw_mad_slimbus_slave_port_cfg config;
1790
1791 pr_debug("%s: enter, port_id = 0x%x\n", __func__, port_id);
1792 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08001793 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001794 pr_err("%s: AFE port index[%d] invalid!\n",
1795 __func__, index);
1796 return -EINVAL;
1797 }
1798 ret = q6audio_validate_port(port_id);
1799 if (ret < 0) {
1800 pr_err("%s: port id = 0x%x ret %d\n", __func__, port_id, ret);
1801 return -EINVAL;
1802 }
1803
1804 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1805 APR_HDR_LEN(APR_HDR_SIZE),
1806 APR_PKT_VER);
1807 config.hdr.pkt_size = sizeof(config);
1808 config.hdr.src_port = 0;
1809 config.hdr.dest_port = 0;
1810 config.hdr.token = index;
1811 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
1812 config.param.port_id = port_id;
1813 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
1814 sizeof(config.param);
1815 config.param.payload_address_lsw = 0x00;
1816 config.param.payload_address_msw = 0x00;
1817 config.param.mem_map_handle = 0x00;
1818 config.pdata.module_id = AFE_MODULE_HW_MAD;
1819 config.pdata.param_id = AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG;
1820 config.pdata.param_size = sizeof(*port_config);
1821 config.sb_port_cfg = *port_config;
1822
1823 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
1824 if (ret) {
1825 pr_err("%s: AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG failed %d\n",
1826 __func__, ret);
1827 }
1828 pr_debug("%s: leave %d\n", __func__, ret);
1829 return ret;
1830}
1831static int afe_aanc_port_cfg(void *apr, uint16_t tx_port, uint16_t rx_port)
1832{
1833 struct afe_port_cmd_set_aanc_param cfg;
1834 int ret = 0;
1835 int index = 0;
1836
1837 pr_debug("%s: tx_port 0x%x, rx_port 0x%x\n",
1838 __func__, tx_port, rx_port);
1839
1840 ret = afe_q6_interface_prepare();
1841 if (ret != 0) {
1842 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
1843 return -EINVAL;
1844 }
1845
1846 index = q6audio_get_port_index(tx_port);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08001847 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001848 pr_err("%s: AFE port index[%d] invalid!\n",
1849 __func__, index);
1850 return -EINVAL;
1851 }
1852 ret = q6audio_validate_port(tx_port);
1853 if (ret < 0) {
1854 pr_err("%s: port id: 0x%x ret %d\n", __func__, tx_port, ret);
1855 return -EINVAL;
1856 }
1857 pr_debug("%s: AANC sample rate tx rate: %d rx rate %d\n",
1858 __func__, this_afe.aanc_info.aanc_tx_port_sample_rate,
1859 this_afe.aanc_info.aanc_rx_port_sample_rate);
1860 /*
1861 * If aanc tx sample rate or rx sample rate is zero, skip aanc
1862 * configuration as AFE resampler will fail for invalid sample
1863 * rates.
1864 */
1865 if (!this_afe.aanc_info.aanc_tx_port_sample_rate ||
1866 !this_afe.aanc_info.aanc_rx_port_sample_rate) {
1867 return -EINVAL;
1868 }
1869
1870 cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1871 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1872 cfg.hdr.pkt_size = sizeof(cfg);
1873 cfg.hdr.src_port = 0;
1874 cfg.hdr.dest_port = 0;
1875 cfg.hdr.token = index;
1876 cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
1877
1878 cfg.param.port_id = tx_port;
1879 cfg.param.payload_size = sizeof(struct afe_port_param_data_v2) +
1880 sizeof(struct afe_param_aanc_port_cfg);
1881 cfg.param.payload_address_lsw = 0;
1882 cfg.param.payload_address_msw = 0;
1883 cfg.param.mem_map_handle = 0;
1884
1885 cfg.pdata.module_id = AFE_MODULE_AANC;
1886 cfg.pdata.param_id = AFE_PARAM_ID_AANC_PORT_CONFIG;
1887 cfg.pdata.param_size = sizeof(struct afe_param_aanc_port_cfg);
1888 cfg.pdata.reserved = 0;
1889
1890 cfg.data.aanc_port_cfg.aanc_port_cfg_minor_version =
1891 AFE_API_VERSION_AANC_PORT_CONFIG;
1892 cfg.data.aanc_port_cfg.tx_port_sample_rate =
1893 this_afe.aanc_info.aanc_tx_port_sample_rate;
1894 cfg.data.aanc_port_cfg.tx_port_channel_map[0] = AANC_TX_VOICE_MIC;
1895 cfg.data.aanc_port_cfg.tx_port_channel_map[1] = AANC_TX_NOISE_MIC;
1896 cfg.data.aanc_port_cfg.tx_port_channel_map[2] = AANC_TX_ERROR_MIC;
1897 cfg.data.aanc_port_cfg.tx_port_channel_map[3] = AANC_TX_MIC_UNUSED;
1898 cfg.data.aanc_port_cfg.tx_port_channel_map[4] = AANC_TX_MIC_UNUSED;
1899 cfg.data.aanc_port_cfg.tx_port_channel_map[5] = AANC_TX_MIC_UNUSED;
1900 cfg.data.aanc_port_cfg.tx_port_channel_map[6] = AANC_TX_MIC_UNUSED;
1901 cfg.data.aanc_port_cfg.tx_port_channel_map[7] = AANC_TX_MIC_UNUSED;
1902 cfg.data.aanc_port_cfg.tx_port_num_channels = 3;
1903 cfg.data.aanc_port_cfg.rx_path_ref_port_id = rx_port;
1904 cfg.data.aanc_port_cfg.ref_port_sample_rate =
1905 this_afe.aanc_info.aanc_rx_port_sample_rate;
1906
1907 ret = afe_apr_send_pkt((uint32_t *) &cfg, &this_afe.wait[index]);
1908 if (ret) {
1909 pr_err("%s: AFE AANC port config failed for tx_port 0x%x, rx_port 0x%x ret %d\n",
1910 __func__, tx_port, rx_port, ret);
1911 }
1912
1913 return ret;
1914}
1915
1916static int afe_aanc_mod_enable(void *apr, uint16_t tx_port, uint16_t enable)
1917{
1918 struct afe_port_cmd_set_aanc_param cfg;
1919 int ret = 0;
1920 int index = 0;
1921
1922 pr_debug("%s: tx_port 0x%x\n",
1923 __func__, tx_port);
1924
1925 ret = afe_q6_interface_prepare();
1926 if (ret != 0) {
1927 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
1928 return -EINVAL;
1929 }
1930
1931 index = q6audio_get_port_index(tx_port);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08001932 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001933 pr_err("%s: AFE port index[%d] invalid!\n",
1934 __func__, index);
1935 return -EINVAL;
1936 }
1937 ret = q6audio_validate_port(tx_port);
1938 if (ret < 0) {
1939 pr_err("%s: port id: 0x%x ret %d\n", __func__, tx_port, ret);
1940 return -EINVAL;
1941 }
1942
1943 cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1944 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1945 cfg.hdr.pkt_size = sizeof(cfg);
1946 cfg.hdr.src_port = 0;
1947 cfg.hdr.dest_port = 0;
1948 cfg.hdr.token = index;
1949 cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
1950
1951 cfg.param.port_id = tx_port;
1952 cfg.param.payload_size = sizeof(struct afe_port_param_data_v2) +
1953 sizeof(struct afe_mod_enable_param);
1954 cfg.param.payload_address_lsw = 0;
1955 cfg.param.payload_address_lsw = 0;
1956 cfg.param.mem_map_handle = 0;
1957
1958 cfg.pdata.module_id = AFE_MODULE_AANC;
1959 cfg.pdata.param_id = AFE_PARAM_ID_ENABLE;
1960 cfg.pdata.param_size = sizeof(struct afe_mod_enable_param);
1961 cfg.pdata.reserved = 0;
1962
1963 cfg.data.mod_enable.enable = enable;
1964 cfg.data.mod_enable.reserved = 0;
1965
1966 ret = afe_apr_send_pkt((uint32_t *) &cfg, &this_afe.wait[index]);
1967 if (ret) {
1968 pr_err("%s: AFE AANC enable failed for tx_port 0x%x ret %d\n",
1969 __func__, tx_port, ret);
1970 }
1971 return ret;
1972}
1973
1974static int afe_send_bank_selection_clip(
1975 struct afe_param_id_clip_bank_sel *param)
1976{
1977 int ret;
1978 struct afe_svc_cmd_set_clip_bank_selection config;
1979
1980 if (!param) {
1981 pr_err("%s: Invalid params", __func__);
1982 return -EINVAL;
1983 }
1984 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1985 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1986 config.hdr.pkt_size = sizeof(config);
1987 config.hdr.src_port = 0;
1988 config.hdr.dest_port = 0;
1989 config.hdr.token = IDX_GLOBAL_CFG;
1990 config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
1991
1992 config.param.payload_size = sizeof(struct afe_port_param_data_v2) +
1993 sizeof(struct afe_param_id_clip_bank_sel);
1994 config.param.payload_address_lsw = 0x00;
1995 config.param.payload_address_msw = 0x00;
1996 config.param.mem_map_handle = 0x00;
1997
1998 config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG;
1999 config.pdata.param_id = AFE_PARAM_ID_CLIP_BANK_SEL_CFG;
2000 config.pdata.param_size =
2001 sizeof(struct afe_param_id_clip_bank_sel);
2002 config.bank_sel = *param;
2003 ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
2004 if (ret) {
2005 pr_err("%s: AFE_PARAM_ID_CLIP_BANK_SEL_CFG failed %d\n",
2006 __func__, ret);
2007 }
2008 return ret;
2009}
2010int afe_send_aanc_version(
2011 struct afe_param_id_cdc_aanc_version *version_cfg)
2012{
2013 int ret;
2014 struct afe_svc_cmd_cdc_aanc_version config;
2015
2016 pr_debug("%s: enter\n", __func__);
2017 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2018 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2019 config.hdr.pkt_size = sizeof(config);
2020 config.hdr.src_port = 0;
2021 config.hdr.dest_port = 0;
2022 config.hdr.token = IDX_GLOBAL_CFG;
2023 config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
2024
2025 config.param.payload_size = sizeof(struct afe_port_param_data_v2) +
2026 sizeof(struct afe_param_id_cdc_aanc_version);
2027 config.param.payload_address_lsw = 0x00;
2028 config.param.payload_address_msw = 0x00;
2029 config.param.mem_map_handle = 0x00;
2030
2031 config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG;
2032 config.pdata.param_id = AFE_PARAM_ID_CDC_AANC_VERSION;
2033 config.pdata.param_size =
2034 sizeof(struct afe_param_id_cdc_aanc_version);
2035 config.version = *version_cfg;
2036 ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
2037 if (ret) {
2038 pr_err("%s: AFE_PARAM_ID_CDC_AANC_VERSION failed %d\n",
2039 __func__, ret);
2040 }
2041 return ret;
2042}
2043
2044int afe_port_set_mad_type(u16 port_id, enum afe_mad_type mad_type)
2045{
2046 int i;
2047
Ashish Jainb31517a2017-02-03 18:26:11 +05302048 if (port_id == AFE_PORT_ID_TERTIARY_MI2S_TX ||
2049 port_id == AFE_PORT_ID_INT3_MI2S_TX) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002050 mad_type = MAD_SW_AUDIO;
2051 return 0;
2052 }
2053
2054 i = port_id - SLIMBUS_0_RX;
2055 if (i < 0 || i >= ARRAY_SIZE(afe_ports_mad_type)) {
2056 pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
2057 return -EINVAL;
2058 }
2059 atomic_set(&afe_ports_mad_type[i], mad_type);
2060 return 0;
2061}
2062
2063enum afe_mad_type afe_port_get_mad_type(u16 port_id)
2064{
2065 int i;
2066
Ashish Jainb31517a2017-02-03 18:26:11 +05302067 if (port_id == AFE_PORT_ID_TERTIARY_MI2S_TX ||
2068 port_id == AFE_PORT_ID_INT3_MI2S_TX)
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002069 return MAD_SW_AUDIO;
2070
2071 i = port_id - SLIMBUS_0_RX;
2072 if (i < 0 || i >= ARRAY_SIZE(afe_ports_mad_type)) {
2073 pr_debug("%s: Non Slimbus port_id 0x%x\n", __func__, port_id);
2074 return MAD_HW_NONE;
2075 }
2076 return (enum afe_mad_type) atomic_read(&afe_ports_mad_type[i]);
2077}
2078
2079int afe_set_config(enum afe_config_type config_type, void *config_data, int arg)
2080{
2081 int ret;
2082
2083 pr_debug("%s: enter config_type %d\n", __func__, config_type);
2084 ret = afe_q6_interface_prepare();
2085 if (ret) {
2086 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
2087 return ret;
2088 }
2089
2090 switch (config_type) {
2091 case AFE_SLIMBUS_SLAVE_CONFIG:
2092 ret = afe_send_slimbus_slave_cfg(config_data);
2093 if (!ret)
2094 ret = afe_init_cdc_reg_config();
2095 else
2096 pr_err("%s: Sending slimbus slave config failed %d\n",
2097 __func__, ret);
2098 break;
2099 case AFE_CDC_REGISTERS_CONFIG:
2100 ret = afe_send_codec_reg_config(config_data);
2101 break;
2102 case AFE_SLIMBUS_SLAVE_PORT_CONFIG:
2103 ret = afe_send_slimbus_slave_port_cfg(config_data, arg);
2104 break;
2105 case AFE_AANC_VERSION:
2106 ret = afe_send_aanc_version(config_data);
2107 break;
2108 case AFE_CLIP_BANK_SEL:
2109 ret = afe_send_bank_selection_clip(config_data);
2110 break;
2111 case AFE_CDC_CLIP_REGISTERS_CONFIG:
2112 ret = afe_send_codec_reg_config(config_data);
2113 break;
2114 case AFE_CDC_REGISTER_PAGE_CONFIG:
2115 ret = afe_send_codec_reg_page_config(config_data);
2116 break;
2117 default:
2118 pr_err("%s: unknown configuration type %d",
2119 __func__, config_type);
2120 ret = -EINVAL;
2121 }
2122
2123 if (!ret)
2124 set_bit(config_type, &afe_configured_cmd);
2125
2126 return ret;
2127}
2128
2129/*
2130 * afe_clear_config - If SSR happens ADSP loses AFE configs, let AFE driver know
2131 * about the state so client driver can wait until AFE is
2132 * reconfigured.
2133 */
2134void afe_clear_config(enum afe_config_type config)
2135{
2136 clear_bit(config, &afe_configured_cmd);
2137}
2138
2139bool afe_has_config(enum afe_config_type config)
2140{
2141 return !!test_bit(config, &afe_configured_cmd);
2142}
2143
2144int afe_send_spdif_clk_cfg(struct afe_param_id_spdif_clk_cfg *cfg,
2145 u16 port_id)
2146{
2147 struct afe_spdif_clk_config_command clk_cfg;
2148 int ret = 0;
2149 int index = 0;
2150
2151 if (!cfg) {
2152 pr_err("%s: Error, no configuration data\n", __func__);
2153 ret = -EINVAL;
2154 return ret;
2155 }
2156 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08002157 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002158 pr_err("%s: AFE port index[%d] invalid!\n",
2159 __func__, index);
2160 return -EINVAL;
2161 }
2162 ret = q6audio_validate_port(port_id);
2163 if (ret < 0) {
2164 pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
2165 return -EINVAL;
2166 }
2167
2168 ret = afe_q6_interface_prepare();
2169 if (ret) {
2170 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
2171 return ret;
2172 }
2173 clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2174 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2175 clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
2176 clk_cfg.hdr.src_port = 0;
2177 clk_cfg.hdr.dest_port = 0;
2178 clk_cfg.hdr.token = index;
2179
2180 clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
2181 clk_cfg.param.port_id = q6audio_get_port_id(port_id);
2182 clk_cfg.param.payload_address_lsw = 0x00;
2183 clk_cfg.param.payload_address_msw = 0x00;
2184 clk_cfg.param.mem_map_handle = 0x00;
2185 clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
2186 clk_cfg.pdata.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG;
2187 clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
2188 clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
2189 - sizeof(clk_cfg.param);
2190 clk_cfg.clk_cfg = *cfg;
2191
2192 pr_debug("%s: Minor version = 0x%x clk val = %d\n"
2193 "clk root = 0x%x\n port id = 0x%x\n",
2194 __func__, cfg->clk_cfg_minor_version,
2195 cfg->clk_value, cfg->clk_root,
2196 q6audio_get_port_id(port_id));
2197
2198 atomic_set(&this_afe.state, 1);
2199 atomic_set(&this_afe.status, 0);
2200 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
2201 if (ret < 0) {
2202 pr_err("%s: AFE send clock config for port 0x%x failed ret = %d\n",
2203 __func__, port_id, ret);
2204 ret = -EINVAL;
2205 goto fail_cmd;
2206 }
2207
2208 ret = wait_event_timeout(this_afe.wait[index],
2209 (atomic_read(&this_afe.state) == 0),
2210 msecs_to_jiffies(TIMEOUT_MS));
2211 if (!ret) {
2212 pr_err("%s: wait_event timeout\n",
2213 __func__);
2214 ret = -EINVAL;
2215 goto fail_cmd;
2216 }
2217 if (atomic_read(&this_afe.status) > 0) {
2218 pr_err("%s: config cmd failed [%s]\n",
2219 __func__, adsp_err_get_err_str(
2220 atomic_read(&this_afe.status)));
2221 ret = adsp_err_get_lnx_err_code(
2222 atomic_read(&this_afe.status));
2223 goto fail_cmd;
2224 }
2225
2226fail_cmd:
2227 return ret;
2228}
2229
2230int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg
2231 *ch_status_cfg, u16 port_id)
2232{
2233 struct afe_spdif_chstatus_config_command ch_status;
2234 int ret = 0;
2235 int index = 0;
2236
2237 if (!ch_status_cfg) {
2238 pr_err("%s: Error, no configuration data\n", __func__);
2239 ret = -EINVAL;
2240 return ret;
2241 }
2242 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08002243 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002244 pr_err("%s: AFE port index[%d] invalid!\n",
2245 __func__, index);
2246 return -EINVAL;
2247 }
2248 ret = q6audio_validate_port(port_id);
2249 if (ret < 0) {
2250 pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
2251 return -EINVAL;
2252 }
2253
2254 ret = afe_q6_interface_prepare();
2255 if (ret != 0) {
2256 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
2257 return ret;
2258 }
2259 ch_status.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2260 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2261 ch_status.hdr.pkt_size = sizeof(ch_status_cfg);
2262 ch_status.hdr.src_port = 0;
2263 ch_status.hdr.dest_port = 0;
2264 ch_status.hdr.token = index;
2265
2266 ch_status.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
2267 ch_status.param.port_id = q6audio_get_port_id(port_id);
2268 ch_status.param.payload_address_lsw = 0x00;
2269 ch_status.param.payload_address_msw = 0x00;
2270 ch_status.param.mem_map_handle = 0x00;
2271 ch_status.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
2272 ch_status.pdata.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG;
2273 ch_status.pdata.param_size = sizeof(ch_status.ch_status);
2274 ch_status.param.payload_size = sizeof(ch_status)
2275 - sizeof(struct apr_hdr) - sizeof(ch_status.param);
2276 ch_status.ch_status = *ch_status_cfg;
2277
2278 atomic_set(&this_afe.state, 1);
2279 atomic_set(&this_afe.status, 0);
2280 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &ch_status);
2281 if (ret < 0) {
2282 pr_err("%s: AFE send channel status for port 0x%x failed ret = %d\n",
2283 __func__, port_id, ret);
2284 ret = -EINVAL;
2285 goto fail_cmd;
2286 }
2287
2288 ret = wait_event_timeout(this_afe.wait[index],
2289 (atomic_read(&this_afe.state) == 0),
2290 msecs_to_jiffies(TIMEOUT_MS));
2291 if (!ret) {
2292 pr_err("%s: wait_event timeout\n",
2293 __func__);
2294 ret = -EINVAL;
2295 goto fail_cmd;
2296 }
2297 if (atomic_read(&this_afe.status) > 0) {
2298 pr_err("%s: config cmd failed [%s]\n",
2299 __func__, adsp_err_get_err_str(
2300 atomic_read(&this_afe.status)));
2301 ret = adsp_err_get_lnx_err_code(
2302 atomic_read(&this_afe.status));
2303 goto fail_cmd;
2304 }
2305
2306fail_cmd:
2307 return ret;
2308}
2309
2310static int afe_send_cmd_port_start(u16 port_id)
2311{
2312 struct afe_port_cmd_device_start start;
2313 int ret, index;
2314
2315 pr_debug("%s: enter\n", __func__);
2316 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08002317 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002318 pr_err("%s: AFE port index[%d] invalid!\n",
2319 __func__, index);
2320 return -EINVAL;
2321 }
2322 ret = q6audio_validate_port(port_id);
2323 if (ret < 0) {
2324 pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
2325 return -EINVAL;
2326 }
2327
2328 start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2329 APR_HDR_LEN(APR_HDR_SIZE),
2330 APR_PKT_VER);
2331 start.hdr.pkt_size = sizeof(start);
2332 start.hdr.src_port = 0;
2333 start.hdr.dest_port = 0;
2334 start.hdr.token = index;
2335 start.hdr.opcode = AFE_PORT_CMD_DEVICE_START;
2336 start.port_id = q6audio_get_port_id(port_id);
2337 pr_debug("%s: cmd device start opcode[0x%x] port id[0x%x]\n",
2338 __func__, start.hdr.opcode, start.port_id);
2339
2340 ret = afe_apr_send_pkt(&start, &this_afe.wait[index]);
2341 if (ret) {
2342 pr_err("%s: AFE enable for port 0x%x failed %d\n", __func__,
2343 port_id, ret);
2344 } else if (this_afe.task != current) {
2345 this_afe.task = current;
2346 pr_debug("task_name = %s pid = %d\n",
2347 this_afe.task->comm, this_afe.task->pid);
2348 }
2349
2350 return ret;
2351}
2352
2353static int afe_aanc_start(uint16_t tx_port_id, uint16_t rx_port_id)
2354{
2355 int ret;
2356
2357 pr_debug("%s: Tx port is 0x%x, Rx port is 0x%x\n",
2358 __func__, tx_port_id, rx_port_id);
2359 ret = afe_aanc_port_cfg(this_afe.apr, tx_port_id, rx_port_id);
2360 if (ret) {
2361 pr_err("%s: Send AANC Port Config failed %d\n",
2362 __func__, ret);
2363 goto fail_cmd;
2364 }
2365 send_afe_cal_type(AFE_AANC_CAL, tx_port_id);
2366
2367fail_cmd:
2368 return ret;
2369}
2370
2371int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port,
2372 u32 rate)
2373{
2374 struct afe_audioif_config_command config;
2375 int ret = 0;
2376 int index = 0;
2377 uint16_t port_index;
2378
2379 if (!spdif_port) {
2380 pr_err("%s: Error, no configuration data\n", __func__);
2381 ret = -EINVAL;
2382 return ret;
2383 }
2384
2385 pr_debug("%s: port id: 0x%x\n", __func__, port_id);
2386
2387 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08002388 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002389 pr_err("%s: AFE port index[%d] invalid!\n",
2390 __func__, index);
2391 return -EINVAL;
2392 }
2393 ret = q6audio_validate_port(port_id);
2394 if (ret < 0) {
2395 pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
2396 return -EINVAL;
2397 }
2398
2399 afe_send_cal(port_id);
2400 afe_send_hw_delay(port_id, rate);
2401
2402 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2403 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2404 config.hdr.pkt_size = sizeof(config);
2405 config.hdr.src_port = 0;
2406 config.hdr.dest_port = 0;
2407 config.hdr.token = index;
2408 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
2409 config.param.port_id = q6audio_get_port_id(port_id);
2410 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
2411 sizeof(config.param);
2412 config.param.payload_address_lsw = 0x00;
2413 config.param.payload_address_msw = 0x00;
2414 config.param.mem_map_handle = 0x00;
2415 config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
2416 config.pdata.param_id = AFE_PARAM_ID_SPDIF_CONFIG;
2417 config.pdata.param_size = sizeof(config.port);
2418 config.port.spdif = spdif_port->cfg;
2419 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
2420 if (ret) {
2421 pr_err("%s: AFE enable for port 0x%x failed ret = %d\n",
2422 __func__, port_id, ret);
2423 goto fail_cmd;
2424 }
2425
2426 port_index = afe_get_port_index(port_id);
2427 if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
2428 this_afe.afe_sample_rates[port_index] = rate;
2429 } else {
2430 pr_err("%s: Invalid port index %d\n", __func__, port_index);
2431 ret = -EINVAL;
2432 goto fail_cmd;
2433 }
2434
2435 ret = afe_send_spdif_ch_status_cfg(&spdif_port->ch_status, port_id);
2436 if (ret < 0) {
2437 pr_err("%s: afe send failed %d\n", __func__, ret);
2438 goto fail_cmd;
2439 }
2440
2441 return afe_send_cmd_port_start(port_id);
2442
2443fail_cmd:
2444 return ret;
2445}
2446
2447int afe_send_slot_mapping_cfg(
2448 struct afe_param_id_slot_mapping_cfg *slot_mapping_cfg,
2449 u16 port_id)
2450{
2451 struct afe_slot_mapping_config_command config;
2452 int ret = 0;
2453 int index = 0;
2454
2455 if (!slot_mapping_cfg) {
2456 pr_err("%s: Error, no configuration data\n", __func__);
2457 return -EINVAL;
2458 }
2459
2460 pr_debug("%s: port id: 0x%x\n", __func__, port_id);
2461
2462 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08002463 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002464 pr_err("%s: AFE port index[%d] invalid!\n",
2465 __func__, index);
2466 return -EINVAL;
2467 }
2468 ret = q6audio_validate_port(port_id);
2469 if (ret < 0) {
2470 pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
2471 return -EINVAL;
2472 }
2473
2474 memset(&config, 0, sizeof(config));
2475 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2476 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2477 config.hdr.pkt_size = sizeof(config);
2478 config.hdr.src_port = 0;
2479 config.hdr.dest_port = 0;
2480 config.hdr.token = index;
2481
2482 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
2483 config.param.port_id = q6audio_get_port_id(port_id);
2484 config.param.payload_size = sizeof(config)
2485 - sizeof(struct apr_hdr) - sizeof(config.param);
2486 config.param.payload_address_lsw = 0x00;
2487 config.param.payload_address_msw = 0x00;
2488 config.param.mem_map_handle = 0x00;
2489 config.pdata.module_id = AFE_MODULE_TDM;
2490 config.pdata.param_id = AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG;
2491 config.pdata.param_size = sizeof(config.slot_mapping);
2492 config.slot_mapping = *slot_mapping_cfg;
2493
2494 atomic_set(&this_afe.state, 1);
2495 atomic_set(&this_afe.status, 0);
2496 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config);
2497 if (ret < 0) {
2498 pr_err("%s: AFE send slot mapping for port 0x%x failed ret = %d\n",
2499 __func__, port_id, ret);
2500 ret = -EINVAL;
2501 goto fail_cmd;
2502 }
2503
2504 ret = wait_event_timeout(this_afe.wait[index],
2505 (atomic_read(&this_afe.state) == 0),
2506 msecs_to_jiffies(TIMEOUT_MS));
2507 if (!ret) {
2508 pr_err("%s: wait_event timeout\n",
2509 __func__);
2510 ret = -EINVAL;
2511 goto fail_cmd;
2512 }
2513 if (atomic_read(&this_afe.status) > 0) {
2514 pr_err("%s: config cmd failed [%s]\n",
2515 __func__, adsp_err_get_err_str(
2516 atomic_read(&this_afe.status)));
2517 ret = adsp_err_get_lnx_err_code(
2518 atomic_read(&this_afe.status));
2519 goto fail_cmd;
2520 }
2521
2522fail_cmd:
2523 return ret;
2524}
2525
2526int afe_send_custom_tdm_header_cfg(
2527 struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header_cfg,
2528 u16 port_id)
2529{
2530 struct afe_custom_tdm_header_config_command config;
2531 int ret = 0;
2532 int index = 0;
2533
2534 if (!custom_tdm_header_cfg) {
2535 pr_err("%s: Error, no configuration data\n", __func__);
2536 return -EINVAL;
2537 }
2538
2539 pr_debug("%s: port id: 0x%x\n", __func__, port_id);
2540
2541 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08002542 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002543 pr_err("%s: AFE port index[%d] invalid!\n",
2544 __func__, index);
2545 return -EINVAL;
2546 }
2547 ret = q6audio_validate_port(port_id);
2548 if (ret < 0) {
2549 pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
2550 return -EINVAL;
2551 }
2552
2553 memset(&config, 0, sizeof(config));
2554 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2555 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2556 config.hdr.pkt_size = sizeof(config);
2557 config.hdr.src_port = 0;
2558 config.hdr.dest_port = 0;
2559 config.hdr.token = index;
2560
2561 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
2562 config.param.port_id = q6audio_get_port_id(port_id);
2563 config.param.payload_size = sizeof(config)
2564 - sizeof(struct apr_hdr) - sizeof(config.param);
2565 config.param.payload_address_lsw = 0x00;
2566 config.param.payload_address_msw = 0x00;
2567 config.param.mem_map_handle = 0x00;
2568 config.pdata.module_id = AFE_MODULE_TDM;
2569 config.pdata.param_id = AFE_PARAM_ID_CUSTOM_TDM_HEADER_CONFIG;
2570 config.pdata.param_size = sizeof(config.custom_tdm_header);
2571 config.custom_tdm_header = *custom_tdm_header_cfg;
2572
2573 atomic_set(&this_afe.state, 1);
2574 atomic_set(&this_afe.status, 0);
2575 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config);
2576 if (ret < 0) {
2577 pr_err("%s: AFE send custom tdm header for port 0x%x failed ret = %d\n",
2578 __func__, port_id, ret);
2579 ret = -EINVAL;
2580 goto fail_cmd;
2581 }
2582
2583 ret = wait_event_timeout(this_afe.wait[index],
2584 (atomic_read(&this_afe.state) == 0),
2585 msecs_to_jiffies(TIMEOUT_MS));
2586 if (!ret) {
2587 pr_err("%s: wait_event timeout\n",
2588 __func__);
2589 ret = -EINVAL;
2590 goto fail_cmd;
2591 }
2592 if (atomic_read(&this_afe.status) > 0) {
2593 pr_err("%s: config cmd failed [%s]\n",
2594 __func__, adsp_err_get_err_str(
2595 atomic_read(&this_afe.status)));
2596 ret = adsp_err_get_lnx_err_code(
2597 atomic_read(&this_afe.status));
2598 goto fail_cmd;
2599 }
2600
2601fail_cmd:
2602 return ret;
2603}
2604
2605int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port,
Josh Kirschdb567c12017-01-04 17:59:30 -08002606 u32 rate, u16 num_groups)
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002607{
2608 struct afe_audioif_config_command config;
2609 int ret = 0;
2610 int index = 0;
2611 uint16_t port_index = 0;
2612 enum afe_mad_type mad_type = MAD_HW_NONE;
2613
2614 if (!tdm_port) {
2615 pr_err("%s: Error, no configuration data\n", __func__);
2616 return -EINVAL;
2617 }
2618
2619 pr_debug("%s: port id: 0x%x\n", __func__, port_id);
2620
2621 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08002622 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002623 pr_err("%s: AFE port index[%d] invalid!\n",
2624 __func__, index);
2625 return -EINVAL;
2626 }
2627 ret = q6audio_validate_port(port_id);
2628 if (ret < 0) {
2629 pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
2630 return -EINVAL;
2631 }
2632
2633 ret = afe_q6_interface_prepare();
2634 if (ret != 0) {
2635 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
2636 return ret;
2637 }
2638
Siena Richard23364c92017-01-11 16:20:55 -08002639 if ((index >= 0) && (index < AFE_MAX_PORTS)) {
2640 this_afe.afe_sample_rates[index] = rate;
2641
2642 if (this_afe.rt_cb)
2643 this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id);
2644 }
2645
Josh Kirschdb567c12017-01-04 17:59:30 -08002646 /* Also send the topology id here if multiple ports: */
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002647 port_index = afe_get_port_index(port_id);
Josh Kirschdb567c12017-01-04 17:59:30 -08002648 if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE) &&
2649 num_groups > 1) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002650 /* One time call: only for first time */
2651 afe_send_custom_topology();
2652 afe_send_port_topology_id(port_id);
2653 afe_send_cal(port_id);
2654 afe_send_hw_delay(port_id, rate);
2655 }
2656
2657 /* Start SW MAD module */
2658 mad_type = afe_port_get_mad_type(port_id);
2659 pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id,
2660 mad_type);
2661 if (mad_type != MAD_HW_NONE && mad_type != MAD_SW_AUDIO) {
2662 if (!afe_has_config(AFE_CDC_REGISTERS_CONFIG) ||
2663 !afe_has_config(AFE_SLIMBUS_SLAVE_CONFIG)) {
2664 pr_err("%s: AFE isn't configured yet for\n"
2665 "HW MAD try Again\n", __func__);
2666 ret = -EAGAIN;
2667 goto fail_cmd;
2668 }
2669 ret = afe_turn_onoff_hw_mad(mad_type, true);
2670 if (ret) {
2671 pr_err("%s: afe_turn_onoff_hw_mad failed %d\n",
2672 __func__, ret);
2673 goto fail_cmd;
2674 }
2675 }
2676
2677 memset(&config, 0, sizeof(config));
2678 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2679 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2680 config.hdr.pkt_size = sizeof(config);
2681 config.hdr.src_port = 0;
2682 config.hdr.dest_port = 0;
2683 config.hdr.token = index;
2684 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
2685 config.param.port_id = q6audio_get_port_id(port_id);
2686 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
2687 sizeof(config.param);
2688 config.param.payload_address_lsw = 0x00;
2689 config.param.payload_address_msw = 0x00;
2690 config.param.mem_map_handle = 0x00;
2691 config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
2692 config.pdata.param_id = AFE_PARAM_ID_TDM_CONFIG;
2693 config.pdata.param_size = sizeof(config.port);
2694 config.port.tdm = tdm_port->tdm;
2695
2696 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
2697 if (ret) {
2698 pr_err("%s: AFE enable for port 0x%x failed ret = %d\n",
2699 __func__, port_id, ret);
2700 goto fail_cmd;
2701 }
2702
2703 port_index = afe_get_port_index(port_id);
2704 if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
2705 this_afe.afe_sample_rates[port_index] = rate;
2706 } else {
2707 pr_err("%s: Invalid port index %d\n", __func__, port_index);
2708 ret = -EINVAL;
2709 goto fail_cmd;
2710 }
Josh Kirschdb567c12017-01-04 17:59:30 -08002711 /* slot mapping is not need if there is only one group */
2712 if (num_groups > 1) {
2713 ret = afe_send_slot_mapping_cfg(&tdm_port->slot_mapping,
2714 port_id);
2715 if (ret < 0) {
2716 pr_err("%s: afe send failed %d\n", __func__, ret);
2717 goto fail_cmd;
2718 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002719 }
2720
2721 if (tdm_port->custom_tdm_header.header_type) {
2722 ret = afe_send_custom_tdm_header_cfg(
2723 &tdm_port->custom_tdm_header, port_id);
2724 if (ret < 0) {
2725 pr_err("%s: afe send failed %d\n", __func__, ret);
2726 goto fail_cmd;
2727 }
2728 }
2729
2730 ret = afe_send_cmd_port_start(port_id);
2731
2732fail_cmd:
2733 return ret;
2734}
2735
2736void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode)
2737{
2738 uint16_t port_index;
2739
2740 port_index = afe_get_port_index(port_id);
2741 this_afe.afe_cal_mode[port_index] = afe_cal_mode;
2742}
2743
Siena Richard23364c92017-01-11 16:20:55 -08002744void afe_set_routing_callback(routing_cb cb)
2745{
2746 this_afe.rt_cb = cb;
2747}
2748
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002749int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config)
2750{
2751 struct afe_usb_audio_dev_param_command config;
2752 int ret = 0, index = 0;
2753
2754 if (!afe_config) {
2755 pr_err("%s: Error, no configuration data\n", __func__);
2756 ret = -EINVAL;
2757 goto exit;
2758 }
2759 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08002760 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002761 pr_err("%s: AFE port index[%d] invalid! for port ID 0x%x\n",
2762 __func__, index, port_id);
2763 ret = -EINVAL;
2764 goto exit;
2765 }
2766 memset(&config, 0, sizeof(config));
2767 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2768 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2769 config.hdr.pkt_size = sizeof(config);
2770 config.hdr.src_port = 0;
2771 config.hdr.dest_port = 0;
2772 config.hdr.token = index;
2773 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
2774 config.param.port_id = q6audio_get_port_id(port_id);
2775 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
2776 sizeof(config.param);
2777 config.param.payload_address_lsw = 0x00;
2778 config.param.payload_address_msw = 0x00;
2779 config.param.mem_map_handle = 0x00;
2780 config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
2781 config.pdata.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS;
2782 config.pdata.param_size = sizeof(config.usb_dev);
2783 config.usb_dev.cfg_minor_version =
2784 AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG;
2785 config.usb_dev.dev_token = afe_config->usb_audio.dev_token;
2786
2787 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
2788 if (ret) {
2789 pr_err("%s: AFE device param cmd failed %d\n",
2790 __func__, ret);
2791 ret = -EINVAL;
2792 goto exit;
2793 }
Haynes Mathew George434a2e12016-10-27 16:56:21 -07002794
2795 config.pdata.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_LPCM_FMT;
2796 config.pdata.param_size = sizeof(config.lpcm_fmt);
2797 config.lpcm_fmt.cfg_minor_version =
2798 AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG;
2799 config.lpcm_fmt.endian = afe_config->usb_audio.endian;
2800
2801 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
2802 if (ret) {
2803 pr_err("%s: AFE device param cmd LPCM_FMT failed %d\n",
2804 __func__, ret);
2805 ret = -EINVAL;
2806 goto exit;
2807 }
2808
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002809exit:
2810 return ret;
2811}
2812
2813static int q6afe_send_enc_config(u16 port_id,
2814 union afe_enc_config_data *cfg, u32 format,
2815 union afe_port_config afe_config,
2816 u16 afe_in_channels, u16 afe_in_bit_width)
2817{
2818 struct afe_audioif_config_command config;
2819 int index;
2820 int ret;
2821 int payload_size = sizeof(config) - sizeof(struct apr_hdr) -
2822 sizeof(config.param) - sizeof(config.port);
2823
2824 pr_debug("%s:update DSP for enc format = %d\n", __func__, format);
2825 if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 &&
2826 format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD) {
2827 pr_err("%s:Unsuppported format Ignore AFE config\n", __func__);
2828 return 0;
2829 }
2830 memset(&config, 0, sizeof(config));
2831 index = q6audio_get_port_index(port_id);
Xiaoyu Yed3650382017-02-02 12:58:01 -08002832 if (index < 0) {
2833 pr_err("%s: Invalid index number: %d\n", __func__, index);
2834 return -EINVAL;
2835 }
2836
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002837 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2838 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2839 config.hdr.pkt_size = sizeof(config);
2840 config.hdr.src_port = 0;
2841 config.hdr.dest_port = 0;
2842 config.hdr.token = index;
2843
2844 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
2845 config.param.port_id = q6audio_get_port_id(port_id);
2846 config.param.payload_size = payload_size + sizeof(config.port.enc_fmt);
2847 config.param.payload_address_lsw = 0x00;
2848 config.param.payload_address_msw = 0x00;
2849 config.param.mem_map_handle = 0x00;
2850 config.pdata.module_id = AFE_MODULE_ID_ENCODER;
2851 config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_FMT_ID;
2852 config.pdata.param_size = sizeof(config.port.enc_fmt);
2853 config.port.enc_fmt.fmt_id = format;
2854 pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENC_FMT_ID payload: %d\n",
2855 __func__, config.param.payload_size);
2856 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
2857 if (ret) {
2858 pr_err("%s:unable to send AFE_ENCODER_PARAM_ID_ENC_FMT_ID",
2859 __func__);
2860 goto exit;
2861 }
2862
2863 config.param.payload_size = payload_size
2864 + sizeof(config.port.enc_blk_param);
2865 pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payload:%d\n",
2866 __func__, config.param.payload_size);
2867 config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK;
2868 config.pdata.param_size = sizeof(config.port.enc_blk_param);
2869 config.port.enc_blk_param.enc_cfg_blk_size =
2870 sizeof(config.port.enc_blk_param.enc_blk_config);
2871 config.port.enc_blk_param.enc_blk_config = *cfg;
2872 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
2873 if (ret) {
2874 pr_err("%s: AFE_ENCODER_PARAM_ID_ENC_CFG_BLK for port 0x%x failed %d\n",
2875 __func__, port_id, ret);
2876 goto exit;
2877 }
2878
2879 config.param.payload_size =
2880 payload_size + sizeof(config.port.enc_pkt_id_param);
2881 pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP payload = %d",
2882 __func__, config.param.payload_size);
2883 config.pdata.param_id = AFE_ENCODER_PARAM_ID_PACKETIZER_ID;
2884 config.pdata.param_size = sizeof(config.port.enc_pkt_id_param);
2885 config.port.enc_pkt_id_param.enc_packetizer_id =
2886 AFE_MODULE_ID_PACKETIZER_COP;
2887 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
2888 if (ret) {
2889 pr_err("%s: AFE_ENCODER_PARAM_ID_PACKETIZER for port 0x%x failed %d\n",
2890 __func__, port_id, ret);
2891 goto exit;
2892 }
2893
2894 config.param.payload_size =
2895 payload_size + sizeof(config.port.media_type);
2896 config.pdata.param_size = sizeof(config.port.media_type);
2897
2898 pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__);
2899 config.pdata.module_id = AFE_MODULE_PORT;
2900 config.pdata.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE;
2901 config.port.media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE;
2902 config.port.media_type.sample_rate = afe_config.slim_sch.sample_rate;
2903 if (afe_in_bit_width)
2904 config.port.media_type.bit_width = afe_in_bit_width;
2905 else
2906 config.port.media_type.bit_width =
2907 afe_config.slim_sch.bit_width;
2908
2909 if (afe_in_channels)
2910 config.port.media_type.num_channels = afe_in_channels;
2911 else
2912 config.port.media_type.num_channels =
2913 afe_config.slim_sch.num_channels;
2914 config.port.media_type.data_format = AFE_PORT_DATA_FORMAT_PCM;
2915 config.port.media_type.reserved = 0;
2916
2917 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
2918 if (ret) {
2919 pr_err("%s: AFE_API_VERSION_PORT_MEDIA_TYPE for port 0x%x failed %d\n",
2920 __func__, port_id, ret);
2921 goto exit;
2922 }
2923
2924exit:
2925 return ret;
2926}
2927
2928static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
2929 u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
2930 union afe_enc_config_data *cfg, u32 enc_format)
2931{
2932 struct afe_audioif_config_command config;
2933 int ret = 0;
2934 int cfg_type;
2935 int index = 0;
2936 enum afe_mad_type mad_type;
2937 uint16_t port_index;
2938
2939 if (!afe_config) {
2940 pr_err("%s: Error, no configuration data\n", __func__);
2941 ret = -EINVAL;
2942 return ret;
2943 }
2944
2945 if ((port_id == RT_PROXY_DAI_001_RX) ||
2946 (port_id == RT_PROXY_DAI_002_TX)) {
Xiaoyu Ye6e29a5f2017-01-30 12:36:23 -08002947 pr_debug("%s: before incrementing pcm_afe_instance %d port_id 0x%x\n",
2948 __func__,
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002949 pcm_afe_instance[port_id & 0x1], port_id);
2950 port_id = VIRTUAL_ID_TO_PORTID(port_id);
2951 pcm_afe_instance[port_id & 0x1]++;
2952 return 0;
2953 }
2954 if ((port_id == RT_PROXY_DAI_002_RX) ||
2955 (port_id == RT_PROXY_DAI_001_TX)) {
Xiaoyu Ye6e29a5f2017-01-30 12:36:23 -08002956 pr_debug("%s: before incrementing proxy_afe_instance %d port_id 0x%x\n",
2957 __func__,
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002958 proxy_afe_instance[port_id & 0x1], port_id);
2959
2960 if (!afe_close_done[port_id & 0x1]) {
2961 /*close pcm dai corresponding to the proxy dai*/
2962 afe_close(port_id - 0x10);
2963 pcm_afe_instance[port_id & 0x1]++;
2964 pr_debug("%s: reconfigure afe port again\n", __func__);
2965 }
2966 proxy_afe_instance[port_id & 0x1]++;
2967 afe_close_done[port_id & 0x1] = false;
2968 port_id = VIRTUAL_ID_TO_PORTID(port_id);
2969 }
2970
2971 pr_debug("%s: port id: 0x%x\n", __func__, port_id);
2972
2973 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08002974 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002975 pr_err("%s: AFE port index[%d] invalid!\n",
2976 __func__, index);
2977 return -EINVAL;
2978 }
2979 ret = q6audio_validate_port(port_id);
2980 if (ret < 0) {
2981 pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
2982 return -EINVAL;
2983 }
2984
2985 ret = afe_q6_interface_prepare();
2986 if (ret != 0) {
2987 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
2988 return ret;
2989 }
2990
Siena Richard23364c92017-01-11 16:20:55 -08002991 if ((index >= 0) && (index < AFE_MAX_PORTS)) {
2992 this_afe.afe_sample_rates[index] = rate;
2993
2994 if (this_afe.rt_cb)
2995 this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id);
2996 }
2997
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002998 mutex_lock(&this_afe.afe_cmd_lock);
2999 /* Also send the topology id here: */
3000 port_index = afe_get_port_index(port_id);
3001 if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) {
3002 /* One time call: only for first time */
3003 afe_send_custom_topology();
3004 afe_send_port_topology_id(port_id);
3005 afe_send_cal(port_id);
3006 afe_send_hw_delay(port_id, rate);
3007 }
3008
3009 /* Start SW MAD module */
3010 mad_type = afe_port_get_mad_type(port_id);
3011 pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id,
3012 mad_type);
3013 if (mad_type != MAD_HW_NONE && mad_type != MAD_SW_AUDIO) {
3014 if (!afe_has_config(AFE_CDC_REGISTERS_CONFIG) ||
3015 !afe_has_config(AFE_SLIMBUS_SLAVE_CONFIG)) {
3016 pr_err("%s: AFE isn't configured yet for\n"
3017 "HW MAD try Again\n", __func__);
3018 ret = -EAGAIN;
3019 goto fail_cmd;
3020 }
3021 ret = afe_turn_onoff_hw_mad(mad_type, true);
3022 if (ret) {
3023 pr_err("%s: afe_turn_onoff_hw_mad failed %d\n",
3024 __func__, ret);
3025 goto fail_cmd;
3026 }
3027 }
3028
3029 if ((this_afe.aanc_info.aanc_active) &&
3030 (this_afe.aanc_info.aanc_tx_port == port_id)) {
3031 this_afe.aanc_info.aanc_tx_port_sample_rate = rate;
3032 port_index =
3033 afe_get_port_index(this_afe.aanc_info.aanc_rx_port);
3034 if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
3035 this_afe.aanc_info.aanc_rx_port_sample_rate =
3036 this_afe.afe_sample_rates[port_index];
3037 } else {
3038 pr_err("%s: Invalid port index %d\n",
3039 __func__, port_index);
3040 ret = -EINVAL;
3041 goto fail_cmd;
3042 }
3043 ret = afe_aanc_start(this_afe.aanc_info.aanc_tx_port,
3044 this_afe.aanc_info.aanc_rx_port);
3045 pr_debug("%s: afe_aanc_start ret %d\n", __func__, ret);
3046 }
3047
3048 if ((port_id == AFE_PORT_ID_USB_RX) ||
3049 (port_id == AFE_PORT_ID_USB_TX)) {
3050 ret = afe_port_send_usb_dev_param(port_id, afe_config);
3051 if (ret) {
3052 pr_err("%s: AFE device param for port 0x%x failed %d\n",
3053 __func__, port_id, ret);
3054 ret = -EINVAL;
3055 goto fail_cmd;
3056 }
3057 }
3058
3059 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3060 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3061 config.hdr.pkt_size = sizeof(config);
3062 config.hdr.src_port = 0;
3063 config.hdr.dest_port = 0;
3064 config.hdr.token = index;
3065
3066 switch (port_id) {
3067 case AFE_PORT_ID_PRIMARY_PCM_RX:
3068 case AFE_PORT_ID_PRIMARY_PCM_TX:
3069 case AFE_PORT_ID_SECONDARY_PCM_RX:
3070 case AFE_PORT_ID_SECONDARY_PCM_TX:
3071 case AFE_PORT_ID_TERTIARY_PCM_RX:
3072 case AFE_PORT_ID_TERTIARY_PCM_TX:
3073 case AFE_PORT_ID_QUATERNARY_PCM_RX:
3074 case AFE_PORT_ID_QUATERNARY_PCM_TX:
3075 cfg_type = AFE_PARAM_ID_PCM_CONFIG;
3076 break;
3077 case PRIMARY_I2S_RX:
3078 case PRIMARY_I2S_TX:
3079 case SECONDARY_I2S_RX:
3080 case SECONDARY_I2S_TX:
3081 case MI2S_RX:
3082 case MI2S_TX:
3083 case AFE_PORT_ID_PRIMARY_MI2S_RX:
3084 case AFE_PORT_ID_PRIMARY_MI2S_TX:
3085 case AFE_PORT_ID_SECONDARY_MI2S_RX:
3086 case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1:
3087 case AFE_PORT_ID_SECONDARY_MI2S_TX:
3088 case AFE_PORT_ID_TERTIARY_MI2S_RX:
3089 case AFE_PORT_ID_TERTIARY_MI2S_TX:
3090 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
3091 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
3092 case AFE_PORT_ID_QUINARY_MI2S_RX:
3093 case AFE_PORT_ID_QUINARY_MI2S_TX:
3094 case AFE_PORT_ID_SENARY_MI2S_TX:
Laxminath Kasam4e444572017-01-15 20:00:11 +05303095 case AFE_PORT_ID_INT0_MI2S_RX:
3096 case AFE_PORT_ID_INT0_MI2S_TX:
3097 case AFE_PORT_ID_INT1_MI2S_RX:
3098 case AFE_PORT_ID_INT1_MI2S_TX:
3099 case AFE_PORT_ID_INT2_MI2S_RX:
3100 case AFE_PORT_ID_INT2_MI2S_TX:
3101 case AFE_PORT_ID_INT3_MI2S_RX:
3102 case AFE_PORT_ID_INT3_MI2S_TX:
3103 case AFE_PORT_ID_INT4_MI2S_RX:
3104 case AFE_PORT_ID_INT4_MI2S_TX:
3105 case AFE_PORT_ID_INT5_MI2S_RX:
3106 case AFE_PORT_ID_INT5_MI2S_TX:
3107 case AFE_PORT_ID_INT6_MI2S_RX:
3108 case AFE_PORT_ID_INT6_MI2S_TX:
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003109 cfg_type = AFE_PARAM_ID_I2S_CONFIG;
3110 break;
3111 case HDMI_RX:
3112 case DISPLAY_PORT_RX:
3113 cfg_type = AFE_PARAM_ID_HDMI_CONFIG;
3114 break;
3115 case VOICE_PLAYBACK_TX:
3116 case VOICE2_PLAYBACK_TX:
3117 case VOICE_RECORD_RX:
3118 case VOICE_RECORD_TX:
3119 cfg_type = AFE_PARAM_ID_PSEUDO_PORT_CONFIG;
3120 break;
3121 case SLIMBUS_0_RX:
3122 case SLIMBUS_0_TX:
3123 case SLIMBUS_1_RX:
3124 case SLIMBUS_1_TX:
3125 case SLIMBUS_2_RX:
3126 case SLIMBUS_2_TX:
3127 case SLIMBUS_3_RX:
3128 case SLIMBUS_3_TX:
3129 case SLIMBUS_4_RX:
3130 case SLIMBUS_4_TX:
3131 case SLIMBUS_5_RX:
3132 case SLIMBUS_5_TX:
3133 case SLIMBUS_6_RX:
3134 case SLIMBUS_6_TX:
3135 case SLIMBUS_7_RX:
3136 case SLIMBUS_7_TX:
3137 case SLIMBUS_8_RX:
3138 case SLIMBUS_8_TX:
3139 cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG;
3140 break;
3141 case AFE_PORT_ID_USB_RX:
3142 case AFE_PORT_ID_USB_TX:
3143 cfg_type = AFE_PARAM_ID_USB_AUDIO_CONFIG;
3144 break;
3145 case RT_PROXY_PORT_001_RX:
3146 case RT_PROXY_PORT_001_TX:
3147 cfg_type = AFE_PARAM_ID_RT_PROXY_CONFIG;
3148 break;
3149 case INT_BT_SCO_RX:
3150 case INT_BT_A2DP_RX:
3151 case INT_BT_SCO_TX:
3152 case INT_FM_RX:
3153 case INT_FM_TX:
3154 cfg_type = AFE_PARAM_ID_INTERNAL_BT_FM_CONFIG;
3155 break;
3156 default:
3157 pr_err("%s: Invalid port id 0x%x\n", __func__, port_id);
3158 ret = -EINVAL;
3159 goto fail_cmd;
3160 }
3161 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
3162 config.param.port_id = q6audio_get_port_id(port_id);
3163 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
3164 sizeof(config.param);
3165 config.param.payload_address_lsw = 0x00;
3166 config.param.payload_address_msw = 0x00;
3167 config.param.mem_map_handle = 0x00;
3168 config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
3169 config.pdata.param_id = cfg_type;
3170 config.pdata.param_size = sizeof(config.port);
3171
3172 config.port = *afe_config;
3173 if ((enc_format != ASM_MEDIA_FMT_NONE) &&
3174 (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) {
3175 config.port.slim_sch.data_format =
3176 AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED;
3177 }
3178 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
3179 if (ret) {
3180 pr_err("%s: AFE enable for port 0x%x failed %d\n",
3181 __func__, port_id, ret);
3182 goto fail_cmd;
3183 }
3184
3185 if ((enc_format != ASM_MEDIA_FMT_NONE) &&
3186 (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) {
3187 pr_debug("%s: Found AFE encoder support for SLIMBUS enc_format = %d\n",
3188 __func__, enc_format);
3189 ret = q6afe_send_enc_config(port_id, cfg, enc_format,
3190 *afe_config, afe_in_channels,
3191 afe_in_bit_width);
3192 if (ret) {
3193 pr_err("%s: AFE encoder config for port 0x%x failed %d\n",
3194 __func__, port_id, ret);
3195 goto fail_cmd;
3196 }
3197 }
3198
3199 port_index = afe_get_port_index(port_id);
3200 if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003201 /*
3202 * If afe_port_start() for tx port called before
3203 * rx port, then aanc rx sample rate is zero. So,
3204 * AANC state machine in AFE will not get triggered.
3205 * Make sure to check whether aanc is active during
3206 * afe_port_start() for rx port and if aanc rx
3207 * sample rate is zero, call afe_aanc_start to configure
3208 * aanc with valid sample rates.
3209 */
3210 if (this_afe.aanc_info.aanc_active &&
3211 !this_afe.aanc_info.aanc_rx_port_sample_rate) {
3212 this_afe.aanc_info.aanc_rx_port_sample_rate =
3213 this_afe.afe_sample_rates[port_index];
3214 ret = afe_aanc_start(this_afe.aanc_info.aanc_tx_port,
3215 this_afe.aanc_info.aanc_rx_port);
3216 pr_debug("%s: afe_aanc_start ret %d\n", __func__, ret);
3217 }
3218 } else {
3219 pr_err("%s: Invalid port index %d\n", __func__, port_index);
3220 ret = -EINVAL;
3221 goto fail_cmd;
3222 }
3223 ret = afe_send_cmd_port_start(port_id);
3224
3225fail_cmd:
3226 mutex_unlock(&this_afe.afe_cmd_lock);
3227 return ret;
3228}
3229
3230/**
3231 * afe_port_start - to configure AFE session with
3232 * specified port configuration
3233 *
3234 * @port_id: AFE port id number
3235 * @afe_config: port configutation
3236 * @rate: sampling rate of port
3237 *
3238 * Returns 0 on success or error value on port start failure.
3239 */
3240int afe_port_start(u16 port_id, union afe_port_config *afe_config,
3241 u32 rate)
3242{
3243 return __afe_port_start(port_id, afe_config, rate,
3244 0, 0, NULL, ASM_MEDIA_FMT_NONE);
3245}
3246EXPORT_SYMBOL(afe_port_start);
3247
3248/**
3249 * afe_port_start_v2 - to configure AFE session with
3250 * specified port configuration and encoder params
3251 *
3252 * @port_id: AFE port id number
3253 * @afe_config: port configutation
3254 * @rate: sampling rate of port
3255 * @cfg: AFE encoder configuration information to setup encoder
3256 * @afe_in_channels: AFE input channel configuration, this needs
3257 * update only if input channel is differ from AFE output
3258 *
3259 * Returns 0 on success or error value on port start failure.
3260 */
3261int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config,
3262 u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
3263 struct afe_enc_config *enc_cfg)
3264{
3265 return __afe_port_start(port_id, afe_config, rate,
3266 afe_in_channels, afe_in_bit_width,
3267 &enc_cfg->data, enc_cfg->format);
3268}
3269EXPORT_SYMBOL(afe_port_start_v2);
3270
3271int afe_get_port_index(u16 port_id)
3272{
3273 switch (port_id) {
3274 case PRIMARY_I2S_RX: return IDX_PRIMARY_I2S_RX;
3275 case PRIMARY_I2S_TX: return IDX_PRIMARY_I2S_TX;
3276 case AFE_PORT_ID_PRIMARY_PCM_RX:
3277 return IDX_AFE_PORT_ID_PRIMARY_PCM_RX;
3278 case AFE_PORT_ID_PRIMARY_PCM_TX:
3279 return IDX_AFE_PORT_ID_PRIMARY_PCM_TX;
3280 case AFE_PORT_ID_SECONDARY_PCM_RX:
3281 return IDX_AFE_PORT_ID_SECONDARY_PCM_RX;
3282 case AFE_PORT_ID_SECONDARY_PCM_TX:
3283 return IDX_AFE_PORT_ID_SECONDARY_PCM_TX;
3284 case AFE_PORT_ID_TERTIARY_PCM_RX:
3285 return IDX_AFE_PORT_ID_TERTIARY_PCM_RX;
3286 case AFE_PORT_ID_TERTIARY_PCM_TX:
3287 return IDX_AFE_PORT_ID_TERTIARY_PCM_TX;
3288 case AFE_PORT_ID_QUATERNARY_PCM_RX:
3289 return IDX_AFE_PORT_ID_QUATERNARY_PCM_RX;
3290 case AFE_PORT_ID_QUATERNARY_PCM_TX:
3291 return IDX_AFE_PORT_ID_QUATERNARY_PCM_TX;
3292 case SECONDARY_I2S_RX: return IDX_SECONDARY_I2S_RX;
3293 case SECONDARY_I2S_TX: return IDX_SECONDARY_I2S_TX;
3294 case MI2S_RX: return IDX_MI2S_RX;
3295 case MI2S_TX: return IDX_MI2S_TX;
3296 case HDMI_RX: return IDX_HDMI_RX;
3297 case DISPLAY_PORT_RX: return IDX_DISPLAY_PORT_RX;
3298 case AFE_PORT_ID_SPDIF_RX: return IDX_SPDIF_RX;
3299 case RSVD_2: return IDX_RSVD_2;
3300 case RSVD_3: return IDX_RSVD_3;
3301 case DIGI_MIC_TX: return IDX_DIGI_MIC_TX;
3302 case VOICE_RECORD_RX: return IDX_VOICE_RECORD_RX;
3303 case VOICE_RECORD_TX: return IDX_VOICE_RECORD_TX;
3304 case VOICE_PLAYBACK_TX: return IDX_VOICE_PLAYBACK_TX;
3305 case VOICE2_PLAYBACK_TX: return IDX_VOICE2_PLAYBACK_TX;
3306 case SLIMBUS_0_RX: return IDX_SLIMBUS_0_RX;
3307 case SLIMBUS_0_TX: return IDX_SLIMBUS_0_TX;
3308 case SLIMBUS_1_RX: return IDX_SLIMBUS_1_RX;
3309 case SLIMBUS_1_TX: return IDX_SLIMBUS_1_TX;
3310 case SLIMBUS_2_RX: return IDX_SLIMBUS_2_RX;
3311 case SLIMBUS_2_TX: return IDX_SLIMBUS_2_TX;
3312 case SLIMBUS_3_RX: return IDX_SLIMBUS_3_RX;
3313 case SLIMBUS_3_TX: return IDX_SLIMBUS_3_TX;
3314 case INT_BT_SCO_RX: return IDX_INT_BT_SCO_RX;
3315 case INT_BT_SCO_TX: return IDX_INT_BT_SCO_TX;
3316 case INT_BT_A2DP_RX: return IDX_INT_BT_A2DP_RX;
3317 case INT_FM_RX: return IDX_INT_FM_RX;
3318 case INT_FM_TX: return IDX_INT_FM_TX;
3319 case RT_PROXY_PORT_001_RX: return IDX_RT_PROXY_PORT_001_RX;
3320 case RT_PROXY_PORT_001_TX: return IDX_RT_PROXY_PORT_001_TX;
3321 case SLIMBUS_4_RX: return IDX_SLIMBUS_4_RX;
3322 case SLIMBUS_4_TX: return IDX_SLIMBUS_4_TX;
3323 case SLIMBUS_5_RX: return IDX_SLIMBUS_5_RX;
3324 case SLIMBUS_5_TX: return IDX_SLIMBUS_5_TX;
3325 case SLIMBUS_6_RX: return IDX_SLIMBUS_6_RX;
3326 case SLIMBUS_6_TX: return IDX_SLIMBUS_6_TX;
3327 case SLIMBUS_7_RX: return IDX_SLIMBUS_7_RX;
3328 case SLIMBUS_7_TX: return IDX_SLIMBUS_7_TX;
3329 case SLIMBUS_8_RX: return IDX_SLIMBUS_8_RX;
3330 case SLIMBUS_8_TX: return IDX_SLIMBUS_8_TX;
3331 case AFE_PORT_ID_USB_RX: return IDX_AFE_PORT_ID_USB_RX;
3332 case AFE_PORT_ID_USB_TX: return IDX_AFE_PORT_ID_USB_TX;
3333 case AFE_PORT_ID_PRIMARY_MI2S_RX:
3334 return IDX_AFE_PORT_ID_PRIMARY_MI2S_RX;
3335 case AFE_PORT_ID_PRIMARY_MI2S_TX:
3336 return IDX_AFE_PORT_ID_PRIMARY_MI2S_TX;
3337 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
3338 return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX;
3339 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
3340 return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX;
3341 case AFE_PORT_ID_SECONDARY_MI2S_RX:
3342 return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX;
3343 case AFE_PORT_ID_SECONDARY_MI2S_TX:
3344 return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX;
3345 case AFE_PORT_ID_TERTIARY_MI2S_RX:
3346 return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX;
3347 case AFE_PORT_ID_TERTIARY_MI2S_TX:
3348 return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX;
3349 case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1:
3350 return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_SD1;
3351 case AFE_PORT_ID_QUINARY_MI2S_RX:
3352 return IDX_AFE_PORT_ID_QUINARY_MI2S_RX;
3353 case AFE_PORT_ID_QUINARY_MI2S_TX:
3354 return IDX_AFE_PORT_ID_QUINARY_MI2S_TX;
3355 case AFE_PORT_ID_SENARY_MI2S_TX:
3356 return IDX_AFE_PORT_ID_SENARY_MI2S_TX;
3357 case AFE_PORT_ID_PRIMARY_TDM_RX:
3358 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_0;
3359 case AFE_PORT_ID_PRIMARY_TDM_TX:
3360 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_0;
3361 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
3362 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_1;
3363 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
3364 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_1;
3365 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
3366 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_2;
3367 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
3368 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_2;
3369 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
3370 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_3;
3371 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
3372 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_3;
3373 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
3374 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_4;
3375 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
3376 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_4;
3377 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
3378 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_5;
3379 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
3380 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_5;
3381 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
3382 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_6;
3383 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
3384 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_6;
3385 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
3386 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_7;
3387 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
3388 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_7;
3389 case AFE_PORT_ID_SECONDARY_TDM_RX:
3390 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_0;
3391 case AFE_PORT_ID_SECONDARY_TDM_TX:
3392 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_0;
3393 case AFE_PORT_ID_SECONDARY_TDM_RX_1:
3394 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_1;
3395 case AFE_PORT_ID_SECONDARY_TDM_TX_1:
3396 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_1;
3397 case AFE_PORT_ID_SECONDARY_TDM_RX_2:
3398 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_2;
3399 case AFE_PORT_ID_SECONDARY_TDM_TX_2:
3400 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_2;
3401 case AFE_PORT_ID_SECONDARY_TDM_RX_3:
3402 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_3;
3403 case AFE_PORT_ID_SECONDARY_TDM_TX_3:
3404 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_3;
3405 case AFE_PORT_ID_SECONDARY_TDM_RX_4:
3406 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_4;
3407 case AFE_PORT_ID_SECONDARY_TDM_TX_4:
3408 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_4;
3409 case AFE_PORT_ID_SECONDARY_TDM_RX_5:
3410 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_5;
3411 case AFE_PORT_ID_SECONDARY_TDM_TX_5:
3412 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_5;
3413 case AFE_PORT_ID_SECONDARY_TDM_RX_6:
3414 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_6;
3415 case AFE_PORT_ID_SECONDARY_TDM_TX_6:
3416 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_6;
3417 case AFE_PORT_ID_SECONDARY_TDM_RX_7:
3418 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_7;
3419 case AFE_PORT_ID_SECONDARY_TDM_TX_7:
3420 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_7;
3421 case AFE_PORT_ID_TERTIARY_TDM_RX:
3422 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_0;
3423 case AFE_PORT_ID_TERTIARY_TDM_TX:
3424 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_0;
3425 case AFE_PORT_ID_TERTIARY_TDM_RX_1:
3426 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_1;
3427 case AFE_PORT_ID_TERTIARY_TDM_TX_1:
3428 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_1;
3429 case AFE_PORT_ID_TERTIARY_TDM_RX_2:
3430 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_2;
3431 case AFE_PORT_ID_TERTIARY_TDM_TX_2:
3432 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_2;
3433 case AFE_PORT_ID_TERTIARY_TDM_RX_3:
3434 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_3;
3435 case AFE_PORT_ID_TERTIARY_TDM_TX_3:
3436 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_3;
3437 case AFE_PORT_ID_TERTIARY_TDM_RX_4:
3438 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_4;
3439 case AFE_PORT_ID_TERTIARY_TDM_TX_4:
3440 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_4;
3441 case AFE_PORT_ID_TERTIARY_TDM_RX_5:
3442 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_5;
3443 case AFE_PORT_ID_TERTIARY_TDM_TX_5:
3444 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_5;
3445 case AFE_PORT_ID_TERTIARY_TDM_RX_6:
3446 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_6;
3447 case AFE_PORT_ID_TERTIARY_TDM_TX_6:
3448 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_6;
3449 case AFE_PORT_ID_TERTIARY_TDM_RX_7:
3450 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_7;
3451 case AFE_PORT_ID_TERTIARY_TDM_TX_7:
3452 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_7;
3453 case AFE_PORT_ID_QUATERNARY_TDM_RX:
3454 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_0;
3455 case AFE_PORT_ID_QUATERNARY_TDM_TX:
3456 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_0;
3457 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
3458 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_1;
3459 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
3460 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_1;
3461 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
3462 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_2;
3463 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
3464 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_2;
3465 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
3466 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_3;
3467 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
3468 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_3;
3469 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
3470 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_4;
3471 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
3472 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_4;
3473 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
3474 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_5;
3475 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
3476 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_5;
3477 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
3478 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_6;
3479 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
3480 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_6;
3481 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
3482 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_7;
3483 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
3484 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_7;
Laxminath Kasam4e444572017-01-15 20:00:11 +05303485 case AFE_PORT_ID_INT0_MI2S_RX:
3486 return IDX_AFE_PORT_ID_INT0_MI2S_RX;
3487 case AFE_PORT_ID_INT0_MI2S_TX:
3488 return IDX_AFE_PORT_ID_INT0_MI2S_TX;
3489 case AFE_PORT_ID_INT1_MI2S_RX:
3490 return IDX_AFE_PORT_ID_INT1_MI2S_RX;
3491 case AFE_PORT_ID_INT1_MI2S_TX:
3492 return IDX_AFE_PORT_ID_INT1_MI2S_TX;
3493 case AFE_PORT_ID_INT2_MI2S_RX:
3494 return IDX_AFE_PORT_ID_INT2_MI2S_RX;
3495 case AFE_PORT_ID_INT2_MI2S_TX:
3496 return IDX_AFE_PORT_ID_INT2_MI2S_TX;
3497 case AFE_PORT_ID_INT3_MI2S_RX:
3498 return IDX_AFE_PORT_ID_INT3_MI2S_RX;
3499 case AFE_PORT_ID_INT3_MI2S_TX:
3500 return IDX_AFE_PORT_ID_INT3_MI2S_TX;
3501 case AFE_PORT_ID_INT4_MI2S_RX:
3502 return IDX_AFE_PORT_ID_INT4_MI2S_RX;
3503 case AFE_PORT_ID_INT4_MI2S_TX:
3504 return IDX_AFE_PORT_ID_INT4_MI2S_TX;
3505 case AFE_PORT_ID_INT5_MI2S_RX:
3506 return IDX_AFE_PORT_ID_INT5_MI2S_RX;
3507 case AFE_PORT_ID_INT5_MI2S_TX:
3508 return IDX_AFE_PORT_ID_INT5_MI2S_TX;
3509 case AFE_PORT_ID_INT6_MI2S_RX:
3510 return IDX_AFE_PORT_ID_INT6_MI2S_RX;
3511 case AFE_PORT_ID_INT6_MI2S_TX:
3512 return IDX_AFE_PORT_ID_INT6_MI2S_TX;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003513 default:
3514 pr_err("%s: port 0x%x\n", __func__, port_id);
3515 return -EINVAL;
3516 }
3517}
3518
3519int afe_open(u16 port_id,
3520 union afe_port_config *afe_config, int rate)
3521{
3522 struct afe_port_cmd_device_start start;
3523 struct afe_audioif_config_command config;
3524 int ret = 0;
3525 int cfg_type;
3526 int index = 0;
3527
3528 if (!afe_config) {
3529 pr_err("%s: Error, no configuration data\n", __func__);
3530 ret = -EINVAL;
3531 return ret;
3532 }
3533
3534 pr_err("%s: port_id 0x%x rate %d\n", __func__, port_id, rate);
3535
3536 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08003537 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003538 pr_err("%s: AFE port index[%d] invalid!\n",
3539 __func__, index);
3540 return -EINVAL;
3541 }
3542 ret = q6audio_validate_port(port_id);
3543 if (ret < 0) {
3544 pr_err("%s: Invalid port 0x%x ret %d", __func__, port_id, ret);
3545 return -EINVAL;
3546 }
3547
3548 if ((port_id == RT_PROXY_DAI_001_RX) ||
3549 (port_id == RT_PROXY_DAI_002_TX)) {
3550 pr_err("%s: wrong port 0x%x\n", __func__, port_id);
3551 return -EINVAL;
3552 }
3553 if ((port_id == RT_PROXY_DAI_002_RX) ||
3554 (port_id == RT_PROXY_DAI_001_TX))
3555 port_id = VIRTUAL_ID_TO_PORTID(port_id);
3556
3557 ret = afe_q6_interface_prepare();
3558 if (ret != 0) {
3559 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
3560 return -EINVAL;
3561 }
Siena Richard23364c92017-01-11 16:20:55 -08003562
3563 if ((index >= 0) && (index < AFE_MAX_PORTS)) {
3564 this_afe.afe_sample_rates[index] = rate;
3565
3566 if (this_afe.rt_cb)
3567 this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id);
3568 }
3569
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003570 /* Also send the topology id here: */
3571 afe_send_custom_topology(); /* One time call: only for first time */
3572 afe_send_port_topology_id(port_id);
3573
3574 ret = q6audio_validate_port(port_id);
3575 if (ret < 0) {
3576 pr_err("%s: Failed : Invalid Port id = 0x%x ret %d\n",
3577 __func__, port_id, ret);
3578 return -EINVAL;
3579 }
3580 mutex_lock(&this_afe.afe_cmd_lock);
3581
3582 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3583 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3584 config.hdr.pkt_size = sizeof(config);
3585 config.hdr.src_port = 0;
3586 config.hdr.dest_port = 0;
3587 config.hdr.token = index;
3588 switch (port_id) {
3589 case PRIMARY_I2S_RX:
3590 case PRIMARY_I2S_TX:
3591 cfg_type = AFE_PARAM_ID_I2S_CONFIG;
3592 break;
3593 case AFE_PORT_ID_PRIMARY_PCM_RX:
3594 case AFE_PORT_ID_PRIMARY_PCM_TX:
3595 case AFE_PORT_ID_SECONDARY_PCM_RX:
3596 case AFE_PORT_ID_SECONDARY_PCM_TX:
3597 case AFE_PORT_ID_TERTIARY_PCM_RX:
3598 case AFE_PORT_ID_TERTIARY_PCM_TX:
3599 case AFE_PORT_ID_QUATERNARY_PCM_RX:
3600 case AFE_PORT_ID_QUATERNARY_PCM_TX:
3601 cfg_type = AFE_PARAM_ID_PCM_CONFIG;
3602 break;
3603 case SECONDARY_I2S_RX:
3604 case SECONDARY_I2S_TX:
3605 case AFE_PORT_ID_PRIMARY_MI2S_RX:
3606 case AFE_PORT_ID_PRIMARY_MI2S_TX:
3607 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
3608 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
3609 case MI2S_RX:
3610 case MI2S_TX:
3611 case AFE_PORT_ID_QUINARY_MI2S_RX:
3612 case AFE_PORT_ID_QUINARY_MI2S_TX:
3613 case AFE_PORT_ID_SENARY_MI2S_TX:
3614 cfg_type = AFE_PARAM_ID_I2S_CONFIG;
3615 break;
3616 case HDMI_RX:
3617 case DISPLAY_PORT_RX:
3618 cfg_type = AFE_PARAM_ID_HDMI_CONFIG;
3619 break;
3620 case SLIMBUS_0_RX:
3621 case SLIMBUS_0_TX:
3622 case SLIMBUS_1_RX:
3623 case SLIMBUS_1_TX:
3624 case SLIMBUS_2_RX:
3625 case SLIMBUS_2_TX:
3626 case SLIMBUS_3_RX:
3627 case SLIMBUS_3_TX:
3628 case SLIMBUS_4_RX:
3629 case SLIMBUS_4_TX:
3630 case SLIMBUS_5_RX:
3631 case SLIMBUS_6_RX:
3632 case SLIMBUS_6_TX:
3633 case SLIMBUS_7_RX:
3634 case SLIMBUS_7_TX:
3635 case SLIMBUS_8_RX:
3636 case SLIMBUS_8_TX:
3637 cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG;
3638 break;
3639 case AFE_PORT_ID_USB_RX:
3640 case AFE_PORT_ID_USB_TX:
3641 cfg_type = AFE_PARAM_ID_USB_AUDIO_CONFIG;
3642 break;
3643 default:
3644 pr_err("%s: Invalid port id 0x%x\n",
3645 __func__, port_id);
3646 ret = -EINVAL;
3647 goto fail_cmd;
3648 }
3649 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
3650 config.param.port_id = q6audio_get_port_id(port_id);
3651 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr)
3652 - sizeof(config.param);
3653 config.param.payload_address_lsw = 0x00;
3654 config.param.payload_address_msw = 0x00;
3655 config.param.mem_map_handle = 0x00;
3656 config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
3657 config.pdata.param_id = cfg_type;
3658 config.pdata.param_size = sizeof(config.port);
3659
3660 config.port = *afe_config;
3661 pr_debug("%s: param PL size=%d iparam_size[%d][%zd %zd %zd %zd] param_id[0x%x]\n",
3662 __func__, config.param.payload_size, config.pdata.param_size,
3663 sizeof(config), sizeof(config.param), sizeof(config.port),
3664 sizeof(struct apr_hdr), config.pdata.param_id);
3665
3666 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
3667 if (ret) {
3668 pr_err("%s: AFE enable for port 0x%x opcode[0x%x]failed %d\n",
3669 __func__, port_id, cfg_type, ret);
3670 goto fail_cmd;
3671 }
3672 start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3673 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3674 start.hdr.pkt_size = sizeof(start);
3675 start.hdr.src_port = 0;
3676 start.hdr.dest_port = 0;
3677 start.hdr.token = index;
3678 start.hdr.opcode = AFE_PORT_CMD_DEVICE_START;
3679 start.port_id = q6audio_get_port_id(port_id);
3680 pr_debug("%s: cmd device start opcode[0x%x] port id[0x%x]\n",
3681 __func__, start.hdr.opcode, start.port_id);
3682
3683 ret = afe_apr_send_pkt(&start, &this_afe.wait[index]);
3684 if (ret) {
3685 pr_err("%s: AFE enable for port 0x%x failed %d\n", __func__,
3686 port_id, ret);
3687 goto fail_cmd;
3688 }
3689
3690fail_cmd:
3691 mutex_unlock(&this_afe.afe_cmd_lock);
3692 return ret;
3693}
3694
3695int afe_loopback(u16 enable, u16 rx_port, u16 tx_port)
3696{
3697 struct afe_loopback_cfg_v1 lb_cmd;
3698 int ret = 0;
3699 int index = 0;
3700
3701 if (rx_port == MI2S_RX)
3702 rx_port = AFE_PORT_ID_PRIMARY_MI2S_RX;
3703 if (tx_port == MI2S_TX)
3704 tx_port = AFE_PORT_ID_PRIMARY_MI2S_TX;
3705
3706 ret = afe_q6_interface_prepare();
3707 if (ret != 0) {
3708 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
3709 return ret;
3710 }
3711
3712 index = q6audio_get_port_index(rx_port);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08003713 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003714 pr_err("%s: AFE port index[%d] invalid!\n",
3715 __func__, index);
3716 return -EINVAL;
3717 }
3718 ret = q6audio_validate_port(rx_port);
3719 if (ret < 0) {
3720 pr_err("%s: Invalid port 0x%x ret %d", __func__, rx_port, ret);
3721 return -EINVAL;
3722 }
3723
3724 lb_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3725 APR_HDR_LEN(20), APR_PKT_VER);
3726 lb_cmd.hdr.pkt_size = sizeof(lb_cmd);
3727 lb_cmd.hdr.src_port = 0;
3728 lb_cmd.hdr.dest_port = 0;
3729 lb_cmd.hdr.token = index;
3730 lb_cmd.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
3731 lb_cmd.param.port_id = tx_port;
3732 lb_cmd.param.payload_size = (sizeof(lb_cmd) - sizeof(struct apr_hdr) -
3733 sizeof(struct afe_port_cmd_set_param_v2));
3734 lb_cmd.param.payload_address_lsw = 0x00;
3735 lb_cmd.param.payload_address_msw = 0x00;
3736 lb_cmd.param.mem_map_handle = 0x00;
3737 lb_cmd.pdata.module_id = AFE_MODULE_LOOPBACK;
3738 lb_cmd.pdata.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG;
3739 lb_cmd.pdata.param_size = lb_cmd.param.payload_size -
3740 sizeof(struct afe_port_param_data_v2);
3741
3742 lb_cmd.dst_port_id = rx_port;
3743 lb_cmd.routing_mode = LB_MODE_DEFAULT;
3744 lb_cmd.enable = (enable ? 1 : 0);
3745 lb_cmd.loopback_cfg_minor_version = AFE_API_VERSION_LOOPBACK_CONFIG;
3746
3747 ret = afe_apr_send_pkt(&lb_cmd, &this_afe.wait[index]);
3748 if (ret)
3749 pr_err("%s: AFE loopback failed %d\n", __func__, ret);
3750 return ret;
3751}
3752
3753int afe_loopback_gain(u16 port_id, u16 volume)
3754{
3755 struct afe_loopback_gain_per_path_param set_param;
3756 int ret = 0;
3757 int index = 0;
3758
3759 if (this_afe.apr == NULL) {
3760 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
3761 0xFFFFFFFF, &this_afe);
3762 pr_debug("%s: Register AFE\n", __func__);
3763 if (this_afe.apr == NULL) {
3764 pr_err("%s: Unable to register AFE\n", __func__);
3765 ret = -ENODEV;
3766 return ret;
3767 }
3768 rtac_set_afe_handle(this_afe.apr);
3769 }
3770
3771 ret = q6audio_validate_port(port_id);
3772 if (ret < 0) {
3773 pr_err("%s: Failed : Invalid Port id = 0x%x ret %d\n",
3774 __func__, port_id, ret);
3775 ret = -EINVAL;
3776 goto fail_cmd;
3777 }
3778 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08003779 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003780 pr_err("%s: AFE port index[%d] invalid!\n",
3781 __func__, index);
3782 return -EINVAL;
3783 }
3784 ret = q6audio_validate_port(port_id);
3785 if (ret < 0) {
3786 pr_err("%s: Invalid port 0x%x ret %d",
3787 __func__, port_id, ret);
3788 return -EINVAL;
3789 }
3790
3791 /* RX ports numbers are even .TX ports numbers are odd. */
3792 if (port_id % 2 == 0) {
3793 pr_err("%s: Failed : afe loopback gain only for TX ports. port_id %d\n",
3794 __func__, port_id);
3795 ret = -EINVAL;
3796 goto fail_cmd;
3797 }
3798
3799 pr_debug("%s: port 0x%x volume %d\n", __func__, port_id, volume);
3800
3801 set_param.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3802 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3803 set_param.hdr.pkt_size = sizeof(set_param);
3804 set_param.hdr.src_port = 0;
3805 set_param.hdr.dest_port = 0;
3806 set_param.hdr.token = index;
3807 set_param.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
3808
3809 set_param.param.port_id = port_id;
3810 set_param.param.payload_size =
3811 (sizeof(struct afe_loopback_gain_per_path_param) -
3812 sizeof(struct apr_hdr) - sizeof(struct afe_port_cmd_set_param_v2));
3813 set_param.param.payload_address_lsw = 0;
3814 set_param.param.payload_address_msw = 0;
3815 set_param.param.mem_map_handle = 0;
3816
3817 set_param.pdata.module_id = AFE_MODULE_LOOPBACK;
3818 set_param.pdata.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH;
3819 set_param.pdata.param_size =
3820 (set_param.param.payload_size -
3821 sizeof(struct afe_port_param_data_v2));
3822 set_param.rx_port_id = port_id;
3823 set_param.gain = volume;
3824
3825 ret = afe_apr_send_pkt(&set_param, &this_afe.wait[index]);
3826 if (ret) {
3827 pr_err("%s: AFE param set failed for port 0x%x ret %d\n",
3828 __func__, port_id, ret);
3829 goto fail_cmd;
3830 }
3831
3832fail_cmd:
3833 return ret;
3834}
3835
3836int afe_pseudo_port_start_nowait(u16 port_id)
3837{
3838 struct afe_pseudoport_start_command start;
3839 int ret = 0;
3840
3841 pr_debug("%s: port_id=0x%x\n", __func__, port_id);
3842 if (this_afe.apr == NULL) {
3843 pr_err("%s: AFE APR is not registered\n", __func__);
3844 return -ENODEV;
3845 }
3846
3847
3848 start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3849 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3850 start.hdr.pkt_size = sizeof(start);
3851 start.hdr.src_port = 0;
3852 start.hdr.dest_port = 0;
3853 start.hdr.token = 0;
3854 start.hdr.opcode = AFE_PSEUDOPORT_CMD_START;
3855 start.port_id = port_id;
3856 start.timing = 1;
3857
3858 ret = afe_apr_send_pkt(&start, NULL);
3859 if (ret) {
3860 pr_err("%s: AFE enable for port 0x%x failed %d\n",
3861 __func__, port_id, ret);
3862 return ret;
3863 }
3864 return 0;
3865}
3866
3867int afe_start_pseudo_port(u16 port_id)
3868{
3869 int ret = 0;
3870 struct afe_pseudoport_start_command start;
3871 int index = 0;
3872
3873 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
3874
3875 ret = afe_q6_interface_prepare();
3876 if (ret != 0) {
3877 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
3878 return ret;
3879 }
3880
3881 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08003882 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003883 pr_err("%s: AFE port index[%d] invalid!\n",
3884 __func__, index);
3885 return -EINVAL;
3886 }
3887 ret = q6audio_validate_port(port_id);
3888 if (ret < 0) {
3889 pr_err("%s: Invalid port 0x%x ret %d",
3890 __func__, port_id, ret);
3891 return -EINVAL;
3892 }
3893
3894 start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3895 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3896 start.hdr.pkt_size = sizeof(start);
3897 start.hdr.src_port = 0;
3898 start.hdr.dest_port = 0;
3899 start.hdr.token = 0;
3900 start.hdr.opcode = AFE_PSEUDOPORT_CMD_START;
3901 start.port_id = port_id;
3902 start.timing = 1;
3903 start.hdr.token = index;
3904
3905 ret = afe_apr_send_pkt(&start, &this_afe.wait[index]);
3906 if (ret)
3907 pr_err("%s: AFE enable for port 0x%x failed %d\n",
3908 __func__, port_id, ret);
3909 return ret;
3910}
3911
3912int afe_pseudo_port_stop_nowait(u16 port_id)
3913{
3914 int ret = 0;
3915 struct afe_pseudoport_stop_command stop;
3916 int index = 0;
3917
3918 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
3919
3920 if (this_afe.apr == NULL) {
3921 pr_err("%s: AFE is already closed\n", __func__);
3922 return -EINVAL;
3923 }
3924 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08003925 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003926 pr_err("%s: AFE port index[%d] invalid!\n",
3927 __func__, index);
3928 return -EINVAL;
3929 }
3930 ret = q6audio_validate_port(port_id);
3931 if (ret < 0) {
3932 pr_err("%s: Invalid port 0x%x ret %d",
3933 __func__, port_id, ret);
3934 return -EINVAL;
3935 }
3936
3937 stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3938 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3939 stop.hdr.pkt_size = sizeof(stop);
3940 stop.hdr.src_port = 0;
3941 stop.hdr.dest_port = 0;
3942 stop.hdr.token = 0;
3943 stop.hdr.opcode = AFE_PSEUDOPORT_CMD_STOP;
3944 stop.port_id = port_id;
3945 stop.reserved = 0;
3946 stop.hdr.token = index;
3947
3948 ret = afe_apr_send_pkt(&stop, NULL);
3949 if (ret)
3950 pr_err("%s: AFE close failed %d\n", __func__, ret);
3951
3952 return ret;
3953}
3954
3955int afe_port_group_set_param(u16 group_id,
3956 union afe_port_group_config *afe_group_config)
3957{
3958 int ret;
3959 struct afe_port_group_create config;
3960 int cfg_type;
3961
3962 if (!afe_group_config) {
3963 pr_err("%s: Error, no configuration data\n", __func__);
3964 return -EINVAL;
3965 }
3966
3967 pr_debug("%s: group id: 0x%x\n", __func__, group_id);
3968
3969 ret = afe_q6_interface_prepare();
3970 if (ret != 0) {
3971 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
3972 return ret;
3973 }
3974
3975 switch (group_id) {
3976 case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX:
3977 case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX:
3978 case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_RX:
3979 case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_TX:
3980 case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_RX:
3981 case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_TX:
3982 case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_RX:
3983 case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_TX:
3984 cfg_type = AFE_PARAM_ID_GROUP_DEVICE_TDM_CONFIG;
3985 break;
3986 default:
3987 pr_err("%s: Invalid group id 0x%x\n", __func__, group_id);
3988 return -EINVAL;
3989 }
3990
3991 memset(&config, 0, sizeof(config));
3992 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3993 APR_HDR_LEN(APR_HDR_SIZE),
3994 APR_PKT_VER);
3995 config.hdr.pkt_size = sizeof(config);
3996 config.hdr.src_port = 0;
3997 config.hdr.dest_port = 0;
3998 config.hdr.token = IDX_GLOBAL_CFG;
3999 config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
4000
4001 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
4002 sizeof(config.param);
4003 config.param.payload_address_lsw = 0x00;
4004 config.param.payload_address_msw = 0x00;
4005 config.param.mem_map_handle = 0x00;
4006 config.pdata.module_id = AFE_MODULE_GROUP_DEVICE;
4007 config.pdata.param_id = cfg_type;
4008 config.pdata.param_size = sizeof(config.data);
4009 config.data = *afe_group_config;
4010
4011 ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
4012 if (ret)
4013 pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_CFG failed %d\n",
4014 __func__, ret);
4015
4016 return ret;
4017}
4018
4019int afe_port_group_enable(u16 group_id,
4020 union afe_port_group_config *afe_group_config,
4021 u16 enable)
4022{
4023 int ret;
4024 struct afe_port_group_create config;
4025
4026 pr_debug("%s: group id: 0x%x enable: %d\n", __func__,
4027 group_id, enable);
4028
4029 ret = afe_q6_interface_prepare();
4030 if (ret != 0) {
4031 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
4032 return ret;
4033 }
4034
4035 if (enable) {
4036 ret = afe_port_group_set_param(group_id, afe_group_config);
4037 if (ret < 0) {
4038 pr_err("%s: afe send failed %d\n", __func__, ret);
4039 return ret;
4040 }
4041 }
4042
4043 memset(&config, 0, sizeof(config));
4044 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4045 APR_HDR_LEN(APR_HDR_SIZE),
4046 APR_PKT_VER);
4047 config.hdr.pkt_size = sizeof(config);
4048 config.hdr.src_port = 0;
4049 config.hdr.dest_port = 0;
4050 config.hdr.token = IDX_GLOBAL_CFG;
4051 config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
4052
4053 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
4054 sizeof(config.param);
4055 config.param.payload_address_lsw = 0x00;
4056 config.param.payload_address_msw = 0x00;
4057 config.param.mem_map_handle = 0x00;
4058 config.pdata.module_id = AFE_MODULE_GROUP_DEVICE;
4059 config.pdata.param_id = AFE_PARAM_ID_GROUP_DEVICE_ENABLE;
4060 config.pdata.param_size = sizeof(config.data);
4061 config.data.group_enable.group_id = group_id;
4062 config.data.group_enable.enable = enable;
4063
4064 ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
4065 if (ret)
4066 pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_ENABLE failed %d\n",
4067 __func__, ret);
4068
4069 return ret;
4070}
4071
4072int afe_stop_pseudo_port(u16 port_id)
4073{
4074 int ret = 0;
4075 struct afe_pseudoport_stop_command stop;
4076 int index = 0;
4077
4078 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
4079
4080 if (this_afe.apr == NULL) {
4081 pr_err("%s: AFE is already closed\n", __func__);
4082 return -EINVAL;
4083 }
4084
4085 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08004086 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08004087 pr_err("%s: AFE port index[%d] invalid!\n",
4088 __func__, index);
4089 return -EINVAL;
4090 }
4091 ret = q6audio_validate_port(port_id);
4092 if (ret < 0) {
4093 pr_err("%s: Invalid port 0x%x ret %d\n",
4094 __func__, port_id, ret);
4095 return -EINVAL;
4096 }
4097
4098 stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4099 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4100 stop.hdr.pkt_size = sizeof(stop);
4101 stop.hdr.src_port = 0;
4102 stop.hdr.dest_port = 0;
4103 stop.hdr.token = 0;
4104 stop.hdr.opcode = AFE_PSEUDOPORT_CMD_STOP;
4105 stop.port_id = port_id;
4106 stop.reserved = 0;
4107 stop.hdr.token = index;
4108
4109 ret = afe_apr_send_pkt(&stop, &this_afe.wait[index]);
4110 if (ret)
4111 pr_err("%s: AFE close failed %d\n", __func__, ret);
4112
4113 return ret;
4114}
4115
4116uint32_t afe_req_mmap_handle(struct afe_audio_client *ac)
4117{
4118 return ac->mem_map_handle;
4119}
4120
4121struct afe_audio_client *q6afe_audio_client_alloc(void *priv)
4122{
4123 struct afe_audio_client *ac;
4124 int lcnt = 0;
4125
4126 ac = kzalloc(sizeof(struct afe_audio_client), GFP_KERNEL);
4127 if (!ac)
4128 return NULL;
4129
4130 ac->priv = priv;
4131
4132 init_waitqueue_head(&ac->cmd_wait);
4133 INIT_LIST_HEAD(&ac->port[0].mem_map_handle);
4134 INIT_LIST_HEAD(&ac->port[1].mem_map_handle);
4135 pr_debug("%s: mem_map_handle list init'ed\n", __func__);
4136 mutex_init(&ac->cmd_lock);
4137 for (lcnt = 0; lcnt <= OUT; lcnt++) {
4138 mutex_init(&ac->port[lcnt].lock);
4139 spin_lock_init(&ac->port[lcnt].dsp_lock);
4140 }
4141 atomic_set(&ac->cmd_state, 0);
4142
4143 return ac;
4144}
4145
4146int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir,
4147 struct afe_audio_client *ac,
4148 unsigned int bufsz,
4149 unsigned int bufcnt)
4150{
4151 int cnt = 0;
4152 int rc = 0;
4153 struct afe_audio_buffer *buf;
4154 size_t len;
4155
4156 if (!(ac) || ((dir != IN) && (dir != OUT))) {
4157 pr_err("%s: ac %pK dir %d\n", __func__, ac, dir);
4158 return -EINVAL;
4159 }
4160
4161 pr_debug("%s: bufsz[%d]bufcnt[%d]\n",
4162 __func__,
4163 bufsz, bufcnt);
4164
4165 if (ac->port[dir].buf) {
4166 pr_debug("%s: buffer already allocated\n", __func__);
4167 return 0;
4168 }
4169 mutex_lock(&ac->cmd_lock);
4170 buf = kzalloc(((sizeof(struct afe_audio_buffer))*bufcnt),
4171 GFP_KERNEL);
4172
4173 if (!buf) {
4174 pr_err("%s: null buf\n", __func__);
4175 mutex_unlock(&ac->cmd_lock);
4176 goto fail;
4177 }
4178
4179 ac->port[dir].buf = buf;
4180
4181 rc = msm_audio_ion_alloc("afe_client", &buf[0].client,
4182 &buf[0].handle, bufsz*bufcnt,
4183 &buf[0].phys, &len,
4184 &buf[0].data);
4185 if (rc) {
4186 pr_err("%s: audio ION alloc failed, rc = %d\n",
4187 __func__, rc);
4188 mutex_unlock(&ac->cmd_lock);
4189 goto fail;
4190 }
4191
4192 buf[0].used = dir ^ 1;
4193 buf[0].size = bufsz;
4194 buf[0].actual_size = bufsz;
4195 cnt = 1;
4196 while (cnt < bufcnt) {
4197 if (bufsz > 0) {
4198 buf[cnt].data = buf[0].data + (cnt * bufsz);
4199 buf[cnt].phys = buf[0].phys + (cnt * bufsz);
4200 if (!buf[cnt].data) {
4201 pr_err("%s: Buf alloc failed\n",
4202 __func__);
4203 mutex_unlock(&ac->cmd_lock);
4204 goto fail;
4205 }
4206 buf[cnt].used = dir ^ 1;
4207 buf[cnt].size = bufsz;
4208 buf[cnt].actual_size = bufsz;
4209 pr_debug("%s: data[%pK]phys[%pK][%pK]\n", __func__,
4210 buf[cnt].data,
4211 &buf[cnt].phys,
4212 &buf[cnt].phys);
4213 }
4214 cnt++;
4215 }
4216 ac->port[dir].max_buf_cnt = cnt;
4217 mutex_unlock(&ac->cmd_lock);
4218 return 0;
4219fail:
4220 pr_err("%s: jump fail\n", __func__);
4221 q6afe_audio_client_buf_free_contiguous(dir, ac);
4222 return -EINVAL;
4223}
4224
4225int afe_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz,
4226 struct afe_audio_client *ac)
4227{
4228 int ret = 0;
4229
4230 mutex_lock(&this_afe.afe_cmd_lock);
4231 ac->mem_map_handle = 0;
4232 ret = afe_cmd_memory_map(dma_addr_p, dma_buf_sz);
4233 if (ret < 0) {
4234 pr_err("%s: afe_cmd_memory_map failed %d\n",
4235 __func__, ret);
4236
4237 mutex_unlock(&this_afe.afe_cmd_lock);
4238 return ret;
4239 }
4240 ac->mem_map_handle = this_afe.mmap_handle;
4241 mutex_unlock(&this_afe.afe_cmd_lock);
4242
4243 return ret;
4244}
4245
4246int afe_cmd_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz)
4247{
4248 int ret = 0;
4249 int cmd_size = 0;
4250 void *payload = NULL;
4251 void *mmap_region_cmd = NULL;
4252 struct afe_service_cmd_shared_mem_map_regions *mregion = NULL;
4253 struct afe_service_shared_map_region_payload *mregion_pl = NULL;
4254 int index = 0;
4255
4256 pr_debug("%s:\n", __func__);
4257
4258 if (this_afe.apr == NULL) {
4259 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
4260 0xFFFFFFFF, &this_afe);
4261 pr_debug("%s: Register AFE\n", __func__);
4262 if (this_afe.apr == NULL) {
4263 pr_err("%s: Unable to register AFE\n", __func__);
4264 ret = -ENODEV;
4265 return ret;
4266 }
4267 rtac_set_afe_handle(this_afe.apr);
4268 }
4269 if (dma_buf_sz % SZ_4K != 0) {
4270 /*
4271 * The memory allocated by msm_audio_ion_alloc is always 4kB
4272 * aligned, ADSP expects the size to be 4kB aligned as well
4273 * so re-adjusts the buffer size before passing to ADSP.
4274 */
4275 dma_buf_sz = PAGE_ALIGN(dma_buf_sz);
4276 }
4277
4278 cmd_size = sizeof(struct afe_service_cmd_shared_mem_map_regions)
4279 + sizeof(struct afe_service_shared_map_region_payload);
4280
4281 mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL);
4282 if (!mmap_region_cmd)
4283 return -ENOMEM;
4284
4285 mregion = (struct afe_service_cmd_shared_mem_map_regions *)
4286 mmap_region_cmd;
4287 mregion->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4288 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4289 mregion->hdr.pkt_size = cmd_size;
4290 mregion->hdr.src_port = 0;
4291 mregion->hdr.dest_port = 0;
4292 mregion->hdr.token = 0;
4293 mregion->hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS;
4294 mregion->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL;
4295 mregion->num_regions = 1;
4296 mregion->property_flag = 0x00;
4297 /* Todo */
4298 index = mregion->hdr.token = IDX_RSVD_2;
4299
4300 payload = ((u8 *) mmap_region_cmd +
4301 sizeof(struct afe_service_cmd_shared_mem_map_regions));
4302
4303 mregion_pl = (struct afe_service_shared_map_region_payload *)payload;
4304
4305 mregion_pl->shm_addr_lsw = lower_32_bits(dma_addr_p);
4306 mregion_pl->shm_addr_msw = msm_audio_populate_upper_32_bits(dma_addr_p);
4307 mregion_pl->mem_size_bytes = dma_buf_sz;
4308
4309 pr_debug("%s: dma_addr_p 0x%pK , size %d\n", __func__,
4310 &dma_addr_p, dma_buf_sz);
4311 atomic_set(&this_afe.state, 1);
4312 atomic_set(&this_afe.status, 0);
4313 this_afe.mmap_handle = 0;
4314 ret = apr_send_pkt(this_afe.apr, (uint32_t *) mmap_region_cmd);
4315 if (ret < 0) {
4316 pr_err("%s: AFE memory map cmd failed %d\n",
4317 __func__, ret);
4318 ret = -EINVAL;
4319 goto fail_cmd;
4320 }
4321
4322 ret = wait_event_timeout(this_afe.wait[index],
4323 (atomic_read(&this_afe.state) == 0),
4324 msecs_to_jiffies(TIMEOUT_MS));
4325 if (!ret) {
4326 pr_err("%s: wait_event timeout\n", __func__);
4327 ret = -EINVAL;
4328 goto fail_cmd;
4329 }
4330 if (atomic_read(&this_afe.status) > 0) {
4331 pr_err("%s: config cmd failed [%s]\n",
4332 __func__, adsp_err_get_err_str(
4333 atomic_read(&this_afe.status)));
4334 ret = adsp_err_get_lnx_err_code(
4335 atomic_read(&this_afe.status));
4336 goto fail_cmd;
4337 }
4338
4339 kfree(mmap_region_cmd);
4340 return 0;
4341fail_cmd:
4342 kfree(mmap_region_cmd);
4343 pr_err("%s: fail_cmd\n", __func__);
4344 return ret;
4345}
4346
4347int afe_cmd_memory_map_nowait(int port_id, phys_addr_t dma_addr_p,
4348 u32 dma_buf_sz)
4349{
4350 int ret = 0;
4351 int cmd_size = 0;
4352 void *payload = NULL;
4353 void *mmap_region_cmd = NULL;
4354 struct afe_service_cmd_shared_mem_map_regions *mregion = NULL;
4355 struct afe_service_shared_map_region_payload *mregion_pl = NULL;
4356 int index = 0;
4357
4358 pr_debug("%s:\n", __func__);
4359
4360 if (this_afe.apr == NULL) {
4361 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
4362 0xFFFFFFFF, &this_afe);
4363 pr_debug("%s: Register AFE\n", __func__);
4364 if (this_afe.apr == NULL) {
4365 pr_err("%s: Unable to register AFE\n", __func__);
4366 ret = -ENODEV;
4367 return ret;
4368 }
4369 rtac_set_afe_handle(this_afe.apr);
4370 }
4371 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08004372 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08004373 pr_err("%s: AFE port index[%d] invalid!\n",
4374 __func__, index);
4375 return -EINVAL;
4376 }
4377 ret = q6audio_validate_port(port_id);
4378 if (ret < 0) {
4379 pr_err("%s: Invalid port 0x%x ret %d",
4380 __func__, port_id, ret);
4381 return -EINVAL;
4382 }
4383
4384 cmd_size = sizeof(struct afe_service_cmd_shared_mem_map_regions)
4385 + sizeof(struct afe_service_shared_map_region_payload);
4386
4387 mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL);
4388 if (!mmap_region_cmd)
4389 return -ENOMEM;
4390
4391 mregion = (struct afe_service_cmd_shared_mem_map_regions *)
4392 mmap_region_cmd;
4393 mregion->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4394 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4395 mregion->hdr.pkt_size = sizeof(mregion);
4396 mregion->hdr.src_port = 0;
4397 mregion->hdr.dest_port = 0;
4398 mregion->hdr.token = 0;
4399 mregion->hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS;
4400 mregion->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL;
4401 mregion->num_regions = 1;
4402 mregion->property_flag = 0x00;
4403
4404 payload = ((u8 *) mmap_region_cmd +
4405 sizeof(struct afe_service_cmd_shared_mem_map_regions));
4406 mregion_pl = (struct afe_service_shared_map_region_payload *)payload;
4407
4408 mregion_pl->shm_addr_lsw = lower_32_bits(dma_addr_p);
4409 mregion_pl->shm_addr_msw = msm_audio_populate_upper_32_bits(dma_addr_p);
4410 mregion_pl->mem_size_bytes = dma_buf_sz;
4411
4412 ret = afe_apr_send_pkt(mmap_region_cmd, NULL);
4413 if (ret)
4414 pr_err("%s: AFE memory map cmd failed %d\n",
4415 __func__, ret);
4416 kfree(mmap_region_cmd);
4417 return ret;
4418}
4419int q6afe_audio_client_buf_free_contiguous(unsigned int dir,
4420 struct afe_audio_client *ac)
4421{
4422 struct afe_audio_port_data *port;
4423 int cnt = 0;
4424
4425 mutex_lock(&ac->cmd_lock);
4426 port = &ac->port[dir];
4427 if (!port->buf) {
4428 pr_err("%s: buf is null\n", __func__);
4429 mutex_unlock(&ac->cmd_lock);
4430 return 0;
4431 }
4432 cnt = port->max_buf_cnt - 1;
4433
4434 if (port->buf[0].data) {
4435 pr_debug("%s: data[%pK]phys[%pK][%pK] , client[%pK] handle[%pK]\n",
4436 __func__,
4437 port->buf[0].data,
4438 &port->buf[0].phys,
4439 &port->buf[0].phys,
4440 port->buf[0].client,
4441 port->buf[0].handle);
4442 msm_audio_ion_free(port->buf[0].client, port->buf[0].handle);
4443 port->buf[0].client = NULL;
4444 port->buf[0].handle = NULL;
4445 }
4446
4447 while (cnt >= 0) {
4448 port->buf[cnt].data = NULL;
4449 port->buf[cnt].phys = 0;
4450 cnt--;
4451 }
4452 port->max_buf_cnt = 0;
4453 kfree(port->buf);
4454 port->buf = NULL;
4455 mutex_unlock(&ac->cmd_lock);
4456 return 0;
4457}
4458
4459void q6afe_audio_client_free(struct afe_audio_client *ac)
4460{
4461 int loopcnt;
4462 struct afe_audio_port_data *port;
4463
4464 if (!ac) {
4465 pr_err("%s: audio client is NULL\n", __func__);
4466 return;
4467 }
4468 for (loopcnt = 0; loopcnt <= OUT; loopcnt++) {
4469 port = &ac->port[loopcnt];
4470 if (!port->buf)
4471 continue;
4472 pr_debug("%s: loopcnt = %d\n", __func__, loopcnt);
4473 q6afe_audio_client_buf_free_contiguous(loopcnt, ac);
4474 }
4475 kfree(ac);
4476}
4477
4478int afe_cmd_memory_unmap(u32 mem_map_handle)
4479{
4480 int ret = 0;
4481 struct afe_service_cmd_shared_mem_unmap_regions mregion;
4482 int index = 0;
4483
4484 pr_debug("%s: handle 0x%x\n", __func__, mem_map_handle);
4485
4486 if (this_afe.apr == NULL) {
4487 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
4488 0xFFFFFFFF, &this_afe);
4489 pr_debug("%s: Register AFE\n", __func__);
4490 if (this_afe.apr == NULL) {
4491 pr_err("%s: Unable to register AFE\n", __func__);
4492 ret = -ENODEV;
4493 return ret;
4494 }
4495 rtac_set_afe_handle(this_afe.apr);
4496 }
4497
4498 mregion.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4499 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4500 mregion.hdr.pkt_size = sizeof(mregion);
4501 mregion.hdr.src_port = 0;
4502 mregion.hdr.dest_port = 0;
4503 mregion.hdr.token = 0;
4504 mregion.hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_UNMAP_REGIONS;
4505 mregion.mem_map_handle = mem_map_handle;
4506
4507 /* Todo */
4508 index = mregion.hdr.token = IDX_RSVD_2;
4509
4510 atomic_set(&this_afe.status, 0);
4511 ret = afe_apr_send_pkt(&mregion, &this_afe.wait[index]);
4512 if (ret)
4513 pr_err("%s: AFE memory unmap cmd failed %d\n",
4514 __func__, ret);
4515
4516 return ret;
4517}
4518
4519int afe_cmd_memory_unmap_nowait(u32 mem_map_handle)
4520{
4521 int ret = 0;
4522 struct afe_service_cmd_shared_mem_unmap_regions mregion;
4523
4524 pr_debug("%s: handle 0x%x\n", __func__, mem_map_handle);
4525
4526 if (this_afe.apr == NULL) {
4527 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
4528 0xFFFFFFFF, &this_afe);
4529 pr_debug("%s: Register AFE\n", __func__);
4530 if (this_afe.apr == NULL) {
4531 pr_err("%s: Unable to register AFE\n", __func__);
4532 ret = -ENODEV;
4533 return ret;
4534 }
4535 rtac_set_afe_handle(this_afe.apr);
4536 }
4537
4538 mregion.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4539 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4540 mregion.hdr.pkt_size = sizeof(mregion);
4541 mregion.hdr.src_port = 0;
4542 mregion.hdr.dest_port = 0;
4543 mregion.hdr.token = 0;
4544 mregion.hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_UNMAP_REGIONS;
4545 mregion.mem_map_handle = mem_map_handle;
4546
4547 ret = afe_apr_send_pkt(&mregion, NULL);
4548 if (ret)
4549 pr_err("%s: AFE memory unmap cmd failed %d\n",
4550 __func__, ret);
4551 return ret;
4552}
4553
4554int afe_register_get_events(u16 port_id,
4555 void (*cb)(uint32_t opcode,
4556 uint32_t token, uint32_t *payload, void *priv),
4557 void *private_data)
4558{
4559 int ret = 0;
4560 struct afe_service_cmd_register_rt_port_driver rtproxy;
4561
4562 pr_debug("%s: port_id: 0x%x\n", __func__, port_id);
4563
4564 if (this_afe.apr == NULL) {
4565 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
4566 0xFFFFFFFF, &this_afe);
4567 pr_debug("%s: Register AFE\n", __func__);
4568 if (this_afe.apr == NULL) {
4569 pr_err("%s: Unable to register AFE\n", __func__);
4570 ret = -ENODEV;
4571 return ret;
4572 }
4573 rtac_set_afe_handle(this_afe.apr);
4574 }
4575 if ((port_id == RT_PROXY_DAI_002_RX) ||
4576 (port_id == RT_PROXY_DAI_001_TX)) {
4577 port_id = VIRTUAL_ID_TO_PORTID(port_id);
4578 } else {
4579 pr_err("%s: wrong port id 0x%x\n", __func__, port_id);
4580 return -EINVAL;
4581 }
4582
4583 if (port_id == RT_PROXY_PORT_001_TX) {
4584 this_afe.tx_cb = cb;
4585 this_afe.tx_private_data = private_data;
4586 } else if (port_id == RT_PROXY_PORT_001_RX) {
4587 this_afe.rx_cb = cb;
4588 this_afe.rx_private_data = private_data;
4589 }
4590
4591 rtproxy.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4592 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4593 rtproxy.hdr.pkt_size = sizeof(rtproxy);
4594 rtproxy.hdr.src_port = 1;
4595 rtproxy.hdr.dest_port = 1;
4596 rtproxy.hdr.opcode = AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER;
4597 rtproxy.port_id = port_id;
4598 rtproxy.reserved = 0;
4599
4600 ret = afe_apr_send_pkt(&rtproxy, NULL);
4601 if (ret)
4602 pr_err("%s: AFE reg. rtproxy_event failed %d\n",
4603 __func__, ret);
4604 return ret;
4605}
4606
4607int afe_unregister_get_events(u16 port_id)
4608{
4609 int ret = 0;
4610 struct afe_service_cmd_unregister_rt_port_driver rtproxy;
4611 int index = 0;
4612
4613 pr_debug("%s:\n", __func__);
4614
4615 if (this_afe.apr == NULL) {
4616 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
4617 0xFFFFFFFF, &this_afe);
4618 pr_debug("%s: Register AFE\n", __func__);
4619 if (this_afe.apr == NULL) {
4620 pr_err("%s: Unable to register AFE\n", __func__);
4621 ret = -ENODEV;
4622 return ret;
4623 }
4624 rtac_set_afe_handle(this_afe.apr);
4625 }
4626
4627 if ((port_id == RT_PROXY_DAI_002_RX) ||
4628 (port_id == RT_PROXY_DAI_001_TX)) {
4629 port_id = VIRTUAL_ID_TO_PORTID(port_id);
4630 } else {
4631 pr_err("%s: wrong port id 0x%x\n", __func__, port_id);
4632 return -EINVAL;
4633 }
4634
4635 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08004636 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08004637 pr_err("%s: AFE port index[%d] invalid!\n",
4638 __func__, index);
4639 return -EINVAL;
4640 }
4641 ret = q6audio_validate_port(port_id);
4642 if (ret < 0) {
4643 pr_err("%s: Invalid port 0x%x ret %d", __func__, port_id, ret);
4644 return -EINVAL;
4645 }
4646
4647 rtproxy.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4648 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4649 rtproxy.hdr.pkt_size = sizeof(rtproxy);
4650 rtproxy.hdr.src_port = 0;
4651 rtproxy.hdr.dest_port = 0;
4652 rtproxy.hdr.token = 0;
4653 rtproxy.hdr.opcode = AFE_SERVICE_CMD_UNREGISTER_RT_PORT_DRIVER;
4654 rtproxy.port_id = port_id;
4655 rtproxy.reserved = 0;
4656
4657 rtproxy.hdr.token = index;
4658
4659 if (port_id == RT_PROXY_PORT_001_TX) {
4660 this_afe.tx_cb = NULL;
4661 this_afe.tx_private_data = NULL;
4662 } else if (port_id == RT_PROXY_PORT_001_RX) {
4663 this_afe.rx_cb = NULL;
4664 this_afe.rx_private_data = NULL;
4665 }
4666
4667 ret = afe_apr_send_pkt(&rtproxy, &this_afe.wait[index]);
4668 if (ret)
4669 pr_err("%s: AFE enable Unreg. rtproxy_event failed %d\n",
4670 __func__, ret);
4671 return ret;
4672}
4673
4674int afe_rt_proxy_port_write(phys_addr_t buf_addr_p,
4675 u32 mem_map_handle, int bytes)
4676{
4677 int ret = 0;
4678 struct afe_port_data_cmd_rt_proxy_port_write_v2 afecmd_wr;
4679
4680 if (this_afe.apr == NULL) {
4681 pr_err("%s: register to AFE is not done\n", __func__);
4682 ret = -ENODEV;
4683 return ret;
4684 }
4685 pr_debug("%s: buf_addr_p = 0x%pK bytes = %d\n", __func__,
4686 &buf_addr_p, bytes);
4687
4688 afecmd_wr.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4689 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4690 afecmd_wr.hdr.pkt_size = sizeof(afecmd_wr);
4691 afecmd_wr.hdr.src_port = 0;
4692 afecmd_wr.hdr.dest_port = 0;
4693 afecmd_wr.hdr.token = 0;
4694 afecmd_wr.hdr.opcode = AFE_PORT_DATA_CMD_RT_PROXY_PORT_WRITE_V2;
4695 afecmd_wr.port_id = RT_PROXY_PORT_001_TX;
4696 afecmd_wr.buffer_address_lsw = lower_32_bits(buf_addr_p);
4697 afecmd_wr.buffer_address_msw =
4698 msm_audio_populate_upper_32_bits(buf_addr_p);
4699 afecmd_wr.mem_map_handle = mem_map_handle;
4700 afecmd_wr.available_bytes = bytes;
4701 afecmd_wr.reserved = 0;
4702
4703 ret = afe_apr_send_pkt(&afecmd_wr, NULL);
4704 if (ret)
4705 pr_err("%s: AFE rtproxy write to port 0x%x failed %d\n",
4706 __func__, afecmd_wr.port_id, ret);
4707 return ret;
4708
4709}
4710
4711int afe_rt_proxy_port_read(phys_addr_t buf_addr_p,
4712 u32 mem_map_handle, int bytes)
4713{
4714 int ret = 0;
4715 struct afe_port_data_cmd_rt_proxy_port_read_v2 afecmd_rd;
4716
4717 if (this_afe.apr == NULL) {
4718 pr_err("%s: register to AFE is not done\n", __func__);
4719 ret = -ENODEV;
4720 return ret;
4721 }
4722 pr_debug("%s: buf_addr_p = 0x%pK bytes = %d\n", __func__,
4723 &buf_addr_p, bytes);
4724
4725 afecmd_rd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4726 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4727 afecmd_rd.hdr.pkt_size = sizeof(afecmd_rd);
4728 afecmd_rd.hdr.src_port = 0;
4729 afecmd_rd.hdr.dest_port = 0;
4730 afecmd_rd.hdr.token = 0;
4731 afecmd_rd.hdr.opcode = AFE_PORT_DATA_CMD_RT_PROXY_PORT_READ_V2;
4732 afecmd_rd.port_id = RT_PROXY_PORT_001_RX;
4733 afecmd_rd.buffer_address_lsw = lower_32_bits(buf_addr_p);
4734 afecmd_rd.buffer_address_msw =
4735 msm_audio_populate_upper_32_bits(buf_addr_p);
4736 afecmd_rd.available_bytes = bytes;
4737 afecmd_rd.mem_map_handle = mem_map_handle;
4738
4739 ret = afe_apr_send_pkt(&afecmd_rd, NULL);
4740 if (ret)
4741 pr_err("%s: AFE rtproxy read cmd to port 0x%x failed %d\n",
4742 __func__, afecmd_rd.port_id, ret);
4743 return ret;
4744}
4745
4746#ifdef CONFIG_DEBUG_FS
4747static struct dentry *debugfs_afelb;
4748static struct dentry *debugfs_afelb_gain;
4749
4750static int afe_debug_open(struct inode *inode, struct file *file)
4751{
4752 file->private_data = inode->i_private;
4753 pr_info("%s: debug intf %s\n", __func__, (char *) file->private_data);
4754 return 0;
4755}
4756
4757static int afe_get_parameters(char *buf, long int *param1, int num_of_par)
4758{
4759 char *token;
4760 int base, cnt;
4761
4762 token = strsep(&buf, " ");
4763
4764 for (cnt = 0; cnt < num_of_par; cnt++) {
4765 if (token != NULL) {
4766 if ((token[1] == 'x') || (token[1] == 'X'))
4767 base = 16;
4768 else
4769 base = 10;
4770
4771 if (kstrtoul(token, base, &param1[cnt]) != 0) {
4772 pr_err("%s: kstrtoul failed\n",
4773 __func__);
4774 return -EINVAL;
4775 }
4776
4777 token = strsep(&buf, " ");
4778 } else {
4779 pr_err("%s: token NULL\n", __func__);
4780 return -EINVAL;
4781 }
4782 }
4783 return 0;
4784}
4785#define AFE_LOOPBACK_ON (1)
4786#define AFE_LOOPBACK_OFF (0)
4787static ssize_t afe_debug_write(struct file *filp,
4788 const char __user *ubuf, size_t cnt, loff_t *ppos)
4789{
4790 char *lb_str = filp->private_data;
4791 char lbuf[32];
4792 int rc;
4793 unsigned long param[5];
4794
4795 if (cnt > sizeof(lbuf) - 1) {
4796 pr_err("%s: cnt %zd size %zd\n", __func__, cnt, sizeof(lbuf)-1);
4797 return -EINVAL;
4798 }
4799
4800 rc = copy_from_user(lbuf, ubuf, cnt);
4801 if (rc) {
4802 pr_err("%s: copy from user failed %d\n", __func__, rc);
4803 return -EFAULT;
4804 }
4805
4806 lbuf[cnt] = '\0';
4807
4808 if (!strcmp(lb_str, "afe_loopback")) {
4809 rc = afe_get_parameters(lbuf, param, 3);
4810 if (!rc) {
4811 pr_info("%s: %lu %lu %lu\n", lb_str, param[0], param[1],
4812 param[2]);
4813
4814 if ((param[0] != AFE_LOOPBACK_ON) && (param[0] !=
4815 AFE_LOOPBACK_OFF)) {
4816 pr_err("%s: Error, parameter 0 incorrect\n",
4817 __func__);
4818 rc = -EINVAL;
4819 goto afe_error;
4820 }
4821 if ((q6audio_validate_port(param[1]) < 0) ||
4822 (q6audio_validate_port(param[2])) < 0) {
4823 pr_err("%s: Error, invalid afe port\n",
4824 __func__);
4825 }
4826 if (this_afe.apr == NULL) {
4827 pr_err("%s: Error, AFE not opened\n", __func__);
4828 rc = -EINVAL;
4829 } else {
4830 rc = afe_loopback(param[0], param[1], param[2]);
4831 }
4832 } else {
4833 pr_err("%s: Error, invalid parameters\n", __func__);
4834 rc = -EINVAL;
4835 }
4836
4837 } else if (!strcmp(lb_str, "afe_loopback_gain")) {
4838 rc = afe_get_parameters(lbuf, param, 2);
4839 if (!rc) {
4840 pr_info("%s: %s %lu %lu\n",
4841 __func__, lb_str, param[0], param[1]);
4842
4843 rc = q6audio_validate_port(param[0]);
4844 if (rc < 0) {
4845 pr_err("%s: Error, invalid afe port %d %lu\n",
4846 __func__, rc, param[0]);
4847 rc = -EINVAL;
4848 goto afe_error;
4849 }
4850
4851 if (param[1] > 100) {
4852 pr_err("%s: Error, volume should be 0 to 100 percentage param = %lu\n",
4853 __func__, param[1]);
4854 rc = -EINVAL;
4855 goto afe_error;
4856 }
4857
4858 param[1] = (Q6AFE_MAX_VOLUME * param[1]) / 100;
4859
4860 if (this_afe.apr == NULL) {
4861 pr_err("%s: Error, AFE not opened\n", __func__);
4862 rc = -EINVAL;
4863 } else {
4864 rc = afe_loopback_gain(param[0], param[1]);
4865 }
4866 } else {
4867 pr_err("%s: Error, invalid parameters\n", __func__);
4868 rc = -EINVAL;
4869 }
4870 }
4871
4872afe_error:
4873 if (rc == 0)
4874 rc = cnt;
4875 else
4876 pr_err("%s: rc = %d\n", __func__, rc);
4877
4878 return rc;
4879}
4880
4881static const struct file_operations afe_debug_fops = {
4882 .open = afe_debug_open,
4883 .write = afe_debug_write
4884};
4885
4886static void config_debug_fs_init(void)
4887{
4888 debugfs_afelb = debugfs_create_file("afe_loopback",
4889 0664, NULL, (void *) "afe_loopback",
4890 &afe_debug_fops);
4891
4892 debugfs_afelb_gain = debugfs_create_file("afe_loopback_gain",
4893 0664, NULL, (void *) "afe_loopback_gain",
4894 &afe_debug_fops);
4895}
4896static void config_debug_fs_exit(void)
4897{
4898 debugfs_remove(debugfs_afelb);
4899 debugfs_remove(debugfs_afelb_gain);
4900}
4901#else
4902static void config_debug_fs_init(void)
4903{
4904}
4905static void config_debug_fs_exit(void)
4906{
4907}
4908#endif
4909
4910void afe_set_dtmf_gen_rx_portid(u16 port_id, int set)
4911{
4912 if (set)
4913 this_afe.dtmf_gen_rx_portid = port_id;
4914 else if (this_afe.dtmf_gen_rx_portid == port_id)
4915 this_afe.dtmf_gen_rx_portid = -1;
4916}
4917
4918int afe_dtmf_generate_rx(int64_t duration_in_ms,
4919 uint16_t high_freq,
4920 uint16_t low_freq, uint16_t gain)
4921{
4922 int ret = 0;
4923 int index = 0;
4924 struct afe_dtmf_generation_command cmd_dtmf;
4925
4926 pr_debug("%s: DTMF AFE Gen\n", __func__);
4927
4928 if (afe_validate_port(this_afe.dtmf_gen_rx_portid) < 0) {
4929 pr_err("%s: Failed : Invalid Port id = 0x%x\n",
4930 __func__, this_afe.dtmf_gen_rx_portid);
4931 ret = -EINVAL;
4932 goto fail_cmd;
4933 }
4934
4935 if (this_afe.apr == NULL) {
4936 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
4937 0xFFFFFFFF, &this_afe);
4938 pr_debug("%s: Register AFE\n", __func__);
4939 if (this_afe.apr == NULL) {
4940 pr_err("%s: Unable to register AFE\n", __func__);
4941 ret = -ENODEV;
4942 return ret;
4943 }
4944 rtac_set_afe_handle(this_afe.apr);
4945 }
4946
4947 pr_debug("%s: dur=%lld: hfreq=%d lfreq=%d gain=%d portid=0x%x\n",
4948 __func__,
4949 duration_in_ms, high_freq, low_freq, gain,
4950 this_afe.dtmf_gen_rx_portid);
4951
4952 cmd_dtmf.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4953 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4954 cmd_dtmf.hdr.pkt_size = sizeof(cmd_dtmf);
4955 cmd_dtmf.hdr.src_port = 0;
4956 cmd_dtmf.hdr.dest_port = 0;
4957 cmd_dtmf.hdr.token = 0;
4958 cmd_dtmf.hdr.opcode = AFE_PORTS_CMD_DTMF_CTL;
4959 cmd_dtmf.duration_in_ms = duration_in_ms;
4960 cmd_dtmf.high_freq = high_freq;
4961 cmd_dtmf.low_freq = low_freq;
4962 cmd_dtmf.gain = gain;
4963 cmd_dtmf.num_ports = 1;
4964 cmd_dtmf.port_ids = q6audio_get_port_id(this_afe.dtmf_gen_rx_portid);
4965
4966 atomic_set(&this_afe.state, 1);
4967 atomic_set(&this_afe.status, 0);
4968 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &cmd_dtmf);
4969 if (ret < 0) {
4970 pr_err("%s: AFE DTMF failed for num_ports:%d ids:0x%x\n",
4971 __func__, cmd_dtmf.num_ports, cmd_dtmf.port_ids);
4972 ret = -EINVAL;
4973 goto fail_cmd;
4974 }
4975 index = q6audio_get_port_index(this_afe.dtmf_gen_rx_portid);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08004976 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08004977 pr_err("%s: AFE port index[%d] invalid!\n",
4978 __func__, index);
4979 ret = -EINVAL;
4980 goto fail_cmd;
4981 }
4982 ret = wait_event_timeout(this_afe.wait[index],
4983 (atomic_read(&this_afe.state) == 0),
4984 msecs_to_jiffies(TIMEOUT_MS));
4985 if (!ret) {
4986 pr_err("%s: wait_event timeout\n", __func__);
4987 ret = -EINVAL;
4988 goto fail_cmd;
4989 }
4990 if (atomic_read(&this_afe.status) > 0) {
4991 pr_err("%s: config cmd failed [%s]\n",
4992 __func__, adsp_err_get_err_str(
4993 atomic_read(&this_afe.status)));
4994 ret = adsp_err_get_lnx_err_code(
4995 atomic_read(&this_afe.status));
4996 goto fail_cmd;
4997 }
4998 return 0;
4999
5000fail_cmd:
5001 pr_err("%s: failed %d\n", __func__, ret);
5002 return ret;
5003}
5004
Siena Richardd83d83f2016-12-15 13:49:41 -08005005static int afe_sidetone_iir(u16 tx_port_id)
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005006{
Siena Richardd83d83f2016-12-15 13:49:41 -08005007 struct afe_loopback_iir_cfg_v2 iir_sidetone;
5008 int ret;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005009 int index = 0;
Siena Richardd83d83f2016-12-15 13:49:41 -08005010 uint16_t size = 0;
5011 int cal_index = AFE_SIDETONE_IIR_CAL;
5012 int iir_pregain = 0;
5013 int iir_num_biquad_stages = 0;
5014 int iir_enable;
5015 struct cal_block_data *cal_block;
5016 int mid;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005017
Siena Richardd83d83f2016-12-15 13:49:41 -08005018 memset(&iir_sidetone, 0, sizeof(iir_sidetone));
5019 index = q6audio_get_port_index(tx_port_id);
5020 iir_sidetone.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5021 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5022 iir_sidetone.hdr.pkt_size = sizeof(iir_sidetone);
5023 iir_sidetone.hdr.src_port = 0;
5024 iir_sidetone.hdr.dest_port = 0;
5025 iir_sidetone.hdr.token = index;
5026 iir_sidetone.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
5027 iir_sidetone.param.port_id = tx_port_id;
5028 iir_sidetone.param.payload_address_lsw = 0x00;
5029 iir_sidetone.param.payload_address_msw = 0x00;
5030 iir_sidetone.param.mem_map_handle = 0x00;
5031
5032 if (this_afe.cal_data[cal_index] == NULL) {
5033 pr_err("%s: cal data is NULL\n", __func__);
5034 ret = -EINVAL;
5035 goto done;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005036 }
Siena Richardd83d83f2016-12-15 13:49:41 -08005037 mutex_lock(&this_afe.cal_data[cal_index]->lock);
5038 cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]);
5039 if (cal_block == NULL) {
5040 pr_err("%s: cal_block not found\n ", __func__);
5041 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
5042 ret = -EINVAL;
5043 goto done;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005044 }
5045
Siena Richardd83d83f2016-12-15 13:49:41 -08005046 iir_pregain = ((struct audio_cal_info_sidetone_iir *)
5047 cal_block->cal_info)->pregain;
5048 iir_enable = ((struct audio_cal_info_sidetone_iir *)
5049 cal_block->cal_info)->iir_enable;
5050 iir_num_biquad_stages = ((struct audio_cal_info_sidetone_iir *)
5051 cal_block->cal_info)->num_biquad_stages;
5052 mid = ((struct audio_cal_info_sidetone_iir *)
5053 cal_block->cal_info)->mid;
5054
5055 /*
5056 * calculate the actual size of payload based on no of stages
5057 * enabled in calibration
5058 */
5059 size = (MAX_SIDETONE_IIR_DATA_SIZE / MAX_NO_IIR_FILTER_STAGE) *
5060 iir_num_biquad_stages;
5061 /*
5062 * For an odd number of stages, 2 bytes of padding are
5063 * required at the end of the payload.
5064 */
5065 if (iir_num_biquad_stages % 2) {
5066 pr_debug("%s: adding 2 to size:%d\n", __func__, size);
5067 size = size + 2;
5068 }
5069 memcpy(&iir_sidetone.st_iir_filter_config_data.iir_config,
5070 &((struct audio_cal_info_sidetone_iir *)
5071 cal_block->cal_info)->iir_config,
5072 sizeof(iir_sidetone.st_iir_filter_config_data.iir_config));
5073 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
5074
5075 /*
5076 * Calculate the payload size for setparams command
5077 */
5078 iir_sidetone.param.payload_size = (sizeof(iir_sidetone) -
5079 sizeof(struct apr_hdr) -
5080 sizeof(struct afe_port_cmd_set_param_v2) -
5081 (MAX_SIDETONE_IIR_DATA_SIZE - size));
5082
5083 pr_debug("%s: payload size :%d\n", __func__,
5084 iir_sidetone.param.payload_size);
5085
5086 /*
5087 * Set IIR enable params
5088 */
5089 iir_sidetone.st_iir_enable_pdata.module_id = mid;
5090 iir_sidetone.st_iir_enable_pdata.param_id =
5091 AFE_PARAM_ID_ENABLE;
5092 iir_sidetone.st_iir_enable_pdata.param_size =
5093 sizeof(iir_sidetone.st_iir_mode_enable_data);
5094 iir_sidetone.st_iir_mode_enable_data.enable = iir_enable;
5095
5096 /*
5097 * Set IIR filter config params
5098 */
5099 iir_sidetone.st_iir_filter_config_pdata.module_id = mid;
5100 iir_sidetone.st_iir_filter_config_pdata.param_id =
5101 AFE_PARAM_ID_SIDETONE_IIR_FILTER_CONFIG;
5102 iir_sidetone.st_iir_filter_config_pdata.param_size =
5103 sizeof(iir_sidetone.st_iir_filter_config_data.num_biquad_stages)
5104 +
5105 sizeof(iir_sidetone.st_iir_filter_config_data.pregain) + size;
5106 iir_sidetone.st_iir_filter_config_pdata.reserved = 0;
5107 iir_sidetone.st_iir_filter_config_data.num_biquad_stages =
5108 iir_num_biquad_stages;
5109 iir_sidetone.st_iir_filter_config_data.pregain = iir_pregain;
5110 pr_debug("%s: tx(0x%x)mid(0x%x)iir_en(%d)stg(%d)gain(0x%x)size(%d)\n",
5111 __func__, tx_port_id, mid,
5112 iir_sidetone.st_iir_mode_enable_data.enable,
5113 iir_sidetone.st_iir_filter_config_data.num_biquad_stages,
5114 iir_sidetone.st_iir_filter_config_data.pregain,
5115 iir_sidetone.st_iir_filter_config_pdata.param_size);
5116 ret = afe_apr_send_pkt(&iir_sidetone, &this_afe.wait[index]);
5117 if (ret)
5118 pr_err("%s: AFE sidetone failed for tx_port(0x%x)\n",
5119 __func__, tx_port_id);
5120
5121done:
5122 return ret;
5123
5124}
5125
5126static int afe_sidetone(u16 tx_port_id, u16 rx_port_id, bool enable)
5127{
5128 struct afe_st_loopback_cfg_v1 cmd_sidetone;
5129 int ret;
5130 int index;
5131 int cal_index = AFE_SIDETONE_CAL;
5132 int sidetone_gain;
5133 int sidetone_enable;
5134 struct cal_block_data *cal_block;
5135 int mid = 0;
5136
5137 memset(&cmd_sidetone, 0, sizeof(cmd_sidetone));
5138 if (this_afe.cal_data[cal_index] == NULL) {
5139 pr_err("%s: cal data is NULL\n", __func__);
5140 ret = -EINVAL;
5141 goto done;
5142 }
5143 mutex_lock(&this_afe.cal_data[cal_index]->lock);
5144 cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]);
5145 if (cal_block == NULL) {
5146 pr_err("%s: cal_block not found\n", __func__);
5147 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
5148 ret = -EINVAL;
5149 goto done;
5150 }
5151 sidetone_gain = ((struct audio_cal_info_sidetone *)
5152 cal_block->cal_info)->gain;
5153 sidetone_enable = ((struct audio_cal_info_sidetone *)
5154 cal_block->cal_info)->enable;
5155 mid = ((struct audio_cal_info_sidetone *)
5156 cal_block->cal_info)->mid;
5157 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
5158
5159 index = q6audio_get_port_index(tx_port_id);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005160 cmd_sidetone.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5161 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5162 cmd_sidetone.hdr.pkt_size = sizeof(cmd_sidetone);
5163 cmd_sidetone.hdr.src_port = 0;
5164 cmd_sidetone.hdr.dest_port = 0;
Siena Richardd83d83f2016-12-15 13:49:41 -08005165 cmd_sidetone.hdr.token = index;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005166 cmd_sidetone.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005167 cmd_sidetone.param.port_id = tx_port_id;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005168 cmd_sidetone.param.payload_size = (sizeof(cmd_sidetone) -
5169 sizeof(struct apr_hdr) -
5170 sizeof(struct afe_port_cmd_set_param_v2));
5171 cmd_sidetone.param.payload_address_lsw = 0x00;
5172 cmd_sidetone.param.payload_address_msw = 0x00;
5173 cmd_sidetone.param.mem_map_handle = 0x00;
Siena Richardd83d83f2016-12-15 13:49:41 -08005174 cmd_sidetone.gain_pdata.module_id = AFE_MODULE_LOOPBACK;
5175 cmd_sidetone.gain_pdata.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH;
5176 /*
5177 * size of actual payload only
5178 */
5179 cmd_sidetone.gain_pdata.param_size = sizeof(
5180 struct afe_loopback_sidetone_gain);
5181 cmd_sidetone.gain_data.rx_port_id = rx_port_id;
5182 cmd_sidetone.gain_data.gain = sidetone_gain;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005183
Siena Richardd83d83f2016-12-15 13:49:41 -08005184 cmd_sidetone.cfg_pdata.module_id = AFE_MODULE_LOOPBACK;
5185 cmd_sidetone.cfg_pdata.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG;
5186 /*
5187 * size of actual payload only
5188 */
5189 cmd_sidetone.cfg_pdata.param_size = sizeof(struct loopback_cfg_data);
5190 cmd_sidetone.cfg_data.loopback_cfg_minor_version =
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005191 AFE_API_VERSION_LOOPBACK_CONFIG;
Siena Richardd83d83f2016-12-15 13:49:41 -08005192 cmd_sidetone.cfg_data.dst_port_id = rx_port_id;
5193 cmd_sidetone.cfg_data.routing_mode = LB_MODE_SIDETONE;
Vikram Panduranga74934752017-03-07 18:03:07 -08005194 cmd_sidetone.cfg_data.enable = enable;
Siena Richardd83d83f2016-12-15 13:49:41 -08005195
5196 pr_debug("%s rx(0x%x) tx(0x%x) enable(%d) mid(0x%x) gain(%d) sidetone_enable(%d)\n",
5197 __func__, rx_port_id, tx_port_id,
5198 enable, mid, sidetone_gain, sidetone_enable);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005199
5200 ret = afe_apr_send_pkt(&cmd_sidetone, &this_afe.wait[index]);
5201 if (ret)
Siena Richardd83d83f2016-12-15 13:49:41 -08005202 pr_err("%s: AFE sidetone send failed for tx_port:%d rx_port:%d ret:%d\n",
5203 __func__, tx_port_id, rx_port_id, ret);
5204done:
5205 return ret;
5206}
5207
5208int afe_sidetone_enable(u16 tx_port_id, u16 rx_port_id, bool enable)
5209{
5210 int ret;
5211 int index;
5212
5213 index = q6audio_get_port_index(rx_port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08005214 if (index < 0 || index >= AFE_MAX_PORTS) {
Siena Richardd83d83f2016-12-15 13:49:41 -08005215 pr_err("%s: AFE port index[%d] invalid!\n",
5216 __func__, index);
5217 ret = -EINVAL;
5218 goto done;
5219 }
5220 if (q6audio_validate_port(rx_port_id) < 0) {
5221 pr_err("%s: Invalid port 0x%x\n",
5222 __func__, rx_port_id);
5223 ret = -EINVAL;
5224 goto done;
5225 }
5226 index = q6audio_get_port_index(tx_port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08005227 if (index < 0 || index >= AFE_MAX_PORTS) {
Siena Richardd83d83f2016-12-15 13:49:41 -08005228 pr_err("%s: AFE port index[%d] invalid!\n",
5229 __func__, index);
5230 ret = -EINVAL;
5231 goto done;
5232 }
5233 if (q6audio_validate_port(tx_port_id) < 0) {
5234 pr_err("%s: Invalid port 0x%x\n",
5235 __func__, tx_port_id);
5236 ret = -EINVAL;
5237 goto done;
5238 }
5239 if (enable) {
5240 ret = afe_sidetone_iir(tx_port_id);
5241 if (ret)
5242 goto done;
5243 }
5244
5245 ret = afe_sidetone(tx_port_id, rx_port_id, enable);
5246
5247done:
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005248 return ret;
5249}
5250
5251int afe_validate_port(u16 port_id)
5252{
5253 int ret;
5254
5255 switch (port_id) {
5256 case PRIMARY_I2S_RX:
5257 case PRIMARY_I2S_TX:
5258 case AFE_PORT_ID_PRIMARY_PCM_RX:
5259 case AFE_PORT_ID_PRIMARY_PCM_TX:
5260 case AFE_PORT_ID_SECONDARY_PCM_RX:
5261 case AFE_PORT_ID_SECONDARY_PCM_TX:
5262 case AFE_PORT_ID_TERTIARY_PCM_RX:
5263 case AFE_PORT_ID_TERTIARY_PCM_TX:
5264 case AFE_PORT_ID_QUATERNARY_PCM_RX:
5265 case AFE_PORT_ID_QUATERNARY_PCM_TX:
5266 case SECONDARY_I2S_RX:
5267 case SECONDARY_I2S_TX:
5268 case MI2S_RX:
5269 case MI2S_TX:
5270 case HDMI_RX:
5271 case DISPLAY_PORT_RX:
5272 case AFE_PORT_ID_SPDIF_RX:
5273 case RSVD_2:
5274 case RSVD_3:
5275 case DIGI_MIC_TX:
5276 case VOICE_RECORD_RX:
5277 case VOICE_RECORD_TX:
5278 case VOICE_PLAYBACK_TX:
5279 case VOICE2_PLAYBACK_TX:
5280 case SLIMBUS_0_RX:
5281 case SLIMBUS_0_TX:
5282 case SLIMBUS_1_RX:
5283 case SLIMBUS_1_TX:
5284 case SLIMBUS_2_RX:
5285 case SLIMBUS_2_TX:
5286 case SLIMBUS_3_RX:
5287 case INT_BT_SCO_RX:
5288 case INT_BT_SCO_TX:
5289 case INT_BT_A2DP_RX:
5290 case INT_FM_RX:
5291 case INT_FM_TX:
5292 case RT_PROXY_PORT_001_RX:
5293 case RT_PROXY_PORT_001_TX:
5294 case SLIMBUS_4_RX:
5295 case SLIMBUS_4_TX:
5296 case SLIMBUS_5_RX:
5297 case SLIMBUS_6_RX:
5298 case SLIMBUS_6_TX:
5299 case SLIMBUS_7_RX:
5300 case SLIMBUS_7_TX:
5301 case SLIMBUS_8_RX:
5302 case SLIMBUS_8_TX:
5303 case AFE_PORT_ID_USB_RX:
5304 case AFE_PORT_ID_USB_TX:
5305 case AFE_PORT_ID_PRIMARY_MI2S_RX:
5306 case AFE_PORT_ID_PRIMARY_MI2S_TX:
5307 case AFE_PORT_ID_SECONDARY_MI2S_RX:
5308 case AFE_PORT_ID_SECONDARY_MI2S_TX:
5309 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
5310 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
5311 case AFE_PORT_ID_TERTIARY_MI2S_RX:
5312 case AFE_PORT_ID_TERTIARY_MI2S_TX:
5313 case AFE_PORT_ID_QUINARY_MI2S_RX:
5314 case AFE_PORT_ID_QUINARY_MI2S_TX:
5315 case AFE_PORT_ID_SENARY_MI2S_TX:
5316 case AFE_PORT_ID_PRIMARY_TDM_RX:
5317 case AFE_PORT_ID_PRIMARY_TDM_TX:
5318 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
5319 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
5320 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
5321 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
5322 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
5323 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
5324 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
5325 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
5326 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
5327 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
5328 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
5329 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
5330 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
5331 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
5332 case AFE_PORT_ID_SECONDARY_TDM_RX:
5333 case AFE_PORT_ID_SECONDARY_TDM_TX:
5334 case AFE_PORT_ID_SECONDARY_TDM_RX_1:
5335 case AFE_PORT_ID_SECONDARY_TDM_TX_1:
5336 case AFE_PORT_ID_SECONDARY_TDM_RX_2:
5337 case AFE_PORT_ID_SECONDARY_TDM_TX_2:
5338 case AFE_PORT_ID_SECONDARY_TDM_RX_3:
5339 case AFE_PORT_ID_SECONDARY_TDM_TX_3:
5340 case AFE_PORT_ID_SECONDARY_TDM_RX_4:
5341 case AFE_PORT_ID_SECONDARY_TDM_TX_4:
5342 case AFE_PORT_ID_SECONDARY_TDM_RX_5:
5343 case AFE_PORT_ID_SECONDARY_TDM_TX_5:
5344 case AFE_PORT_ID_SECONDARY_TDM_RX_6:
5345 case AFE_PORT_ID_SECONDARY_TDM_TX_6:
5346 case AFE_PORT_ID_SECONDARY_TDM_RX_7:
5347 case AFE_PORT_ID_SECONDARY_TDM_TX_7:
5348 case AFE_PORT_ID_TERTIARY_TDM_RX:
5349 case AFE_PORT_ID_TERTIARY_TDM_TX:
5350 case AFE_PORT_ID_TERTIARY_TDM_RX_1:
5351 case AFE_PORT_ID_TERTIARY_TDM_TX_1:
5352 case AFE_PORT_ID_TERTIARY_TDM_RX_2:
5353 case AFE_PORT_ID_TERTIARY_TDM_TX_2:
5354 case AFE_PORT_ID_TERTIARY_TDM_RX_3:
5355 case AFE_PORT_ID_TERTIARY_TDM_TX_3:
5356 case AFE_PORT_ID_TERTIARY_TDM_RX_4:
5357 case AFE_PORT_ID_TERTIARY_TDM_TX_4:
5358 case AFE_PORT_ID_TERTIARY_TDM_RX_5:
5359 case AFE_PORT_ID_TERTIARY_TDM_TX_5:
5360 case AFE_PORT_ID_TERTIARY_TDM_RX_6:
5361 case AFE_PORT_ID_TERTIARY_TDM_TX_6:
5362 case AFE_PORT_ID_TERTIARY_TDM_RX_7:
5363 case AFE_PORT_ID_TERTIARY_TDM_TX_7:
5364 case AFE_PORT_ID_QUATERNARY_TDM_RX:
5365 case AFE_PORT_ID_QUATERNARY_TDM_TX:
5366 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
5367 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
5368 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
5369 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
5370 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
5371 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
5372 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
5373 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
5374 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
5375 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
5376 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
5377 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
5378 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
5379 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
Laxminath Kasam24f049a2017-01-24 18:05:32 +05305380 case AFE_PORT_ID_INT0_MI2S_RX:
5381 case AFE_PORT_ID_INT1_MI2S_RX:
5382 case AFE_PORT_ID_INT2_MI2S_RX:
5383 case AFE_PORT_ID_INT3_MI2S_RX:
5384 case AFE_PORT_ID_INT4_MI2S_RX:
5385 case AFE_PORT_ID_INT5_MI2S_RX:
5386 case AFE_PORT_ID_INT6_MI2S_RX:
5387 case AFE_PORT_ID_INT0_MI2S_TX:
5388 case AFE_PORT_ID_INT1_MI2S_TX:
5389 case AFE_PORT_ID_INT2_MI2S_TX:
5390 case AFE_PORT_ID_INT3_MI2S_TX:
5391 case AFE_PORT_ID_INT4_MI2S_TX:
5392 case AFE_PORT_ID_INT5_MI2S_TX:
5393 case AFE_PORT_ID_INT6_MI2S_TX:
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005394 {
5395 ret = 0;
5396 break;
5397 }
5398
5399 default:
5400 pr_err("%s: default ret 0x%x\n", __func__, port_id);
5401 ret = -EINVAL;
5402 }
5403
5404 return ret;
5405}
5406
5407int afe_convert_virtual_to_portid(u16 port_id)
5408{
5409 int ret;
5410
5411 /*
5412 * if port_id is virtual, convert to physical..
5413 * if port_id is already physical, return physical
5414 */
5415 if (afe_validate_port(port_id) < 0) {
5416 if (port_id == RT_PROXY_DAI_001_RX ||
5417 port_id == RT_PROXY_DAI_001_TX ||
5418 port_id == RT_PROXY_DAI_002_RX ||
5419 port_id == RT_PROXY_DAI_002_TX) {
5420 ret = VIRTUAL_ID_TO_PORTID(port_id);
5421 } else {
5422 pr_err("%s: wrong port 0x%x\n",
5423 __func__, port_id);
5424 ret = -EINVAL;
5425 }
5426 } else
5427 ret = port_id;
5428
5429 return ret;
5430}
5431int afe_port_stop_nowait(int port_id)
5432{
5433 struct afe_port_cmd_device_stop stop;
5434 int ret = 0;
5435
5436 if (this_afe.apr == NULL) {
5437 pr_err("%s: AFE is already closed\n", __func__);
5438 ret = -EINVAL;
5439 goto fail_cmd;
5440 }
5441 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
5442 port_id = q6audio_convert_virtual_to_portid(port_id);
5443
5444 stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5445 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5446 stop.hdr.pkt_size = sizeof(stop);
5447 stop.hdr.src_port = 0;
5448 stop.hdr.dest_port = 0;
5449 stop.hdr.token = 0;
5450 stop.hdr.opcode = AFE_PORT_CMD_DEVICE_STOP;
5451 stop.port_id = port_id;
5452 stop.reserved = 0;
5453
5454 ret = afe_apr_send_pkt(&stop, NULL);
5455 if (ret)
5456 pr_err("%s: AFE close failed %d\n", __func__, ret);
5457
5458fail_cmd:
5459 return ret;
5460
5461}
5462
5463int afe_close(int port_id)
5464{
5465 struct afe_port_cmd_device_stop stop;
5466 enum afe_mad_type mad_type;
5467 int ret = 0;
5468 int index = 0;
5469 uint16_t port_index;
5470
5471 if (this_afe.apr == NULL) {
5472 pr_err("%s: AFE is already closed\n", __func__);
5473 if ((port_id == RT_PROXY_DAI_001_RX) ||
5474 (port_id == RT_PROXY_DAI_002_TX))
5475 pcm_afe_instance[port_id & 0x1] = 0;
5476 if ((port_id == RT_PROXY_DAI_002_RX) ||
5477 (port_id == RT_PROXY_DAI_001_TX))
5478 proxy_afe_instance[port_id & 0x1] = 0;
5479 afe_close_done[port_id & 0x1] = true;
5480 ret = -EINVAL;
5481 goto fail_cmd;
5482 }
5483 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
5484 if ((port_id == RT_PROXY_DAI_001_RX) ||
5485 (port_id == RT_PROXY_DAI_002_TX)) {
5486 pr_debug("%s: before decrementing pcm_afe_instance %d\n",
5487 __func__, pcm_afe_instance[port_id & 0x1]);
5488 port_id = VIRTUAL_ID_TO_PORTID(port_id);
5489 pcm_afe_instance[port_id & 0x1]--;
5490 if ((!(pcm_afe_instance[port_id & 0x1] == 0 &&
5491 proxy_afe_instance[port_id & 0x1] == 0)) ||
5492 afe_close_done[port_id & 0x1] == true)
5493 return 0;
5494
5495 afe_close_done[port_id & 0x1] = true;
5496 }
5497
5498 if ((port_id == RT_PROXY_DAI_002_RX) ||
5499 (port_id == RT_PROXY_DAI_001_TX)) {
5500 pr_debug("%s: before decrementing proxy_afe_instance %d\n",
5501 __func__, proxy_afe_instance[port_id & 0x1]);
5502 port_id = VIRTUAL_ID_TO_PORTID(port_id);
5503 proxy_afe_instance[port_id & 0x1]--;
5504 if ((!(pcm_afe_instance[port_id & 0x1] == 0 &&
5505 proxy_afe_instance[port_id & 0x1] == 0)) ||
5506 afe_close_done[port_id & 0x1] == true)
5507 return 0;
5508
5509 afe_close_done[port_id & 0x1] = true;
5510 }
5511
5512 port_id = q6audio_convert_virtual_to_portid(port_id);
5513 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08005514 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005515 pr_err("%s: AFE port index[%d] invalid!\n",
5516 __func__, index);
5517 return -EINVAL;
5518 }
5519 ret = q6audio_validate_port(port_id);
5520 if (ret < 0) {
5521 pr_warn("%s: Not a valid port id 0x%x ret %d\n",
5522 __func__, port_id, ret);
5523 return -EINVAL;
5524 }
5525
5526 mad_type = afe_port_get_mad_type(port_id);
5527 pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id,
5528 mad_type);
5529 if (mad_type != MAD_HW_NONE && mad_type != MAD_SW_AUDIO) {
5530 pr_debug("%s: Turn off MAD\n", __func__);
5531 ret = afe_turn_onoff_hw_mad(mad_type, false);
5532 if (ret) {
5533 pr_err("%s: afe_turn_onoff_hw_mad failed %d\n",
5534 __func__, ret);
5535 return ret;
5536 }
5537 } else {
5538 pr_debug("%s: Not a MAD port\n", __func__);
5539 }
5540
5541 port_index = afe_get_port_index(port_id);
5542 if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
5543 this_afe.afe_sample_rates[port_index] = 0;
5544 this_afe.topology[port_index] = 0;
Siena Richard23364c92017-01-11 16:20:55 -08005545 this_afe.dev_acdb_id[port_index] = 0;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005546 } else {
5547 pr_err("%s: port %d\n", __func__, port_index);
5548 ret = -EINVAL;
5549 goto fail_cmd;
5550 }
5551
5552 if ((port_id == this_afe.aanc_info.aanc_tx_port) &&
5553 (this_afe.aanc_info.aanc_active)) {
5554 memset(&this_afe.aanc_info, 0x00, sizeof(this_afe.aanc_info));
5555 ret = afe_aanc_mod_enable(this_afe.apr, port_id, 0);
5556 if (ret)
5557 pr_err("%s: AFE mod disable failed %d\n",
5558 __func__, ret);
5559 }
5560
5561 /*
5562 * even if ramp down configuration failed it is not serious enough to
5563 * warrant bailaing out.
5564 */
5565 if (afe_spk_ramp_dn_cfg(port_id) < 0)
5566 pr_err("%s: ramp down configuration failed\n", __func__);
5567
5568 stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5569 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5570 stop.hdr.pkt_size = sizeof(stop);
5571 stop.hdr.src_port = 0;
5572 stop.hdr.dest_port = 0;
5573 stop.hdr.token = index;
5574 stop.hdr.opcode = AFE_PORT_CMD_DEVICE_STOP;
5575 stop.port_id = q6audio_get_port_id(port_id);
5576 stop.reserved = 0;
5577
5578 ret = afe_apr_send_pkt(&stop, &this_afe.wait[index]);
5579 if (ret)
5580 pr_err("%s: AFE close failed %d\n", __func__, ret);
5581
5582fail_cmd:
5583 return ret;
5584}
5585
5586int afe_set_digital_codec_core_clock(u16 port_id,
5587 struct afe_digital_clk_cfg *cfg)
5588{
5589 struct afe_lpass_digital_clk_config_command clk_cfg;
5590 int index = 0;
5591 int ret = 0;
5592
5593 if (!cfg) {
5594 pr_err("%s: clock cfg is NULL\n", __func__);
5595 ret = -EINVAL;
5596 return ret;
5597 }
5598
5599 ret = afe_q6_interface_prepare();
5600 if (ret != 0) {
5601 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
5602 return ret;
5603 }
5604
5605 clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5606 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5607 clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
5608 clk_cfg.hdr.src_port = 0;
5609 clk_cfg.hdr.dest_port = 0;
5610 clk_cfg.hdr.token = index;
5611
5612 clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
5613 /*default rx port is taken to enable the codec digital clock*/
5614 clk_cfg.param.port_id = q6audio_get_port_id(port_id);
5615 clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
5616 - sizeof(clk_cfg.param);
5617 clk_cfg.param.payload_address_lsw = 0x00;
5618 clk_cfg.param.payload_address_msw = 0x00;
5619 clk_cfg.param.mem_map_handle = 0x00;
5620 clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
5621 clk_cfg.pdata.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG;
5622 clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
5623 clk_cfg.clk_cfg = *cfg;
5624
5625 pr_debug("%s: Minor version =0x%x clk val = %d\n"
5626 "clk root = 0x%x resrv = 0x%x\n",
5627 __func__, cfg->i2s_cfg_minor_version,
5628 cfg->clk_val, cfg->clk_root, cfg->reserved);
5629
5630 atomic_set(&this_afe.state, 1);
5631 atomic_set(&this_afe.status, 0);
5632 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
5633 if (ret < 0) {
5634 pr_err("%s: AFE enable for port 0x%x ret %d\n",
5635 __func__, port_id, ret);
5636 ret = -EINVAL;
5637 goto fail_cmd;
5638 }
5639
5640 ret = wait_event_timeout(this_afe.wait[index],
5641 (atomic_read(&this_afe.state) == 0),
5642 msecs_to_jiffies(TIMEOUT_MS));
5643 if (!ret) {
5644 pr_err("%s: wait_event timeout\n", __func__);
5645 ret = -EINVAL;
5646 goto fail_cmd;
5647 }
5648 if (atomic_read(&this_afe.status) > 0) {
5649 pr_err("%s: config cmd failed [%s]\n",
5650 __func__, adsp_err_get_err_str(
5651 atomic_read(&this_afe.status)));
5652 ret = adsp_err_get_lnx_err_code(
5653 atomic_read(&this_afe.status));
5654 goto fail_cmd;
5655 }
5656
5657fail_cmd:
5658 return ret;
5659}
5660
5661int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg)
5662{
5663 struct afe_lpass_clk_config_command clk_cfg;
5664 int index = 0;
5665 int ret = 0;
5666
5667 if (!cfg) {
5668 pr_err("%s: clock cfg is NULL\n", __func__);
5669 ret = -EINVAL;
5670 return ret;
5671 }
5672 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08005673 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005674 pr_err("%s: AFE port index[%d] invalid!\n",
5675 __func__, index);
5676 return -EINVAL;
5677 }
5678 ret = q6audio_is_digital_pcm_interface(port_id);
5679 if (ret < 0) {
5680 pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n",
5681 __func__, ret);
5682 return -EINVAL;
5683 }
5684
5685 ret = afe_q6_interface_prepare();
5686 if (ret != 0) {
5687 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
5688 return ret;
5689 }
5690
5691 mutex_lock(&this_afe.afe_cmd_lock);
5692 clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5693 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5694 clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
5695 clk_cfg.hdr.src_port = 0;
5696 clk_cfg.hdr.dest_port = 0;
5697 clk_cfg.hdr.token = index;
5698
5699 clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
5700 clk_cfg.param.port_id = q6audio_get_port_id(port_id);
5701 clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
5702 - sizeof(clk_cfg.param);
5703 clk_cfg.param.payload_address_lsw = 0x00;
5704 clk_cfg.param.payload_address_msw = 0x00;
5705 clk_cfg.param.mem_map_handle = 0x00;
5706 clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
5707 clk_cfg.pdata.param_id = AFE_PARAM_ID_LPAIF_CLK_CONFIG;
5708 clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
5709 clk_cfg.clk_cfg = *cfg;
5710
5711 pr_debug("%s: Minor version =0x%x clk val1 = %d\n"
5712 "clk val2 = %d, clk src = 0x%x\n"
5713 "clk root = 0x%x clk mode = 0x%x resrv = 0x%x\n"
5714 "port id = 0x%x\n",
5715 __func__, cfg->i2s_cfg_minor_version,
5716 cfg->clk_val1, cfg->clk_val2, cfg->clk_src,
5717 cfg->clk_root, cfg->clk_set_mode,
5718 cfg->reserved, q6audio_get_port_id(port_id));
5719
5720 atomic_set(&this_afe.state, 1);
5721 atomic_set(&this_afe.status, 0);
5722 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
5723 if (ret < 0) {
5724 pr_err("%s: AFE enable for port 0x%x ret %d\n",
5725 __func__, port_id, ret);
5726 ret = -EINVAL;
5727 goto fail_cmd;
5728 }
5729
5730 ret = wait_event_timeout(this_afe.wait[index],
5731 (atomic_read(&this_afe.state) == 0),
5732 msecs_to_jiffies(TIMEOUT_MS));
5733 if (!ret) {
5734 pr_err("%s: wait_event timeout\n", __func__);
5735 ret = -EINVAL;
5736 goto fail_cmd;
5737 }
5738 if (atomic_read(&this_afe.status) > 0) {
5739 pr_err("%s: config cmd failed [%s]\n",
5740 __func__, adsp_err_get_err_str(
5741 atomic_read(&this_afe.status)));
5742 ret = adsp_err_get_lnx_err_code(
5743 atomic_read(&this_afe.status));
5744 goto fail_cmd;
5745 }
5746
5747fail_cmd:
5748 mutex_unlock(&this_afe.afe_cmd_lock);
5749 return ret;
5750}
5751
5752int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg)
5753{
5754 struct afe_lpass_clk_config_command_v2 clk_cfg;
5755 int ret = 0;
5756
5757 if (!cfg) {
5758 pr_err("%s: clock cfg is NULL\n", __func__);
5759 ret = -EINVAL;
5760 return ret;
5761 }
5762
5763 if (index < 0 || index >= AFE_MAX_PORTS) {
5764 pr_err("%s: index[%d] invalid!\n", __func__, index);
5765 return -EINVAL;
5766 }
5767
5768 ret = afe_q6_interface_prepare();
5769 if (ret != 0) {
5770 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
5771 return ret;
5772 }
5773
5774 mutex_lock(&this_afe.afe_cmd_lock);
5775 clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5776 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5777 clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
5778 clk_cfg.hdr.src_port = 0;
5779 clk_cfg.hdr.dest_port = 0;
5780 clk_cfg.hdr.token = index;
5781
5782 clk_cfg.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
5783 clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
5784 - sizeof(clk_cfg.param);
5785 clk_cfg.param.payload_address_lsw = 0x00;
5786 clk_cfg.param.payload_address_msw = 0x00;
5787 clk_cfg.param.mem_map_handle = 0x00;
5788 clk_cfg.pdata.module_id = AFE_MODULE_CLOCK_SET;
5789 clk_cfg.pdata.param_id = AFE_PARAM_ID_CLOCK_SET;
5790 clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
5791 clk_cfg.clk_cfg = *cfg;
5792
5793
5794 pr_debug("%s: Minor version =0x%x clk id = %d\n"
5795 "clk freq (Hz) = %d, clk attri = 0x%x\n"
5796 "clk root = 0x%x clk enable = 0x%x\n",
5797 __func__, cfg->clk_set_minor_version,
5798 cfg->clk_id, cfg->clk_freq_in_hz, cfg->clk_attri,
5799 cfg->clk_root, cfg->enable);
5800
5801 atomic_set(&this_afe.state, 1);
5802 atomic_set(&this_afe.status, 0);
5803 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
5804 if (ret < 0) {
5805 pr_err("%s: AFE clk cfg failed with ret %d\n",
5806 __func__, ret);
5807 ret = -EINVAL;
5808 goto fail_cmd;
5809 }
5810
5811 ret = wait_event_timeout(this_afe.wait[index],
5812 (atomic_read(&this_afe.state) == 0),
5813 msecs_to_jiffies(TIMEOUT_MS));
5814 if (!ret) {
5815 pr_err("%s: wait_event timeout\n", __func__);
5816 ret = -EINVAL;
5817 goto fail_cmd;
5818 } else {
5819 /* set ret to 0 as no timeout happened */
5820 ret = 0;
5821 }
5822 if (atomic_read(&this_afe.status) != 0) {
5823 pr_err("%s: config cmd failed\n", __func__);
5824 ret = -EINVAL;
5825 goto fail_cmd;
5826 }
5827
5828fail_cmd:
5829 mutex_unlock(&this_afe.afe_cmd_lock);
5830 return ret;
5831}
5832
5833int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg)
5834{
5835 int index = 0;
5836 int ret = 0;
5837
5838 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08005839 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005840 pr_err("%s: AFE port index[%d] invalid!\n",
5841 __func__, index);
5842 return -EINVAL;
5843 }
5844 ret = q6audio_is_digital_pcm_interface(port_id);
5845 if (ret < 0) {
5846 pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n",
5847 __func__, ret);
5848 return -EINVAL;
5849 }
5850
5851 ret = afe_set_lpass_clk_cfg(index, cfg);
5852 if (ret)
5853 pr_err("%s: afe_set_lpass_clk_cfg_v2 failed %d\n",
5854 __func__, ret);
5855
5856 return ret;
5857}
5858
5859int afe_set_lpass_internal_digital_codec_clock(u16 port_id,
5860 struct afe_digital_clk_cfg *cfg)
5861{
5862 struct afe_lpass_digital_clk_config_command clk_cfg;
5863 int index = 0;
5864 int ret = 0;
5865
5866 if (!cfg) {
5867 pr_err("%s: clock cfg is NULL\n", __func__);
5868 ret = -EINVAL;
5869 return ret;
5870 }
5871 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08005872 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005873 pr_err("%s: AFE port index[%d] invalid!\n",
5874 __func__, index);
5875 return -EINVAL;
5876 }
5877 ret = q6audio_is_digital_pcm_interface(port_id);
5878 if (ret < 0) {
5879 pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n",
5880 __func__, ret);
5881 return -EINVAL;
5882 }
5883
5884 ret = afe_q6_interface_prepare();
5885 if (ret != 0) {
5886 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
5887 return ret;
5888 }
5889
5890 clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5891 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5892 clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
5893 clk_cfg.hdr.src_port = 0;
5894 clk_cfg.hdr.dest_port = 0;
5895 clk_cfg.hdr.token = index;
5896
5897 clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
5898 clk_cfg.param.port_id = q6audio_get_port_id(port_id);
5899 clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
5900 - sizeof(clk_cfg.param);
5901 clk_cfg.param.payload_address_lsw = 0x00;
5902 clk_cfg.param.payload_address_msw = 0x00;
5903 clk_cfg.param.mem_map_handle = 0x00;
5904 clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
5905 clk_cfg.pdata.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG;
5906 clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
5907 clk_cfg.clk_cfg = *cfg;
5908
5909 pr_debug("%s: Minor version =0x%x clk val = %d\n"
5910 "clk root = 0x%x resrv = 0x%x port id = 0x%x\n",
5911 __func__, cfg->i2s_cfg_minor_version,
5912 cfg->clk_val, cfg->clk_root, cfg->reserved,
5913 q6audio_get_port_id(port_id));
5914
5915 atomic_set(&this_afe.state, 1);
5916 atomic_set(&this_afe.status, 0);
5917 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
5918 if (ret < 0) {
5919 pr_err("%s: AFE enable for port 0x0x%x ret %d\n",
5920 __func__, port_id, ret);
5921 ret = -EINVAL;
5922 goto fail_cmd;
5923 }
5924
5925 ret = wait_event_timeout(this_afe.wait[index],
5926 (atomic_read(&this_afe.state) == 0),
5927 msecs_to_jiffies(TIMEOUT_MS));
5928 if (!ret) {
5929 pr_err("%s: wait_event timeout\n", __func__);
5930 ret = -EINVAL;
5931 goto fail_cmd;
5932 }
5933 if (atomic_read(&this_afe.status) > 0) {
5934 pr_err("%s: config cmd failed [%s]\n",
5935 __func__, adsp_err_get_err_str(
5936 atomic_read(&this_afe.status)));
5937 ret = adsp_err_get_lnx_err_code(
5938 atomic_read(&this_afe.status));
5939 goto fail_cmd;
5940 }
5941
5942fail_cmd:
5943 return ret;
5944}
5945
5946int afe_enable_lpass_core_shared_clock(u16 port_id, u32 enable)
5947{
5948 struct afe_lpass_core_shared_clk_config_command clk_cfg;
5949 int index = 0;
5950 int ret = 0;
5951
5952 index = q6audio_get_port_index(port_id);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08005953 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08005954 pr_err("%s: AFE port index[%d] invalid!\n",
5955 __func__, index);
5956 return -EINVAL;
5957 }
5958 ret = q6audio_is_digital_pcm_interface(port_id);
5959 if (ret < 0) {
5960 pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n",
5961 __func__, ret);
5962 return -EINVAL;
5963 }
5964
5965 ret = afe_q6_interface_prepare();
5966 if (ret != 0) {
5967 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
5968 return ret;
5969 }
5970
5971 mutex_lock(&this_afe.afe_cmd_lock);
5972 clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5973 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5974 clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
5975 clk_cfg.hdr.src_port = 0;
5976 clk_cfg.hdr.dest_port = 0;
5977 clk_cfg.hdr.token = index;
5978
5979 clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
5980 clk_cfg.param.port_id = q6audio_get_port_id(port_id);
5981 clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
5982 - sizeof(clk_cfg.param);
5983 clk_cfg.param.payload_address_lsw = 0x00;
5984 clk_cfg.param.payload_address_msw = 0x00;
5985 clk_cfg.param.mem_map_handle = 0x00;
5986 clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
5987 clk_cfg.pdata.param_id = AFE_PARAM_ID_LPASS_CORE_SHARED_CLOCK_CONFIG;
5988 clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
5989 clk_cfg.clk_cfg.lpass_core_shared_clk_cfg_minor_version =
5990 AFE_API_VERSION_LPASS_CORE_SHARED_CLK_CONFIG;
5991 clk_cfg.clk_cfg.enable = enable;
5992
5993 pr_debug("%s: port id = %d, enable = %d\n",
5994 __func__, q6audio_get_port_id(port_id), enable);
5995
5996 atomic_set(&this_afe.state, 1);
5997 atomic_set(&this_afe.status, 0);
5998 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
5999 if (ret < 0) {
6000 pr_err("%s: AFE enable for port 0x%x ret %d\n",
6001 __func__, port_id, ret);
6002 ret = -EINVAL;
6003 goto fail_cmd;
6004 }
6005
6006 ret = wait_event_timeout(this_afe.wait[index],
6007 (atomic_read(&this_afe.state) == 0),
6008 msecs_to_jiffies(TIMEOUT_MS));
6009 if (!ret) {
6010 pr_err("%s: wait_event timeout\n", __func__);
6011 ret = -EINVAL;
6012 goto fail_cmd;
6013 }
6014 if (atomic_read(&this_afe.status) > 0) {
6015 pr_err("%s: config cmd failed [%s]\n",
6016 __func__, adsp_err_get_err_str(
6017 atomic_read(&this_afe.status)));
6018 ret = adsp_err_get_lnx_err_code(
6019 atomic_read(&this_afe.status));
6020 goto fail_cmd;
6021 }
6022
6023fail_cmd:
6024 mutex_unlock(&this_afe.afe_cmd_lock);
6025 return ret;
6026}
6027
6028int q6afe_check_osr_clk_freq(u32 freq)
6029{
6030 int ret = 0;
6031
6032 switch (freq) {
6033 case Q6AFE_LPASS_OSR_CLK_12_P288_MHZ:
6034 case Q6AFE_LPASS_OSR_CLK_8_P192_MHZ:
6035 case Q6AFE_LPASS_OSR_CLK_6_P144_MHZ:
6036 case Q6AFE_LPASS_OSR_CLK_4_P096_MHZ:
6037 case Q6AFE_LPASS_OSR_CLK_3_P072_MHZ:
6038 case Q6AFE_LPASS_OSR_CLK_2_P048_MHZ:
6039 case Q6AFE_LPASS_OSR_CLK_1_P536_MHZ:
6040 case Q6AFE_LPASS_OSR_CLK_1_P024_MHZ:
6041 case Q6AFE_LPASS_OSR_CLK_768_kHZ:
6042 case Q6AFE_LPASS_OSR_CLK_512_kHZ:
6043 break;
6044 default:
6045 pr_err("%s: deafault freq 0x%x\n",
6046 __func__, freq);
6047 ret = -EINVAL;
6048 }
6049 return ret;
6050}
6051
6052int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi)
6053{
6054 int ret = -EINVAL;
6055 int index = 0, port = SLIMBUS_4_TX;
6056
6057 if (!th_vi) {
6058 pr_err("%s: Invalid params\n", __func__);
6059 goto done;
6060 }
6061 if (this_afe.vi_tx_port != -1)
6062 port = this_afe.vi_tx_port;
6063
6064 ret = q6audio_validate_port(port);
6065 if (ret < 0) {
6066 pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret);
6067 goto done;
6068 }
6069 index = q6audio_get_port_index(port);
6070 if (index < 0) {
6071 pr_err("%s: invalid port 0x%x, index %d\n",
6072 __func__, port, index);
6073 ret = -EINVAL;
6074 goto done;
6075 }
6076 th_vi->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
6077 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
6078 th_vi->hdr.pkt_size = sizeof(*th_vi);
6079 th_vi->hdr.src_port = 0;
6080 th_vi->hdr.dest_port = 0;
6081 th_vi->hdr.token = index;
6082 th_vi->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
6083 th_vi->get_param.mem_map_handle = 0;
6084 th_vi->get_param.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI;
6085 th_vi->get_param.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS;
6086 th_vi->get_param.payload_address_lsw = 0;
6087 th_vi->get_param.payload_address_msw = 0;
6088 th_vi->get_param.payload_size = sizeof(*th_vi)
6089 - sizeof(th_vi->get_param) - sizeof(th_vi->hdr);
6090 th_vi->get_param.port_id = q6audio_get_port_id(port);
6091 th_vi->pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI;
6092 th_vi->pdata.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS;
6093 th_vi->pdata.param_size = sizeof(th_vi->param);
6094 atomic_set(&this_afe.status, 0);
6095 atomic_set(&this_afe.state, 1);
6096 ret = apr_send_pkt(this_afe.apr, (uint32_t *)th_vi);
6097 if (ret < 0) {
6098 pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n",
6099 __func__, port, th_vi->get_param.param_id, ret);
6100 goto done;
6101 }
6102 ret = wait_event_timeout(this_afe.wait[index],
6103 (atomic_read(&this_afe.state) == 0),
6104 msecs_to_jiffies(TIMEOUT_MS));
6105 if (!ret) {
6106 pr_err("%s: wait_event timeout\n", __func__);
6107 ret = -EINVAL;
6108 goto done;
6109 }
6110 if (atomic_read(&this_afe.status) > 0) {
6111 pr_err("%s: config cmd failed [%s]\n",
6112 __func__, adsp_err_get_err_str(
6113 atomic_read(&this_afe.status)));
6114 ret = adsp_err_get_lnx_err_code(atomic_read(&this_afe.status));
6115 goto done;
6116 }
6117 memcpy(&th_vi->param, &this_afe.th_vi_resp.param,
6118 sizeof(this_afe.th_vi_resp.param));
6119 pr_debug("%s: DC resistance %d %d temp %d %d status %d %d\n",
6120 __func__, th_vi->param.dc_res_q24[SP_V2_SPKR_1],
6121 th_vi->param.dc_res_q24[SP_V2_SPKR_2],
6122 th_vi->param.temp_q22[SP_V2_SPKR_1],
6123 th_vi->param.temp_q22[SP_V2_SPKR_2],
6124 th_vi->param.status[SP_V2_SPKR_1],
6125 th_vi->param.status[SP_V2_SPKR_2]);
6126 ret = 0;
6127done:
6128 return ret;
6129}
6130
6131int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi)
6132{
6133 int ret = -EINVAL;
6134 int index = 0, port = SLIMBUS_4_TX;
6135
6136 if (!ex_vi) {
6137 pr_err("%s: Invalid params\n", __func__);
6138 goto done;
6139 }
6140 if (this_afe.vi_tx_port != -1)
6141 port = this_afe.vi_tx_port;
6142
6143 ret = q6audio_validate_port(port);
6144 if (ret < 0) {
6145 pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret);
6146 goto done;
6147 }
6148
6149 index = q6audio_get_port_index(port);
6150 if (index < 0) {
6151 pr_err("%s: invalid index %d port 0x%x\n", __func__,
6152 index, port);
6153 ret = -EINVAL;
6154 goto done;
6155 }
6156
6157 ex_vi->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
6158 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
6159 ex_vi->hdr.pkt_size = sizeof(*ex_vi);
6160 ex_vi->hdr.src_port = 0;
6161 ex_vi->hdr.dest_port = 0;
6162 ex_vi->hdr.token = index;
6163 ex_vi->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
6164 ex_vi->get_param.mem_map_handle = 0;
6165 ex_vi->get_param.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI;
6166 ex_vi->get_param.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS;
6167 ex_vi->get_param.payload_address_lsw = 0;
6168 ex_vi->get_param.payload_address_msw = 0;
6169 ex_vi->get_param.payload_size = sizeof(*ex_vi)
6170 - sizeof(ex_vi->get_param) - sizeof(ex_vi->hdr);
6171 ex_vi->get_param.port_id = q6audio_get_port_id(port);
6172 ex_vi->pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI;
6173 ex_vi->pdata.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS;
6174 ex_vi->pdata.param_size = sizeof(ex_vi->param);
6175 atomic_set(&this_afe.status, 0);
6176 atomic_set(&this_afe.state, 1);
6177 ret = apr_send_pkt(this_afe.apr, (uint32_t *)ex_vi);
6178 if (ret < 0) {
6179 pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n",
6180 __func__, port, ex_vi->get_param.param_id, ret);
6181 goto done;
6182 }
6183 ret = wait_event_timeout(this_afe.wait[index],
6184 (atomic_read(&this_afe.state) == 0),
6185 msecs_to_jiffies(TIMEOUT_MS));
6186 if (!ret) {
6187 pr_err("%s: wait_event timeout\n", __func__);
6188 ret = -EINVAL;
6189 goto done;
6190 }
6191 if (atomic_read(&this_afe.status) > 0) {
6192 pr_err("%s: config cmd failed [%s]\n",
6193 __func__, adsp_err_get_err_str(
6194 atomic_read(&this_afe.status)));
6195 ret = adsp_err_get_lnx_err_code(atomic_read(&this_afe.status));
6196 goto done;
6197 }
6198 memcpy(&ex_vi->param, &this_afe.ex_vi_resp.param,
6199 sizeof(this_afe.ex_vi_resp.param));
6200 pr_debug("%s: freq %d %d resistance %d %d qfactor %d %d state %d %d\n",
6201 __func__, ex_vi->param.freq_q20[SP_V2_SPKR_1],
6202 ex_vi->param.freq_q20[SP_V2_SPKR_2],
6203 ex_vi->param.resis_q24[SP_V2_SPKR_1],
6204 ex_vi->param.resis_q24[SP_V2_SPKR_2],
6205 ex_vi->param.qmct_q24[SP_V2_SPKR_1],
6206 ex_vi->param.qmct_q24[SP_V2_SPKR_2],
6207 ex_vi->param.status[SP_V2_SPKR_1],
6208 ex_vi->param.status[SP_V2_SPKR_2]);
6209 ret = 0;
6210done:
6211 return ret;
6212}
6213
Manish Dewangan1903ffb2016-12-20 12:56:24 +05306214int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats,
6215 u16 port)
6216{
6217 int ret = -EINVAL;
6218 int index = 0;
6219 struct afe_av_dev_drift_get_param av_dev_drift;
6220
6221 if (!timing_stats) {
6222 pr_err("%s: Invalid params\n", __func__);
6223 goto exit;
6224 }
6225
6226 ret = q6audio_validate_port(port);
6227 if (ret < 0) {
6228 pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret);
6229 ret = -EINVAL;
6230 goto exit;
6231 }
6232
6233 index = q6audio_get_port_index(port);
6234 if (index < 0 || index >= AFE_MAX_PORTS) {
6235 pr_err("%s: Invalid AFE port index[%d]\n",
6236 __func__, index);
6237 ret = -EINVAL;
6238 goto exit;
6239 }
6240
6241 memset(&av_dev_drift, 0, sizeof(struct afe_av_dev_drift_get_param));
6242
6243 av_dev_drift.hdr.hdr_field =
6244 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
6245 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
6246 av_dev_drift.hdr.pkt_size = sizeof(av_dev_drift);
6247 av_dev_drift.hdr.src_port = 0;
6248 av_dev_drift.hdr.dest_port = 0;
6249 av_dev_drift.hdr.token = index;
6250 av_dev_drift.hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
6251 av_dev_drift.get_param.mem_map_handle = 0;
6252 av_dev_drift.get_param.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
6253 av_dev_drift.get_param.param_id = AFE_PARAM_ID_DEV_TIMING_STATS;
6254 av_dev_drift.get_param.payload_address_lsw = 0;
6255 av_dev_drift.get_param.payload_address_msw = 0;
6256 av_dev_drift.get_param.payload_size = sizeof(av_dev_drift)
6257 - sizeof(av_dev_drift.get_param) - sizeof(av_dev_drift.hdr);
6258 av_dev_drift.get_param.port_id = q6audio_get_port_id(port);
6259 av_dev_drift.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
6260 av_dev_drift.pdata.param_id = AFE_PARAM_ID_DEV_TIMING_STATS;
6261 av_dev_drift.pdata.param_size = sizeof(av_dev_drift.timing_stats);
6262 atomic_set(&this_afe.status, 0);
6263 atomic_set(&this_afe.state, 1);
6264 ret = apr_send_pkt(this_afe.apr, (uint32_t *)&av_dev_drift);
6265 if (ret < 0) {
6266 pr_err("%s: get param port 0x%x param id[0x%x] failed %d\n",
6267 __func__, port, av_dev_drift.get_param.param_id, ret);
6268 goto exit;
6269 }
6270
6271 ret = wait_event_timeout(this_afe.wait[index],
6272 (atomic_read(&this_afe.state) == 0),
6273 msecs_to_jiffies(TIMEOUT_MS));
6274 if (!ret) {
6275 pr_err("%s: wait_event timeout\n", __func__);
6276 ret = -EINVAL;
6277 goto exit;
6278 }
6279
6280 if (atomic_read(&this_afe.status) > 0) {
6281 pr_err("%s: config cmd failed [%s]\n",
6282 __func__, adsp_err_get_err_str(
6283 atomic_read(&this_afe.status)));
6284 ret = adsp_err_get_lnx_err_code(
6285 atomic_read(&this_afe.status));
6286 goto exit;
6287 }
6288
6289 memcpy(timing_stats, &this_afe.av_dev_drift_resp.timing_stats,
6290 sizeof(this_afe.av_dev_drift_resp.timing_stats));
6291 ret = 0;
6292exit:
6293 return ret;
6294}
6295
Banajit Goswami0530e2f2016-12-09 21:34:37 -08006296int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp)
6297{
6298 int ret = -EINVAL;
6299 int index = 0, port = SLIMBUS_4_TX;
6300
6301 if (!calib_resp) {
6302 pr_err("%s: Invalid params\n", __func__);
6303 goto fail_cmd;
6304 }
6305 if (this_afe.vi_tx_port != -1)
6306 port = this_afe.vi_tx_port;
6307
6308 ret = q6audio_validate_port(port);
6309 if (ret < 0) {
6310 pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret);
6311 ret = -EINVAL;
6312 goto fail_cmd;
6313 }
6314 index = q6audio_get_port_index(port);
Xiaoyu Ye38ae2252017-01-26 18:20:06 -08006315 if (index < 0 || index >= AFE_MAX_PORTS) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08006316 pr_err("%s: AFE port index[%d] invalid!\n",
6317 __func__, index);
6318 ret = -EINVAL;
6319 goto fail_cmd;
6320 }
6321 calib_resp->hdr.hdr_field =
6322 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
6323 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
6324 calib_resp->hdr.pkt_size = sizeof(*calib_resp);
6325 calib_resp->hdr.src_port = 0;
6326 calib_resp->hdr.dest_port = 0;
6327 calib_resp->hdr.token = index;
6328 calib_resp->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
6329 calib_resp->get_param.mem_map_handle = 0;
6330 calib_resp->get_param.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2;
6331 calib_resp->get_param.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2;
6332 calib_resp->get_param.payload_address_lsw = 0;
6333 calib_resp->get_param.payload_address_msw = 0;
6334 calib_resp->get_param.payload_size = sizeof(*calib_resp)
6335 - sizeof(calib_resp->get_param) - sizeof(calib_resp->hdr);
6336 calib_resp->get_param.port_id = q6audio_get_port_id(port);
6337 calib_resp->pdata.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2;
6338 calib_resp->pdata.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2;
6339 calib_resp->pdata.param_size = sizeof(calib_resp->res_cfg);
6340 atomic_set(&this_afe.status, 0);
6341 atomic_set(&this_afe.state, 1);
6342 ret = apr_send_pkt(this_afe.apr, (uint32_t *)calib_resp);
6343 if (ret < 0) {
6344 pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n",
6345 __func__, port, calib_resp->get_param.param_id, ret);
6346 goto fail_cmd;
6347 }
6348 ret = wait_event_timeout(this_afe.wait[index],
6349 (atomic_read(&this_afe.state) == 0),
6350 msecs_to_jiffies(TIMEOUT_MS));
6351 if (!ret) {
6352 pr_err("%s: wait_event timeout\n", __func__);
6353 ret = -EINVAL;
6354 goto fail_cmd;
6355 }
6356 if (atomic_read(&this_afe.status) > 0) {
6357 pr_err("%s: config cmd failed [%s]\n",
6358 __func__, adsp_err_get_err_str(
6359 atomic_read(&this_afe.status)));
6360 ret = adsp_err_get_lnx_err_code(
6361 atomic_read(&this_afe.status));
6362 goto fail_cmd;
6363 }
6364 memcpy(&calib_resp->res_cfg, &this_afe.calib_data.res_cfg,
6365 sizeof(this_afe.calib_data.res_cfg));
6366 pr_info("%s: state %s resistance %d %d\n", __func__,
6367 fbsp_state[calib_resp->res_cfg.th_vi_ca_state],
6368 calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_1],
6369 calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_2]);
6370 ret = 0;
6371fail_cmd:
6372 return ret;
6373}
6374
6375int afe_spk_prot_feed_back_cfg(int src_port, int dst_port,
6376 int l_ch, int r_ch, u32 enable)
6377{
6378 int ret = -EINVAL;
6379 union afe_spkr_prot_config prot_config;
6380 int index = 0;
6381
6382 if (!enable) {
6383 pr_debug("%s: Disable Feedback tx path", __func__);
6384 this_afe.vi_tx_port = -1;
6385 this_afe.vi_rx_port = -1;
6386 return 0;
6387 }
6388
6389 if ((q6audio_validate_port(src_port) < 0) ||
6390 (q6audio_validate_port(dst_port) < 0)) {
6391 pr_err("%s: invalid ports src 0x%x dst 0x%x",
6392 __func__, src_port, dst_port);
6393 goto fail_cmd;
6394 }
6395 if (!l_ch && !r_ch) {
6396 pr_err("%s: error ch values zero\n", __func__);
6397 goto fail_cmd;
6398 }
6399 pr_debug("%s: src_port 0x%x dst_port 0x%x l_ch %d r_ch %d\n",
6400 __func__, src_port, dst_port, l_ch, r_ch);
6401 memset(&prot_config, 0, sizeof(prot_config));
6402 prot_config.feedback_path_cfg.dst_portid =
6403 q6audio_get_port_id(dst_port);
6404 if (l_ch) {
6405 prot_config.feedback_path_cfg.chan_info[index++] = 1;
6406 prot_config.feedback_path_cfg.chan_info[index++] = 2;
6407 }
6408 if (r_ch) {
6409 prot_config.feedback_path_cfg.chan_info[index++] = 3;
6410 prot_config.feedback_path_cfg.chan_info[index++] = 4;
6411 }
6412 prot_config.feedback_path_cfg.num_channels = index;
6413 pr_debug("%s no of channels: %d\n", __func__, index);
6414 prot_config.feedback_path_cfg.minor_version = 1;
6415 ret = afe_spk_prot_prepare(src_port, dst_port,
6416 AFE_PARAM_ID_FEEDBACK_PATH_CFG, &prot_config);
6417fail_cmd:
6418 return ret;
6419}
6420
6421static int get_cal_type_index(int32_t cal_type)
6422{
6423 int ret = -EINVAL;
6424
6425 switch (cal_type) {
6426 case AFE_COMMON_RX_CAL_TYPE:
6427 ret = AFE_COMMON_RX_CAL;
6428 break;
6429 case AFE_COMMON_TX_CAL_TYPE:
6430 ret = AFE_COMMON_TX_CAL;
6431 break;
6432 case AFE_AANC_CAL_TYPE:
6433 ret = AFE_AANC_CAL;
6434 break;
6435 case AFE_HW_DELAY_CAL_TYPE:
6436 ret = AFE_HW_DELAY_CAL;
6437 break;
6438 case AFE_FB_SPKR_PROT_CAL_TYPE:
6439 ret = AFE_FB_SPKR_PROT_CAL;
6440 break;
6441 case AFE_SIDETONE_CAL_TYPE:
6442 ret = AFE_SIDETONE_CAL;
6443 break;
Siena Richardd83d83f2016-12-15 13:49:41 -08006444 case AFE_SIDETONE_IIR_CAL_TYPE:
6445 ret = AFE_SIDETONE_IIR_CAL;
6446 break;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08006447 case AFE_TOPOLOGY_CAL_TYPE:
6448 ret = AFE_TOPOLOGY_CAL;
6449 break;
6450 case AFE_CUST_TOPOLOGY_CAL_TYPE:
6451 ret = AFE_CUST_TOPOLOGY_CAL;
6452 break;
6453 default:
6454 pr_err("%s: invalid cal type %d!\n", __func__, cal_type);
6455 }
6456 return ret;
6457}
6458
6459int afe_alloc_cal(int32_t cal_type, size_t data_size,
6460 void *data)
6461{
6462 int ret = 0;
6463 int cal_index;
6464
6465 cal_index = get_cal_type_index(cal_type);
6466 pr_debug("%s: cal_type = %d cal_index = %d\n",
6467 __func__, cal_type, cal_index);
6468
6469 if (cal_index < 0) {
6470 pr_err("%s: could not get cal index %d!\n",
6471 __func__, cal_index);
6472 ret = -EINVAL;
6473 goto done;
6474 }
6475
6476 ret = cal_utils_alloc_cal(data_size, data,
6477 this_afe.cal_data[cal_index], 0, NULL);
6478 if (ret < 0) {
6479 pr_err("%s: cal_utils_alloc_block failed, ret = %d, cal type = %d!\n",
6480 __func__, ret, cal_type);
6481 ret = -EINVAL;
6482 goto done;
6483 }
6484done:
6485 return ret;
6486}
6487
6488static int afe_dealloc_cal(int32_t cal_type, size_t data_size,
6489 void *data)
6490{
6491 int ret = 0;
6492 int cal_index;
6493
6494 pr_debug("%s:\n", __func__);
6495
6496 cal_index = get_cal_type_index(cal_type);
6497 if (cal_index < 0) {
6498 pr_err("%s: could not get cal index %d!\n",
6499 __func__, cal_index);
6500 ret = -EINVAL;
6501 goto done;
6502 }
6503
6504 ret = cal_utils_dealloc_cal(data_size, data,
6505 this_afe.cal_data[cal_index]);
6506 if (ret < 0) {
6507 pr_err("%s: cal_utils_dealloc_block failed, ret = %d, cal type = %d!\n",
6508 __func__, ret, cal_type);
6509 ret = -EINVAL;
6510 goto done;
6511 }
6512done:
6513 return ret;
6514}
6515
6516static int afe_set_cal(int32_t cal_type, size_t data_size,
6517 void *data)
6518{
6519 int ret = 0;
6520 int cal_index;
6521
6522 pr_debug("%s:\n", __func__);
6523
6524 cal_index = get_cal_type_index(cal_type);
6525 if (cal_index < 0) {
6526 pr_err("%s: could not get cal index %d!\n",
6527 __func__, cal_index);
6528 ret = -EINVAL;
6529 goto done;
6530 }
6531
6532 ret = cal_utils_set_cal(data_size, data,
6533 this_afe.cal_data[cal_index], 0, NULL);
6534 if (ret < 0) {
6535 pr_err("%s: cal_utils_set_cal failed, ret = %d, cal type = %d!\n",
6536 __func__, ret, cal_type);
6537 ret = -EINVAL;
6538 goto done;
6539 }
6540
6541 if (cal_index == AFE_CUST_TOPOLOGY_CAL) {
6542 mutex_lock(&this_afe.cal_data[AFE_CUST_TOPOLOGY_CAL]->lock);
6543 this_afe.set_custom_topology = 1;
6544 pr_debug("%s:[AFE_CUSTOM_TOPOLOGY] ret = %d, cal type = %d!\n",
6545 __func__, ret, cal_type);
6546 mutex_unlock(&this_afe.cal_data[AFE_CUST_TOPOLOGY_CAL]->lock);
6547 }
6548
6549done:
6550 return ret;
6551}
6552
6553static struct cal_block_data *afe_find_hw_delay_by_path(
6554 struct cal_type_data *cal_type, int path)
6555{
6556 struct list_head *ptr, *next;
6557 struct cal_block_data *cal_block = NULL;
6558
6559 pr_debug("%s:\n", __func__);
6560
6561 list_for_each_safe(ptr, next,
6562 &cal_type->cal_blocks) {
6563
6564 cal_block = list_entry(ptr,
6565 struct cal_block_data, list);
6566
6567 if (((struct audio_cal_info_hw_delay *)cal_block->cal_info)
6568 ->path == path) {
6569 return cal_block;
6570 }
6571 }
6572 return NULL;
6573}
6574
6575static int afe_get_cal_hw_delay(int32_t path,
6576 struct audio_cal_hw_delay_entry *entry)
6577{
6578 int ret = 0;
6579 int i;
6580 struct cal_block_data *cal_block = NULL;
6581 struct audio_cal_hw_delay_data *hw_delay_info = NULL;
6582
6583 pr_debug("%s:\n", __func__);
6584
6585 if (this_afe.cal_data[AFE_HW_DELAY_CAL] == NULL) {
6586 pr_err("%s: AFE_HW_DELAY_CAL not initialized\n", __func__);
6587 ret = -EINVAL;
6588 goto done;
6589 }
6590 if (entry == NULL) {
6591 pr_err("%s: entry is NULL\n", __func__);
6592 ret = -EINVAL;
6593 goto done;
6594 }
6595 if ((path >= MAX_PATH_TYPE) || (path < 0)) {
6596 pr_err("%s: bad path: %d\n",
6597 __func__, path);
6598 ret = -EINVAL;
6599 goto done;
6600 }
6601
6602 mutex_lock(&this_afe.cal_data[AFE_HW_DELAY_CAL]->lock);
6603 cal_block = afe_find_hw_delay_by_path(
6604 this_afe.cal_data[AFE_HW_DELAY_CAL], path);
6605 if (cal_block == NULL)
6606 goto unlock;
6607
6608 hw_delay_info = &((struct audio_cal_info_hw_delay *)
6609 cal_block->cal_info)->data;
6610 if (hw_delay_info->num_entries > MAX_HW_DELAY_ENTRIES) {
6611 pr_err("%s: invalid num entries: %d\n",
6612 __func__, hw_delay_info->num_entries);
6613 ret = -EINVAL;
6614 goto unlock;
6615 }
6616
6617 for (i = 0; i < hw_delay_info->num_entries; i++) {
6618 if (hw_delay_info->entry[i].sample_rate ==
6619 entry->sample_rate) {
6620 entry->delay_usec = hw_delay_info->entry[i].delay_usec;
6621 break;
6622 }
6623 }
6624 if (i == hw_delay_info->num_entries) {
6625 pr_err("%s: Unable to find delay for sample rate %d\n",
6626 __func__, entry->sample_rate);
6627 ret = -EFAULT;
6628 goto unlock;
6629 }
6630 pr_debug("%s: Path = %d samplerate = %u usec = %u status %d\n",
6631 __func__, path, entry->sample_rate, entry->delay_usec, ret);
6632unlock:
6633 mutex_unlock(&this_afe.cal_data[AFE_HW_DELAY_CAL]->lock);
6634done:
6635 return ret;
6636}
6637
6638static int afe_set_cal_sp_th_vi_ftm_cfg(int32_t cal_type, size_t data_size,
6639 void *data)
6640{
6641 int ret = 0;
6642 struct audio_cal_type_sp_th_vi_ftm_cfg *cal_data = data;
6643
6644 if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL ||
6645 cal_data == NULL ||
6646 data_size != sizeof(*cal_data))
6647 goto done;
6648
6649 pr_debug("%s: cal_type = %d\n", __func__, cal_type);
6650 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
6651 memcpy(&this_afe.th_ftm_cfg, &cal_data->cal_info,
6652 sizeof(this_afe.th_ftm_cfg));
6653 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
6654done:
6655 return ret;
6656}
6657
6658static int afe_set_cal_sp_ex_vi_ftm_cfg(int32_t cal_type, size_t data_size,
6659 void *data)
6660{
6661 int ret = 0;
6662 struct audio_cal_type_sp_ex_vi_ftm_cfg *cal_data = data;
6663
6664 if (this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL ||
6665 cal_data == NULL ||
6666 data_size != sizeof(*cal_data))
6667 goto done;
6668
6669 pr_debug("%s: cal_type = %d\n", __func__, cal_type);
6670 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
6671 memcpy(&this_afe.ex_ftm_cfg, &cal_data->cal_info,
6672 sizeof(this_afe.ex_ftm_cfg));
6673 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
6674done:
6675 return ret;
6676}
6677
6678static int afe_set_cal_fb_spkr_prot(int32_t cal_type, size_t data_size,
6679 void *data)
6680{
6681 int ret = 0;
6682 struct audio_cal_type_fb_spk_prot_cfg *cal_data = data;
6683
6684 pr_debug("%s:\n", __func__);
6685
6686 if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL)
6687 goto done;
6688 if (cal_data == NULL)
6689 goto done;
6690 if (data_size != sizeof(*cal_data))
6691 goto done;
6692
6693 if (cal_data->cal_info.mode == MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS)
6694 __pm_wakeup_event(&wl.ws, jiffies_to_msecs(WAKELOCK_TIMEOUT));
6695 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
6696 memcpy(&this_afe.prot_cfg, &cal_data->cal_info,
6697 sizeof(this_afe.prot_cfg));
Banajit Goswami0530e2f2016-12-09 21:34:37 -08006698 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
6699done:
6700 return ret;
6701}
6702
6703static int afe_get_cal_sp_th_vi_ftm_param(int32_t cal_type, size_t data_size,
6704 void *data)
6705{
6706 int i, ret = 0;
6707 struct audio_cal_type_sp_th_vi_param *cal_data = data;
6708 struct afe_sp_th_vi_get_param th_vi;
6709
6710 pr_debug("%s: cal_type = %d\n", __func__, cal_type);
6711 if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL ||
6712 cal_data == NULL ||
6713 data_size != sizeof(*cal_data))
6714 goto done;
6715
6716 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
6717 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
6718 cal_data->cal_info.status[i] = -EINVAL;
6719 cal_data->cal_info.r_dc_q24[i] = -1;
6720 cal_data->cal_info.temp_q22[i] = -1;
6721 }
6722 if (!afe_get_sp_th_vi_ftm_data(&th_vi)) {
6723 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
6724 pr_debug("%s: ftm param status = %d\n",
6725 __func__, th_vi.param.status[i]);
6726 if (th_vi.param.status[i] == FBSP_IN_PROGRESS) {
6727 cal_data->cal_info.status[i] = -EAGAIN;
6728 } else if (th_vi.param.status[i] == FBSP_SUCCESS) {
6729 cal_data->cal_info.status[i] = 0;
6730 cal_data->cal_info.r_dc_q24[i] =
6731 th_vi.param.dc_res_q24[i];
6732 cal_data->cal_info.temp_q22[i] =
6733 th_vi.param.temp_q22[i];
6734 }
6735 }
6736 }
6737 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
6738done:
6739 return ret;
6740}
6741
6742static int afe_get_cal_sp_ex_vi_ftm_param(int32_t cal_type, size_t data_size,
6743 void *data)
6744{
6745 int i, ret = 0;
6746 struct audio_cal_type_sp_ex_vi_param *cal_data = data;
6747 struct afe_sp_ex_vi_get_param ex_vi;
6748
6749 pr_debug("%s: cal_type = %d\n", __func__, cal_type);
6750 if (this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL ||
6751 cal_data == NULL ||
6752 data_size != sizeof(*cal_data))
6753 goto done;
6754
6755 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
6756 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
6757 cal_data->cal_info.status[i] = -EINVAL;
6758 cal_data->cal_info.freq_q20[i] = -1;
6759 cal_data->cal_info.resis_q24[i] = -1;
6760 cal_data->cal_info.qmct_q24[i] = -1;
6761 }
6762 if (!afe_get_sp_ex_vi_ftm_data(&ex_vi)) {
6763 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
6764 pr_debug("%s: ftm param status = %d\n",
6765 __func__, ex_vi.param.status[i]);
6766 if (ex_vi.param.status[i] == FBSP_IN_PROGRESS) {
6767 cal_data->cal_info.status[i] = -EAGAIN;
6768 } else if (ex_vi.param.status[i] == FBSP_SUCCESS) {
6769 cal_data->cal_info.status[i] = 0;
6770 cal_data->cal_info.freq_q20[i] =
6771 ex_vi.param.freq_q20[i];
6772 cal_data->cal_info.resis_q24[i] =
6773 ex_vi.param.resis_q24[i];
6774 cal_data->cal_info.qmct_q24[i] =
6775 ex_vi.param.qmct_q24[i];
6776 }
6777 }
6778 }
6779 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
6780done:
6781 return ret;
6782}
6783
6784static int afe_get_cal_fb_spkr_prot(int32_t cal_type, size_t data_size,
6785 void *data)
6786{
6787 int ret = 0;
6788 struct audio_cal_type_fb_spk_prot_status *cal_data = data;
6789 struct afe_spkr_prot_get_vi_calib calib_resp;
6790
6791 pr_debug("%s:\n", __func__);
6792
6793 if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL)
6794 goto done;
6795 if (cal_data == NULL)
6796 goto done;
6797 if (data_size != sizeof(*cal_data))
6798 goto done;
6799
6800 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
6801 if (this_afe.prot_cfg.mode == MSM_SPKR_PROT_CALIBRATED) {
6802 cal_data->cal_info.r0[SP_V2_SPKR_1] =
6803 this_afe.prot_cfg.r0[SP_V2_SPKR_1];
6804 cal_data->cal_info.r0[SP_V2_SPKR_2] =
6805 this_afe.prot_cfg.r0[SP_V2_SPKR_2];
6806 cal_data->cal_info.status = 0;
6807 } else if (this_afe.prot_cfg.mode ==
6808 MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) {
6809 /*Call AFE to query the status*/
6810 cal_data->cal_info.status = -EINVAL;
6811 cal_data->cal_info.r0[SP_V2_SPKR_1] = -1;
6812 cal_data->cal_info.r0[SP_V2_SPKR_2] = -1;
6813 if (!afe_spk_prot_get_calib_data(&calib_resp)) {
6814 if (calib_resp.res_cfg.th_vi_ca_state ==
6815 FBSP_IN_PROGRESS)
6816 cal_data->cal_info.status = -EAGAIN;
6817 else if (calib_resp.res_cfg.th_vi_ca_state ==
6818 FBSP_SUCCESS) {
6819 cal_data->cal_info.status = 0;
6820 cal_data->cal_info.r0[SP_V2_SPKR_1] =
6821 calib_resp.res_cfg.r0_cali_q24[SP_V2_SPKR_1];
6822 cal_data->cal_info.r0[SP_V2_SPKR_2] =
6823 calib_resp.res_cfg.r0_cali_q24[SP_V2_SPKR_2];
6824 }
6825 }
6826 if (!cal_data->cal_info.status) {
6827 this_afe.prot_cfg.mode =
6828 MSM_SPKR_PROT_CALIBRATED;
6829 this_afe.prot_cfg.r0[SP_V2_SPKR_1] =
6830 cal_data->cal_info.r0[SP_V2_SPKR_1];
6831 this_afe.prot_cfg.r0[SP_V2_SPKR_2] =
6832 cal_data->cal_info.r0[SP_V2_SPKR_2];
6833 }
6834 } else {
6835 /*Indicates calibration data is invalid*/
6836 cal_data->cal_info.status = -EINVAL;
6837 cal_data->cal_info.r0[SP_V2_SPKR_1] = -1;
6838 cal_data->cal_info.r0[SP_V2_SPKR_2] = -1;
6839 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -08006840 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
6841 __pm_relax(&wl.ws);
6842done:
6843 return ret;
6844}
6845
6846static int afe_map_cal_data(int32_t cal_type,
6847 struct cal_block_data *cal_block)
6848{
6849 int ret = 0;
6850 int cal_index;
6851
6852 pr_debug("%s:\n", __func__);
6853
6854 cal_index = get_cal_type_index(cal_type);
6855 if (cal_index < 0) {
6856 pr_err("%s: could not get cal index %d!\n",
6857 __func__, cal_index);
6858 ret = -EINVAL;
6859 goto done;
6860 }
6861
6862
Rohit Kumara888c5c2016-11-28 12:23:18 +05306863 mutex_lock(&this_afe.afe_cmd_lock);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08006864 atomic_set(&this_afe.mem_map_cal_index, cal_index);
6865 ret = afe_cmd_memory_map(cal_block->cal_data.paddr,
6866 cal_block->map_data.map_size);
6867 atomic_set(&this_afe.mem_map_cal_index, -1);
6868 if (ret < 0) {
6869 pr_err("%s: mmap did not work! size = %zd ret %d\n",
6870 __func__,
6871 cal_block->map_data.map_size, ret);
6872 pr_debug("%s: mmap did not work! addr = 0x%pK, size = %zd\n",
6873 __func__,
6874 &cal_block->cal_data.paddr,
6875 cal_block->map_data.map_size);
Rohit Kumara888c5c2016-11-28 12:23:18 +05306876 mutex_unlock(&this_afe.afe_cmd_lock);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08006877 goto done;
6878 }
6879 cal_block->map_data.q6map_handle = atomic_read(&this_afe.
6880 mem_map_cal_handles[cal_index]);
Rohit Kumara888c5c2016-11-28 12:23:18 +05306881 mutex_unlock(&this_afe.afe_cmd_lock);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08006882done:
6883 return ret;
6884}
6885
6886static int afe_unmap_cal_data(int32_t cal_type,
6887 struct cal_block_data *cal_block)
6888{
6889 int ret = 0;
6890 int cal_index;
6891
6892 pr_debug("%s:\n", __func__);
6893
6894 cal_index = get_cal_type_index(cal_type);
6895 if (cal_index < 0) {
6896 pr_err("%s: could not get cal index %d!\n",
6897 __func__, cal_index);
6898 ret = -EINVAL;
6899 goto done;
6900 }
6901
6902 if (cal_block == NULL) {
6903 pr_err("%s: Cal block is NULL!\n",
6904 __func__);
6905 goto done;
6906 }
6907
6908 if (cal_block->map_data.q6map_handle == 0) {
6909 pr_err("%s: Map handle is NULL, nothing to unmap\n",
6910 __func__);
6911 goto done;
6912 }
6913
6914 atomic_set(&this_afe.mem_map_cal_handles[cal_index],
6915 cal_block->map_data.q6map_handle);
6916 atomic_set(&this_afe.mem_map_cal_index, cal_index);
6917 ret = afe_cmd_memory_unmap_nowait(
6918 cal_block->map_data.q6map_handle);
6919 atomic_set(&this_afe.mem_map_cal_index, -1);
6920 if (ret < 0) {
6921 pr_err("%s: unmap did not work! cal_type %i ret %d\n",
6922 __func__, cal_index, ret);
6923 }
6924 cal_block->map_data.q6map_handle = 0;
6925done:
6926 return ret;
6927}
6928
6929static void afe_delete_cal_data(void)
6930{
6931 pr_debug("%s:\n", __func__);
6932
6933 cal_utils_destroy_cal_types(MAX_AFE_CAL_TYPES, this_afe.cal_data);
6934}
6935
6936static int afe_init_cal_data(void)
6937{
6938 int ret = 0;
6939 struct cal_type_info cal_type_info[] = {
6940 {{AFE_COMMON_RX_CAL_TYPE,
6941 {afe_alloc_cal, afe_dealloc_cal, NULL,
6942 afe_set_cal, NULL, NULL} },
6943 {afe_map_cal_data, afe_unmap_cal_data,
6944 cal_utils_match_buf_num} },
6945
6946 {{AFE_COMMON_TX_CAL_TYPE,
6947 {afe_alloc_cal, afe_dealloc_cal, NULL,
6948 afe_set_cal, NULL, NULL} },
6949 {afe_map_cal_data, afe_unmap_cal_data,
6950 cal_utils_match_buf_num} },
6951
6952 {{AFE_AANC_CAL_TYPE,
6953 {afe_alloc_cal, afe_dealloc_cal, NULL,
6954 afe_set_cal, NULL, NULL} },
6955 {afe_map_cal_data, afe_unmap_cal_data,
6956 cal_utils_match_buf_num} },
6957
6958 {{AFE_FB_SPKR_PROT_CAL_TYPE,
6959 {NULL, NULL, NULL, afe_set_cal_fb_spkr_prot,
6960 afe_get_cal_fb_spkr_prot, NULL} },
6961 {NULL, NULL, cal_utils_match_buf_num} },
6962
6963 {{AFE_HW_DELAY_CAL_TYPE,
6964 {NULL, NULL, NULL,
6965 afe_set_cal, NULL, NULL} },
6966 {NULL, NULL, cal_utils_match_buf_num} },
6967
6968 {{AFE_SIDETONE_CAL_TYPE,
6969 {NULL, NULL, NULL,
6970 afe_set_cal, NULL, NULL} },
6971 {NULL, NULL, cal_utils_match_buf_num} },
6972
Siena Richardd83d83f2016-12-15 13:49:41 -08006973 {{AFE_SIDETONE_IIR_CAL_TYPE,
6974 {NULL, NULL, NULL,
6975 afe_set_cal, NULL, NULL} },
6976 {NULL, NULL, cal_utils_match_buf_num} },
6977
Banajit Goswami0530e2f2016-12-09 21:34:37 -08006978 {{AFE_TOPOLOGY_CAL_TYPE,
6979 {NULL, NULL, NULL,
6980 afe_set_cal, NULL, NULL} },
6981 {NULL, NULL,
6982 cal_utils_match_buf_num} },
6983
6984 {{AFE_CUST_TOPOLOGY_CAL_TYPE,
6985 {afe_alloc_cal, afe_dealloc_cal, NULL,
6986 afe_set_cal, NULL, NULL} },
6987 {afe_map_cal_data, afe_unmap_cal_data,
6988 cal_utils_match_buf_num} },
6989
6990 {{AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE,
6991 {NULL, NULL, NULL, afe_set_cal_sp_th_vi_ftm_cfg,
6992 afe_get_cal_sp_th_vi_ftm_param, NULL} },
6993 {NULL, NULL, cal_utils_match_buf_num} },
6994
6995 {{AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE,
6996 {NULL, NULL, NULL, afe_set_cal_sp_ex_vi_ftm_cfg,
6997 afe_get_cal_sp_ex_vi_ftm_param, NULL} },
6998 {NULL, NULL, cal_utils_match_buf_num} },
6999 };
7000 pr_debug("%s:\n", __func__);
7001
7002 ret = cal_utils_create_cal_types(MAX_AFE_CAL_TYPES, this_afe.cal_data,
7003 cal_type_info);
7004 if (ret < 0) {
7005 pr_err("%s: could not create cal type! %d\n",
7006 __func__, ret);
7007 ret = -EINVAL;
7008 goto err;
7009 }
7010
7011 return ret;
7012err:
7013 afe_delete_cal_data();
7014 return ret;
7015}
7016
7017int afe_map_rtac_block(struct rtac_cal_block_data *cal_block)
7018{
7019 int result = 0;
7020
7021 pr_debug("%s:\n", __func__);
7022
7023 if (cal_block == NULL) {
7024 pr_err("%s: cal_block is NULL!\n",
7025 __func__);
7026 result = -EINVAL;
7027 goto done;
7028 }
7029
7030 if (cal_block->cal_data.paddr == 0) {
7031 pr_debug("%s: No address to map!\n",
7032 __func__);
7033 result = -EINVAL;
7034 goto done;
7035 }
7036
7037 if (cal_block->map_data.map_size == 0) {
7038 pr_debug("%s: map size is 0!\n",
7039 __func__);
7040 result = -EINVAL;
7041 goto done;
7042 }
7043
7044 result = afe_cmd_memory_map(cal_block->cal_data.paddr,
7045 cal_block->map_data.map_size);
7046 if (result < 0) {
7047 pr_err("%s: afe_cmd_memory_map failed for addr = 0x%pK, size = %d, err %d\n",
7048 __func__, &cal_block->cal_data.paddr,
7049 cal_block->map_data.map_size, result);
7050 return result;
7051 }
7052 cal_block->map_data.map_handle = this_afe.mmap_handle;
7053
7054done:
7055 return result;
7056}
7057
7058int afe_unmap_rtac_block(uint32_t *mem_map_handle)
7059{
7060 int result = 0;
7061
7062 pr_debug("%s:\n", __func__);
7063
7064 if (mem_map_handle == NULL) {
7065 pr_err("%s: Map handle is NULL, nothing to unmap\n",
7066 __func__);
7067 goto done;
7068 }
7069
7070 if (*mem_map_handle == 0) {
7071 pr_debug("%s: Map handle is 0, nothing to unmap\n",
7072 __func__);
7073 goto done;
7074 }
7075
7076 result = afe_cmd_memory_unmap(*mem_map_handle);
7077 if (result) {
7078 pr_err("%s: AFE memory unmap failed %d, handle 0x%x\n",
7079 __func__, result, *mem_map_handle);
7080 goto done;
7081 } else {
7082 *mem_map_handle = 0;
7083 }
7084
7085done:
7086 return result;
7087}
7088
7089static int __init afe_init(void)
7090{
7091 int i = 0, ret;
7092
7093 atomic_set(&this_afe.state, 0);
7094 atomic_set(&this_afe.status, 0);
7095 atomic_set(&this_afe.mem_map_cal_index, -1);
7096 this_afe.apr = NULL;
7097 this_afe.dtmf_gen_rx_portid = -1;
7098 this_afe.mmap_handle = 0;
7099 this_afe.vi_tx_port = -1;
7100 this_afe.vi_rx_port = -1;
7101 this_afe.prot_cfg.mode = MSM_SPKR_PROT_DISABLED;
7102 this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED;
7103 this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED;
7104 mutex_init(&this_afe.afe_cmd_lock);
7105 for (i = 0; i < AFE_MAX_PORTS; i++) {
7106 this_afe.afe_cal_mode[i] = AFE_CAL_MODE_DEFAULT;
Siena Richard23364c92017-01-11 16:20:55 -08007107 this_afe.afe_sample_rates[i] = 0;
7108 this_afe.dev_acdb_id[i] = 0;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08007109 init_waitqueue_head(&this_afe.wait[i]);
7110 }
7111 wakeup_source_init(&wl.ws, "spkr-prot");
7112 ret = afe_init_cal_data();
7113 if (ret)
7114 pr_err("%s: could not init cal data! %d\n", __func__, ret);
7115
7116 config_debug_fs_init();
7117 return 0;
7118}
7119
7120static void __exit afe_exit(void)
7121{
7122 afe_delete_cal_data();
7123
7124 config_debug_fs_exit();
7125 mutex_destroy(&this_afe.afe_cmd_lock);
7126 wakeup_source_trash(&wl.ws);
7127}
7128
7129device_initcall(afe_init);
7130__exitcall(afe_exit);