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