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