blob: 78be555eb8eb42e62b1eb58214df4a74105767ff [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 &&
2827 format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD) {
2828 pr_err("%s:Unsuppported format Ignore AFE config\n", __func__);
2829 return 0;
2830 }
2831 memset(&config, 0, sizeof(config));
2832 index = q6audio_get_port_index(port_id);
2833 if (index < 0) {
2834 pr_err("%s: Invalid index number: %d\n", __func__, index);
2835 return -EINVAL;
2836 }
2837
2838 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2839 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2840 config.hdr.pkt_size = sizeof(config);
2841 config.hdr.src_port = 0;
2842 config.hdr.dest_port = 0;
2843 config.hdr.token = index;
2844
2845 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
2846 config.param.port_id = q6audio_get_port_id(port_id);
2847 config.param.payload_size = payload_size + sizeof(config.port.enc_fmt);
2848 config.param.payload_address_lsw = 0x00;
2849 config.param.payload_address_msw = 0x00;
2850 config.param.mem_map_handle = 0x00;
2851 config.pdata.module_id = AFE_MODULE_ID_ENCODER;
2852 config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_FMT_ID;
2853 config.pdata.param_size = sizeof(config.port.enc_fmt);
2854 config.port.enc_fmt.fmt_id = format;
2855 pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENC_FMT_ID payload: %d\n",
2856 __func__, config.param.payload_size);
2857 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
2858 if (ret) {
2859 pr_err("%s:unable to send AFE_ENCODER_PARAM_ID_ENC_FMT_ID",
2860 __func__);
2861 goto exit;
2862 }
2863
2864 config.param.payload_size = payload_size
2865 + sizeof(config.port.enc_blk_param);
2866 pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payload:%d\n",
2867 __func__, config.param.payload_size);
2868 config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK;
2869 config.pdata.param_size = sizeof(config.port.enc_blk_param);
2870 config.port.enc_blk_param.enc_cfg_blk_size =
2871 sizeof(config.port.enc_blk_param.enc_blk_config);
2872 config.port.enc_blk_param.enc_blk_config = *cfg;
2873 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
2874 if (ret) {
2875 pr_err("%s: AFE_ENCODER_PARAM_ID_ENC_CFG_BLK for port 0x%x failed %d\n",
2876 __func__, port_id, ret);
2877 goto exit;
2878 }
2879
2880 config.param.payload_size =
2881 payload_size + sizeof(config.port.enc_pkt_id_param);
2882 pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP payload = %d",
2883 __func__, config.param.payload_size);
2884 config.pdata.param_id = AFE_ENCODER_PARAM_ID_PACKETIZER_ID;
2885 config.pdata.param_size = sizeof(config.port.enc_pkt_id_param);
2886 config.port.enc_pkt_id_param.enc_packetizer_id =
2887 AFE_MODULE_ID_PACKETIZER_COP;
2888 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
2889 if (ret) {
2890 pr_err("%s: AFE_ENCODER_PARAM_ID_PACKETIZER for port 0x%x failed %d\n",
2891 __func__, port_id, ret);
2892 goto exit;
2893 }
2894
2895 config.param.payload_size =
2896 payload_size + sizeof(config.port.media_type);
2897 config.pdata.param_size = sizeof(config.port.media_type);
2898
2899 pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__);
2900 config.pdata.module_id = AFE_MODULE_PORT;
2901 config.pdata.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE;
2902 config.port.media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE;
2903 config.port.media_type.sample_rate = afe_config.slim_sch.sample_rate;
2904 if (afe_in_bit_width)
2905 config.port.media_type.bit_width = afe_in_bit_width;
2906 else
2907 config.port.media_type.bit_width =
2908 afe_config.slim_sch.bit_width;
2909
2910 if (afe_in_channels)
2911 config.port.media_type.num_channels = afe_in_channels;
2912 else
2913 config.port.media_type.num_channels =
2914 afe_config.slim_sch.num_channels;
2915 config.port.media_type.data_format = AFE_PORT_DATA_FORMAT_PCM;
2916 config.port.media_type.reserved = 0;
2917
2918 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
2919 if (ret) {
2920 pr_err("%s: AFE_API_VERSION_PORT_MEDIA_TYPE for port 0x%x failed %d\n",
2921 __func__, port_id, ret);
2922 goto exit;
2923 }
2924
2925exit:
2926 return ret;
2927}
2928
2929static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
2930 u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
2931 union afe_enc_config_data *cfg, u32 enc_format)
2932{
2933 struct afe_audioif_config_command config;
2934 int ret = 0;
2935 int cfg_type;
2936 int index = 0;
2937 enum afe_mad_type mad_type;
2938 uint16_t port_index;
2939
2940 if (!afe_config) {
2941 pr_err("%s: Error, no configuration data\n", __func__);
2942 ret = -EINVAL;
2943 return ret;
2944 }
2945
2946 if ((port_id == RT_PROXY_DAI_001_RX) ||
2947 (port_id == RT_PROXY_DAI_002_TX)) {
2948 pr_debug("%s: before incrementing pcm_afe_instance %d port_id 0x%x\n",
2949 __func__,
2950 pcm_afe_instance[port_id & 0x1], port_id);
2951 port_id = VIRTUAL_ID_TO_PORTID(port_id);
2952 pcm_afe_instance[port_id & 0x1]++;
2953 return 0;
2954 }
2955 if ((port_id == RT_PROXY_DAI_002_RX) ||
2956 (port_id == RT_PROXY_DAI_001_TX)) {
2957 pr_debug("%s: before incrementing proxy_afe_instance %d port_id 0x%x\n",
2958 __func__,
2959 proxy_afe_instance[port_id & 0x1], port_id);
2960
2961 if (!afe_close_done[port_id & 0x1]) {
2962 /*close pcm dai corresponding to the proxy dai*/
2963 afe_close(port_id - 0x10);
2964 pcm_afe_instance[port_id & 0x1]++;
2965 pr_debug("%s: reconfigure afe port again\n", __func__);
2966 }
2967 proxy_afe_instance[port_id & 0x1]++;
2968 afe_close_done[port_id & 0x1] = false;
2969 port_id = VIRTUAL_ID_TO_PORTID(port_id);
2970 }
2971
2972 pr_debug("%s: port id: 0x%x\n", __func__, port_id);
2973
2974 index = q6audio_get_port_index(port_id);
2975 if (index < 0 || index >= AFE_MAX_PORTS) {
2976 pr_err("%s: AFE port index[%d] invalid!\n",
2977 __func__, index);
2978 return -EINVAL;
2979 }
2980 ret = q6audio_validate_port(port_id);
2981 if (ret < 0) {
2982 pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
2983 return -EINVAL;
2984 }
2985
2986 ret = afe_q6_interface_prepare();
2987 if (ret != 0) {
2988 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
2989 return ret;
2990 }
2991
2992 if ((index >= 0) && (index < AFE_MAX_PORTS)) {
2993 this_afe.afe_sample_rates[index] = rate;
2994
2995 if (this_afe.rt_cb)
2996 this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id);
2997 }
2998
2999 mutex_lock(&this_afe.afe_cmd_lock);
3000 /* Also send the topology id here: */
3001 port_index = afe_get_port_index(port_id);
3002 if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) {
3003 /* One time call: only for first time */
3004 afe_send_custom_topology();
3005 afe_send_port_topology_id(port_id);
3006 afe_send_cal(port_id);
3007 afe_send_hw_delay(port_id, rate);
3008 }
3009
3010 /* Start SW MAD module */
3011 mad_type = afe_port_get_mad_type(port_id);
3012 pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id,
3013 mad_type);
3014 if (mad_type != MAD_HW_NONE && mad_type != MAD_SW_AUDIO) {
3015 if (!afe_has_config(AFE_CDC_REGISTERS_CONFIG) ||
3016 !afe_has_config(AFE_SLIMBUS_SLAVE_CONFIG)) {
3017 pr_err("%s: AFE isn't configured yet for\n"
3018 "HW MAD try Again\n", __func__);
3019 ret = -EAGAIN;
3020 goto fail_cmd;
3021 }
3022 ret = afe_turn_onoff_hw_mad(mad_type, true);
3023 if (ret) {
3024 pr_err("%s: afe_turn_onoff_hw_mad failed %d\n",
3025 __func__, ret);
3026 goto fail_cmd;
3027 }
3028 }
3029
3030 if ((this_afe.aanc_info.aanc_active) &&
3031 (this_afe.aanc_info.aanc_tx_port == port_id)) {
3032 this_afe.aanc_info.aanc_tx_port_sample_rate = rate;
3033 port_index =
3034 afe_get_port_index(this_afe.aanc_info.aanc_rx_port);
3035 if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
3036 this_afe.aanc_info.aanc_rx_port_sample_rate =
3037 this_afe.afe_sample_rates[port_index];
3038 } else {
3039 pr_err("%s: Invalid port index %d\n",
3040 __func__, port_index);
3041 ret = -EINVAL;
3042 goto fail_cmd;
3043 }
3044 ret = afe_aanc_start(this_afe.aanc_info.aanc_tx_port,
3045 this_afe.aanc_info.aanc_rx_port);
3046 pr_debug("%s: afe_aanc_start ret %d\n", __func__, ret);
3047 }
3048
3049 if ((port_id == AFE_PORT_ID_USB_RX) ||
3050 (port_id == AFE_PORT_ID_USB_TX)) {
3051 ret = afe_port_send_usb_dev_param(port_id, afe_config);
3052 if (ret) {
3053 pr_err("%s: AFE device param for port 0x%x failed %d\n",
3054 __func__, port_id, ret);
3055 ret = -EINVAL;
3056 goto fail_cmd;
3057 }
3058 }
3059
3060 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3061 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3062 config.hdr.pkt_size = sizeof(config);
3063 config.hdr.src_port = 0;
3064 config.hdr.dest_port = 0;
3065 config.hdr.token = index;
3066
3067 switch (port_id) {
3068 case AFE_PORT_ID_PRIMARY_PCM_RX:
3069 case AFE_PORT_ID_PRIMARY_PCM_TX:
3070 case AFE_PORT_ID_SECONDARY_PCM_RX:
3071 case AFE_PORT_ID_SECONDARY_PCM_TX:
3072 case AFE_PORT_ID_TERTIARY_PCM_RX:
3073 case AFE_PORT_ID_TERTIARY_PCM_TX:
3074 case AFE_PORT_ID_QUATERNARY_PCM_RX:
3075 case AFE_PORT_ID_QUATERNARY_PCM_TX:
3076 cfg_type = AFE_PARAM_ID_PCM_CONFIG;
3077 break;
3078 case PRIMARY_I2S_RX:
3079 case PRIMARY_I2S_TX:
3080 case SECONDARY_I2S_RX:
3081 case SECONDARY_I2S_TX:
3082 case MI2S_RX:
3083 case MI2S_TX:
3084 case AFE_PORT_ID_PRIMARY_MI2S_RX:
3085 case AFE_PORT_ID_PRIMARY_MI2S_TX:
3086 case AFE_PORT_ID_SECONDARY_MI2S_RX:
3087 case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1:
3088 case AFE_PORT_ID_SECONDARY_MI2S_TX:
3089 case AFE_PORT_ID_TERTIARY_MI2S_RX:
3090 case AFE_PORT_ID_TERTIARY_MI2S_TX:
3091 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
3092 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
3093 case AFE_PORT_ID_QUINARY_MI2S_RX:
3094 case AFE_PORT_ID_QUINARY_MI2S_TX:
3095 case AFE_PORT_ID_SENARY_MI2S_TX:
3096 case AFE_PORT_ID_INT0_MI2S_RX:
3097 case AFE_PORT_ID_INT0_MI2S_TX:
3098 case AFE_PORT_ID_INT1_MI2S_RX:
3099 case AFE_PORT_ID_INT1_MI2S_TX:
3100 case AFE_PORT_ID_INT2_MI2S_RX:
3101 case AFE_PORT_ID_INT2_MI2S_TX:
3102 case AFE_PORT_ID_INT3_MI2S_RX:
3103 case AFE_PORT_ID_INT3_MI2S_TX:
3104 case AFE_PORT_ID_INT4_MI2S_RX:
3105 case AFE_PORT_ID_INT4_MI2S_TX:
3106 case AFE_PORT_ID_INT5_MI2S_RX:
3107 case AFE_PORT_ID_INT5_MI2S_TX:
3108 case AFE_PORT_ID_INT6_MI2S_RX:
3109 case AFE_PORT_ID_INT6_MI2S_TX:
3110 cfg_type = AFE_PARAM_ID_I2S_CONFIG;
3111 break;
3112 case HDMI_RX:
3113 case DISPLAY_PORT_RX:
3114 cfg_type = AFE_PARAM_ID_HDMI_CONFIG;
3115 break;
3116 case VOICE_PLAYBACK_TX:
3117 case VOICE2_PLAYBACK_TX:
3118 case VOICE_RECORD_RX:
3119 case VOICE_RECORD_TX:
3120 cfg_type = AFE_PARAM_ID_PSEUDO_PORT_CONFIG;
3121 break;
3122 case SLIMBUS_0_RX:
3123 case SLIMBUS_0_TX:
3124 case SLIMBUS_1_RX:
3125 case SLIMBUS_1_TX:
3126 case SLIMBUS_2_RX:
3127 case SLIMBUS_2_TX:
3128 case SLIMBUS_3_RX:
3129 case SLIMBUS_3_TX:
3130 case SLIMBUS_4_RX:
3131 case SLIMBUS_4_TX:
3132 case SLIMBUS_5_RX:
3133 case SLIMBUS_5_TX:
3134 case SLIMBUS_6_RX:
3135 case SLIMBUS_6_TX:
3136 case SLIMBUS_7_RX:
3137 case SLIMBUS_7_TX:
3138 case SLIMBUS_8_RX:
3139 case SLIMBUS_8_TX:
3140 cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG;
3141 break;
3142 case AFE_PORT_ID_USB_RX:
3143 case AFE_PORT_ID_USB_TX:
3144 cfg_type = AFE_PARAM_ID_USB_AUDIO_CONFIG;
3145 break;
3146 case RT_PROXY_PORT_001_RX:
3147 case RT_PROXY_PORT_001_TX:
3148 cfg_type = AFE_PARAM_ID_RT_PROXY_CONFIG;
3149 break;
3150 case INT_BT_SCO_RX:
3151 case INT_BT_A2DP_RX:
3152 case INT_BT_SCO_TX:
3153 case INT_FM_RX:
3154 case INT_FM_TX:
3155 cfg_type = AFE_PARAM_ID_INTERNAL_BT_FM_CONFIG;
3156 break;
3157 default:
3158 pr_err("%s: Invalid port id 0x%x\n", __func__, port_id);
3159 ret = -EINVAL;
3160 goto fail_cmd;
3161 }
3162 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
3163 config.param.port_id = q6audio_get_port_id(port_id);
3164 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
3165 sizeof(config.param);
3166 config.param.payload_address_lsw = 0x00;
3167 config.param.payload_address_msw = 0x00;
3168 config.param.mem_map_handle = 0x00;
3169 config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
3170 config.pdata.param_id = cfg_type;
3171 config.pdata.param_size = sizeof(config.port);
3172
3173 config.port = *afe_config;
3174 if ((enc_format != ASM_MEDIA_FMT_NONE) &&
3175 (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) {
3176 config.port.slim_sch.data_format =
3177 AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED;
3178 }
3179 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
3180 if (ret) {
3181 pr_err("%s: AFE enable for port 0x%x failed %d\n",
3182 __func__, port_id, ret);
3183 goto fail_cmd;
3184 }
3185
3186 if ((enc_format != ASM_MEDIA_FMT_NONE) &&
3187 (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) {
3188 pr_debug("%s: Found AFE encoder support for SLIMBUS enc_format = %d\n",
3189 __func__, enc_format);
3190 ret = q6afe_send_enc_config(port_id, cfg, enc_format,
3191 *afe_config, afe_in_channels,
3192 afe_in_bit_width);
3193 if (ret) {
3194 pr_err("%s: AFE encoder config for port 0x%x failed %d\n",
3195 __func__, port_id, ret);
3196 goto fail_cmd;
3197 }
3198 }
3199
3200 port_index = afe_get_port_index(port_id);
3201 if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
3202 /*
3203 * If afe_port_start() for tx port called before
3204 * rx port, then aanc rx sample rate is zero. So,
3205 * AANC state machine in AFE will not get triggered.
3206 * Make sure to check whether aanc is active during
3207 * afe_port_start() for rx port and if aanc rx
3208 * sample rate is zero, call afe_aanc_start to configure
3209 * aanc with valid sample rates.
3210 */
3211 if (this_afe.aanc_info.aanc_active &&
3212 !this_afe.aanc_info.aanc_rx_port_sample_rate) {
3213 this_afe.aanc_info.aanc_rx_port_sample_rate =
3214 this_afe.afe_sample_rates[port_index];
3215 ret = afe_aanc_start(this_afe.aanc_info.aanc_tx_port,
3216 this_afe.aanc_info.aanc_rx_port);
3217 pr_debug("%s: afe_aanc_start ret %d\n", __func__, ret);
3218 }
3219 } else {
3220 pr_err("%s: Invalid port index %d\n", __func__, port_index);
3221 ret = -EINVAL;
3222 goto fail_cmd;
3223 }
3224 ret = afe_send_cmd_port_start(port_id);
3225
3226fail_cmd:
3227 mutex_unlock(&this_afe.afe_cmd_lock);
3228 return ret;
3229}
3230
3231/**
3232 * afe_port_start - to configure AFE session with
3233 * specified port configuration
3234 *
3235 * @port_id: AFE port id number
3236 * @afe_config: port configutation
3237 * @rate: sampling rate of port
3238 *
3239 * Returns 0 on success or error value on port start failure.
3240 */
3241int afe_port_start(u16 port_id, union afe_port_config *afe_config,
3242 u32 rate)
3243{
3244 return __afe_port_start(port_id, afe_config, rate,
3245 0, 0, NULL, ASM_MEDIA_FMT_NONE);
3246}
3247EXPORT_SYMBOL(afe_port_start);
3248
3249/**
3250 * afe_port_start_v2 - to configure AFE session with
3251 * specified port configuration and encoder params
3252 *
3253 * @port_id: AFE port id number
3254 * @afe_config: port configutation
3255 * @rate: sampling rate of port
3256 * @cfg: AFE encoder configuration information to setup encoder
3257 * @afe_in_channels: AFE input channel configuration, this needs
3258 * update only if input channel is differ from AFE output
3259 *
3260 * Returns 0 on success or error value on port start failure.
3261 */
3262int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config,
3263 u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
3264 struct afe_enc_config *enc_cfg)
3265{
3266 return __afe_port_start(port_id, afe_config, rate,
3267 afe_in_channels, afe_in_bit_width,
3268 &enc_cfg->data, enc_cfg->format);
3269}
3270EXPORT_SYMBOL(afe_port_start_v2);
3271
3272int afe_get_port_index(u16 port_id)
3273{
3274 switch (port_id) {
3275 case PRIMARY_I2S_RX: return IDX_PRIMARY_I2S_RX;
3276 case PRIMARY_I2S_TX: return IDX_PRIMARY_I2S_TX;
3277 case AFE_PORT_ID_PRIMARY_PCM_RX:
3278 return IDX_AFE_PORT_ID_PRIMARY_PCM_RX;
3279 case AFE_PORT_ID_PRIMARY_PCM_TX:
3280 return IDX_AFE_PORT_ID_PRIMARY_PCM_TX;
3281 case AFE_PORT_ID_SECONDARY_PCM_RX:
3282 return IDX_AFE_PORT_ID_SECONDARY_PCM_RX;
3283 case AFE_PORT_ID_SECONDARY_PCM_TX:
3284 return IDX_AFE_PORT_ID_SECONDARY_PCM_TX;
3285 case AFE_PORT_ID_TERTIARY_PCM_RX:
3286 return IDX_AFE_PORT_ID_TERTIARY_PCM_RX;
3287 case AFE_PORT_ID_TERTIARY_PCM_TX:
3288 return IDX_AFE_PORT_ID_TERTIARY_PCM_TX;
3289 case AFE_PORT_ID_QUATERNARY_PCM_RX:
3290 return IDX_AFE_PORT_ID_QUATERNARY_PCM_RX;
3291 case AFE_PORT_ID_QUATERNARY_PCM_TX:
3292 return IDX_AFE_PORT_ID_QUATERNARY_PCM_TX;
3293 case SECONDARY_I2S_RX: return IDX_SECONDARY_I2S_RX;
3294 case SECONDARY_I2S_TX: return IDX_SECONDARY_I2S_TX;
3295 case MI2S_RX: return IDX_MI2S_RX;
3296 case MI2S_TX: return IDX_MI2S_TX;
3297 case HDMI_RX: return IDX_HDMI_RX;
3298 case DISPLAY_PORT_RX: return IDX_DISPLAY_PORT_RX;
3299 case AFE_PORT_ID_SPDIF_RX: return IDX_SPDIF_RX;
3300 case RSVD_2: return IDX_RSVD_2;
3301 case RSVD_3: return IDX_RSVD_3;
3302 case DIGI_MIC_TX: return IDX_DIGI_MIC_TX;
3303 case VOICE_RECORD_RX: return IDX_VOICE_RECORD_RX;
3304 case VOICE_RECORD_TX: return IDX_VOICE_RECORD_TX;
3305 case VOICE_PLAYBACK_TX: return IDX_VOICE_PLAYBACK_TX;
3306 case VOICE2_PLAYBACK_TX: return IDX_VOICE2_PLAYBACK_TX;
3307 case SLIMBUS_0_RX: return IDX_SLIMBUS_0_RX;
3308 case SLIMBUS_0_TX: return IDX_SLIMBUS_0_TX;
3309 case SLIMBUS_1_RX: return IDX_SLIMBUS_1_RX;
3310 case SLIMBUS_1_TX: return IDX_SLIMBUS_1_TX;
3311 case SLIMBUS_2_RX: return IDX_SLIMBUS_2_RX;
3312 case SLIMBUS_2_TX: return IDX_SLIMBUS_2_TX;
3313 case SLIMBUS_3_RX: return IDX_SLIMBUS_3_RX;
3314 case SLIMBUS_3_TX: return IDX_SLIMBUS_3_TX;
3315 case INT_BT_SCO_RX: return IDX_INT_BT_SCO_RX;
3316 case INT_BT_SCO_TX: return IDX_INT_BT_SCO_TX;
3317 case INT_BT_A2DP_RX: return IDX_INT_BT_A2DP_RX;
3318 case INT_FM_RX: return IDX_INT_FM_RX;
3319 case INT_FM_TX: return IDX_INT_FM_TX;
3320 case RT_PROXY_PORT_001_RX: return IDX_RT_PROXY_PORT_001_RX;
3321 case RT_PROXY_PORT_001_TX: return IDX_RT_PROXY_PORT_001_TX;
3322 case SLIMBUS_4_RX: return IDX_SLIMBUS_4_RX;
3323 case SLIMBUS_4_TX: return IDX_SLIMBUS_4_TX;
3324 case SLIMBUS_5_RX: return IDX_SLIMBUS_5_RX;
3325 case SLIMBUS_5_TX: return IDX_SLIMBUS_5_TX;
3326 case SLIMBUS_6_RX: return IDX_SLIMBUS_6_RX;
3327 case SLIMBUS_6_TX: return IDX_SLIMBUS_6_TX;
3328 case SLIMBUS_7_RX: return IDX_SLIMBUS_7_RX;
3329 case SLIMBUS_7_TX: return IDX_SLIMBUS_7_TX;
3330 case SLIMBUS_8_RX: return IDX_SLIMBUS_8_RX;
3331 case SLIMBUS_8_TX: return IDX_SLIMBUS_8_TX;
3332 case AFE_PORT_ID_USB_RX: return IDX_AFE_PORT_ID_USB_RX;
3333 case AFE_PORT_ID_USB_TX: return IDX_AFE_PORT_ID_USB_TX;
3334 case AFE_PORT_ID_PRIMARY_MI2S_RX:
3335 return IDX_AFE_PORT_ID_PRIMARY_MI2S_RX;
3336 case AFE_PORT_ID_PRIMARY_MI2S_TX:
3337 return IDX_AFE_PORT_ID_PRIMARY_MI2S_TX;
3338 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
3339 return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX;
3340 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
3341 return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX;
3342 case AFE_PORT_ID_SECONDARY_MI2S_RX:
3343 return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX;
3344 case AFE_PORT_ID_SECONDARY_MI2S_TX:
3345 return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX;
3346 case AFE_PORT_ID_TERTIARY_MI2S_RX:
3347 return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX;
3348 case AFE_PORT_ID_TERTIARY_MI2S_TX:
3349 return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX;
3350 case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1:
3351 return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_SD1;
3352 case AFE_PORT_ID_QUINARY_MI2S_RX:
3353 return IDX_AFE_PORT_ID_QUINARY_MI2S_RX;
3354 case AFE_PORT_ID_QUINARY_MI2S_TX:
3355 return IDX_AFE_PORT_ID_QUINARY_MI2S_TX;
3356 case AFE_PORT_ID_SENARY_MI2S_TX:
3357 return IDX_AFE_PORT_ID_SENARY_MI2S_TX;
3358 case AFE_PORT_ID_PRIMARY_TDM_RX:
3359 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_0;
3360 case AFE_PORT_ID_PRIMARY_TDM_TX:
3361 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_0;
3362 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
3363 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_1;
3364 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
3365 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_1;
3366 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
3367 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_2;
3368 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
3369 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_2;
3370 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
3371 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_3;
3372 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
3373 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_3;
3374 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
3375 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_4;
3376 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
3377 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_4;
3378 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
3379 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_5;
3380 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
3381 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_5;
3382 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
3383 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_6;
3384 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
3385 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_6;
3386 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
3387 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_7;
3388 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
3389 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_7;
3390 case AFE_PORT_ID_SECONDARY_TDM_RX:
3391 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_0;
3392 case AFE_PORT_ID_SECONDARY_TDM_TX:
3393 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_0;
3394 case AFE_PORT_ID_SECONDARY_TDM_RX_1:
3395 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_1;
3396 case AFE_PORT_ID_SECONDARY_TDM_TX_1:
3397 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_1;
3398 case AFE_PORT_ID_SECONDARY_TDM_RX_2:
3399 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_2;
3400 case AFE_PORT_ID_SECONDARY_TDM_TX_2:
3401 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_2;
3402 case AFE_PORT_ID_SECONDARY_TDM_RX_3:
3403 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_3;
3404 case AFE_PORT_ID_SECONDARY_TDM_TX_3:
3405 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_3;
3406 case AFE_PORT_ID_SECONDARY_TDM_RX_4:
3407 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_4;
3408 case AFE_PORT_ID_SECONDARY_TDM_TX_4:
3409 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_4;
3410 case AFE_PORT_ID_SECONDARY_TDM_RX_5:
3411 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_5;
3412 case AFE_PORT_ID_SECONDARY_TDM_TX_5:
3413 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_5;
3414 case AFE_PORT_ID_SECONDARY_TDM_RX_6:
3415 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_6;
3416 case AFE_PORT_ID_SECONDARY_TDM_TX_6:
3417 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_6;
3418 case AFE_PORT_ID_SECONDARY_TDM_RX_7:
3419 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_7;
3420 case AFE_PORT_ID_SECONDARY_TDM_TX_7:
3421 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_7;
3422 case AFE_PORT_ID_TERTIARY_TDM_RX:
3423 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_0;
3424 case AFE_PORT_ID_TERTIARY_TDM_TX:
3425 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_0;
3426 case AFE_PORT_ID_TERTIARY_TDM_RX_1:
3427 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_1;
3428 case AFE_PORT_ID_TERTIARY_TDM_TX_1:
3429 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_1;
3430 case AFE_PORT_ID_TERTIARY_TDM_RX_2:
3431 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_2;
3432 case AFE_PORT_ID_TERTIARY_TDM_TX_2:
3433 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_2;
3434 case AFE_PORT_ID_TERTIARY_TDM_RX_3:
3435 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_3;
3436 case AFE_PORT_ID_TERTIARY_TDM_TX_3:
3437 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_3;
3438 case AFE_PORT_ID_TERTIARY_TDM_RX_4:
3439 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_4;
3440 case AFE_PORT_ID_TERTIARY_TDM_TX_4:
3441 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_4;
3442 case AFE_PORT_ID_TERTIARY_TDM_RX_5:
3443 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_5;
3444 case AFE_PORT_ID_TERTIARY_TDM_TX_5:
3445 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_5;
3446 case AFE_PORT_ID_TERTIARY_TDM_RX_6:
3447 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_6;
3448 case AFE_PORT_ID_TERTIARY_TDM_TX_6:
3449 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_6;
3450 case AFE_PORT_ID_TERTIARY_TDM_RX_7:
3451 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_7;
3452 case AFE_PORT_ID_TERTIARY_TDM_TX_7:
3453 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_7;
3454 case AFE_PORT_ID_QUATERNARY_TDM_RX:
3455 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_0;
3456 case AFE_PORT_ID_QUATERNARY_TDM_TX:
3457 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_0;
3458 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
3459 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_1;
3460 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
3461 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_1;
3462 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
3463 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_2;
3464 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
3465 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_2;
3466 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
3467 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_3;
3468 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
3469 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_3;
3470 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
3471 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_4;
3472 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
3473 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_4;
3474 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
3475 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_5;
3476 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
3477 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_5;
3478 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
3479 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_6;
3480 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
3481 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_6;
3482 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
3483 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_7;
3484 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
3485 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_7;
3486 case AFE_PORT_ID_INT0_MI2S_RX:
3487 return IDX_AFE_PORT_ID_INT0_MI2S_RX;
3488 case AFE_PORT_ID_INT0_MI2S_TX:
3489 return IDX_AFE_PORT_ID_INT0_MI2S_TX;
3490 case AFE_PORT_ID_INT1_MI2S_RX:
3491 return IDX_AFE_PORT_ID_INT1_MI2S_RX;
3492 case AFE_PORT_ID_INT1_MI2S_TX:
3493 return IDX_AFE_PORT_ID_INT1_MI2S_TX;
3494 case AFE_PORT_ID_INT2_MI2S_RX:
3495 return IDX_AFE_PORT_ID_INT2_MI2S_RX;
3496 case AFE_PORT_ID_INT2_MI2S_TX:
3497 return IDX_AFE_PORT_ID_INT2_MI2S_TX;
3498 case AFE_PORT_ID_INT3_MI2S_RX:
3499 return IDX_AFE_PORT_ID_INT3_MI2S_RX;
3500 case AFE_PORT_ID_INT3_MI2S_TX:
3501 return IDX_AFE_PORT_ID_INT3_MI2S_TX;
3502 case AFE_PORT_ID_INT4_MI2S_RX:
3503 return IDX_AFE_PORT_ID_INT4_MI2S_RX;
3504 case AFE_PORT_ID_INT4_MI2S_TX:
3505 return IDX_AFE_PORT_ID_INT4_MI2S_TX;
3506 case AFE_PORT_ID_INT5_MI2S_RX:
3507 return IDX_AFE_PORT_ID_INT5_MI2S_RX;
3508 case AFE_PORT_ID_INT5_MI2S_TX:
3509 return IDX_AFE_PORT_ID_INT5_MI2S_TX;
3510 case AFE_PORT_ID_INT6_MI2S_RX:
3511 return IDX_AFE_PORT_ID_INT6_MI2S_RX;
3512 case AFE_PORT_ID_INT6_MI2S_TX:
3513 return IDX_AFE_PORT_ID_INT6_MI2S_TX;
3514 default:
3515 pr_err("%s: port 0x%x\n", __func__, port_id);
3516 return -EINVAL;
3517 }
3518}
3519
3520int afe_open(u16 port_id,
3521 union afe_port_config *afe_config, int rate)
3522{
3523 struct afe_port_cmd_device_start start;
3524 struct afe_audioif_config_command config;
3525 int ret = 0;
3526 int cfg_type;
3527 int index = 0;
3528
3529 if (!afe_config) {
3530 pr_err("%s: Error, no configuration data\n", __func__);
3531 ret = -EINVAL;
3532 return ret;
3533 }
3534
3535 pr_err("%s: port_id 0x%x rate %d\n", __func__, port_id, rate);
3536
3537 index = q6audio_get_port_index(port_id);
3538 if (index < 0 || index >= AFE_MAX_PORTS) {
3539 pr_err("%s: AFE port index[%d] invalid!\n",
3540 __func__, index);
3541 return -EINVAL;
3542 }
3543 ret = q6audio_validate_port(port_id);
3544 if (ret < 0) {
3545 pr_err("%s: Invalid port 0x%x ret %d", __func__, port_id, ret);
3546 return -EINVAL;
3547 }
3548
3549 if ((port_id == RT_PROXY_DAI_001_RX) ||
3550 (port_id == RT_PROXY_DAI_002_TX)) {
3551 pr_err("%s: wrong port 0x%x\n", __func__, port_id);
3552 return -EINVAL;
3553 }
3554 if ((port_id == RT_PROXY_DAI_002_RX) ||
3555 (port_id == RT_PROXY_DAI_001_TX))
3556 port_id = VIRTUAL_ID_TO_PORTID(port_id);
3557
3558 ret = afe_q6_interface_prepare();
3559 if (ret != 0) {
3560 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
3561 return -EINVAL;
3562 }
3563
3564 if ((index >= 0) && (index < AFE_MAX_PORTS)) {
3565 this_afe.afe_sample_rates[index] = rate;
3566
3567 if (this_afe.rt_cb)
3568 this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id);
3569 }
3570
3571 /* Also send the topology id here: */
3572 afe_send_custom_topology(); /* One time call: only for first time */
3573 afe_send_port_topology_id(port_id);
3574
3575 ret = q6audio_validate_port(port_id);
3576 if (ret < 0) {
3577 pr_err("%s: Failed : Invalid Port id = 0x%x ret %d\n",
3578 __func__, port_id, ret);
3579 return -EINVAL;
3580 }
3581 mutex_lock(&this_afe.afe_cmd_lock);
3582
3583 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3584 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3585 config.hdr.pkt_size = sizeof(config);
3586 config.hdr.src_port = 0;
3587 config.hdr.dest_port = 0;
3588 config.hdr.token = index;
3589 switch (port_id) {
3590 case PRIMARY_I2S_RX:
3591 case PRIMARY_I2S_TX:
3592 cfg_type = AFE_PARAM_ID_I2S_CONFIG;
3593 break;
3594 case AFE_PORT_ID_PRIMARY_PCM_RX:
3595 case AFE_PORT_ID_PRIMARY_PCM_TX:
3596 case AFE_PORT_ID_SECONDARY_PCM_RX:
3597 case AFE_PORT_ID_SECONDARY_PCM_TX:
3598 case AFE_PORT_ID_TERTIARY_PCM_RX:
3599 case AFE_PORT_ID_TERTIARY_PCM_TX:
3600 case AFE_PORT_ID_QUATERNARY_PCM_RX:
3601 case AFE_PORT_ID_QUATERNARY_PCM_TX:
3602 cfg_type = AFE_PARAM_ID_PCM_CONFIG;
3603 break;
3604 case SECONDARY_I2S_RX:
3605 case SECONDARY_I2S_TX:
3606 case AFE_PORT_ID_PRIMARY_MI2S_RX:
3607 case AFE_PORT_ID_PRIMARY_MI2S_TX:
3608 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
3609 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
3610 case MI2S_RX:
3611 case MI2S_TX:
3612 case AFE_PORT_ID_QUINARY_MI2S_RX:
3613 case AFE_PORT_ID_QUINARY_MI2S_TX:
3614 case AFE_PORT_ID_SENARY_MI2S_TX:
3615 cfg_type = AFE_PARAM_ID_I2S_CONFIG;
3616 break;
3617 case HDMI_RX:
3618 case DISPLAY_PORT_RX:
3619 cfg_type = AFE_PARAM_ID_HDMI_CONFIG;
3620 break;
3621 case SLIMBUS_0_RX:
3622 case SLIMBUS_0_TX:
3623 case SLIMBUS_1_RX:
3624 case SLIMBUS_1_TX:
3625 case SLIMBUS_2_RX:
3626 case SLIMBUS_2_TX:
3627 case SLIMBUS_3_RX:
3628 case SLIMBUS_3_TX:
3629 case SLIMBUS_4_RX:
3630 case SLIMBUS_4_TX:
3631 case SLIMBUS_5_RX:
3632 case SLIMBUS_6_RX:
3633 case SLIMBUS_6_TX:
3634 case SLIMBUS_7_RX:
3635 case SLIMBUS_7_TX:
3636 case SLIMBUS_8_RX:
3637 case SLIMBUS_8_TX:
3638 cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG;
3639 break;
3640 case AFE_PORT_ID_USB_RX:
3641 case AFE_PORT_ID_USB_TX:
3642 cfg_type = AFE_PARAM_ID_USB_AUDIO_CONFIG;
3643 break;
3644 default:
3645 pr_err("%s: Invalid port id 0x%x\n",
3646 __func__, port_id);
3647 ret = -EINVAL;
3648 goto fail_cmd;
3649 }
3650 config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
3651 config.param.port_id = q6audio_get_port_id(port_id);
3652 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr)
3653 - sizeof(config.param);
3654 config.param.payload_address_lsw = 0x00;
3655 config.param.payload_address_msw = 0x00;
3656 config.param.mem_map_handle = 0x00;
3657 config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
3658 config.pdata.param_id = cfg_type;
3659 config.pdata.param_size = sizeof(config.port);
3660
3661 config.port = *afe_config;
3662 pr_debug("%s: param PL size=%d iparam_size[%d][%zd %zd %zd %zd] param_id[0x%x]\n",
3663 __func__, config.param.payload_size, config.pdata.param_size,
3664 sizeof(config), sizeof(config.param), sizeof(config.port),
3665 sizeof(struct apr_hdr), config.pdata.param_id);
3666
3667 ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
3668 if (ret) {
3669 pr_err("%s: AFE enable for port 0x%x opcode[0x%x]failed %d\n",
3670 __func__, port_id, cfg_type, ret);
3671 goto fail_cmd;
3672 }
3673 start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3674 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3675 start.hdr.pkt_size = sizeof(start);
3676 start.hdr.src_port = 0;
3677 start.hdr.dest_port = 0;
3678 start.hdr.token = index;
3679 start.hdr.opcode = AFE_PORT_CMD_DEVICE_START;
3680 start.port_id = q6audio_get_port_id(port_id);
3681 pr_debug("%s: cmd device start opcode[0x%x] port id[0x%x]\n",
3682 __func__, start.hdr.opcode, start.port_id);
3683
3684 ret = afe_apr_send_pkt(&start, &this_afe.wait[index]);
3685 if (ret) {
3686 pr_err("%s: AFE enable for port 0x%x failed %d\n", __func__,
3687 port_id, ret);
3688 goto fail_cmd;
3689 }
3690
3691fail_cmd:
3692 mutex_unlock(&this_afe.afe_cmd_lock);
3693 return ret;
3694}
3695
3696int afe_loopback(u16 enable, u16 rx_port, u16 tx_port)
3697{
3698 struct afe_loopback_cfg_v1 lb_cmd;
3699 int ret = 0;
3700 int index = 0;
3701
3702 if (rx_port == MI2S_RX)
3703 rx_port = AFE_PORT_ID_PRIMARY_MI2S_RX;
3704 if (tx_port == MI2S_TX)
3705 tx_port = AFE_PORT_ID_PRIMARY_MI2S_TX;
3706
3707 ret = afe_q6_interface_prepare();
3708 if (ret != 0) {
3709 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
3710 return ret;
3711 }
3712
3713 index = q6audio_get_port_index(rx_port);
3714 if (index < 0 || index >= AFE_MAX_PORTS) {
3715 pr_err("%s: AFE port index[%d] invalid!\n",
3716 __func__, index);
3717 return -EINVAL;
3718 }
3719 ret = q6audio_validate_port(rx_port);
3720 if (ret < 0) {
3721 pr_err("%s: Invalid port 0x%x ret %d", __func__, rx_port, ret);
3722 return -EINVAL;
3723 }
3724
3725 lb_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3726 APR_HDR_LEN(20), APR_PKT_VER);
3727 lb_cmd.hdr.pkt_size = sizeof(lb_cmd);
3728 lb_cmd.hdr.src_port = 0;
3729 lb_cmd.hdr.dest_port = 0;
3730 lb_cmd.hdr.token = index;
3731 lb_cmd.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
3732 lb_cmd.param.port_id = tx_port;
3733 lb_cmd.param.payload_size = (sizeof(lb_cmd) - sizeof(struct apr_hdr) -
3734 sizeof(struct afe_port_cmd_set_param_v2));
3735 lb_cmd.param.payload_address_lsw = 0x00;
3736 lb_cmd.param.payload_address_msw = 0x00;
3737 lb_cmd.param.mem_map_handle = 0x00;
3738 lb_cmd.pdata.module_id = AFE_MODULE_LOOPBACK;
3739 lb_cmd.pdata.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG;
3740 lb_cmd.pdata.param_size = lb_cmd.param.payload_size -
3741 sizeof(struct afe_port_param_data_v2);
3742
3743 lb_cmd.dst_port_id = rx_port;
3744 lb_cmd.routing_mode = LB_MODE_DEFAULT;
3745 lb_cmd.enable = (enable ? 1 : 0);
3746 lb_cmd.loopback_cfg_minor_version = AFE_API_VERSION_LOOPBACK_CONFIG;
3747
3748 ret = afe_apr_send_pkt(&lb_cmd, &this_afe.wait[index]);
3749 if (ret)
3750 pr_err("%s: AFE loopback failed %d\n", __func__, ret);
3751 return ret;
3752}
3753
3754int afe_loopback_gain(u16 port_id, u16 volume)
3755{
3756 struct afe_loopback_gain_per_path_param set_param;
3757 int ret = 0;
3758 int index = 0;
3759
3760 if (this_afe.apr == NULL) {
3761 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
3762 0xFFFFFFFF, &this_afe);
3763 pr_debug("%s: Register AFE\n", __func__);
3764 if (this_afe.apr == NULL) {
3765 pr_err("%s: Unable to register AFE\n", __func__);
3766 ret = -ENODEV;
3767 return ret;
3768 }
3769 rtac_set_afe_handle(this_afe.apr);
3770 }
3771
3772 ret = q6audio_validate_port(port_id);
3773 if (ret < 0) {
3774 pr_err("%s: Failed : Invalid Port id = 0x%x ret %d\n",
3775 __func__, port_id, ret);
3776 ret = -EINVAL;
3777 goto fail_cmd;
3778 }
3779 index = q6audio_get_port_index(port_id);
3780 if (index < 0 || index >= AFE_MAX_PORTS) {
3781 pr_err("%s: AFE port index[%d] invalid!\n",
3782 __func__, index);
3783 return -EINVAL;
3784 }
3785 ret = q6audio_validate_port(port_id);
3786 if (ret < 0) {
3787 pr_err("%s: Invalid port 0x%x ret %d",
3788 __func__, port_id, ret);
3789 return -EINVAL;
3790 }
3791
3792 /* RX ports numbers are even .TX ports numbers are odd. */
3793 if (port_id % 2 == 0) {
3794 pr_err("%s: Failed : afe loopback gain only for TX ports. port_id %d\n",
3795 __func__, port_id);
3796 ret = -EINVAL;
3797 goto fail_cmd;
3798 }
3799
3800 pr_debug("%s: port 0x%x volume %d\n", __func__, port_id, volume);
3801
3802 set_param.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3803 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3804 set_param.hdr.pkt_size = sizeof(set_param);
3805 set_param.hdr.src_port = 0;
3806 set_param.hdr.dest_port = 0;
3807 set_param.hdr.token = index;
3808 set_param.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
3809
3810 set_param.param.port_id = port_id;
3811 set_param.param.payload_size =
3812 (sizeof(struct afe_loopback_gain_per_path_param) -
3813 sizeof(struct apr_hdr) - sizeof(struct afe_port_cmd_set_param_v2));
3814 set_param.param.payload_address_lsw = 0;
3815 set_param.param.payload_address_msw = 0;
3816 set_param.param.mem_map_handle = 0;
3817
3818 set_param.pdata.module_id = AFE_MODULE_LOOPBACK;
3819 set_param.pdata.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH;
3820 set_param.pdata.param_size =
3821 (set_param.param.payload_size -
3822 sizeof(struct afe_port_param_data_v2));
3823 set_param.rx_port_id = port_id;
3824 set_param.gain = volume;
3825
3826 ret = afe_apr_send_pkt(&set_param, &this_afe.wait[index]);
3827 if (ret) {
3828 pr_err("%s: AFE param set failed for port 0x%x ret %d\n",
3829 __func__, port_id, ret);
3830 goto fail_cmd;
3831 }
3832
3833fail_cmd:
3834 return ret;
3835}
3836
3837int afe_pseudo_port_start_nowait(u16 port_id)
3838{
3839 struct afe_pseudoport_start_command start;
3840 int ret = 0;
3841
3842 pr_debug("%s: port_id=0x%x\n", __func__, port_id);
3843 if (this_afe.apr == NULL) {
3844 pr_err("%s: AFE APR is not registered\n", __func__);
3845 return -ENODEV;
3846 }
3847
3848
3849 start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3850 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3851 start.hdr.pkt_size = sizeof(start);
3852 start.hdr.src_port = 0;
3853 start.hdr.dest_port = 0;
3854 start.hdr.token = 0;
3855 start.hdr.opcode = AFE_PSEUDOPORT_CMD_START;
3856 start.port_id = port_id;
3857 start.timing = 1;
3858
3859 ret = afe_apr_send_pkt(&start, NULL);
3860 if (ret) {
3861 pr_err("%s: AFE enable for port 0x%x failed %d\n",
3862 __func__, port_id, ret);
3863 return ret;
3864 }
3865 return 0;
3866}
3867
3868int afe_start_pseudo_port(u16 port_id)
3869{
3870 int ret = 0;
3871 struct afe_pseudoport_start_command start;
3872 int index = 0;
3873
3874 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
3875
3876 ret = afe_q6_interface_prepare();
3877 if (ret != 0) {
3878 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
3879 return ret;
3880 }
3881
3882 index = q6audio_get_port_index(port_id);
3883 if (index < 0 || index >= AFE_MAX_PORTS) {
3884 pr_err("%s: AFE port index[%d] invalid!\n",
3885 __func__, index);
3886 return -EINVAL;
3887 }
3888 ret = q6audio_validate_port(port_id);
3889 if (ret < 0) {
3890 pr_err("%s: Invalid port 0x%x ret %d",
3891 __func__, port_id, ret);
3892 return -EINVAL;
3893 }
3894
3895 start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3896 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3897 start.hdr.pkt_size = sizeof(start);
3898 start.hdr.src_port = 0;
3899 start.hdr.dest_port = 0;
3900 start.hdr.token = 0;
3901 start.hdr.opcode = AFE_PSEUDOPORT_CMD_START;
3902 start.port_id = port_id;
3903 start.timing = 1;
3904 start.hdr.token = index;
3905
3906 ret = afe_apr_send_pkt(&start, &this_afe.wait[index]);
3907 if (ret)
3908 pr_err("%s: AFE enable for port 0x%x failed %d\n",
3909 __func__, port_id, ret);
3910 return ret;
3911}
3912
3913int afe_pseudo_port_stop_nowait(u16 port_id)
3914{
3915 int ret = 0;
3916 struct afe_pseudoport_stop_command stop;
3917 int index = 0;
3918
3919 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
3920
3921 if (this_afe.apr == NULL) {
3922 pr_err("%s: AFE is already closed\n", __func__);
3923 return -EINVAL;
3924 }
3925 index = q6audio_get_port_index(port_id);
3926 if (index < 0 || index >= AFE_MAX_PORTS) {
3927 pr_err("%s: AFE port index[%d] invalid!\n",
3928 __func__, index);
3929 return -EINVAL;
3930 }
3931 ret = q6audio_validate_port(port_id);
3932 if (ret < 0) {
3933 pr_err("%s: Invalid port 0x%x ret %d",
3934 __func__, port_id, ret);
3935 return -EINVAL;
3936 }
3937
3938 stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3939 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
3940 stop.hdr.pkt_size = sizeof(stop);
3941 stop.hdr.src_port = 0;
3942 stop.hdr.dest_port = 0;
3943 stop.hdr.token = 0;
3944 stop.hdr.opcode = AFE_PSEUDOPORT_CMD_STOP;
3945 stop.port_id = port_id;
3946 stop.reserved = 0;
3947 stop.hdr.token = index;
3948
3949 ret = afe_apr_send_pkt(&stop, NULL);
3950 if (ret)
3951 pr_err("%s: AFE close failed %d\n", __func__, ret);
3952
3953 return ret;
3954}
3955
3956int afe_port_group_set_param(u16 group_id,
3957 union afe_port_group_config *afe_group_config)
3958{
3959 int ret;
3960 struct afe_port_group_create config;
3961 int cfg_type;
3962
3963 if (!afe_group_config) {
3964 pr_err("%s: Error, no configuration data\n", __func__);
3965 return -EINVAL;
3966 }
3967
3968 pr_debug("%s: group id: 0x%x\n", __func__, group_id);
3969
3970 ret = afe_q6_interface_prepare();
3971 if (ret != 0) {
3972 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
3973 return ret;
3974 }
3975
3976 switch (group_id) {
3977 case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX:
3978 case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX:
3979 case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_RX:
3980 case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_TX:
3981 case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_RX:
3982 case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_TX:
3983 case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_RX:
3984 case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_TX:
3985 cfg_type = AFE_PARAM_ID_GROUP_DEVICE_TDM_CONFIG;
3986 break;
3987 default:
3988 pr_err("%s: Invalid group id 0x%x\n", __func__, group_id);
3989 return -EINVAL;
3990 }
3991
3992 memset(&config, 0, sizeof(config));
3993 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
3994 APR_HDR_LEN(APR_HDR_SIZE),
3995 APR_PKT_VER);
3996 config.hdr.pkt_size = sizeof(config);
3997 config.hdr.src_port = 0;
3998 config.hdr.dest_port = 0;
3999 config.hdr.token = IDX_GLOBAL_CFG;
4000 config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
4001
4002 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
4003 sizeof(config.param);
4004 config.param.payload_address_lsw = 0x00;
4005 config.param.payload_address_msw = 0x00;
4006 config.param.mem_map_handle = 0x00;
4007 config.pdata.module_id = AFE_MODULE_GROUP_DEVICE;
4008 config.pdata.param_id = cfg_type;
4009 config.pdata.param_size = sizeof(config.data);
4010 config.data = *afe_group_config;
4011
4012 ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
4013 if (ret)
4014 pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_CFG failed %d\n",
4015 __func__, ret);
4016
4017 return ret;
4018}
4019
4020int afe_port_group_enable(u16 group_id,
4021 union afe_port_group_config *afe_group_config,
4022 u16 enable)
4023{
4024 int ret;
4025 struct afe_port_group_create config;
4026
4027 pr_debug("%s: group id: 0x%x enable: %d\n", __func__,
4028 group_id, enable);
4029
4030 ret = afe_q6_interface_prepare();
4031 if (ret != 0) {
4032 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
4033 return ret;
4034 }
4035
4036 if (enable) {
4037 ret = afe_port_group_set_param(group_id, afe_group_config);
4038 if (ret < 0) {
4039 pr_err("%s: afe send failed %d\n", __func__, ret);
4040 return ret;
4041 }
4042 }
4043
4044 memset(&config, 0, sizeof(config));
4045 config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4046 APR_HDR_LEN(APR_HDR_SIZE),
4047 APR_PKT_VER);
4048 config.hdr.pkt_size = sizeof(config);
4049 config.hdr.src_port = 0;
4050 config.hdr.dest_port = 0;
4051 config.hdr.token = IDX_GLOBAL_CFG;
4052 config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
4053
4054 config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
4055 sizeof(config.param);
4056 config.param.payload_address_lsw = 0x00;
4057 config.param.payload_address_msw = 0x00;
4058 config.param.mem_map_handle = 0x00;
4059 config.pdata.module_id = AFE_MODULE_GROUP_DEVICE;
4060 config.pdata.param_id = AFE_PARAM_ID_GROUP_DEVICE_ENABLE;
4061 config.pdata.param_size = sizeof(config.data);
4062 config.data.group_enable.group_id = group_id;
4063 config.data.group_enable.enable = enable;
4064
4065 ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
4066 if (ret)
4067 pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_ENABLE failed %d\n",
4068 __func__, ret);
4069
4070 return ret;
4071}
4072
4073int afe_stop_pseudo_port(u16 port_id)
4074{
4075 int ret = 0;
4076 struct afe_pseudoport_stop_command stop;
4077 int index = 0;
4078
4079 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
4080
4081 if (this_afe.apr == NULL) {
4082 pr_err("%s: AFE is already closed\n", __func__);
4083 return -EINVAL;
4084 }
4085
4086 index = q6audio_get_port_index(port_id);
4087 if (index < 0 || index >= AFE_MAX_PORTS) {
4088 pr_err("%s: AFE port index[%d] invalid!\n",
4089 __func__, index);
4090 return -EINVAL;
4091 }
4092 ret = q6audio_validate_port(port_id);
4093 if (ret < 0) {
4094 pr_err("%s: Invalid port 0x%x ret %d\n",
4095 __func__, port_id, ret);
4096 return -EINVAL;
4097 }
4098
4099 stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4100 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4101 stop.hdr.pkt_size = sizeof(stop);
4102 stop.hdr.src_port = 0;
4103 stop.hdr.dest_port = 0;
4104 stop.hdr.token = 0;
4105 stop.hdr.opcode = AFE_PSEUDOPORT_CMD_STOP;
4106 stop.port_id = port_id;
4107 stop.reserved = 0;
4108 stop.hdr.token = index;
4109
4110 ret = afe_apr_send_pkt(&stop, &this_afe.wait[index]);
4111 if (ret)
4112 pr_err("%s: AFE close failed %d\n", __func__, ret);
4113
4114 return ret;
4115}
4116
4117uint32_t afe_req_mmap_handle(struct afe_audio_client *ac)
4118{
4119 return ac->mem_map_handle;
4120}
4121
4122struct afe_audio_client *q6afe_audio_client_alloc(void *priv)
4123{
4124 struct afe_audio_client *ac;
4125 int lcnt = 0;
4126
4127 ac = kzalloc(sizeof(struct afe_audio_client), GFP_KERNEL);
4128 if (!ac)
4129 return NULL;
4130
4131 ac->priv = priv;
4132
4133 init_waitqueue_head(&ac->cmd_wait);
4134 INIT_LIST_HEAD(&ac->port[0].mem_map_handle);
4135 INIT_LIST_HEAD(&ac->port[1].mem_map_handle);
4136 pr_debug("%s: mem_map_handle list init'ed\n", __func__);
4137 mutex_init(&ac->cmd_lock);
4138 for (lcnt = 0; lcnt <= OUT; lcnt++) {
4139 mutex_init(&ac->port[lcnt].lock);
4140 spin_lock_init(&ac->port[lcnt].dsp_lock);
4141 }
4142 atomic_set(&ac->cmd_state, 0);
4143
4144 return ac;
4145}
4146
4147int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir,
4148 struct afe_audio_client *ac,
4149 unsigned int bufsz,
4150 unsigned int bufcnt)
4151{
4152 int cnt = 0;
4153 int rc = 0;
4154 struct afe_audio_buffer *buf;
4155 size_t len;
4156
4157 if (!(ac) || ((dir != IN) && (dir != OUT))) {
4158 pr_err("%s: ac %pK dir %d\n", __func__, ac, dir);
4159 return -EINVAL;
4160 }
4161
4162 pr_debug("%s: bufsz[%d]bufcnt[%d]\n",
4163 __func__,
4164 bufsz, bufcnt);
4165
4166 if (ac->port[dir].buf) {
4167 pr_debug("%s: buffer already allocated\n", __func__);
4168 return 0;
4169 }
4170 mutex_lock(&ac->cmd_lock);
4171 buf = kzalloc(((sizeof(struct afe_audio_buffer))*bufcnt),
4172 GFP_KERNEL);
4173
4174 if (!buf) {
4175 pr_err("%s: null buf\n", __func__);
4176 mutex_unlock(&ac->cmd_lock);
4177 goto fail;
4178 }
4179
4180 ac->port[dir].buf = buf;
4181
4182 rc = msm_audio_ion_alloc("afe_client", &buf[0].client,
4183 &buf[0].handle, bufsz*bufcnt,
4184 &buf[0].phys, &len,
4185 &buf[0].data);
4186 if (rc) {
4187 pr_err("%s: audio ION alloc failed, rc = %d\n",
4188 __func__, rc);
4189 mutex_unlock(&ac->cmd_lock);
4190 goto fail;
4191 }
4192
4193 buf[0].used = dir ^ 1;
4194 buf[0].size = bufsz;
4195 buf[0].actual_size = bufsz;
4196 cnt = 1;
4197 while (cnt < bufcnt) {
4198 if (bufsz > 0) {
4199 buf[cnt].data = buf[0].data + (cnt * bufsz);
4200 buf[cnt].phys = buf[0].phys + (cnt * bufsz);
4201 if (!buf[cnt].data) {
4202 pr_err("%s: Buf alloc failed\n",
4203 __func__);
4204 mutex_unlock(&ac->cmd_lock);
4205 goto fail;
4206 }
4207 buf[cnt].used = dir ^ 1;
4208 buf[cnt].size = bufsz;
4209 buf[cnt].actual_size = bufsz;
4210 pr_debug("%s: data[%pK]phys[%pK][%pK]\n", __func__,
4211 buf[cnt].data,
4212 &buf[cnt].phys,
4213 &buf[cnt].phys);
4214 }
4215 cnt++;
4216 }
4217 ac->port[dir].max_buf_cnt = cnt;
4218 mutex_unlock(&ac->cmd_lock);
4219 return 0;
4220fail:
4221 pr_err("%s: jump fail\n", __func__);
4222 q6afe_audio_client_buf_free_contiguous(dir, ac);
4223 return -EINVAL;
4224}
4225
4226int afe_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz,
4227 struct afe_audio_client *ac)
4228{
4229 int ret = 0;
4230
4231 mutex_lock(&this_afe.afe_cmd_lock);
4232 ac->mem_map_handle = 0;
4233 ret = afe_cmd_memory_map(dma_addr_p, dma_buf_sz);
4234 if (ret < 0) {
4235 pr_err("%s: afe_cmd_memory_map failed %d\n",
4236 __func__, ret);
4237
4238 mutex_unlock(&this_afe.afe_cmd_lock);
4239 return ret;
4240 }
4241 ac->mem_map_handle = this_afe.mmap_handle;
4242 mutex_unlock(&this_afe.afe_cmd_lock);
4243
4244 return ret;
4245}
4246
4247int afe_cmd_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz)
4248{
4249 int ret = 0;
4250 int cmd_size = 0;
4251 void *payload = NULL;
4252 void *mmap_region_cmd = NULL;
4253 struct afe_service_cmd_shared_mem_map_regions *mregion = NULL;
4254 struct afe_service_shared_map_region_payload *mregion_pl = NULL;
4255 int index = 0;
4256
4257 pr_debug("%s:\n", __func__);
4258
4259 if (this_afe.apr == NULL) {
4260 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
4261 0xFFFFFFFF, &this_afe);
4262 pr_debug("%s: Register AFE\n", __func__);
4263 if (this_afe.apr == NULL) {
4264 pr_err("%s: Unable to register AFE\n", __func__);
4265 ret = -ENODEV;
4266 return ret;
4267 }
4268 rtac_set_afe_handle(this_afe.apr);
4269 }
4270 if (dma_buf_sz % SZ_4K != 0) {
4271 /*
4272 * The memory allocated by msm_audio_ion_alloc is always 4kB
4273 * aligned, ADSP expects the size to be 4kB aligned as well
4274 * so re-adjusts the buffer size before passing to ADSP.
4275 */
4276 dma_buf_sz = PAGE_ALIGN(dma_buf_sz);
4277 }
4278
4279 cmd_size = sizeof(struct afe_service_cmd_shared_mem_map_regions)
4280 + sizeof(struct afe_service_shared_map_region_payload);
4281
4282 mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL);
4283 if (!mmap_region_cmd)
4284 return -ENOMEM;
4285
4286 mregion = (struct afe_service_cmd_shared_mem_map_regions *)
4287 mmap_region_cmd;
4288 mregion->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4289 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4290 mregion->hdr.pkt_size = cmd_size;
4291 mregion->hdr.src_port = 0;
4292 mregion->hdr.dest_port = 0;
4293 mregion->hdr.token = 0;
4294 mregion->hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS;
4295 mregion->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL;
4296 mregion->num_regions = 1;
4297 mregion->property_flag = 0x00;
4298 /* Todo */
4299 index = mregion->hdr.token = IDX_RSVD_2;
4300
4301 payload = ((u8 *) mmap_region_cmd +
4302 sizeof(struct afe_service_cmd_shared_mem_map_regions));
4303
4304 mregion_pl = (struct afe_service_shared_map_region_payload *)payload;
4305
4306 mregion_pl->shm_addr_lsw = lower_32_bits(dma_addr_p);
4307 mregion_pl->shm_addr_msw = msm_audio_populate_upper_32_bits(dma_addr_p);
4308 mregion_pl->mem_size_bytes = dma_buf_sz;
4309
4310 pr_debug("%s: dma_addr_p 0x%pK , size %d\n", __func__,
4311 &dma_addr_p, dma_buf_sz);
4312 atomic_set(&this_afe.state, 1);
4313 atomic_set(&this_afe.status, 0);
4314 this_afe.mmap_handle = 0;
4315 ret = apr_send_pkt(this_afe.apr, (uint32_t *) mmap_region_cmd);
4316 if (ret < 0) {
4317 pr_err("%s: AFE memory map cmd failed %d\n",
4318 __func__, ret);
4319 ret = -EINVAL;
4320 goto fail_cmd;
4321 }
4322
4323 ret = wait_event_timeout(this_afe.wait[index],
4324 (atomic_read(&this_afe.state) == 0),
4325 msecs_to_jiffies(TIMEOUT_MS));
4326 if (!ret) {
4327 pr_err("%s: wait_event timeout\n", __func__);
4328 ret = -EINVAL;
4329 goto fail_cmd;
4330 }
4331 if (atomic_read(&this_afe.status) > 0) {
4332 pr_err("%s: config cmd failed [%s]\n",
4333 __func__, adsp_err_get_err_str(
4334 atomic_read(&this_afe.status)));
4335 ret = adsp_err_get_lnx_err_code(
4336 atomic_read(&this_afe.status));
4337 goto fail_cmd;
4338 }
4339
4340 kfree(mmap_region_cmd);
4341 return 0;
4342fail_cmd:
4343 kfree(mmap_region_cmd);
4344 pr_err("%s: fail_cmd\n", __func__);
4345 return ret;
4346}
4347
4348int afe_cmd_memory_map_nowait(int port_id, phys_addr_t dma_addr_p,
4349 u32 dma_buf_sz)
4350{
4351 int ret = 0;
4352 int cmd_size = 0;
4353 void *payload = NULL;
4354 void *mmap_region_cmd = NULL;
4355 struct afe_service_cmd_shared_mem_map_regions *mregion = NULL;
4356 struct afe_service_shared_map_region_payload *mregion_pl = NULL;
4357 int index = 0;
4358
4359 pr_debug("%s:\n", __func__);
4360
4361 if (this_afe.apr == NULL) {
4362 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
4363 0xFFFFFFFF, &this_afe);
4364 pr_debug("%s: Register AFE\n", __func__);
4365 if (this_afe.apr == NULL) {
4366 pr_err("%s: Unable to register AFE\n", __func__);
4367 ret = -ENODEV;
4368 return ret;
4369 }
4370 rtac_set_afe_handle(this_afe.apr);
4371 }
4372 index = q6audio_get_port_index(port_id);
4373 if (index < 0 || index >= AFE_MAX_PORTS) {
4374 pr_err("%s: AFE port index[%d] invalid!\n",
4375 __func__, index);
4376 return -EINVAL;
4377 }
4378 ret = q6audio_validate_port(port_id);
4379 if (ret < 0) {
4380 pr_err("%s: Invalid port 0x%x ret %d",
4381 __func__, port_id, ret);
4382 return -EINVAL;
4383 }
4384
4385 cmd_size = sizeof(struct afe_service_cmd_shared_mem_map_regions)
4386 + sizeof(struct afe_service_shared_map_region_payload);
4387
4388 mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL);
4389 if (!mmap_region_cmd)
4390 return -ENOMEM;
4391
4392 mregion = (struct afe_service_cmd_shared_mem_map_regions *)
4393 mmap_region_cmd;
4394 mregion->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4395 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4396 mregion->hdr.pkt_size = sizeof(mregion);
4397 mregion->hdr.src_port = 0;
4398 mregion->hdr.dest_port = 0;
4399 mregion->hdr.token = 0;
4400 mregion->hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS;
4401 mregion->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL;
4402 mregion->num_regions = 1;
4403 mregion->property_flag = 0x00;
4404
4405 payload = ((u8 *) mmap_region_cmd +
4406 sizeof(struct afe_service_cmd_shared_mem_map_regions));
4407 mregion_pl = (struct afe_service_shared_map_region_payload *)payload;
4408
4409 mregion_pl->shm_addr_lsw = lower_32_bits(dma_addr_p);
4410 mregion_pl->shm_addr_msw = msm_audio_populate_upper_32_bits(dma_addr_p);
4411 mregion_pl->mem_size_bytes = dma_buf_sz;
4412
4413 ret = afe_apr_send_pkt(mmap_region_cmd, NULL);
4414 if (ret)
4415 pr_err("%s: AFE memory map cmd failed %d\n",
4416 __func__, ret);
4417 kfree(mmap_region_cmd);
4418 return ret;
4419}
4420int q6afe_audio_client_buf_free_contiguous(unsigned int dir,
4421 struct afe_audio_client *ac)
4422{
4423 struct afe_audio_port_data *port;
4424 int cnt = 0;
4425
4426 mutex_lock(&ac->cmd_lock);
4427 port = &ac->port[dir];
4428 if (!port->buf) {
4429 pr_err("%s: buf is null\n", __func__);
4430 mutex_unlock(&ac->cmd_lock);
4431 return 0;
4432 }
4433 cnt = port->max_buf_cnt - 1;
4434
4435 if (port->buf[0].data) {
4436 pr_debug("%s: data[%pK]phys[%pK][%pK] , client[%pK] handle[%pK]\n",
4437 __func__,
4438 port->buf[0].data,
4439 &port->buf[0].phys,
4440 &port->buf[0].phys,
4441 port->buf[0].client,
4442 port->buf[0].handle);
4443 msm_audio_ion_free(port->buf[0].client, port->buf[0].handle);
4444 port->buf[0].client = NULL;
4445 port->buf[0].handle = NULL;
4446 }
4447
4448 while (cnt >= 0) {
4449 port->buf[cnt].data = NULL;
4450 port->buf[cnt].phys = 0;
4451 cnt--;
4452 }
4453 port->max_buf_cnt = 0;
4454 kfree(port->buf);
4455 port->buf = NULL;
4456 mutex_unlock(&ac->cmd_lock);
4457 return 0;
4458}
4459
4460void q6afe_audio_client_free(struct afe_audio_client *ac)
4461{
4462 int loopcnt;
4463 struct afe_audio_port_data *port;
4464
4465 if (!ac) {
4466 pr_err("%s: audio client is NULL\n", __func__);
4467 return;
4468 }
4469 for (loopcnt = 0; loopcnt <= OUT; loopcnt++) {
4470 port = &ac->port[loopcnt];
4471 if (!port->buf)
4472 continue;
4473 pr_debug("%s: loopcnt = %d\n", __func__, loopcnt);
4474 q6afe_audio_client_buf_free_contiguous(loopcnt, ac);
4475 }
4476 kfree(ac);
4477}
4478
4479int afe_cmd_memory_unmap(u32 mem_map_handle)
4480{
4481 int ret = 0;
4482 struct afe_service_cmd_shared_mem_unmap_regions mregion;
4483 int index = 0;
4484
4485 pr_debug("%s: handle 0x%x\n", __func__, mem_map_handle);
4486
4487 if (this_afe.apr == NULL) {
4488 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
4489 0xFFFFFFFF, &this_afe);
4490 pr_debug("%s: Register AFE\n", __func__);
4491 if (this_afe.apr == NULL) {
4492 pr_err("%s: Unable to register AFE\n", __func__);
4493 ret = -ENODEV;
4494 return ret;
4495 }
4496 rtac_set_afe_handle(this_afe.apr);
4497 }
4498
4499 mregion.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4500 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4501 mregion.hdr.pkt_size = sizeof(mregion);
4502 mregion.hdr.src_port = 0;
4503 mregion.hdr.dest_port = 0;
4504 mregion.hdr.token = 0;
4505 mregion.hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_UNMAP_REGIONS;
4506 mregion.mem_map_handle = mem_map_handle;
4507
4508 /* Todo */
4509 index = mregion.hdr.token = IDX_RSVD_2;
4510
4511 atomic_set(&this_afe.status, 0);
4512 ret = afe_apr_send_pkt(&mregion, &this_afe.wait[index]);
4513 if (ret)
4514 pr_err("%s: AFE memory unmap cmd failed %d\n",
4515 __func__, ret);
4516
4517 return ret;
4518}
4519
4520int afe_cmd_memory_unmap_nowait(u32 mem_map_handle)
4521{
4522 int ret = 0;
4523 struct afe_service_cmd_shared_mem_unmap_regions mregion;
4524
4525 pr_debug("%s: handle 0x%x\n", __func__, mem_map_handle);
4526
4527 if (this_afe.apr == NULL) {
4528 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
4529 0xFFFFFFFF, &this_afe);
4530 pr_debug("%s: Register AFE\n", __func__);
4531 if (this_afe.apr == NULL) {
4532 pr_err("%s: Unable to register AFE\n", __func__);
4533 ret = -ENODEV;
4534 return ret;
4535 }
4536 rtac_set_afe_handle(this_afe.apr);
4537 }
4538
4539 mregion.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4540 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4541 mregion.hdr.pkt_size = sizeof(mregion);
4542 mregion.hdr.src_port = 0;
4543 mregion.hdr.dest_port = 0;
4544 mregion.hdr.token = 0;
4545 mregion.hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_UNMAP_REGIONS;
4546 mregion.mem_map_handle = mem_map_handle;
4547
4548 ret = afe_apr_send_pkt(&mregion, NULL);
4549 if (ret)
4550 pr_err("%s: AFE memory unmap cmd failed %d\n",
4551 __func__, ret);
4552 return ret;
4553}
4554
4555int afe_register_get_events(u16 port_id,
4556 void (*cb)(uint32_t opcode,
4557 uint32_t token, uint32_t *payload, void *priv),
4558 void *private_data)
4559{
4560 int ret = 0;
4561 struct afe_service_cmd_register_rt_port_driver rtproxy;
4562
4563 pr_debug("%s: port_id: 0x%x\n", __func__, port_id);
4564
4565 if (this_afe.apr == NULL) {
4566 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
4567 0xFFFFFFFF, &this_afe);
4568 pr_debug("%s: Register AFE\n", __func__);
4569 if (this_afe.apr == NULL) {
4570 pr_err("%s: Unable to register AFE\n", __func__);
4571 ret = -ENODEV;
4572 return ret;
4573 }
4574 rtac_set_afe_handle(this_afe.apr);
4575 }
4576 if ((port_id == RT_PROXY_DAI_002_RX) ||
4577 (port_id == RT_PROXY_DAI_001_TX)) {
4578 port_id = VIRTUAL_ID_TO_PORTID(port_id);
4579 } else {
4580 pr_err("%s: wrong port id 0x%x\n", __func__, port_id);
4581 return -EINVAL;
4582 }
4583
4584 if (port_id == RT_PROXY_PORT_001_TX) {
4585 this_afe.tx_cb = cb;
4586 this_afe.tx_private_data = private_data;
4587 } else if (port_id == RT_PROXY_PORT_001_RX) {
4588 this_afe.rx_cb = cb;
4589 this_afe.rx_private_data = private_data;
4590 }
4591
4592 rtproxy.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4593 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4594 rtproxy.hdr.pkt_size = sizeof(rtproxy);
4595 rtproxy.hdr.src_port = 1;
4596 rtproxy.hdr.dest_port = 1;
4597 rtproxy.hdr.opcode = AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER;
4598 rtproxy.port_id = port_id;
4599 rtproxy.reserved = 0;
4600
4601 ret = afe_apr_send_pkt(&rtproxy, NULL);
4602 if (ret)
4603 pr_err("%s: AFE reg. rtproxy_event failed %d\n",
4604 __func__, ret);
4605 return ret;
4606}
4607
4608int afe_unregister_get_events(u16 port_id)
4609{
4610 int ret = 0;
4611 struct afe_service_cmd_unregister_rt_port_driver rtproxy;
4612 int index = 0;
4613
4614 pr_debug("%s:\n", __func__);
4615
4616 if (this_afe.apr == NULL) {
4617 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
4618 0xFFFFFFFF, &this_afe);
4619 pr_debug("%s: Register AFE\n", __func__);
4620 if (this_afe.apr == NULL) {
4621 pr_err("%s: Unable to register AFE\n", __func__);
4622 ret = -ENODEV;
4623 return ret;
4624 }
4625 rtac_set_afe_handle(this_afe.apr);
4626 }
4627
4628 if ((port_id == RT_PROXY_DAI_002_RX) ||
4629 (port_id == RT_PROXY_DAI_001_TX)) {
4630 port_id = VIRTUAL_ID_TO_PORTID(port_id);
4631 } else {
4632 pr_err("%s: wrong port id 0x%x\n", __func__, port_id);
4633 return -EINVAL;
4634 }
4635
4636 index = q6audio_get_port_index(port_id);
4637 if (index < 0 || index >= AFE_MAX_PORTS) {
4638 pr_err("%s: AFE port index[%d] invalid!\n",
4639 __func__, index);
4640 return -EINVAL;
4641 }
4642 ret = q6audio_validate_port(port_id);
4643 if (ret < 0) {
4644 pr_err("%s: Invalid port 0x%x ret %d", __func__, port_id, ret);
4645 return -EINVAL;
4646 }
4647
4648 rtproxy.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4649 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4650 rtproxy.hdr.pkt_size = sizeof(rtproxy);
4651 rtproxy.hdr.src_port = 0;
4652 rtproxy.hdr.dest_port = 0;
4653 rtproxy.hdr.token = 0;
4654 rtproxy.hdr.opcode = AFE_SERVICE_CMD_UNREGISTER_RT_PORT_DRIVER;
4655 rtproxy.port_id = port_id;
4656 rtproxy.reserved = 0;
4657
4658 rtproxy.hdr.token = index;
4659
4660 if (port_id == RT_PROXY_PORT_001_TX) {
4661 this_afe.tx_cb = NULL;
4662 this_afe.tx_private_data = NULL;
4663 } else if (port_id == RT_PROXY_PORT_001_RX) {
4664 this_afe.rx_cb = NULL;
4665 this_afe.rx_private_data = NULL;
4666 }
4667
4668 ret = afe_apr_send_pkt(&rtproxy, &this_afe.wait[index]);
4669 if (ret)
4670 pr_err("%s: AFE enable Unreg. rtproxy_event failed %d\n",
4671 __func__, ret);
4672 return ret;
4673}
4674
4675int afe_rt_proxy_port_write(phys_addr_t buf_addr_p,
4676 u32 mem_map_handle, int bytes)
4677{
4678 int ret = 0;
4679 struct afe_port_data_cmd_rt_proxy_port_write_v2 afecmd_wr;
4680
4681 if (this_afe.apr == NULL) {
4682 pr_err("%s: register to AFE is not done\n", __func__);
4683 ret = -ENODEV;
4684 return ret;
4685 }
4686 pr_debug("%s: buf_addr_p = 0x%pK bytes = %d\n", __func__,
4687 &buf_addr_p, bytes);
4688
4689 afecmd_wr.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4690 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4691 afecmd_wr.hdr.pkt_size = sizeof(afecmd_wr);
4692 afecmd_wr.hdr.src_port = 0;
4693 afecmd_wr.hdr.dest_port = 0;
4694 afecmd_wr.hdr.token = 0;
4695 afecmd_wr.hdr.opcode = AFE_PORT_DATA_CMD_RT_PROXY_PORT_WRITE_V2;
4696 afecmd_wr.port_id = RT_PROXY_PORT_001_TX;
4697 afecmd_wr.buffer_address_lsw = lower_32_bits(buf_addr_p);
4698 afecmd_wr.buffer_address_msw =
4699 msm_audio_populate_upper_32_bits(buf_addr_p);
4700 afecmd_wr.mem_map_handle = mem_map_handle;
4701 afecmd_wr.available_bytes = bytes;
4702 afecmd_wr.reserved = 0;
4703
4704 ret = afe_apr_send_pkt(&afecmd_wr, NULL);
4705 if (ret)
4706 pr_err("%s: AFE rtproxy write to port 0x%x failed %d\n",
4707 __func__, afecmd_wr.port_id, ret);
4708 return ret;
4709
4710}
4711
4712int afe_rt_proxy_port_read(phys_addr_t buf_addr_p,
4713 u32 mem_map_handle, int bytes)
4714{
4715 int ret = 0;
4716 struct afe_port_data_cmd_rt_proxy_port_read_v2 afecmd_rd;
4717
4718 if (this_afe.apr == NULL) {
4719 pr_err("%s: register to AFE is not done\n", __func__);
4720 ret = -ENODEV;
4721 return ret;
4722 }
4723 pr_debug("%s: buf_addr_p = 0x%pK bytes = %d\n", __func__,
4724 &buf_addr_p, bytes);
4725
4726 afecmd_rd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4727 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4728 afecmd_rd.hdr.pkt_size = sizeof(afecmd_rd);
4729 afecmd_rd.hdr.src_port = 0;
4730 afecmd_rd.hdr.dest_port = 0;
4731 afecmd_rd.hdr.token = 0;
4732 afecmd_rd.hdr.opcode = AFE_PORT_DATA_CMD_RT_PROXY_PORT_READ_V2;
4733 afecmd_rd.port_id = RT_PROXY_PORT_001_RX;
4734 afecmd_rd.buffer_address_lsw = lower_32_bits(buf_addr_p);
4735 afecmd_rd.buffer_address_msw =
4736 msm_audio_populate_upper_32_bits(buf_addr_p);
4737 afecmd_rd.available_bytes = bytes;
4738 afecmd_rd.mem_map_handle = mem_map_handle;
4739
4740 ret = afe_apr_send_pkt(&afecmd_rd, NULL);
4741 if (ret)
4742 pr_err("%s: AFE rtproxy read cmd to port 0x%x failed %d\n",
4743 __func__, afecmd_rd.port_id, ret);
4744 return ret;
4745}
4746
4747#ifdef CONFIG_DEBUG_FS
4748static struct dentry *debugfs_afelb;
4749static struct dentry *debugfs_afelb_gain;
4750
4751static int afe_debug_open(struct inode *inode, struct file *file)
4752{
4753 file->private_data = inode->i_private;
4754 pr_info("%s: debug intf %s\n", __func__, (char *) file->private_data);
4755 return 0;
4756}
4757
4758static int afe_get_parameters(char *buf, long int *param1, int num_of_par)
4759{
4760 char *token;
4761 int base, cnt;
4762
4763 token = strsep(&buf, " ");
4764
4765 for (cnt = 0; cnt < num_of_par; cnt++) {
4766 if (token != NULL) {
4767 if ((token[1] == 'x') || (token[1] == 'X'))
4768 base = 16;
4769 else
4770 base = 10;
4771
4772 if (kstrtoul(token, base, &param1[cnt]) != 0) {
4773 pr_err("%s: kstrtoul failed\n",
4774 __func__);
4775 return -EINVAL;
4776 }
4777
4778 token = strsep(&buf, " ");
4779 } else {
4780 pr_err("%s: token NULL\n", __func__);
4781 return -EINVAL;
4782 }
4783 }
4784 return 0;
4785}
4786#define AFE_LOOPBACK_ON (1)
4787#define AFE_LOOPBACK_OFF (0)
4788static ssize_t afe_debug_write(struct file *filp,
4789 const char __user *ubuf, size_t cnt, loff_t *ppos)
4790{
4791 char *lb_str = filp->private_data;
4792 char lbuf[32];
4793 int rc;
4794 unsigned long param[5];
4795
4796 if (cnt > sizeof(lbuf) - 1) {
4797 pr_err("%s: cnt %zd size %zd\n", __func__, cnt, sizeof(lbuf)-1);
4798 return -EINVAL;
4799 }
4800
4801 rc = copy_from_user(lbuf, ubuf, cnt);
4802 if (rc) {
4803 pr_err("%s: copy from user failed %d\n", __func__, rc);
4804 return -EFAULT;
4805 }
4806
4807 lbuf[cnt] = '\0';
4808
4809 if (!strcmp(lb_str, "afe_loopback")) {
4810 rc = afe_get_parameters(lbuf, param, 3);
4811 if (!rc) {
4812 pr_info("%s: %lu %lu %lu\n", lb_str, param[0], param[1],
4813 param[2]);
4814
4815 if ((param[0] != AFE_LOOPBACK_ON) && (param[0] !=
4816 AFE_LOOPBACK_OFF)) {
4817 pr_err("%s: Error, parameter 0 incorrect\n",
4818 __func__);
4819 rc = -EINVAL;
4820 goto afe_error;
4821 }
4822 if ((q6audio_validate_port(param[1]) < 0) ||
4823 (q6audio_validate_port(param[2])) < 0) {
4824 pr_err("%s: Error, invalid afe port\n",
4825 __func__);
4826 }
4827 if (this_afe.apr == NULL) {
4828 pr_err("%s: Error, AFE not opened\n", __func__);
4829 rc = -EINVAL;
4830 } else {
4831 rc = afe_loopback(param[0], param[1], param[2]);
4832 }
4833 } else {
4834 pr_err("%s: Error, invalid parameters\n", __func__);
4835 rc = -EINVAL;
4836 }
4837
4838 } else if (!strcmp(lb_str, "afe_loopback_gain")) {
4839 rc = afe_get_parameters(lbuf, param, 2);
4840 if (!rc) {
4841 pr_info("%s: %s %lu %lu\n",
4842 __func__, lb_str, param[0], param[1]);
4843
4844 rc = q6audio_validate_port(param[0]);
4845 if (rc < 0) {
4846 pr_err("%s: Error, invalid afe port %d %lu\n",
4847 __func__, rc, param[0]);
4848 rc = -EINVAL;
4849 goto afe_error;
4850 }
4851
4852 if (param[1] > 100) {
4853 pr_err("%s: Error, volume should be 0 to 100 percentage param = %lu\n",
4854 __func__, param[1]);
4855 rc = -EINVAL;
4856 goto afe_error;
4857 }
4858
4859 param[1] = (Q6AFE_MAX_VOLUME * param[1]) / 100;
4860
4861 if (this_afe.apr == NULL) {
4862 pr_err("%s: Error, AFE not opened\n", __func__);
4863 rc = -EINVAL;
4864 } else {
4865 rc = afe_loopback_gain(param[0], param[1]);
4866 }
4867 } else {
4868 pr_err("%s: Error, invalid parameters\n", __func__);
4869 rc = -EINVAL;
4870 }
4871 }
4872
4873afe_error:
4874 if (rc == 0)
4875 rc = cnt;
4876 else
4877 pr_err("%s: rc = %d\n", __func__, rc);
4878
4879 return rc;
4880}
4881
4882static const struct file_operations afe_debug_fops = {
4883 .open = afe_debug_open,
4884 .write = afe_debug_write
4885};
4886
4887static void config_debug_fs_init(void)
4888{
4889 debugfs_afelb = debugfs_create_file("afe_loopback",
4890 0664, NULL, (void *) "afe_loopback",
4891 &afe_debug_fops);
4892
4893 debugfs_afelb_gain = debugfs_create_file("afe_loopback_gain",
4894 0664, NULL, (void *) "afe_loopback_gain",
4895 &afe_debug_fops);
4896}
4897static void config_debug_fs_exit(void)
4898{
4899 debugfs_remove(debugfs_afelb);
4900 debugfs_remove(debugfs_afelb_gain);
4901}
4902#else
4903static void config_debug_fs_init(void)
4904{
4905}
4906static void config_debug_fs_exit(void)
4907{
4908}
4909#endif
4910
4911void afe_set_dtmf_gen_rx_portid(u16 port_id, int set)
4912{
4913 if (set)
4914 this_afe.dtmf_gen_rx_portid = port_id;
4915 else if (this_afe.dtmf_gen_rx_portid == port_id)
4916 this_afe.dtmf_gen_rx_portid = -1;
4917}
4918
4919int afe_dtmf_generate_rx(int64_t duration_in_ms,
4920 uint16_t high_freq,
4921 uint16_t low_freq, uint16_t gain)
4922{
4923 int ret = 0;
4924 int index = 0;
4925 struct afe_dtmf_generation_command cmd_dtmf;
4926
4927 pr_debug("%s: DTMF AFE Gen\n", __func__);
4928
4929 if (afe_validate_port(this_afe.dtmf_gen_rx_portid) < 0) {
4930 pr_err("%s: Failed : Invalid Port id = 0x%x\n",
4931 __func__, this_afe.dtmf_gen_rx_portid);
4932 ret = -EINVAL;
4933 goto fail_cmd;
4934 }
4935
4936 if (this_afe.apr == NULL) {
4937 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
4938 0xFFFFFFFF, &this_afe);
4939 pr_debug("%s: Register AFE\n", __func__);
4940 if (this_afe.apr == NULL) {
4941 pr_err("%s: Unable to register AFE\n", __func__);
4942 ret = -ENODEV;
4943 return ret;
4944 }
4945 rtac_set_afe_handle(this_afe.apr);
4946 }
4947
4948 pr_debug("%s: dur=%lld: hfreq=%d lfreq=%d gain=%d portid=0x%x\n",
4949 __func__,
4950 duration_in_ms, high_freq, low_freq, gain,
4951 this_afe.dtmf_gen_rx_portid);
4952
4953 cmd_dtmf.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4954 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4955 cmd_dtmf.hdr.pkt_size = sizeof(cmd_dtmf);
4956 cmd_dtmf.hdr.src_port = 0;
4957 cmd_dtmf.hdr.dest_port = 0;
4958 cmd_dtmf.hdr.token = 0;
4959 cmd_dtmf.hdr.opcode = AFE_PORTS_CMD_DTMF_CTL;
4960 cmd_dtmf.duration_in_ms = duration_in_ms;
4961 cmd_dtmf.high_freq = high_freq;
4962 cmd_dtmf.low_freq = low_freq;
4963 cmd_dtmf.gain = gain;
4964 cmd_dtmf.num_ports = 1;
4965 cmd_dtmf.port_ids = q6audio_get_port_id(this_afe.dtmf_gen_rx_portid);
4966
4967 atomic_set(&this_afe.state, 1);
4968 atomic_set(&this_afe.status, 0);
4969 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &cmd_dtmf);
4970 if (ret < 0) {
4971 pr_err("%s: AFE DTMF failed for num_ports:%d ids:0x%x\n",
4972 __func__, cmd_dtmf.num_ports, cmd_dtmf.port_ids);
4973 ret = -EINVAL;
4974 goto fail_cmd;
4975 }
4976 index = q6audio_get_port_index(this_afe.dtmf_gen_rx_portid);
4977 if (index < 0 || index >= AFE_MAX_PORTS) {
4978 pr_err("%s: AFE port index[%d] invalid!\n",
4979 __func__, index);
4980 ret = -EINVAL;
4981 goto fail_cmd;
4982 }
4983 ret = wait_event_timeout(this_afe.wait[index],
4984 (atomic_read(&this_afe.state) == 0),
4985 msecs_to_jiffies(TIMEOUT_MS));
4986 if (!ret) {
4987 pr_err("%s: wait_event timeout\n", __func__);
4988 ret = -EINVAL;
4989 goto fail_cmd;
4990 }
4991 if (atomic_read(&this_afe.status) > 0) {
4992 pr_err("%s: config cmd failed [%s]\n",
4993 __func__, adsp_err_get_err_str(
4994 atomic_read(&this_afe.status)));
4995 ret = adsp_err_get_lnx_err_code(
4996 atomic_read(&this_afe.status));
4997 goto fail_cmd;
4998 }
4999 return 0;
5000
5001fail_cmd:
5002 pr_err("%s: failed %d\n", __func__, ret);
5003 return ret;
5004}
5005
5006static int afe_sidetone_iir(u16 tx_port_id)
5007{
5008 struct afe_loopback_iir_cfg_v2 iir_sidetone;
5009 int ret;
5010 int index = 0;
5011 uint16_t size = 0;
5012 int cal_index = AFE_SIDETONE_IIR_CAL;
5013 int iir_pregain = 0;
5014 int iir_num_biquad_stages = 0;
5015 int iir_enable;
5016 struct cal_block_data *cal_block;
5017 int mid;
5018
5019 memset(&iir_sidetone, 0, sizeof(iir_sidetone));
5020 index = q6audio_get_port_index(tx_port_id);
5021 iir_sidetone.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5022 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5023 iir_sidetone.hdr.pkt_size = sizeof(iir_sidetone);
5024 iir_sidetone.hdr.src_port = 0;
5025 iir_sidetone.hdr.dest_port = 0;
5026 iir_sidetone.hdr.token = index;
5027 iir_sidetone.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
5028 iir_sidetone.param.port_id = tx_port_id;
5029 iir_sidetone.param.payload_address_lsw = 0x00;
5030 iir_sidetone.param.payload_address_msw = 0x00;
5031 iir_sidetone.param.mem_map_handle = 0x00;
5032
5033 if (this_afe.cal_data[cal_index] == NULL) {
5034 pr_err("%s: cal data is NULL\n", __func__);
5035 ret = -EINVAL;
5036 goto done;
5037 }
5038 mutex_lock(&this_afe.cal_data[cal_index]->lock);
5039 cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]);
5040 if (cal_block == NULL) {
5041 pr_err("%s: cal_block not found\n ", __func__);
5042 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
5043 ret = -EINVAL;
5044 goto done;
5045 }
5046
5047 iir_pregain = ((struct audio_cal_info_sidetone_iir *)
5048 cal_block->cal_info)->pregain;
5049 iir_enable = ((struct audio_cal_info_sidetone_iir *)
5050 cal_block->cal_info)->iir_enable;
5051 iir_num_biquad_stages = ((struct audio_cal_info_sidetone_iir *)
5052 cal_block->cal_info)->num_biquad_stages;
5053 mid = ((struct audio_cal_info_sidetone_iir *)
5054 cal_block->cal_info)->mid;
5055
5056 /*
5057 * calculate the actual size of payload based on no of stages
5058 * enabled in calibration
5059 */
5060 size = (MAX_SIDETONE_IIR_DATA_SIZE / MAX_NO_IIR_FILTER_STAGE) *
5061 iir_num_biquad_stages;
5062 /*
5063 * For an odd number of stages, 2 bytes of padding are
5064 * required at the end of the payload.
5065 */
5066 if (iir_num_biquad_stages % 2) {
5067 pr_debug("%s: adding 2 to size:%d\n", __func__, size);
5068 size = size + 2;
5069 }
5070 memcpy(&iir_sidetone.st_iir_filter_config_data.iir_config,
5071 &((struct audio_cal_info_sidetone_iir *)
5072 cal_block->cal_info)->iir_config,
5073 sizeof(iir_sidetone.st_iir_filter_config_data.iir_config));
5074 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
5075
5076 /*
5077 * Calculate the payload size for setparams command
5078 */
5079 iir_sidetone.param.payload_size = (sizeof(iir_sidetone) -
5080 sizeof(struct apr_hdr) -
5081 sizeof(struct afe_port_cmd_set_param_v2) -
5082 (MAX_SIDETONE_IIR_DATA_SIZE - size));
5083
5084 pr_debug("%s: payload size :%d\n", __func__,
5085 iir_sidetone.param.payload_size);
5086
5087 /*
5088 * Set IIR enable params
5089 */
5090 iir_sidetone.st_iir_enable_pdata.module_id = mid;
5091 iir_sidetone.st_iir_enable_pdata.param_id =
5092 AFE_PARAM_ID_ENABLE;
5093 iir_sidetone.st_iir_enable_pdata.param_size =
5094 sizeof(iir_sidetone.st_iir_mode_enable_data);
5095 iir_sidetone.st_iir_mode_enable_data.enable = iir_enable;
5096
5097 /*
5098 * Set IIR filter config params
5099 */
5100 iir_sidetone.st_iir_filter_config_pdata.module_id = mid;
5101 iir_sidetone.st_iir_filter_config_pdata.param_id =
5102 AFE_PARAM_ID_SIDETONE_IIR_FILTER_CONFIG;
5103 iir_sidetone.st_iir_filter_config_pdata.param_size =
5104 sizeof(iir_sidetone.st_iir_filter_config_data.num_biquad_stages)
5105 +
5106 sizeof(iir_sidetone.st_iir_filter_config_data.pregain) + size;
5107 iir_sidetone.st_iir_filter_config_pdata.reserved = 0;
5108 iir_sidetone.st_iir_filter_config_data.num_biquad_stages =
5109 iir_num_biquad_stages;
5110 iir_sidetone.st_iir_filter_config_data.pregain = iir_pregain;
5111 pr_debug("%s: tx(0x%x)mid(0x%x)iir_en(%d)stg(%d)gain(0x%x)size(%d)\n",
5112 __func__, tx_port_id, mid,
5113 iir_sidetone.st_iir_mode_enable_data.enable,
5114 iir_sidetone.st_iir_filter_config_data.num_biquad_stages,
5115 iir_sidetone.st_iir_filter_config_data.pregain,
5116 iir_sidetone.st_iir_filter_config_pdata.param_size);
5117 ret = afe_apr_send_pkt(&iir_sidetone, &this_afe.wait[index]);
5118 if (ret)
5119 pr_err("%s: AFE sidetone failed for tx_port(0x%x)\n",
5120 __func__, tx_port_id);
5121
5122done:
5123 return ret;
5124
5125}
5126
5127static int afe_sidetone(u16 tx_port_id, u16 rx_port_id, bool enable)
5128{
5129 struct afe_st_loopback_cfg_v1 cmd_sidetone;
5130 int ret;
5131 int index;
5132 int cal_index = AFE_SIDETONE_CAL;
5133 int sidetone_gain;
5134 int sidetone_enable;
5135 struct cal_block_data *cal_block;
5136 int mid = 0;
5137
5138 memset(&cmd_sidetone, 0, sizeof(cmd_sidetone));
5139 if (this_afe.cal_data[cal_index] == NULL) {
5140 pr_err("%s: cal data is NULL\n", __func__);
5141 ret = -EINVAL;
5142 goto done;
5143 }
5144 mutex_lock(&this_afe.cal_data[cal_index]->lock);
5145 cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]);
5146 if (cal_block == NULL) {
5147 pr_err("%s: cal_block not found\n", __func__);
5148 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
5149 ret = -EINVAL;
5150 goto done;
5151 }
5152 sidetone_gain = ((struct audio_cal_info_sidetone *)
5153 cal_block->cal_info)->gain;
5154 sidetone_enable = ((struct audio_cal_info_sidetone *)
5155 cal_block->cal_info)->enable;
5156 mid = ((struct audio_cal_info_sidetone *)
5157 cal_block->cal_info)->mid;
5158 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
5159
5160 index = q6audio_get_port_index(tx_port_id);
5161 cmd_sidetone.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5162 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5163 cmd_sidetone.hdr.pkt_size = sizeof(cmd_sidetone);
5164 cmd_sidetone.hdr.src_port = 0;
5165 cmd_sidetone.hdr.dest_port = 0;
5166 cmd_sidetone.hdr.token = index;
5167 cmd_sidetone.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
5168 cmd_sidetone.param.port_id = tx_port_id;
5169 cmd_sidetone.param.payload_size = (sizeof(cmd_sidetone) -
5170 sizeof(struct apr_hdr) -
5171 sizeof(struct afe_port_cmd_set_param_v2));
5172 cmd_sidetone.param.payload_address_lsw = 0x00;
5173 cmd_sidetone.param.payload_address_msw = 0x00;
5174 cmd_sidetone.param.mem_map_handle = 0x00;
5175 cmd_sidetone.gain_pdata.module_id = AFE_MODULE_LOOPBACK;
5176 cmd_sidetone.gain_pdata.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH;
5177 /*
5178 * size of actual payload only
5179 */
5180 cmd_sidetone.gain_pdata.param_size = sizeof(
5181 struct afe_loopback_sidetone_gain);
5182 cmd_sidetone.gain_data.rx_port_id = rx_port_id;
5183 cmd_sidetone.gain_data.gain = sidetone_gain;
5184
5185 cmd_sidetone.cfg_pdata.module_id = AFE_MODULE_LOOPBACK;
5186 cmd_sidetone.cfg_pdata.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG;
5187 /*
5188 * size of actual payload only
5189 */
5190 cmd_sidetone.cfg_pdata.param_size = sizeof(struct loopback_cfg_data);
5191 cmd_sidetone.cfg_data.loopback_cfg_minor_version =
5192 AFE_API_VERSION_LOOPBACK_CONFIG;
5193 cmd_sidetone.cfg_data.dst_port_id = rx_port_id;
5194 cmd_sidetone.cfg_data.routing_mode = LB_MODE_SIDETONE;
5195 cmd_sidetone.cfg_data.enable = enable;
5196
5197 pr_debug("%s rx(0x%x) tx(0x%x) enable(%d) mid(0x%x) gain(%d) sidetone_enable(%d)\n",
5198 __func__, rx_port_id, tx_port_id,
5199 enable, mid, sidetone_gain, sidetone_enable);
5200
5201 ret = afe_apr_send_pkt(&cmd_sidetone, &this_afe.wait[index]);
5202 if (ret)
5203 pr_err("%s: AFE sidetone send failed for tx_port:%d rx_port:%d ret:%d\n",
5204 __func__, tx_port_id, rx_port_id, ret);
5205done:
5206 return ret;
5207}
5208
5209int afe_sidetone_enable(u16 tx_port_id, u16 rx_port_id, bool enable)
5210{
5211 int ret;
5212 int index;
5213
5214 index = q6audio_get_port_index(rx_port_id);
5215 if (index < 0 || index >= AFE_MAX_PORTS) {
5216 pr_err("%s: AFE port index[%d] invalid!\n",
5217 __func__, index);
5218 ret = -EINVAL;
5219 goto done;
5220 }
5221 if (q6audio_validate_port(rx_port_id) < 0) {
5222 pr_err("%s: Invalid port 0x%x\n",
5223 __func__, rx_port_id);
5224 ret = -EINVAL;
5225 goto done;
5226 }
5227 index = q6audio_get_port_index(tx_port_id);
5228 if (index < 0 || index >= AFE_MAX_PORTS) {
5229 pr_err("%s: AFE port index[%d] invalid!\n",
5230 __func__, index);
5231 ret = -EINVAL;
5232 goto done;
5233 }
5234 if (q6audio_validate_port(tx_port_id) < 0) {
5235 pr_err("%s: Invalid port 0x%x\n",
5236 __func__, tx_port_id);
5237 ret = -EINVAL;
5238 goto done;
5239 }
5240 if (enable) {
5241 ret = afe_sidetone_iir(tx_port_id);
5242 if (ret)
5243 goto done;
5244 }
5245
5246 ret = afe_sidetone(tx_port_id, rx_port_id, enable);
5247
5248done:
5249 return ret;
5250}
5251
5252int afe_validate_port(u16 port_id)
5253{
5254 int ret;
5255
5256 switch (port_id) {
5257 case PRIMARY_I2S_RX:
5258 case PRIMARY_I2S_TX:
5259 case AFE_PORT_ID_PRIMARY_PCM_RX:
5260 case AFE_PORT_ID_PRIMARY_PCM_TX:
5261 case AFE_PORT_ID_SECONDARY_PCM_RX:
5262 case AFE_PORT_ID_SECONDARY_PCM_TX:
5263 case AFE_PORT_ID_TERTIARY_PCM_RX:
5264 case AFE_PORT_ID_TERTIARY_PCM_TX:
5265 case AFE_PORT_ID_QUATERNARY_PCM_RX:
5266 case AFE_PORT_ID_QUATERNARY_PCM_TX:
5267 case SECONDARY_I2S_RX:
5268 case SECONDARY_I2S_TX:
5269 case MI2S_RX:
5270 case MI2S_TX:
5271 case HDMI_RX:
5272 case DISPLAY_PORT_RX:
5273 case AFE_PORT_ID_SPDIF_RX:
5274 case RSVD_2:
5275 case RSVD_3:
5276 case DIGI_MIC_TX:
5277 case VOICE_RECORD_RX:
5278 case VOICE_RECORD_TX:
5279 case VOICE_PLAYBACK_TX:
5280 case VOICE2_PLAYBACK_TX:
5281 case SLIMBUS_0_RX:
5282 case SLIMBUS_0_TX:
5283 case SLIMBUS_1_RX:
5284 case SLIMBUS_1_TX:
5285 case SLIMBUS_2_RX:
5286 case SLIMBUS_2_TX:
5287 case SLIMBUS_3_RX:
5288 case INT_BT_SCO_RX:
5289 case INT_BT_SCO_TX:
5290 case INT_BT_A2DP_RX:
5291 case INT_FM_RX:
5292 case INT_FM_TX:
5293 case RT_PROXY_PORT_001_RX:
5294 case RT_PROXY_PORT_001_TX:
5295 case SLIMBUS_4_RX:
5296 case SLIMBUS_4_TX:
5297 case SLIMBUS_5_RX:
5298 case SLIMBUS_6_RX:
5299 case SLIMBUS_6_TX:
5300 case SLIMBUS_7_RX:
5301 case SLIMBUS_7_TX:
5302 case SLIMBUS_8_RX:
5303 case SLIMBUS_8_TX:
5304 case AFE_PORT_ID_USB_RX:
5305 case AFE_PORT_ID_USB_TX:
5306 case AFE_PORT_ID_PRIMARY_MI2S_RX:
5307 case AFE_PORT_ID_PRIMARY_MI2S_TX:
5308 case AFE_PORT_ID_SECONDARY_MI2S_RX:
5309 case AFE_PORT_ID_SECONDARY_MI2S_TX:
5310 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
5311 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
5312 case AFE_PORT_ID_TERTIARY_MI2S_RX:
5313 case AFE_PORT_ID_TERTIARY_MI2S_TX:
5314 case AFE_PORT_ID_QUINARY_MI2S_RX:
5315 case AFE_PORT_ID_QUINARY_MI2S_TX:
5316 case AFE_PORT_ID_SENARY_MI2S_TX:
5317 case AFE_PORT_ID_PRIMARY_TDM_RX:
5318 case AFE_PORT_ID_PRIMARY_TDM_TX:
5319 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
5320 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
5321 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
5322 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
5323 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
5324 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
5325 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
5326 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
5327 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
5328 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
5329 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
5330 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
5331 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
5332 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
5333 case AFE_PORT_ID_SECONDARY_TDM_RX:
5334 case AFE_PORT_ID_SECONDARY_TDM_TX:
5335 case AFE_PORT_ID_SECONDARY_TDM_RX_1:
5336 case AFE_PORT_ID_SECONDARY_TDM_TX_1:
5337 case AFE_PORT_ID_SECONDARY_TDM_RX_2:
5338 case AFE_PORT_ID_SECONDARY_TDM_TX_2:
5339 case AFE_PORT_ID_SECONDARY_TDM_RX_3:
5340 case AFE_PORT_ID_SECONDARY_TDM_TX_3:
5341 case AFE_PORT_ID_SECONDARY_TDM_RX_4:
5342 case AFE_PORT_ID_SECONDARY_TDM_TX_4:
5343 case AFE_PORT_ID_SECONDARY_TDM_RX_5:
5344 case AFE_PORT_ID_SECONDARY_TDM_TX_5:
5345 case AFE_PORT_ID_SECONDARY_TDM_RX_6:
5346 case AFE_PORT_ID_SECONDARY_TDM_TX_6:
5347 case AFE_PORT_ID_SECONDARY_TDM_RX_7:
5348 case AFE_PORT_ID_SECONDARY_TDM_TX_7:
5349 case AFE_PORT_ID_TERTIARY_TDM_RX:
5350 case AFE_PORT_ID_TERTIARY_TDM_TX:
5351 case AFE_PORT_ID_TERTIARY_TDM_RX_1:
5352 case AFE_PORT_ID_TERTIARY_TDM_TX_1:
5353 case AFE_PORT_ID_TERTIARY_TDM_RX_2:
5354 case AFE_PORT_ID_TERTIARY_TDM_TX_2:
5355 case AFE_PORT_ID_TERTIARY_TDM_RX_3:
5356 case AFE_PORT_ID_TERTIARY_TDM_TX_3:
5357 case AFE_PORT_ID_TERTIARY_TDM_RX_4:
5358 case AFE_PORT_ID_TERTIARY_TDM_TX_4:
5359 case AFE_PORT_ID_TERTIARY_TDM_RX_5:
5360 case AFE_PORT_ID_TERTIARY_TDM_TX_5:
5361 case AFE_PORT_ID_TERTIARY_TDM_RX_6:
5362 case AFE_PORT_ID_TERTIARY_TDM_TX_6:
5363 case AFE_PORT_ID_TERTIARY_TDM_RX_7:
5364 case AFE_PORT_ID_TERTIARY_TDM_TX_7:
5365 case AFE_PORT_ID_QUATERNARY_TDM_RX:
5366 case AFE_PORT_ID_QUATERNARY_TDM_TX:
5367 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
5368 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
5369 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
5370 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
5371 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
5372 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
5373 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
5374 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
5375 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
5376 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
5377 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
5378 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
5379 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
5380 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
5381 case AFE_PORT_ID_INT0_MI2S_RX:
5382 case AFE_PORT_ID_INT1_MI2S_RX:
5383 case AFE_PORT_ID_INT2_MI2S_RX:
5384 case AFE_PORT_ID_INT3_MI2S_RX:
5385 case AFE_PORT_ID_INT4_MI2S_RX:
5386 case AFE_PORT_ID_INT5_MI2S_RX:
5387 case AFE_PORT_ID_INT6_MI2S_RX:
5388 case AFE_PORT_ID_INT0_MI2S_TX:
5389 case AFE_PORT_ID_INT1_MI2S_TX:
5390 case AFE_PORT_ID_INT2_MI2S_TX:
5391 case AFE_PORT_ID_INT3_MI2S_TX:
5392 case AFE_PORT_ID_INT4_MI2S_TX:
5393 case AFE_PORT_ID_INT5_MI2S_TX:
5394 case AFE_PORT_ID_INT6_MI2S_TX:
5395 {
5396 ret = 0;
5397 break;
5398 }
5399
5400 default:
5401 pr_err("%s: default ret 0x%x\n", __func__, port_id);
5402 ret = -EINVAL;
5403 }
5404
5405 return ret;
5406}
5407
5408int afe_convert_virtual_to_portid(u16 port_id)
5409{
5410 int ret;
5411
5412 /*
5413 * if port_id is virtual, convert to physical..
5414 * if port_id is already physical, return physical
5415 */
5416 if (afe_validate_port(port_id) < 0) {
5417 if (port_id == RT_PROXY_DAI_001_RX ||
5418 port_id == RT_PROXY_DAI_001_TX ||
5419 port_id == RT_PROXY_DAI_002_RX ||
5420 port_id == RT_PROXY_DAI_002_TX) {
5421 ret = VIRTUAL_ID_TO_PORTID(port_id);
5422 } else {
5423 pr_err("%s: wrong port 0x%x\n",
5424 __func__, port_id);
5425 ret = -EINVAL;
5426 }
5427 } else
5428 ret = port_id;
5429
5430 return ret;
5431}
5432int afe_port_stop_nowait(int port_id)
5433{
5434 struct afe_port_cmd_device_stop stop;
5435 int ret = 0;
5436
5437 if (this_afe.apr == NULL) {
5438 pr_err("%s: AFE is already closed\n", __func__);
5439 ret = -EINVAL;
5440 goto fail_cmd;
5441 }
5442 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
5443 port_id = q6audio_convert_virtual_to_portid(port_id);
5444
5445 stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5446 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5447 stop.hdr.pkt_size = sizeof(stop);
5448 stop.hdr.src_port = 0;
5449 stop.hdr.dest_port = 0;
5450 stop.hdr.token = 0;
5451 stop.hdr.opcode = AFE_PORT_CMD_DEVICE_STOP;
5452 stop.port_id = port_id;
5453 stop.reserved = 0;
5454
5455 ret = afe_apr_send_pkt(&stop, NULL);
5456 if (ret)
5457 pr_err("%s: AFE close failed %d\n", __func__, ret);
5458
5459fail_cmd:
5460 return ret;
5461
5462}
5463
5464int afe_close(int port_id)
5465{
5466 struct afe_port_cmd_device_stop stop;
5467 enum afe_mad_type mad_type;
5468 int ret = 0;
5469 int index = 0;
5470 uint16_t port_index;
5471
5472 if (this_afe.apr == NULL) {
5473 pr_err("%s: AFE is already closed\n", __func__);
5474 if ((port_id == RT_PROXY_DAI_001_RX) ||
5475 (port_id == RT_PROXY_DAI_002_TX))
5476 pcm_afe_instance[port_id & 0x1] = 0;
5477 if ((port_id == RT_PROXY_DAI_002_RX) ||
5478 (port_id == RT_PROXY_DAI_001_TX))
5479 proxy_afe_instance[port_id & 0x1] = 0;
5480 afe_close_done[port_id & 0x1] = true;
5481 ret = -EINVAL;
5482 goto fail_cmd;
5483 }
5484 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
5485 if ((port_id == RT_PROXY_DAI_001_RX) ||
5486 (port_id == RT_PROXY_DAI_002_TX)) {
5487 pr_debug("%s: before decrementing pcm_afe_instance %d\n",
5488 __func__, pcm_afe_instance[port_id & 0x1]);
5489 port_id = VIRTUAL_ID_TO_PORTID(port_id);
5490 pcm_afe_instance[port_id & 0x1]--;
5491 if ((!(pcm_afe_instance[port_id & 0x1] == 0 &&
5492 proxy_afe_instance[port_id & 0x1] == 0)) ||
5493 afe_close_done[port_id & 0x1] == true)
5494 return 0;
5495
5496 afe_close_done[port_id & 0x1] = true;
5497 }
5498
5499 if ((port_id == RT_PROXY_DAI_002_RX) ||
5500 (port_id == RT_PROXY_DAI_001_TX)) {
5501 pr_debug("%s: before decrementing proxy_afe_instance %d\n",
5502 __func__, proxy_afe_instance[port_id & 0x1]);
5503 port_id = VIRTUAL_ID_TO_PORTID(port_id);
5504 proxy_afe_instance[port_id & 0x1]--;
5505 if ((!(pcm_afe_instance[port_id & 0x1] == 0 &&
5506 proxy_afe_instance[port_id & 0x1] == 0)) ||
5507 afe_close_done[port_id & 0x1] == true)
5508 return 0;
5509
5510 afe_close_done[port_id & 0x1] = true;
5511 }
5512
5513 port_id = q6audio_convert_virtual_to_portid(port_id);
5514 index = q6audio_get_port_index(port_id);
5515 if (index < 0 || index >= AFE_MAX_PORTS) {
5516 pr_err("%s: AFE port index[%d] invalid!\n",
5517 __func__, index);
5518 return -EINVAL;
5519 }
5520 ret = q6audio_validate_port(port_id);
5521 if (ret < 0) {
5522 pr_warn("%s: Not a valid port id 0x%x ret %d\n",
5523 __func__, port_id, ret);
5524 return -EINVAL;
5525 }
5526
5527 mad_type = afe_port_get_mad_type(port_id);
5528 pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id,
5529 mad_type);
5530 if (mad_type != MAD_HW_NONE && mad_type != MAD_SW_AUDIO) {
5531 pr_debug("%s: Turn off MAD\n", __func__);
5532 ret = afe_turn_onoff_hw_mad(mad_type, false);
5533 if (ret) {
5534 pr_err("%s: afe_turn_onoff_hw_mad failed %d\n",
5535 __func__, ret);
5536 return ret;
5537 }
5538 } else {
5539 pr_debug("%s: Not a MAD port\n", __func__);
5540 }
5541
5542 port_index = afe_get_port_index(port_id);
5543 if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
5544 this_afe.afe_sample_rates[port_index] = 0;
5545 this_afe.topology[port_index] = 0;
5546 this_afe.dev_acdb_id[port_index] = 0;
5547 } else {
5548 pr_err("%s: port %d\n", __func__, port_index);
5549 ret = -EINVAL;
5550 goto fail_cmd;
5551 }
5552
5553 if ((port_id == this_afe.aanc_info.aanc_tx_port) &&
5554 (this_afe.aanc_info.aanc_active)) {
5555 memset(&this_afe.aanc_info, 0x00, sizeof(this_afe.aanc_info));
5556 ret = afe_aanc_mod_enable(this_afe.apr, port_id, 0);
5557 if (ret)
5558 pr_err("%s: AFE mod disable failed %d\n",
5559 __func__, ret);
5560 }
5561
5562 /*
5563 * even if ramp down configuration failed it is not serious enough to
5564 * warrant bailaing out.
5565 */
5566 if (afe_spk_ramp_dn_cfg(port_id) < 0)
5567 pr_err("%s: ramp down configuration failed\n", __func__);
5568
5569 stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5570 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5571 stop.hdr.pkt_size = sizeof(stop);
5572 stop.hdr.src_port = 0;
5573 stop.hdr.dest_port = 0;
5574 stop.hdr.token = index;
5575 stop.hdr.opcode = AFE_PORT_CMD_DEVICE_STOP;
5576 stop.port_id = q6audio_get_port_id(port_id);
5577 stop.reserved = 0;
5578
5579 ret = afe_apr_send_pkt(&stop, &this_afe.wait[index]);
5580 if (ret)
5581 pr_err("%s: AFE close failed %d\n", __func__, ret);
5582
5583fail_cmd:
5584 return ret;
5585}
5586
5587int afe_set_digital_codec_core_clock(u16 port_id,
5588 struct afe_digital_clk_cfg *cfg)
5589{
5590 struct afe_lpass_digital_clk_config_command clk_cfg;
5591 int index = 0;
5592 int ret = 0;
5593
5594 if (!cfg) {
5595 pr_err("%s: clock cfg is NULL\n", __func__);
5596 ret = -EINVAL;
5597 return ret;
5598 }
5599
5600 ret = afe_q6_interface_prepare();
5601 if (ret != 0) {
5602 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
5603 return ret;
5604 }
5605
5606 clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5607 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5608 clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
5609 clk_cfg.hdr.src_port = 0;
5610 clk_cfg.hdr.dest_port = 0;
5611 clk_cfg.hdr.token = index;
5612
5613 clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
5614 /*default rx port is taken to enable the codec digital clock*/
5615 clk_cfg.param.port_id = q6audio_get_port_id(port_id);
5616 clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
5617 - sizeof(clk_cfg.param);
5618 clk_cfg.param.payload_address_lsw = 0x00;
5619 clk_cfg.param.payload_address_msw = 0x00;
5620 clk_cfg.param.mem_map_handle = 0x00;
5621 clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
5622 clk_cfg.pdata.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG;
5623 clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
5624 clk_cfg.clk_cfg = *cfg;
5625
5626 pr_debug("%s: Minor version =0x%x clk val = %d\n"
5627 "clk root = 0x%x resrv = 0x%x\n",
5628 __func__, cfg->i2s_cfg_minor_version,
5629 cfg->clk_val, cfg->clk_root, cfg->reserved);
5630
5631 atomic_set(&this_afe.state, 1);
5632 atomic_set(&this_afe.status, 0);
5633 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
5634 if (ret < 0) {
5635 pr_err("%s: AFE enable for port 0x%x ret %d\n",
5636 __func__, port_id, ret);
5637 ret = -EINVAL;
5638 goto fail_cmd;
5639 }
5640
5641 ret = wait_event_timeout(this_afe.wait[index],
5642 (atomic_read(&this_afe.state) == 0),
5643 msecs_to_jiffies(TIMEOUT_MS));
5644 if (!ret) {
5645 pr_err("%s: wait_event timeout\n", __func__);
5646 ret = -EINVAL;
5647 goto fail_cmd;
5648 }
5649 if (atomic_read(&this_afe.status) > 0) {
5650 pr_err("%s: config cmd failed [%s]\n",
5651 __func__, adsp_err_get_err_str(
5652 atomic_read(&this_afe.status)));
5653 ret = adsp_err_get_lnx_err_code(
5654 atomic_read(&this_afe.status));
5655 goto fail_cmd;
5656 }
5657
5658fail_cmd:
5659 return ret;
5660}
5661
5662int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg)
5663{
5664 struct afe_lpass_clk_config_command clk_cfg;
5665 int index = 0;
5666 int ret = 0;
5667
5668 if (!cfg) {
5669 pr_err("%s: clock cfg is NULL\n", __func__);
5670 ret = -EINVAL;
5671 return ret;
5672 }
5673 index = q6audio_get_port_index(port_id);
5674 if (index < 0 || index >= AFE_MAX_PORTS) {
5675 pr_err("%s: AFE port index[%d] invalid!\n",
5676 __func__, index);
5677 return -EINVAL;
5678 }
5679 ret = q6audio_is_digital_pcm_interface(port_id);
5680 if (ret < 0) {
5681 pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n",
5682 __func__, ret);
5683 return -EINVAL;
5684 }
5685
5686 ret = afe_q6_interface_prepare();
5687 if (ret != 0) {
5688 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
5689 return ret;
5690 }
5691
5692 mutex_lock(&this_afe.afe_cmd_lock);
5693 clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5694 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5695 clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
5696 clk_cfg.hdr.src_port = 0;
5697 clk_cfg.hdr.dest_port = 0;
5698 clk_cfg.hdr.token = index;
5699
5700 clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
5701 clk_cfg.param.port_id = q6audio_get_port_id(port_id);
5702 clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
5703 - sizeof(clk_cfg.param);
5704 clk_cfg.param.payload_address_lsw = 0x00;
5705 clk_cfg.param.payload_address_msw = 0x00;
5706 clk_cfg.param.mem_map_handle = 0x00;
5707 clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
5708 clk_cfg.pdata.param_id = AFE_PARAM_ID_LPAIF_CLK_CONFIG;
5709 clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
5710 clk_cfg.clk_cfg = *cfg;
5711
5712 pr_debug("%s: Minor version =0x%x clk val1 = %d\n"
5713 "clk val2 = %d, clk src = 0x%x\n"
5714 "clk root = 0x%x clk mode = 0x%x resrv = 0x%x\n"
5715 "port id = 0x%x\n",
5716 __func__, cfg->i2s_cfg_minor_version,
5717 cfg->clk_val1, cfg->clk_val2, cfg->clk_src,
5718 cfg->clk_root, cfg->clk_set_mode,
5719 cfg->reserved, q6audio_get_port_id(port_id));
5720
5721 atomic_set(&this_afe.state, 1);
5722 atomic_set(&this_afe.status, 0);
5723 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
5724 if (ret < 0) {
5725 pr_err("%s: AFE enable for port 0x%x ret %d\n",
5726 __func__, port_id, ret);
5727 ret = -EINVAL;
5728 goto fail_cmd;
5729 }
5730
5731 ret = wait_event_timeout(this_afe.wait[index],
5732 (atomic_read(&this_afe.state) == 0),
5733 msecs_to_jiffies(TIMEOUT_MS));
5734 if (!ret) {
5735 pr_err("%s: wait_event timeout\n", __func__);
5736 ret = -EINVAL;
5737 goto fail_cmd;
5738 }
5739 if (atomic_read(&this_afe.status) > 0) {
5740 pr_err("%s: config cmd failed [%s]\n",
5741 __func__, adsp_err_get_err_str(
5742 atomic_read(&this_afe.status)));
5743 ret = adsp_err_get_lnx_err_code(
5744 atomic_read(&this_afe.status));
5745 goto fail_cmd;
5746 }
5747
5748fail_cmd:
5749 mutex_unlock(&this_afe.afe_cmd_lock);
5750 return ret;
5751}
5752
5753/**
5754 * afe_set_lpass_clk_cfg - Set AFE clk config
5755 *
5756 * @index: port index
5757 * @cfg: pointer to clk set struct
5758 *
5759 * Returns 0 on success, appropriate error code otherwise
5760 */
5761int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg)
5762{
5763 struct afe_lpass_clk_config_command_v2 clk_cfg;
5764 int ret = 0;
5765
5766 if (!cfg) {
5767 pr_err("%s: clock cfg is NULL\n", __func__);
5768 ret = -EINVAL;
5769 return ret;
5770 }
5771
5772 if (index < 0 || index >= AFE_MAX_PORTS) {
5773 pr_err("%s: index[%d] invalid!\n", __func__, index);
5774 return -EINVAL;
5775 }
5776
5777 ret = afe_q6_interface_prepare();
5778 if (ret != 0) {
5779 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
5780 return ret;
5781 }
5782
5783 mutex_lock(&this_afe.afe_cmd_lock);
5784 clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5785 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5786 clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
5787 clk_cfg.hdr.src_port = 0;
5788 clk_cfg.hdr.dest_port = 0;
5789 clk_cfg.hdr.token = index;
5790
5791 clk_cfg.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
5792 clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
5793 - sizeof(clk_cfg.param);
5794 clk_cfg.param.payload_address_lsw = 0x00;
5795 clk_cfg.param.payload_address_msw = 0x00;
5796 clk_cfg.param.mem_map_handle = 0x00;
5797 clk_cfg.pdata.module_id = AFE_MODULE_CLOCK_SET;
5798 clk_cfg.pdata.param_id = AFE_PARAM_ID_CLOCK_SET;
5799 clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
5800 clk_cfg.clk_cfg = *cfg;
5801
5802
5803 pr_debug("%s: Minor version =0x%x clk id = %d\n"
5804 "clk freq (Hz) = %d, clk attri = 0x%x\n"
5805 "clk root = 0x%x clk enable = 0x%x\n",
5806 __func__, cfg->clk_set_minor_version,
5807 cfg->clk_id, cfg->clk_freq_in_hz, cfg->clk_attri,
5808 cfg->clk_root, cfg->enable);
5809
5810 atomic_set(&this_afe.state, 1);
5811 atomic_set(&this_afe.status, 0);
5812 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
5813 if (ret < 0) {
5814 pr_err("%s: AFE clk cfg failed with ret %d\n",
5815 __func__, ret);
5816 ret = -EINVAL;
5817 goto fail_cmd;
5818 }
5819
5820 ret = wait_event_timeout(this_afe.wait[index],
5821 (atomic_read(&this_afe.state) == 0),
5822 msecs_to_jiffies(TIMEOUT_MS));
5823 if (!ret) {
5824 pr_err("%s: wait_event timeout\n", __func__);
5825 ret = -EINVAL;
5826 goto fail_cmd;
5827 } else {
5828 /* set ret to 0 as no timeout happened */
5829 ret = 0;
5830 }
5831 if (atomic_read(&this_afe.status) != 0) {
5832 pr_err("%s: config cmd failed\n", __func__);
5833 ret = -EINVAL;
5834 goto fail_cmd;
5835 }
5836
5837fail_cmd:
5838 mutex_unlock(&this_afe.afe_cmd_lock);
5839 return ret;
5840}
5841EXPORT_SYMBOL(afe_set_lpass_clk_cfg);
5842
5843/**
5844 * afe_set_lpass_clock_v2 - Enable AFE lpass clock
5845 *
5846 * @port_id: AFE port id
5847 * @cfg: pointer to clk set struct
5848 *
5849 * Returns 0 on success, appropriate error code otherwise
5850 */
5851int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg)
5852{
5853 int index = 0;
5854 int ret = 0;
5855
5856 index = q6audio_get_port_index(port_id);
5857 if (index < 0 || index >= AFE_MAX_PORTS) {
5858 pr_err("%s: AFE port index[%d] invalid!\n",
5859 __func__, index);
5860 return -EINVAL;
5861 }
5862 ret = q6audio_is_digital_pcm_interface(port_id);
5863 if (ret < 0) {
5864 pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n",
5865 __func__, ret);
5866 return -EINVAL;
5867 }
5868
5869 ret = afe_set_lpass_clk_cfg(index, cfg);
5870 if (ret)
5871 pr_err("%s: afe_set_lpass_clk_cfg_v2 failed %d\n",
5872 __func__, ret);
5873
5874 return ret;
5875}
5876EXPORT_SYMBOL(afe_set_lpass_clock_v2);
5877
5878int afe_set_lpass_internal_digital_codec_clock(u16 port_id,
5879 struct afe_digital_clk_cfg *cfg)
5880{
5881 struct afe_lpass_digital_clk_config_command clk_cfg;
5882 int index = 0;
5883 int ret = 0;
5884
5885 if (!cfg) {
5886 pr_err("%s: clock cfg is NULL\n", __func__);
5887 ret = -EINVAL;
5888 return ret;
5889 }
5890 index = q6audio_get_port_index(port_id);
5891 if (index < 0 || index >= AFE_MAX_PORTS) {
5892 pr_err("%s: AFE port index[%d] invalid!\n",
5893 __func__, index);
5894 return -EINVAL;
5895 }
5896 ret = q6audio_is_digital_pcm_interface(port_id);
5897 if (ret < 0) {
5898 pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n",
5899 __func__, ret);
5900 return -EINVAL;
5901 }
5902
5903 ret = afe_q6_interface_prepare();
5904 if (ret != 0) {
5905 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
5906 return ret;
5907 }
5908
5909 clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5910 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5911 clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
5912 clk_cfg.hdr.src_port = 0;
5913 clk_cfg.hdr.dest_port = 0;
5914 clk_cfg.hdr.token = index;
5915
5916 clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
5917 clk_cfg.param.port_id = q6audio_get_port_id(port_id);
5918 clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
5919 - sizeof(clk_cfg.param);
5920 clk_cfg.param.payload_address_lsw = 0x00;
5921 clk_cfg.param.payload_address_msw = 0x00;
5922 clk_cfg.param.mem_map_handle = 0x00;
5923 clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
5924 clk_cfg.pdata.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG;
5925 clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
5926 clk_cfg.clk_cfg = *cfg;
5927
5928 pr_debug("%s: Minor version =0x%x clk val = %d\n"
5929 "clk root = 0x%x resrv = 0x%x port id = 0x%x\n",
5930 __func__, cfg->i2s_cfg_minor_version,
5931 cfg->clk_val, cfg->clk_root, cfg->reserved,
5932 q6audio_get_port_id(port_id));
5933
5934 atomic_set(&this_afe.state, 1);
5935 atomic_set(&this_afe.status, 0);
5936 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
5937 if (ret < 0) {
5938 pr_err("%s: AFE enable for port 0x0x%x ret %d\n",
5939 __func__, port_id, ret);
5940 ret = -EINVAL;
5941 goto fail_cmd;
5942 }
5943
5944 ret = wait_event_timeout(this_afe.wait[index],
5945 (atomic_read(&this_afe.state) == 0),
5946 msecs_to_jiffies(TIMEOUT_MS));
5947 if (!ret) {
5948 pr_err("%s: wait_event timeout\n", __func__);
5949 ret = -EINVAL;
5950 goto fail_cmd;
5951 }
5952 if (atomic_read(&this_afe.status) > 0) {
5953 pr_err("%s: config cmd failed [%s]\n",
5954 __func__, adsp_err_get_err_str(
5955 atomic_read(&this_afe.status)));
5956 ret = adsp_err_get_lnx_err_code(
5957 atomic_read(&this_afe.status));
5958 goto fail_cmd;
5959 }
5960
5961fail_cmd:
5962 return ret;
5963}
5964
5965int afe_enable_lpass_core_shared_clock(u16 port_id, u32 enable)
5966{
5967 struct afe_lpass_core_shared_clk_config_command clk_cfg;
5968 int index = 0;
5969 int ret = 0;
5970
5971 index = q6audio_get_port_index(port_id);
5972 if (index < 0 || index >= AFE_MAX_PORTS) {
5973 pr_err("%s: AFE port index[%d] invalid!\n",
5974 __func__, index);
5975 return -EINVAL;
5976 }
5977 ret = q6audio_is_digital_pcm_interface(port_id);
5978 if (ret < 0) {
5979 pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n",
5980 __func__, ret);
5981 return -EINVAL;
5982 }
5983
5984 ret = afe_q6_interface_prepare();
5985 if (ret != 0) {
5986 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
5987 return ret;
5988 }
5989
5990 mutex_lock(&this_afe.afe_cmd_lock);
5991 clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
5992 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
5993 clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
5994 clk_cfg.hdr.src_port = 0;
5995 clk_cfg.hdr.dest_port = 0;
5996 clk_cfg.hdr.token = index;
5997
5998 clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
5999 clk_cfg.param.port_id = q6audio_get_port_id(port_id);
6000 clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
6001 - sizeof(clk_cfg.param);
6002 clk_cfg.param.payload_address_lsw = 0x00;
6003 clk_cfg.param.payload_address_msw = 0x00;
6004 clk_cfg.param.mem_map_handle = 0x00;
6005 clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
6006 clk_cfg.pdata.param_id = AFE_PARAM_ID_LPASS_CORE_SHARED_CLOCK_CONFIG;
6007 clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
6008 clk_cfg.clk_cfg.lpass_core_shared_clk_cfg_minor_version =
6009 AFE_API_VERSION_LPASS_CORE_SHARED_CLK_CONFIG;
6010 clk_cfg.clk_cfg.enable = enable;
6011
6012 pr_debug("%s: port id = %d, enable = %d\n",
6013 __func__, q6audio_get_port_id(port_id), enable);
6014
6015 atomic_set(&this_afe.state, 1);
6016 atomic_set(&this_afe.status, 0);
6017 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
6018 if (ret < 0) {
6019 pr_err("%s: AFE enable for port 0x%x ret %d\n",
6020 __func__, port_id, ret);
6021 ret = -EINVAL;
6022 goto fail_cmd;
6023 }
6024
6025 ret = wait_event_timeout(this_afe.wait[index],
6026 (atomic_read(&this_afe.state) == 0),
6027 msecs_to_jiffies(TIMEOUT_MS));
6028 if (!ret) {
6029 pr_err("%s: wait_event timeout\n", __func__);
6030 ret = -EINVAL;
6031 goto fail_cmd;
6032 }
6033 if (atomic_read(&this_afe.status) > 0) {
6034 pr_err("%s: config cmd failed [%s]\n",
6035 __func__, adsp_err_get_err_str(
6036 atomic_read(&this_afe.status)));
6037 ret = adsp_err_get_lnx_err_code(
6038 atomic_read(&this_afe.status));
6039 goto fail_cmd;
6040 }
6041
6042fail_cmd:
6043 mutex_unlock(&this_afe.afe_cmd_lock);
6044 return ret;
6045}
6046
6047int q6afe_check_osr_clk_freq(u32 freq)
6048{
6049 int ret = 0;
6050
6051 switch (freq) {
6052 case Q6AFE_LPASS_OSR_CLK_12_P288_MHZ:
6053 case Q6AFE_LPASS_OSR_CLK_8_P192_MHZ:
6054 case Q6AFE_LPASS_OSR_CLK_6_P144_MHZ:
6055 case Q6AFE_LPASS_OSR_CLK_4_P096_MHZ:
6056 case Q6AFE_LPASS_OSR_CLK_3_P072_MHZ:
6057 case Q6AFE_LPASS_OSR_CLK_2_P048_MHZ:
6058 case Q6AFE_LPASS_OSR_CLK_1_P536_MHZ:
6059 case Q6AFE_LPASS_OSR_CLK_1_P024_MHZ:
6060 case Q6AFE_LPASS_OSR_CLK_768_kHZ:
6061 case Q6AFE_LPASS_OSR_CLK_512_kHZ:
6062 break;
6063 default:
6064 pr_err("%s: deafault freq 0x%x\n",
6065 __func__, freq);
6066 ret = -EINVAL;
6067 }
6068 return ret;
6069}
6070
6071int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi)
6072{
6073 int ret = -EINVAL;
6074 int index = 0, port = SLIMBUS_4_TX;
6075
6076 if (!th_vi) {
6077 pr_err("%s: Invalid params\n", __func__);
6078 goto done;
6079 }
6080 if (this_afe.vi_tx_port != -1)
6081 port = this_afe.vi_tx_port;
6082
6083 ret = q6audio_validate_port(port);
6084 if (ret < 0) {
6085 pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret);
6086 goto done;
6087 }
6088 index = q6audio_get_port_index(port);
6089 if (index < 0) {
6090 pr_err("%s: invalid port 0x%x, index %d\n",
6091 __func__, port, index);
6092 ret = -EINVAL;
6093 goto done;
6094 }
6095 th_vi->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
6096 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
6097 th_vi->hdr.pkt_size = sizeof(*th_vi);
6098 th_vi->hdr.src_port = 0;
6099 th_vi->hdr.dest_port = 0;
6100 th_vi->hdr.token = index;
6101 th_vi->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
6102 th_vi->get_param.mem_map_handle = 0;
6103 th_vi->get_param.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI;
6104 th_vi->get_param.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS;
6105 th_vi->get_param.payload_address_lsw = 0;
6106 th_vi->get_param.payload_address_msw = 0;
6107 th_vi->get_param.payload_size = sizeof(*th_vi)
6108 - sizeof(th_vi->get_param) - sizeof(th_vi->hdr);
6109 th_vi->get_param.port_id = q6audio_get_port_id(port);
6110 th_vi->pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI;
6111 th_vi->pdata.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS;
6112 th_vi->pdata.param_size = sizeof(th_vi->param);
6113 atomic_set(&this_afe.status, 0);
6114 atomic_set(&this_afe.state, 1);
6115 ret = apr_send_pkt(this_afe.apr, (uint32_t *)th_vi);
6116 if (ret < 0) {
6117 pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n",
6118 __func__, port, th_vi->get_param.param_id, ret);
6119 goto done;
6120 }
6121 ret = wait_event_timeout(this_afe.wait[index],
6122 (atomic_read(&this_afe.state) == 0),
6123 msecs_to_jiffies(TIMEOUT_MS));
6124 if (!ret) {
6125 pr_err("%s: wait_event timeout\n", __func__);
6126 ret = -EINVAL;
6127 goto done;
6128 }
6129 if (atomic_read(&this_afe.status) > 0) {
6130 pr_err("%s: config cmd failed [%s]\n",
6131 __func__, adsp_err_get_err_str(
6132 atomic_read(&this_afe.status)));
6133 ret = adsp_err_get_lnx_err_code(atomic_read(&this_afe.status));
6134 goto done;
6135 }
6136 memcpy(&th_vi->param, &this_afe.th_vi_resp.param,
6137 sizeof(this_afe.th_vi_resp.param));
6138 pr_debug("%s: DC resistance %d %d temp %d %d status %d %d\n",
6139 __func__, th_vi->param.dc_res_q24[SP_V2_SPKR_1],
6140 th_vi->param.dc_res_q24[SP_V2_SPKR_2],
6141 th_vi->param.temp_q22[SP_V2_SPKR_1],
6142 th_vi->param.temp_q22[SP_V2_SPKR_2],
6143 th_vi->param.status[SP_V2_SPKR_1],
6144 th_vi->param.status[SP_V2_SPKR_2]);
6145 ret = 0;
6146done:
6147 return ret;
6148}
6149
6150int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi)
6151{
6152 int ret = -EINVAL;
6153 int index = 0, port = SLIMBUS_4_TX;
6154
6155 if (!ex_vi) {
6156 pr_err("%s: Invalid params\n", __func__);
6157 goto done;
6158 }
6159 if (this_afe.vi_tx_port != -1)
6160 port = this_afe.vi_tx_port;
6161
6162 ret = q6audio_validate_port(port);
6163 if (ret < 0) {
6164 pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret);
6165 goto done;
6166 }
6167
6168 index = q6audio_get_port_index(port);
6169 if (index < 0) {
6170 pr_err("%s: invalid index %d port 0x%x\n", __func__,
6171 index, port);
6172 ret = -EINVAL;
6173 goto done;
6174 }
6175
6176 ex_vi->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
6177 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
6178 ex_vi->hdr.pkt_size = sizeof(*ex_vi);
6179 ex_vi->hdr.src_port = 0;
6180 ex_vi->hdr.dest_port = 0;
6181 ex_vi->hdr.token = index;
6182 ex_vi->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
6183 ex_vi->get_param.mem_map_handle = 0;
6184 ex_vi->get_param.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI;
6185 ex_vi->get_param.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS;
6186 ex_vi->get_param.payload_address_lsw = 0;
6187 ex_vi->get_param.payload_address_msw = 0;
6188 ex_vi->get_param.payload_size = sizeof(*ex_vi)
6189 - sizeof(ex_vi->get_param) - sizeof(ex_vi->hdr);
6190 ex_vi->get_param.port_id = q6audio_get_port_id(port);
6191 ex_vi->pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI;
6192 ex_vi->pdata.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS;
6193 ex_vi->pdata.param_size = sizeof(ex_vi->param);
6194 atomic_set(&this_afe.status, 0);
6195 atomic_set(&this_afe.state, 1);
6196 ret = apr_send_pkt(this_afe.apr, (uint32_t *)ex_vi);
6197 if (ret < 0) {
6198 pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n",
6199 __func__, port, ex_vi->get_param.param_id, ret);
6200 goto done;
6201 }
6202 ret = wait_event_timeout(this_afe.wait[index],
6203 (atomic_read(&this_afe.state) == 0),
6204 msecs_to_jiffies(TIMEOUT_MS));
6205 if (!ret) {
6206 pr_err("%s: wait_event timeout\n", __func__);
6207 ret = -EINVAL;
6208 goto done;
6209 }
6210 if (atomic_read(&this_afe.status) > 0) {
6211 pr_err("%s: config cmd failed [%s]\n",
6212 __func__, adsp_err_get_err_str(
6213 atomic_read(&this_afe.status)));
6214 ret = adsp_err_get_lnx_err_code(atomic_read(&this_afe.status));
6215 goto done;
6216 }
6217 memcpy(&ex_vi->param, &this_afe.ex_vi_resp.param,
6218 sizeof(this_afe.ex_vi_resp.param));
6219 pr_debug("%s: freq %d %d resistance %d %d qfactor %d %d state %d %d\n",
6220 __func__, ex_vi->param.freq_q20[SP_V2_SPKR_1],
6221 ex_vi->param.freq_q20[SP_V2_SPKR_2],
6222 ex_vi->param.resis_q24[SP_V2_SPKR_1],
6223 ex_vi->param.resis_q24[SP_V2_SPKR_2],
6224 ex_vi->param.qmct_q24[SP_V2_SPKR_1],
6225 ex_vi->param.qmct_q24[SP_V2_SPKR_2],
6226 ex_vi->param.status[SP_V2_SPKR_1],
6227 ex_vi->param.status[SP_V2_SPKR_2]);
6228 ret = 0;
6229done:
6230 return ret;
6231}
6232
6233int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats,
6234 u16 port)
6235{
6236 int ret = -EINVAL;
6237 int index = 0;
6238 struct afe_av_dev_drift_get_param av_dev_drift;
6239
6240 if (!timing_stats) {
6241 pr_err("%s: Invalid params\n", __func__);
6242 goto exit;
6243 }
6244
6245 ret = q6audio_validate_port(port);
6246 if (ret < 0) {
6247 pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret);
6248 ret = -EINVAL;
6249 goto exit;
6250 }
6251
6252 index = q6audio_get_port_index(port);
6253 if (index < 0 || index >= AFE_MAX_PORTS) {
6254 pr_err("%s: Invalid AFE port index[%d]\n",
6255 __func__, index);
6256 ret = -EINVAL;
6257 goto exit;
6258 }
6259
6260 memset(&av_dev_drift, 0, sizeof(struct afe_av_dev_drift_get_param));
6261
6262 av_dev_drift.hdr.hdr_field =
6263 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
6264 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
6265 av_dev_drift.hdr.pkt_size = sizeof(av_dev_drift);
6266 av_dev_drift.hdr.src_port = 0;
6267 av_dev_drift.hdr.dest_port = 0;
6268 av_dev_drift.hdr.token = index;
6269 av_dev_drift.hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
6270 av_dev_drift.get_param.mem_map_handle = 0;
6271 av_dev_drift.get_param.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
6272 av_dev_drift.get_param.param_id = AFE_PARAM_ID_DEV_TIMING_STATS;
6273 av_dev_drift.get_param.payload_address_lsw = 0;
6274 av_dev_drift.get_param.payload_address_msw = 0;
6275 av_dev_drift.get_param.payload_size = sizeof(av_dev_drift)
6276 - sizeof(av_dev_drift.get_param) - sizeof(av_dev_drift.hdr);
6277 av_dev_drift.get_param.port_id = q6audio_get_port_id(port);
6278 av_dev_drift.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
6279 av_dev_drift.pdata.param_id = AFE_PARAM_ID_DEV_TIMING_STATS;
6280 av_dev_drift.pdata.param_size = sizeof(av_dev_drift.timing_stats);
6281 atomic_set(&this_afe.status, 0);
6282 atomic_set(&this_afe.state, 1);
6283 ret = apr_send_pkt(this_afe.apr, (uint32_t *)&av_dev_drift);
6284 if (ret < 0) {
6285 pr_err("%s: get param port 0x%x param id[0x%x] failed %d\n",
6286 __func__, port, av_dev_drift.get_param.param_id, ret);
6287 goto exit;
6288 }
6289
6290 ret = wait_event_timeout(this_afe.wait[index],
6291 (atomic_read(&this_afe.state) == 0),
6292 msecs_to_jiffies(TIMEOUT_MS));
6293 if (!ret) {
6294 pr_err("%s: wait_event timeout\n", __func__);
6295 ret = -EINVAL;
6296 goto exit;
6297 }
6298
6299 if (atomic_read(&this_afe.status) > 0) {
6300 pr_err("%s: config cmd failed [%s]\n",
6301 __func__, adsp_err_get_err_str(
6302 atomic_read(&this_afe.status)));
6303 ret = adsp_err_get_lnx_err_code(
6304 atomic_read(&this_afe.status));
6305 goto exit;
6306 }
6307
6308 memcpy(timing_stats, &this_afe.av_dev_drift_resp.timing_stats,
6309 sizeof(this_afe.av_dev_drift_resp.timing_stats));
6310 ret = 0;
6311exit:
6312 return ret;
6313}
6314
6315int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp)
6316{
6317 int ret = -EINVAL;
6318 int index = 0, port = SLIMBUS_4_TX;
6319
6320 if (!calib_resp) {
6321 pr_err("%s: Invalid params\n", __func__);
6322 goto fail_cmd;
6323 }
6324 if (this_afe.vi_tx_port != -1)
6325 port = this_afe.vi_tx_port;
6326
6327 ret = q6audio_validate_port(port);
6328 if (ret < 0) {
6329 pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret);
6330 ret = -EINVAL;
6331 goto fail_cmd;
6332 }
6333 index = q6audio_get_port_index(port);
6334 if (index < 0 || index >= AFE_MAX_PORTS) {
6335 pr_err("%s: AFE port index[%d] invalid!\n",
6336 __func__, index);
6337 ret = -EINVAL;
6338 goto fail_cmd;
6339 }
6340 calib_resp->hdr.hdr_field =
6341 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
6342 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
6343 calib_resp->hdr.pkt_size = sizeof(*calib_resp);
6344 calib_resp->hdr.src_port = 0;
6345 calib_resp->hdr.dest_port = 0;
6346 calib_resp->hdr.token = index;
6347 calib_resp->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
6348 calib_resp->get_param.mem_map_handle = 0;
6349 calib_resp->get_param.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2;
6350 calib_resp->get_param.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2;
6351 calib_resp->get_param.payload_address_lsw = 0;
6352 calib_resp->get_param.payload_address_msw = 0;
6353 calib_resp->get_param.payload_size = sizeof(*calib_resp)
6354 - sizeof(calib_resp->get_param) - sizeof(calib_resp->hdr);
6355 calib_resp->get_param.port_id = q6audio_get_port_id(port);
6356 calib_resp->pdata.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2;
6357 calib_resp->pdata.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2;
6358 calib_resp->pdata.param_size = sizeof(calib_resp->res_cfg);
6359 atomic_set(&this_afe.status, 0);
6360 atomic_set(&this_afe.state, 1);
6361 ret = apr_send_pkt(this_afe.apr, (uint32_t *)calib_resp);
6362 if (ret < 0) {
6363 pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n",
6364 __func__, port, calib_resp->get_param.param_id, ret);
6365 goto fail_cmd;
6366 }
6367 ret = wait_event_timeout(this_afe.wait[index],
6368 (atomic_read(&this_afe.state) == 0),
6369 msecs_to_jiffies(TIMEOUT_MS));
6370 if (!ret) {
6371 pr_err("%s: wait_event timeout\n", __func__);
6372 ret = -EINVAL;
6373 goto fail_cmd;
6374 }
6375 if (atomic_read(&this_afe.status) > 0) {
6376 pr_err("%s: config cmd failed [%s]\n",
6377 __func__, adsp_err_get_err_str(
6378 atomic_read(&this_afe.status)));
6379 ret = adsp_err_get_lnx_err_code(
6380 atomic_read(&this_afe.status));
6381 goto fail_cmd;
6382 }
6383 memcpy(&calib_resp->res_cfg, &this_afe.calib_data.res_cfg,
6384 sizeof(this_afe.calib_data.res_cfg));
6385 pr_info("%s: state %s resistance %d %d\n", __func__,
6386 fbsp_state[calib_resp->res_cfg.th_vi_ca_state],
6387 calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_1],
6388 calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_2]);
6389 ret = 0;
6390fail_cmd:
6391 return ret;
6392}
6393
6394int afe_spk_prot_feed_back_cfg(int src_port, int dst_port,
6395 int l_ch, int r_ch, u32 enable)
6396{
6397 int ret = -EINVAL;
6398 union afe_spkr_prot_config prot_config;
6399 int index = 0;
6400
6401 if (!enable) {
6402 pr_debug("%s: Disable Feedback tx path", __func__);
6403 this_afe.vi_tx_port = -1;
6404 this_afe.vi_rx_port = -1;
6405 return 0;
6406 }
6407
6408 if ((q6audio_validate_port(src_port) < 0) ||
6409 (q6audio_validate_port(dst_port) < 0)) {
6410 pr_err("%s: invalid ports src 0x%x dst 0x%x",
6411 __func__, src_port, dst_port);
6412 goto fail_cmd;
6413 }
6414 if (!l_ch && !r_ch) {
6415 pr_err("%s: error ch values zero\n", __func__);
6416 goto fail_cmd;
6417 }
6418 pr_debug("%s: src_port 0x%x dst_port 0x%x l_ch %d r_ch %d\n",
6419 __func__, src_port, dst_port, l_ch, r_ch);
6420 memset(&prot_config, 0, sizeof(prot_config));
6421 prot_config.feedback_path_cfg.dst_portid =
6422 q6audio_get_port_id(dst_port);
6423 if (l_ch) {
6424 prot_config.feedback_path_cfg.chan_info[index++] = 1;
6425 prot_config.feedback_path_cfg.chan_info[index++] = 2;
6426 }
6427 if (r_ch) {
6428 prot_config.feedback_path_cfg.chan_info[index++] = 3;
6429 prot_config.feedback_path_cfg.chan_info[index++] = 4;
6430 }
6431 prot_config.feedback_path_cfg.num_channels = index;
6432 pr_debug("%s no of channels: %d\n", __func__, index);
6433 prot_config.feedback_path_cfg.minor_version = 1;
6434 ret = afe_spk_prot_prepare(src_port, dst_port,
6435 AFE_PARAM_ID_FEEDBACK_PATH_CFG, &prot_config);
6436fail_cmd:
6437 return ret;
6438}
6439
6440static int get_cal_type_index(int32_t cal_type)
6441{
6442 int ret = -EINVAL;
6443
6444 switch (cal_type) {
6445 case AFE_COMMON_RX_CAL_TYPE:
6446 ret = AFE_COMMON_RX_CAL;
6447 break;
6448 case AFE_COMMON_TX_CAL_TYPE:
6449 ret = AFE_COMMON_TX_CAL;
6450 break;
6451 case AFE_AANC_CAL_TYPE:
6452 ret = AFE_AANC_CAL;
6453 break;
6454 case AFE_HW_DELAY_CAL_TYPE:
6455 ret = AFE_HW_DELAY_CAL;
6456 break;
6457 case AFE_FB_SPKR_PROT_CAL_TYPE:
6458 ret = AFE_FB_SPKR_PROT_CAL;
6459 break;
6460 case AFE_SIDETONE_CAL_TYPE:
6461 ret = AFE_SIDETONE_CAL;
6462 break;
6463 case AFE_SIDETONE_IIR_CAL_TYPE:
6464 ret = AFE_SIDETONE_IIR_CAL;
6465 break;
6466 case AFE_TOPOLOGY_CAL_TYPE:
6467 ret = AFE_TOPOLOGY_CAL;
6468 break;
6469 case AFE_CUST_TOPOLOGY_CAL_TYPE:
6470 ret = AFE_CUST_TOPOLOGY_CAL;
6471 break;
6472 default:
6473 pr_err("%s: invalid cal type %d!\n", __func__, cal_type);
6474 }
6475 return ret;
6476}
6477
6478int afe_alloc_cal(int32_t cal_type, size_t data_size,
6479 void *data)
6480{
6481 int ret = 0;
6482 int cal_index;
6483
6484 cal_index = get_cal_type_index(cal_type);
6485 pr_debug("%s: cal_type = %d cal_index = %d\n",
6486 __func__, cal_type, cal_index);
6487
6488 if (cal_index < 0) {
6489 pr_err("%s: could not get cal index %d!\n",
6490 __func__, cal_index);
6491 ret = -EINVAL;
6492 goto done;
6493 }
6494
6495 ret = cal_utils_alloc_cal(data_size, data,
6496 this_afe.cal_data[cal_index], 0, NULL);
6497 if (ret < 0) {
6498 pr_err("%s: cal_utils_alloc_block failed, ret = %d, cal type = %d!\n",
6499 __func__, ret, cal_type);
6500 ret = -EINVAL;
6501 goto done;
6502 }
6503done:
6504 return ret;
6505}
6506
6507static int afe_dealloc_cal(int32_t cal_type, size_t data_size,
6508 void *data)
6509{
6510 int ret = 0;
6511 int cal_index;
6512
6513 pr_debug("%s:\n", __func__);
6514
6515 cal_index = get_cal_type_index(cal_type);
6516 if (cal_index < 0) {
6517 pr_err("%s: could not get cal index %d!\n",
6518 __func__, cal_index);
6519 ret = -EINVAL;
6520 goto done;
6521 }
6522
6523 ret = cal_utils_dealloc_cal(data_size, data,
6524 this_afe.cal_data[cal_index]);
6525 if (ret < 0) {
6526 pr_err("%s: cal_utils_dealloc_block failed, ret = %d, cal type = %d!\n",
6527 __func__, ret, cal_type);
6528 ret = -EINVAL;
6529 goto done;
6530 }
6531done:
6532 return ret;
6533}
6534
6535static int afe_set_cal(int32_t cal_type, size_t data_size,
6536 void *data)
6537{
6538 int ret = 0;
6539 int cal_index;
6540
6541 pr_debug("%s:\n", __func__);
6542
6543 cal_index = get_cal_type_index(cal_type);
6544 if (cal_index < 0) {
6545 pr_err("%s: could not get cal index %d!\n",
6546 __func__, cal_index);
6547 ret = -EINVAL;
6548 goto done;
6549 }
6550
6551 ret = cal_utils_set_cal(data_size, data,
6552 this_afe.cal_data[cal_index], 0, NULL);
6553 if (ret < 0) {
6554 pr_err("%s: cal_utils_set_cal failed, ret = %d, cal type = %d!\n",
6555 __func__, ret, cal_type);
6556 ret = -EINVAL;
6557 goto done;
6558 }
6559
6560 if (cal_index == AFE_CUST_TOPOLOGY_CAL) {
6561 mutex_lock(&this_afe.cal_data[AFE_CUST_TOPOLOGY_CAL]->lock);
6562 this_afe.set_custom_topology = 1;
6563 pr_debug("%s:[AFE_CUSTOM_TOPOLOGY] ret = %d, cal type = %d!\n",
6564 __func__, ret, cal_type);
6565 mutex_unlock(&this_afe.cal_data[AFE_CUST_TOPOLOGY_CAL]->lock);
6566 }
6567
6568done:
6569 return ret;
6570}
6571
6572static struct cal_block_data *afe_find_hw_delay_by_path(
6573 struct cal_type_data *cal_type, int path)
6574{
6575 struct list_head *ptr, *next;
6576 struct cal_block_data *cal_block = NULL;
6577
6578 pr_debug("%s:\n", __func__);
6579
6580 list_for_each_safe(ptr, next,
6581 &cal_type->cal_blocks) {
6582
6583 cal_block = list_entry(ptr,
6584 struct cal_block_data, list);
6585
6586 if (((struct audio_cal_info_hw_delay *)cal_block->cal_info)
6587 ->path == path) {
6588 return cal_block;
6589 }
6590 }
6591 return NULL;
6592}
6593
6594static int afe_get_cal_hw_delay(int32_t path,
6595 struct audio_cal_hw_delay_entry *entry)
6596{
6597 int ret = 0;
6598 int i;
6599 struct cal_block_data *cal_block = NULL;
6600 struct audio_cal_hw_delay_data *hw_delay_info = NULL;
6601
6602 pr_debug("%s:\n", __func__);
6603
6604 if (this_afe.cal_data[AFE_HW_DELAY_CAL] == NULL) {
6605 pr_err("%s: AFE_HW_DELAY_CAL not initialized\n", __func__);
6606 ret = -EINVAL;
6607 goto done;
6608 }
6609 if (entry == NULL) {
6610 pr_err("%s: entry is NULL\n", __func__);
6611 ret = -EINVAL;
6612 goto done;
6613 }
6614 if ((path >= MAX_PATH_TYPE) || (path < 0)) {
6615 pr_err("%s: bad path: %d\n",
6616 __func__, path);
6617 ret = -EINVAL;
6618 goto done;
6619 }
6620
6621 mutex_lock(&this_afe.cal_data[AFE_HW_DELAY_CAL]->lock);
6622 cal_block = afe_find_hw_delay_by_path(
6623 this_afe.cal_data[AFE_HW_DELAY_CAL], path);
6624 if (cal_block == NULL)
6625 goto unlock;
6626
6627 hw_delay_info = &((struct audio_cal_info_hw_delay *)
6628 cal_block->cal_info)->data;
6629 if (hw_delay_info->num_entries > MAX_HW_DELAY_ENTRIES) {
6630 pr_err("%s: invalid num entries: %d\n",
6631 __func__, hw_delay_info->num_entries);
6632 ret = -EINVAL;
6633 goto unlock;
6634 }
6635
6636 for (i = 0; i < hw_delay_info->num_entries; i++) {
6637 if (hw_delay_info->entry[i].sample_rate ==
6638 entry->sample_rate) {
6639 entry->delay_usec = hw_delay_info->entry[i].delay_usec;
6640 break;
6641 }
6642 }
6643 if (i == hw_delay_info->num_entries) {
6644 pr_err("%s: Unable to find delay for sample rate %d\n",
6645 __func__, entry->sample_rate);
6646 ret = -EFAULT;
6647 goto unlock;
6648 }
6649 pr_debug("%s: Path = %d samplerate = %u usec = %u status %d\n",
6650 __func__, path, entry->sample_rate, entry->delay_usec, ret);
6651unlock:
6652 mutex_unlock(&this_afe.cal_data[AFE_HW_DELAY_CAL]->lock);
6653done:
6654 return ret;
6655}
6656
6657static int afe_set_cal_sp_th_vi_ftm_cfg(int32_t cal_type, size_t data_size,
6658 void *data)
6659{
6660 int ret = 0;
6661 struct audio_cal_type_sp_th_vi_ftm_cfg *cal_data = data;
6662
6663 if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL ||
6664 cal_data == NULL ||
6665 data_size != sizeof(*cal_data))
6666 goto done;
6667
6668 pr_debug("%s: cal_type = %d\n", __func__, cal_type);
6669 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
6670 memcpy(&this_afe.th_ftm_cfg, &cal_data->cal_info,
6671 sizeof(this_afe.th_ftm_cfg));
6672 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
6673done:
6674 return ret;
6675}
6676
6677static int afe_set_cal_sp_ex_vi_ftm_cfg(int32_t cal_type, size_t data_size,
6678 void *data)
6679{
6680 int ret = 0;
6681 struct audio_cal_type_sp_ex_vi_ftm_cfg *cal_data = data;
6682
6683 if (this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL ||
6684 cal_data == NULL ||
6685 data_size != sizeof(*cal_data))
6686 goto done;
6687
6688 pr_debug("%s: cal_type = %d\n", __func__, cal_type);
6689 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
6690 memcpy(&this_afe.ex_ftm_cfg, &cal_data->cal_info,
6691 sizeof(this_afe.ex_ftm_cfg));
6692 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
6693done:
6694 return ret;
6695}
6696
6697static int afe_set_cal_fb_spkr_prot(int32_t cal_type, size_t data_size,
6698 void *data)
6699{
6700 int ret = 0;
6701 struct audio_cal_type_fb_spk_prot_cfg *cal_data = data;
6702
6703 pr_debug("%s:\n", __func__);
6704
6705 if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL)
6706 goto done;
6707 if (cal_data == NULL)
6708 goto done;
6709 if (data_size != sizeof(*cal_data))
6710 goto done;
6711
6712 if (cal_data->cal_info.mode == MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS)
6713 __pm_wakeup_event(&wl.ws, jiffies_to_msecs(WAKELOCK_TIMEOUT));
6714 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
6715 memcpy(&this_afe.prot_cfg, &cal_data->cal_info,
6716 sizeof(this_afe.prot_cfg));
6717 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
6718done:
6719 return ret;
6720}
6721
6722static int afe_get_cal_sp_th_vi_ftm_param(int32_t cal_type, size_t data_size,
6723 void *data)
6724{
6725 int i, ret = 0;
6726 struct audio_cal_type_sp_th_vi_param *cal_data = data;
6727 struct afe_sp_th_vi_get_param th_vi;
6728
6729 pr_debug("%s: cal_type = %d\n", __func__, cal_type);
6730 if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL ||
6731 cal_data == NULL ||
6732 data_size != sizeof(*cal_data))
6733 goto done;
6734
6735 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
6736 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
6737 cal_data->cal_info.status[i] = -EINVAL;
6738 cal_data->cal_info.r_dc_q24[i] = -1;
6739 cal_data->cal_info.temp_q22[i] = -1;
6740 }
6741 if (!afe_get_sp_th_vi_ftm_data(&th_vi)) {
6742 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
6743 pr_debug("%s: ftm param status = %d\n",
6744 __func__, th_vi.param.status[i]);
6745 if (th_vi.param.status[i] == FBSP_IN_PROGRESS) {
6746 cal_data->cal_info.status[i] = -EAGAIN;
6747 } else if (th_vi.param.status[i] == FBSP_SUCCESS) {
6748 cal_data->cal_info.status[i] = 0;
6749 cal_data->cal_info.r_dc_q24[i] =
6750 th_vi.param.dc_res_q24[i];
6751 cal_data->cal_info.temp_q22[i] =
6752 th_vi.param.temp_q22[i];
6753 }
6754 }
6755 }
6756 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
6757done:
6758 return ret;
6759}
6760
6761static int afe_get_cal_sp_ex_vi_ftm_param(int32_t cal_type, size_t data_size,
6762 void *data)
6763{
6764 int i, ret = 0;
6765 struct audio_cal_type_sp_ex_vi_param *cal_data = data;
6766 struct afe_sp_ex_vi_get_param ex_vi;
6767
6768 pr_debug("%s: cal_type = %d\n", __func__, cal_type);
6769 if (this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL ||
6770 cal_data == NULL ||
6771 data_size != sizeof(*cal_data))
6772 goto done;
6773
6774 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
6775 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
6776 cal_data->cal_info.status[i] = -EINVAL;
6777 cal_data->cal_info.freq_q20[i] = -1;
6778 cal_data->cal_info.resis_q24[i] = -1;
6779 cal_data->cal_info.qmct_q24[i] = -1;
6780 }
6781 if (!afe_get_sp_ex_vi_ftm_data(&ex_vi)) {
6782 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
6783 pr_debug("%s: ftm param status = %d\n",
6784 __func__, ex_vi.param.status[i]);
6785 if (ex_vi.param.status[i] == FBSP_IN_PROGRESS) {
6786 cal_data->cal_info.status[i] = -EAGAIN;
6787 } else if (ex_vi.param.status[i] == FBSP_SUCCESS) {
6788 cal_data->cal_info.status[i] = 0;
6789 cal_data->cal_info.freq_q20[i] =
6790 ex_vi.param.freq_q20[i];
6791 cal_data->cal_info.resis_q24[i] =
6792 ex_vi.param.resis_q24[i];
6793 cal_data->cal_info.qmct_q24[i] =
6794 ex_vi.param.qmct_q24[i];
6795 }
6796 }
6797 }
6798 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
6799done:
6800 return ret;
6801}
6802
6803static int afe_get_cal_fb_spkr_prot(int32_t cal_type, size_t data_size,
6804 void *data)
6805{
6806 int ret = 0;
6807 struct audio_cal_type_fb_spk_prot_status *cal_data = data;
6808 struct afe_spkr_prot_get_vi_calib calib_resp;
6809
6810 pr_debug("%s:\n", __func__);
6811
6812 if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL)
6813 goto done;
6814 if (cal_data == NULL)
6815 goto done;
6816 if (data_size != sizeof(*cal_data))
6817 goto done;
6818
6819 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
6820 if (this_afe.prot_cfg.mode == MSM_SPKR_PROT_CALIBRATED) {
6821 cal_data->cal_info.r0[SP_V2_SPKR_1] =
6822 this_afe.prot_cfg.r0[SP_V2_SPKR_1];
6823 cal_data->cal_info.r0[SP_V2_SPKR_2] =
6824 this_afe.prot_cfg.r0[SP_V2_SPKR_2];
6825 cal_data->cal_info.status = 0;
6826 } else if (this_afe.prot_cfg.mode ==
6827 MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) {
6828 /*Call AFE to query the status*/
6829 cal_data->cal_info.status = -EINVAL;
6830 cal_data->cal_info.r0[SP_V2_SPKR_1] = -1;
6831 cal_data->cal_info.r0[SP_V2_SPKR_2] = -1;
6832 if (!afe_spk_prot_get_calib_data(&calib_resp)) {
6833 if (calib_resp.res_cfg.th_vi_ca_state ==
6834 FBSP_IN_PROGRESS)
6835 cal_data->cal_info.status = -EAGAIN;
6836 else if (calib_resp.res_cfg.th_vi_ca_state ==
6837 FBSP_SUCCESS) {
6838 cal_data->cal_info.status = 0;
6839 cal_data->cal_info.r0[SP_V2_SPKR_1] =
6840 calib_resp.res_cfg.r0_cali_q24[SP_V2_SPKR_1];
6841 cal_data->cal_info.r0[SP_V2_SPKR_2] =
6842 calib_resp.res_cfg.r0_cali_q24[SP_V2_SPKR_2];
6843 }
6844 }
6845 if (!cal_data->cal_info.status) {
6846 this_afe.prot_cfg.mode =
6847 MSM_SPKR_PROT_CALIBRATED;
6848 this_afe.prot_cfg.r0[SP_V2_SPKR_1] =
6849 cal_data->cal_info.r0[SP_V2_SPKR_1];
6850 this_afe.prot_cfg.r0[SP_V2_SPKR_2] =
6851 cal_data->cal_info.r0[SP_V2_SPKR_2];
6852 }
6853 } else {
6854 /*Indicates calibration data is invalid*/
6855 cal_data->cal_info.status = -EINVAL;
6856 cal_data->cal_info.r0[SP_V2_SPKR_1] = -1;
6857 cal_data->cal_info.r0[SP_V2_SPKR_2] = -1;
6858 }
6859 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
6860 __pm_relax(&wl.ws);
6861done:
6862 return ret;
6863}
6864
6865static int afe_map_cal_data(int32_t cal_type,
6866 struct cal_block_data *cal_block)
6867{
6868 int ret = 0;
6869 int cal_index;
6870
6871 pr_debug("%s:\n", __func__);
6872
6873 cal_index = get_cal_type_index(cal_type);
6874 if (cal_index < 0) {
6875 pr_err("%s: could not get cal index %d!\n",
6876 __func__, cal_index);
6877 ret = -EINVAL;
6878 goto done;
6879 }
6880
6881
6882 mutex_lock(&this_afe.afe_cmd_lock);
6883 atomic_set(&this_afe.mem_map_cal_index, cal_index);
6884 ret = afe_cmd_memory_map(cal_block->cal_data.paddr,
6885 cal_block->map_data.map_size);
6886 atomic_set(&this_afe.mem_map_cal_index, -1);
6887 if (ret < 0) {
6888 pr_err("%s: mmap did not work! size = %zd ret %d\n",
6889 __func__,
6890 cal_block->map_data.map_size, ret);
6891 pr_debug("%s: mmap did not work! addr = 0x%pK, size = %zd\n",
6892 __func__,
6893 &cal_block->cal_data.paddr,
6894 cal_block->map_data.map_size);
6895 mutex_unlock(&this_afe.afe_cmd_lock);
6896 goto done;
6897 }
6898 cal_block->map_data.q6map_handle = atomic_read(&this_afe.
6899 mem_map_cal_handles[cal_index]);
6900 mutex_unlock(&this_afe.afe_cmd_lock);
6901done:
6902 return ret;
6903}
6904
6905static int afe_unmap_cal_data(int32_t cal_type,
6906 struct cal_block_data *cal_block)
6907{
6908 int ret = 0;
6909 int cal_index;
6910
6911 pr_debug("%s:\n", __func__);
6912
6913 cal_index = get_cal_type_index(cal_type);
6914 if (cal_index < 0) {
6915 pr_err("%s: could not get cal index %d!\n",
6916 __func__, cal_index);
6917 ret = -EINVAL;
6918 goto done;
6919 }
6920
6921 if (cal_block == NULL) {
6922 pr_err("%s: Cal block is NULL!\n",
6923 __func__);
6924 goto done;
6925 }
6926
6927 if (cal_block->map_data.q6map_handle == 0) {
6928 pr_err("%s: Map handle is NULL, nothing to unmap\n",
6929 __func__);
6930 goto done;
6931 }
6932
6933 atomic_set(&this_afe.mem_map_cal_handles[cal_index],
6934 cal_block->map_data.q6map_handle);
6935 atomic_set(&this_afe.mem_map_cal_index, cal_index);
6936 ret = afe_cmd_memory_unmap_nowait(
6937 cal_block->map_data.q6map_handle);
6938 atomic_set(&this_afe.mem_map_cal_index, -1);
6939 if (ret < 0) {
6940 pr_err("%s: unmap did not work! cal_type %i ret %d\n",
6941 __func__, cal_index, ret);
6942 }
6943 cal_block->map_data.q6map_handle = 0;
6944done:
6945 return ret;
6946}
6947
6948static void afe_delete_cal_data(void)
6949{
6950 pr_debug("%s:\n", __func__);
6951
6952 cal_utils_destroy_cal_types(MAX_AFE_CAL_TYPES, this_afe.cal_data);
6953}
6954
6955static int afe_init_cal_data(void)
6956{
6957 int ret = 0;
6958 struct cal_type_info cal_type_info[] = {
6959 {{AFE_COMMON_RX_CAL_TYPE,
6960 {afe_alloc_cal, afe_dealloc_cal, NULL,
6961 afe_set_cal, NULL, NULL} },
6962 {afe_map_cal_data, afe_unmap_cal_data,
6963 cal_utils_match_buf_num} },
6964
6965 {{AFE_COMMON_TX_CAL_TYPE,
6966 {afe_alloc_cal, afe_dealloc_cal, NULL,
6967 afe_set_cal, NULL, NULL} },
6968 {afe_map_cal_data, afe_unmap_cal_data,
6969 cal_utils_match_buf_num} },
6970
6971 {{AFE_AANC_CAL_TYPE,
6972 {afe_alloc_cal, afe_dealloc_cal, NULL,
6973 afe_set_cal, NULL, NULL} },
6974 {afe_map_cal_data, afe_unmap_cal_data,
6975 cal_utils_match_buf_num} },
6976
6977 {{AFE_FB_SPKR_PROT_CAL_TYPE,
6978 {NULL, NULL, NULL, afe_set_cal_fb_spkr_prot,
6979 afe_get_cal_fb_spkr_prot, NULL} },
6980 {NULL, NULL, cal_utils_match_buf_num} },
6981
6982 {{AFE_HW_DELAY_CAL_TYPE,
6983 {NULL, NULL, NULL,
6984 afe_set_cal, NULL, NULL} },
6985 {NULL, NULL, cal_utils_match_buf_num} },
6986
6987 {{AFE_SIDETONE_CAL_TYPE,
6988 {NULL, NULL, NULL,
6989 afe_set_cal, NULL, NULL} },
6990 {NULL, NULL, cal_utils_match_buf_num} },
6991
6992 {{AFE_SIDETONE_IIR_CAL_TYPE,
6993 {NULL, NULL, NULL,
6994 afe_set_cal, NULL, NULL} },
6995 {NULL, NULL, cal_utils_match_buf_num} },
6996
6997 {{AFE_TOPOLOGY_CAL_TYPE,
6998 {NULL, NULL, NULL,
6999 afe_set_cal, NULL, NULL} },
7000 {NULL, NULL,
7001 cal_utils_match_buf_num} },
7002
7003 {{AFE_CUST_TOPOLOGY_CAL_TYPE,
7004 {afe_alloc_cal, afe_dealloc_cal, NULL,
7005 afe_set_cal, NULL, NULL} },
7006 {afe_map_cal_data, afe_unmap_cal_data,
7007 cal_utils_match_buf_num} },
7008
7009 {{AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE,
7010 {NULL, NULL, NULL, afe_set_cal_sp_th_vi_ftm_cfg,
7011 afe_get_cal_sp_th_vi_ftm_param, NULL} },
7012 {NULL, NULL, cal_utils_match_buf_num} },
7013
7014 {{AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE,
7015 {NULL, NULL, NULL, afe_set_cal_sp_ex_vi_ftm_cfg,
7016 afe_get_cal_sp_ex_vi_ftm_param, NULL} },
7017 {NULL, NULL, cal_utils_match_buf_num} },
7018 };
7019 pr_debug("%s:\n", __func__);
7020
7021 ret = cal_utils_create_cal_types(MAX_AFE_CAL_TYPES, this_afe.cal_data,
7022 cal_type_info);
7023 if (ret < 0) {
7024 pr_err("%s: could not create cal type! %d\n",
7025 __func__, ret);
7026 ret = -EINVAL;
7027 goto err;
7028 }
7029
7030 return ret;
7031err:
7032 afe_delete_cal_data();
7033 return ret;
7034}
7035
7036int afe_map_rtac_block(struct rtac_cal_block_data *cal_block)
7037{
7038 int result = 0;
7039
7040 pr_debug("%s:\n", __func__);
7041
7042 if (cal_block == NULL) {
7043 pr_err("%s: cal_block is NULL!\n",
7044 __func__);
7045 result = -EINVAL;
7046 goto done;
7047 }
7048
7049 if (cal_block->cal_data.paddr == 0) {
7050 pr_debug("%s: No address to map!\n",
7051 __func__);
7052 result = -EINVAL;
7053 goto done;
7054 }
7055
7056 if (cal_block->map_data.map_size == 0) {
7057 pr_debug("%s: map size is 0!\n",
7058 __func__);
7059 result = -EINVAL;
7060 goto done;
7061 }
7062
7063 result = afe_cmd_memory_map(cal_block->cal_data.paddr,
7064 cal_block->map_data.map_size);
7065 if (result < 0) {
7066 pr_err("%s: afe_cmd_memory_map failed for addr = 0x%pK, size = %d, err %d\n",
7067 __func__, &cal_block->cal_data.paddr,
7068 cal_block->map_data.map_size, result);
7069 return result;
7070 }
7071 cal_block->map_data.map_handle = this_afe.mmap_handle;
7072
7073done:
7074 return result;
7075}
7076
7077int afe_unmap_rtac_block(uint32_t *mem_map_handle)
7078{
7079 int result = 0;
7080
7081 pr_debug("%s:\n", __func__);
7082
7083 if (mem_map_handle == NULL) {
7084 pr_err("%s: Map handle is NULL, nothing to unmap\n",
7085 __func__);
7086 goto done;
7087 }
7088
7089 if (*mem_map_handle == 0) {
7090 pr_debug("%s: Map handle is 0, nothing to unmap\n",
7091 __func__);
7092 goto done;
7093 }
7094
7095 result = afe_cmd_memory_unmap(*mem_map_handle);
7096 if (result) {
7097 pr_err("%s: AFE memory unmap failed %d, handle 0x%x\n",
7098 __func__, result, *mem_map_handle);
7099 goto done;
7100 } else {
7101 *mem_map_handle = 0;
7102 }
7103
7104done:
7105 return result;
7106}
7107
7108static int __init afe_init(void)
7109{
7110 int i = 0, ret;
7111
7112 atomic_set(&this_afe.state, 0);
7113 atomic_set(&this_afe.status, 0);
7114 atomic_set(&this_afe.mem_map_cal_index, -1);
7115 this_afe.apr = NULL;
7116 this_afe.dtmf_gen_rx_portid = -1;
7117 this_afe.mmap_handle = 0;
7118 this_afe.vi_tx_port = -1;
7119 this_afe.vi_rx_port = -1;
7120 this_afe.prot_cfg.mode = MSM_SPKR_PROT_DISABLED;
7121 this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED;
7122 this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED;
7123 mutex_init(&this_afe.afe_cmd_lock);
7124 for (i = 0; i < AFE_MAX_PORTS; i++) {
7125 this_afe.afe_cal_mode[i] = AFE_CAL_MODE_DEFAULT;
7126 this_afe.afe_sample_rates[i] = 0;
7127 this_afe.dev_acdb_id[i] = 0;
7128 init_waitqueue_head(&this_afe.wait[i]);
7129 }
7130 wakeup_source_init(&wl.ws, "spkr-prot");
7131 ret = afe_init_cal_data();
7132 if (ret)
7133 pr_err("%s: could not init cal data! %d\n", __func__, ret);
7134
7135 config_debug_fs_init();
7136 return 0;
7137}
7138
7139static void __exit afe_exit(void)
7140{
7141 afe_delete_cal_data();
7142
7143 config_debug_fs_exit();
7144 mutex_destroy(&this_afe.afe_cmd_lock);
7145 wakeup_source_trash(&wl.ws);
7146}
7147
7148device_initcall(afe_init);
7149__exitcall(afe_exit);