blob: d05936adec71be3349a0e65a7c57f2244dee76c9 [file] [log] [blame]
Meng Wang688a8672019-01-29 13:43:33 +08001// SPDX-License-Identifier: GPL-2.0-only
Aditya Bavanari1c53d882020-02-13 11:14:58 +05302/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303 */
4#include <linux/slab.h>
5#include <linux/debugfs.h>
6#include <linux/kernel.h>
7#include <linux/kthread.h>
8#include <linux/uaccess.h>
9#include <linux/wait.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010#include <linux/jiffies.h>
11#include <linux/sched.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012#include <linux/delay.h>
Meng Wang9524bda2020-03-09 08:37:53 +080013#include <linux/version.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053014#include <dsp/msm_audio_ion.h>
15#include <dsp/apr_audio-v2.h>
16#include <dsp/audio_cal_utils.h>
17#include <dsp/q6afe-v2.h>
18#include <dsp/q6audio-v2.h>
Vignesh Kulothungan85073c02018-01-26 10:27:56 -080019#include <dsp/q6common.h>
Vignesh Kulothunganc3f38982018-05-22 18:08:20 -070020#include <dsp/q6core.h>
Vidyakumar Athota94bd8732018-02-28 17:13:35 -080021#include <dsp/msm-audio-event-notify.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053022#include <ipc/apr_tal.h>
23#include "adsp_err.h"
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +053024#include "q6afecal-hwdep.h"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053025
26#define WAKELOCK_TIMEOUT 5000
Meng Wang9eacb962019-11-19 09:16:55 +080027#define AFE_CLK_TOKEN 1024
Harshal Ahire10e83842020-03-27 04:37:23 +053028
Vangala, Amarnathe1815842020-07-14 03:39:52 +053029#define SP_V4_NUM_MAX_SPKRS SP_V2_NUM_MAX_SPKRS
Soumya Managoliadeb3312020-11-27 15:43:55 +053030#define MAX_LSM_SESSIONS 8
Vangala, Amarnathe1815842020-07-14 03:39:52 +053031
Harshal Ahire10e83842020-03-27 04:37:23 +053032struct afe_avcs_payload_port_mapping {
33 u16 port_id;
34 struct avcs_load_unload_modules_payload *payload;
35} __packed;
36
37enum {
38 ENCODER_CASE,
39 DECODER_CASE,
40 /* Add new use case here */
41 MAX_ALLOWED_USE_CASES
42};
43
44static struct afe_avcs_payload_port_mapping *pm[MAX_ALLOWED_USE_CASES];
45
lintaopei746b0122021-03-16 19:35:42 +080046#ifdef CONFIG_SND_SMARTPA_AW882XX
47#include <sound/aw882xx_afe.h>
48#define AFE_MODULE_ID_AWDSP_TX (0x10013D00)
49#define AFE_MODULE_ID_AWDSP_RX (0x10013D01)
50#define AFE_PARAM_ID_AWDSP_RX_SET_ENABLE (0x10013D11)
51#define AFE_PARAM_ID_AWDSP_TX_SET_ENABLE (0x10013D13)
52#define AFE_PARAM_ID_AWDSP_RX_PARAMS (0x10013D12)
53#define AFE_PORT_ID_AWDSP_RX (AFE_PORT_ID_QUINARY_MI2S_RX)
54#define AFE_PORT_ID_AWDSP_TX (AFE_PORT_ID_QUINARY_MI2S_TX)
55#endif /* #ifdef CONFIG_SND_SMARTPA_AW882XX */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053056enum {
57 AFE_COMMON_RX_CAL = 0,
58 AFE_COMMON_TX_CAL,
Aditya Bavanari3889b4a2017-11-21 19:52:26 +053059 AFE_LSM_TX_CAL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053060 AFE_AANC_CAL,
61 AFE_FB_SPKR_PROT_CAL,
62 AFE_HW_DELAY_CAL,
63 AFE_SIDETONE_CAL,
64 AFE_SIDETONE_IIR_CAL,
65 AFE_TOPOLOGY_CAL,
Aditya Bavanari3889b4a2017-11-21 19:52:26 +053066 AFE_LSM_TOPOLOGY_CAL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053067 AFE_CUST_TOPOLOGY_CAL,
68 AFE_FB_SPKR_PROT_TH_VI_CAL,
69 AFE_FB_SPKR_PROT_EX_VI_CAL,
Vangala, Amarnath78732302020-04-09 03:57:14 +053070 AFE_FB_SPKR_PROT_V4_EX_VI_CAL,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053071 MAX_AFE_CAL_TYPES
72};
73
74enum fbsp_state {
75 FBSP_INCORRECT_OP_MODE,
76 FBSP_INACTIVE,
77 FBSP_WARMUP,
78 FBSP_IN_PROGRESS,
79 FBSP_SUCCESS,
80 FBSP_FAILED,
81 MAX_FBSP_STATE
82};
83
84static char fbsp_state[MAX_FBSP_STATE][50] = {
85 [FBSP_INCORRECT_OP_MODE] = "incorrect operation mode",
86 [FBSP_INACTIVE] = "port not started",
87 [FBSP_WARMUP] = "waiting for warmup",
88 [FBSP_IN_PROGRESS] = "in progress state",
89 [FBSP_SUCCESS] = "success",
90 [FBSP_FAILED] = "failed"
91};
92
Laxminath Kasam2e13d952019-02-20 15:05:39 +053093enum v_vali_state {
94 V_VALI_FAILED,
95 V_VALI_SUCCESS,
96 V_VALI_INCORRECT_OP_MODE,
97 V_VALI_INACTIVE,
98 V_VALI_WARMUP,
99 V_VALI_IN_PROGRESS,
100 MAX_V_VALI_STATE
101};
102
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530103enum {
104 USE_CALIBRATED_R0TO,
105 USE_SAFE_R0TO
106};
107
108enum {
109 QUICK_CALIB_DISABLE,
110 QUICK_CALIB_ENABLE
111};
112
113enum {
114 Q6AFE_MSM_SPKR_PROCESSING = 0,
115 Q6AFE_MSM_SPKR_CALIBRATION,
Laxminath Kasam2e13d952019-02-20 15:05:39 +0530116 Q6AFE_MSM_SPKR_FTM_MODE,
117 Q6AFE_MSM_SPKR_V_VALI_MODE
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530118};
119
Chaithanya Krishna Bacharaju4a466532019-01-21 10:59:51 +0530120enum {
121 APTX_AD_48 = 0,
122 APTX_AD_44_1 = 1
123};
124
Zhou Songcaa541d2019-02-19 18:37:47 +0800125enum {
126 AFE_MATCHED_PORT_DISABLE,
127 AFE_MATCHED_PORT_ENABLE
128};
129
Vangala, Amarnath78732302020-04-09 03:57:14 +0530130enum {
131 AFE_FBSP_V4_EX_VI_MODE_NORMAL = 0,
132 AFE_FBSP_V4_EX_VI_MODE_FTM = 1
133};
134
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530135struct wlock {
Meng Wang9524bda2020-03-09 08:37:53 +0800136 struct wakeup_source *ws;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530137};
138
139static struct wlock wl;
140
Vangala, Amarnathe1815842020-07-14 03:39:52 +0530141struct afe_sp_v4_th_vi_ftm_get_param_resp {
142 struct afe_sp_v4_gen_get_param_resp gen_resp;
143 int32_t num_ch;
144 /* Number of channels for Rx signal.
145 */
146
147 struct afe_sp_v4_channel_ftm_params
148 ch_ftm_params[SP_V4_NUM_MAX_SPKRS];
149} __packed;
150
151struct afe_sp_v4_v_vali_get_param_resp {
152 struct afe_sp_v4_gen_get_param_resp gen_resp;
153 int32_t num_ch;
154 /* Number of channels for Rx signal.
155 */
156
157 struct afe_sp_v4_channel_v_vali_params
158 ch_v_vali_params[SP_V4_NUM_MAX_SPKRS];
159} __packed;
160
161struct afe_sp_v4_ex_vi_ftm_get_param_resp {
162 struct afe_sp_v4_gen_get_param_resp gen_resp;
163 int32_t num_ch;
164 /* Number of channels for Rx signal.
165 */
166
167 struct afe_sp_v4_channel_ex_vi_ftm_params
168 ch_ex_vi_ftm_params[SP_V4_NUM_MAX_SPKRS];
169} __packed;
170
171struct afe_sp_v4_max_log_get_param_resp {
172 struct afe_sp_v4_gen_get_param_resp gen_resp;
173 int32_t num_ch;
174 /* Number of channels for Rx signal.
175 */
176
177 struct afe_sp_v4_channel_tmax_xmax_params
178 ch_max_params[SP_V4_NUM_MAX_SPKRS];
179} __packed;
180
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530181struct afe_ctl {
182 void *apr;
183 atomic_t state;
184 atomic_t status;
Meng Wang9eacb962019-11-19 09:16:55 +0800185 atomic_t clk_state;
186 atomic_t clk_status;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530187 wait_queue_head_t wait[AFE_MAX_PORTS];
Ramprasad Katkam250075f2018-08-31 03:31:54 +0530188 wait_queue_head_t wait_wakeup;
Meng Wang9eacb962019-11-19 09:16:55 +0800189 wait_queue_head_t clk_wait;
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +0530190 struct task_struct *task;
191 wait_queue_head_t lpass_core_hw_wait;
Laxminath Kasam688db8a2019-11-05 13:11:30 +0530192 uint32_t lpass_hw_core_client_hdl[AFE_LPASS_CORE_HW_VOTE_MAX];
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530193 void (*tx_cb)(uint32_t opcode,
194 uint32_t token, uint32_t *payload, void *priv);
195 void (*rx_cb)(uint32_t opcode,
196 uint32_t token, uint32_t *payload, void *priv);
197 void *tx_private_data;
198 void *rx_private_data;
199 uint32_t mmap_handle;
200
Ralf Herzcc29b9e2018-07-17 20:19:04 +0530201 void (*pri_spdif_tx_cb)(uint32_t opcode,
202 uint32_t token, uint32_t *payload, void *priv);
203 void (*sec_spdif_tx_cb)(uint32_t opcode,
204 uint32_t token, uint32_t *payload, void *priv);
205 void *pri_spdif_tx_private_data;
206 void *sec_spdif_tx_private_data;
Ralf Herz044e4762018-09-10 11:04:16 +0200207 int pri_spdif_config_change;
208 int sec_spdif_config_change;
209 struct work_struct afe_spdif_work;
Ralf Herzcc29b9e2018-07-17 20:19:04 +0530210
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530211 int topology[AFE_MAX_PORTS];
212 struct cal_type_data *cal_data[MAX_AFE_CAL_TYPES];
213
214 atomic_t mem_map_cal_handles[MAX_AFE_CAL_TYPES];
215 atomic_t mem_map_cal_index;
216 u32 afe_cal_mode[AFE_MAX_PORTS];
217
218 u16 dtmf_gen_rx_portid;
219 struct audio_cal_info_spk_prot_cfg prot_cfg;
220 struct afe_spkr_prot_calib_get_resp calib_data;
221 struct audio_cal_info_sp_th_vi_ftm_cfg th_ftm_cfg;
Laxminath Kasam2e13d952019-02-20 15:05:39 +0530222 struct audio_cal_info_sp_th_vi_v_vali_cfg v_vali_cfg;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530223 struct audio_cal_info_sp_ex_vi_ftm_cfg ex_ftm_cfg;
224 struct afe_sp_th_vi_get_param_resp th_vi_resp;
Laxminath Kasam2e13d952019-02-20 15:05:39 +0530225 struct afe_sp_th_vi_v_vali_get_param_resp th_vi_v_vali_resp;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530226 struct afe_sp_ex_vi_get_param_resp ex_vi_resp;
Aditya Bavanari740b4832018-12-24 18:46:12 +0530227 struct afe_sp_rx_tmax_xmax_logging_resp xt_logging_resp;
Vangala, Amarnath78732302020-04-09 03:57:14 +0530228 struct afe_sp_v4_th_vi_calib_resp spv4_calib_data;
229 struct afe_sp_v4_param_vi_channel_map_cfg v4_ch_map_cfg;
Vangala, Amarnathe1815842020-07-14 03:39:52 +0530230 struct afe_sp_v4_th_vi_ftm_get_param_resp spv4_th_vi_ftm_resp;
231 uint32_t spv4_th_vi_ftm_rcvd_param_size;
232 struct afe_sp_v4_v_vali_get_param_resp spv4_v_vali_resp;
233 uint32_t spv4_v_vali_rcvd_param_size;
234 struct afe_sp_v4_ex_vi_ftm_get_param_resp spv4_ex_vi_ftm_resp;
235 uint32_t spv4_ex_vi_ftm_rcvd_param_size;
236 struct afe_sp_v4_max_log_get_param_resp spv4_max_log_resp;
237 uint32_t spv4_max_log_rcvd_param_size;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530238 struct afe_av_dev_drift_get_param_resp av_dev_drift_resp;
Chaithanya Krishna Bacharaju8c6a1842018-11-16 15:02:39 +0530239 struct afe_doa_tracking_mon_get_param_resp doa_tracking_mon_resp;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530240 int vi_tx_port;
241 int vi_rx_port;
242 uint32_t afe_sample_rates[AFE_MAX_PORTS];
243 struct aanc_data aanc_info;
244 struct mutex afe_cmd_lock;
Aditya Bavanarid6546e32019-10-29 17:24:59 +0530245 struct mutex afe_apr_lock;
Meng Wang9eacb962019-11-19 09:16:55 +0800246 struct mutex afe_clk_lock;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530247 int set_custom_topology;
248 int dev_acdb_id[AFE_MAX_PORTS];
249 routing_cb rt_cb;
Vignesh Kulothunganc3f38982018-05-22 18:08:20 -0700250 struct audio_uevent_data *uevent_data;
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +0530251 /* cal info for AFE */
252 struct afe_fw_info *fw_data;
253 u32 island_mode[AFE_MAX_PORTS];
254 struct vad_config vad_cfg[AFE_MAX_PORTS];
Xiaoyu Yebaf28392018-06-22 15:22:27 -0700255 struct work_struct afe_dc_work;
Ramprasad Katkam250075f2018-08-31 03:31:54 +0530256 struct notifier_block event_notifier;
Laxminath Kasam36384ec2019-02-18 21:57:19 +0530257 /* FTM spk params */
258 uint32_t initial_cal;
259 uint32_t v_vali_flag;
Vangala, Amarnath3e3537e2020-05-13 23:11:14 +0530260 uint32_t num_spkrs;
Faiz Nabi Kuchay29093022020-10-08 18:25:49 +0530261 uint32_t cps_ch_mask;
262 struct afe_cps_hw_intf_cfg *cps_config;
Soumya Managoliadeb3312020-11-27 15:43:55 +0530263 int lsm_afe_ports[MAX_LSM_SESSIONS];
lintaopei746b0122021-03-16 19:35:42 +0800264
265#ifdef CONFIG_SND_SMARTPA_AW882XX
266 struct rtac_cal_block_data aw_cal;
267 atomic_t aw_state;
268#endif /*CONFIG_SND_SMARTPA_AW882XX*/
269
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530270};
271
Surendar Karkacf3f8e62020-01-24 14:35:07 +0530272struct afe_clkinfo_per_port {
273 u16 port_id; /* AFE port ID */
274 uint32_t clk_id; /* Clock ID */
275};
276
277struct afe_clkinfo_per_port clkinfo_per_port[] = {
278 { AFE_PORT_ID_PRIMARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT},
279 { AFE_PORT_ID_SECONDARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT},
280 { AFE_PORT_ID_TERTIARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT},
281 { AFE_PORT_ID_QUATERNARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT},
282 { AFE_PORT_ID_QUINARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT},
283 { AFE_PORT_ID_SENARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT},
284 { AFE_PORT_ID_PRIMARY_PCM_RX, Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT},
285 { AFE_PORT_ID_SECONDARY_PCM_RX, Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT},
286 { AFE_PORT_ID_TERTIARY_PCM_RX, Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT},
287 { AFE_PORT_ID_QUATERNARY_PCM_RX, Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT},
288 { AFE_PORT_ID_QUINARY_PCM_RX, Q6AFE_LPASS_CLK_ID_QUIN_PCM_IBIT},
289 { AFE_PORT_ID_SENARY_PCM_RX, Q6AFE_LPASS_CLK_ID_SEN_PCM_IBIT},
290 { AFE_PORT_ID_PRIMARY_TDM_RX, Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT},
291 { AFE_PORT_ID_SECONDARY_TDM_RX, Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT},
292 { AFE_PORT_ID_TERTIARY_TDM_RX, Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT},
293 { AFE_PORT_ID_QUATERNARY_TDM_RX, Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT},
294 { AFE_PORT_ID_QUINARY_TDM_RX, Q6AFE_LPASS_CLK_ID_QUIN_TDM_IBIT},
295 { AFE_PORT_ID_PRIMARY_SPDIF_RX,
296 AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_OUTPUT_CORE},
297 { AFE_PORT_ID_PRIMARY_SPDIF_TX,
298 AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_INPUT_CORE},
299 { AFE_PORT_ID_SECONDARY_SPDIF_RX,
300 AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_OUTPUT_CORE},
301 { AFE_PORT_ID_SECONDARY_SPDIF_TX,
302 AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_INPUT_CORE},
303 { AFE_PORT_ID_PRIMARY_META_MI2S_RX,
304 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT},
305 { AFE_PORT_ID_SECONDARY_META_MI2S_RX,
306 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT},
307};
308
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530309static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX];
310static unsigned long afe_configured_cmd;
311
312static struct afe_ctl this_afe;
313
314#define TIMEOUT_MS 1000
315#define Q6AFE_MAX_VOLUME 0x3FFF
316
317static int pcm_afe_instance[2];
318static int proxy_afe_instance[2];
319bool afe_close_done[2] = {true, true};
320
321#define SIZEOF_CFG_CMD(y) \
322 (sizeof(struct apr_hdr) + sizeof(u16) + (sizeof(struct y)))
323
Soumya Managoliadeb3312020-11-27 15:43:55 +0530324static bool q6afe_is_afe_lsm_port(int port_id);
325
Harshal Ahire10e83842020-03-27 04:37:23 +0530326static void q6afe_unload_avcs_modules(u16 port_id, int index)
327{
328 int ret = 0;
329
330 ret = q6core_avcs_load_unload_modules(pm[index]->payload,
331 AVCS_UNLOAD_MODULES);
332
333 if (ret < 0)
334 pr_err("%s: avcs module unload failed %d\n", __func__, ret);
335
336 kfree(pm[index]->payload);
337 pm[index]->payload = NULL;
338 kfree(pm[index]);
339 pm[index] = NULL;
340}
341
342static int q6afe_load_avcs_modules(int num_modules, u16 port_id,
343 uint32_t use_case, u32 format_id)
344{
345 int i = 0;
346 int32_t ret = 0;
347 size_t payload_size = 0, port_struct_size = 0;
348 struct afe_avcs_payload_port_mapping payload_map;
349 struct avcs_load_unload_modules_sec_payload sec_payload;
350
351 if (num_modules <= 0) {
352 pr_err("%s: Invalid number of modules to load\n", __func__);
353 return -EINVAL;
354 }
355
356 for (i = 0; i < MAX_ALLOWED_USE_CASES; i++) {
357 if (pm[i] == NULL) {
358 port_struct_size = sizeof(payload_map);
359 pm[i] = kzalloc(port_struct_size, GFP_KERNEL);
360 if (!pm[i])
361 return -ENOMEM;
362
363 pm[i]->port_id = port_id;
364 payload_size = sizeof(uint32_t) + (sizeof(sec_payload)
365 * num_modules);
366 pm[i]->payload = kzalloc(payload_size, GFP_KERNEL);
367 if (!pm[i]->payload) {
368 kfree(pm[i]);
369 pm[i] = NULL;
370 return -ENOMEM;
371 }
372
373 /*
374 * index 0 : packetizer/de-packetizer
375 * index 1 : encoder/decoder
376 */
377
378 pm[i]->payload->num_modules = num_modules;
379
380 /*
381 * Remaining fields of payload
382 * are initialized to zero
383 */
384
385 if (use_case == ENCODER_CASE) {
386 pm[i]->payload->load_unload_info[0].module_type =
387 AMDB_MODULE_TYPE_PACKETIZER;
388 pm[i]->payload->load_unload_info[0].id1 =
389 AVS_MODULE_ID_PACKETIZER_COP;
390 pm[i]->payload->load_unload_info[1].module_type =
391 AMDB_MODULE_TYPE_ENCODER;
392 pm[i]->payload->load_unload_info[1].id1 =
393 format_id;
394 } else if (use_case == DECODER_CASE) {
395 pm[i]->payload->load_unload_info[0].module_type =
396 AMDB_MODULE_TYPE_DEPACKETIZER;
397 pm[i]->payload->load_unload_info[0].id1 =
398 AVS_MODULE_ID_DEPACKETIZER_COP_V1;
399
400 if (format_id == ENC_CODEC_TYPE_LDAC) {
401 pm[i]->payload->load_unload_info[0].id1 =
402 AVS_MODULE_ID_DEPACKETIZER_COP;
403 goto load_unload;
404 }
405
406 pm[i]->payload->load_unload_info[1].module_type =
407 AMDB_MODULE_TYPE_DECODER;
408 pm[i]->payload->load_unload_info[1].id1 =
409 format_id;
410
411 } else {
412 pr_err("%s:load usecase %d not supported\n",
413 __func__, use_case);
414 ret = -EINVAL;
415 goto fail;
416 }
417
418load_unload:
419 ret = q6core_avcs_load_unload_modules(pm[i]->payload,
420 AVCS_LOAD_MODULES);
421
422 if (ret < 0) {
423 pr_err("%s: load failed %d\n", __func__, ret);
424 goto fail;
425 }
426 return 0;
427 }
428
429 }
430
431 ret = -EINVAL;
432 if (i == MAX_ALLOWED_USE_CASES) {
433 pr_err("%s: Not enough ports available\n", __func__);
434 return ret;
435 }
436fail:
437 kfree(pm[i]->payload);
438 pm[i]->payload = NULL;
439 kfree(pm[i]);
440 pm[i] = NULL;
441 return ret;
442}
443
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530444static int afe_get_cal_hw_delay(int32_t path,
445 struct audio_cal_hw_delay_entry *entry);
446static int remap_cal_data(struct cal_block_data *cal_block, int cal_index);
447
Laxminath Kasam36384ec2019-02-18 21:57:19 +0530448int afe_get_spk_initial_cal(void)
449{
450 return this_afe.initial_cal;
451}
452
453void afe_get_spk_r0(int *spk_r0)
454{
455 uint16_t i = 0;
456
457 for (; i < SP_V2_NUM_MAX_SPKRS; i++)
458 spk_r0[i] = this_afe.prot_cfg.r0[i];
459}
460
461void afe_get_spk_t0(int *spk_t0)
462{
463 uint16_t i = 0;
464
465 for (; i < SP_V2_NUM_MAX_SPKRS; i++)
466 spk_t0[i] = this_afe.prot_cfg.t0[i];
467}
468
469int afe_get_spk_v_vali_flag(void)
470{
471 return this_afe.v_vali_flag;
472}
473
474void afe_get_spk_v_vali_sts(int *spk_v_vali_sts)
475{
476 uint16_t i = 0;
477
478 for (; i < SP_V2_NUM_MAX_SPKRS; i++)
479 spk_v_vali_sts[i] =
480 this_afe.th_vi_v_vali_resp.param.status[i];
481}
482
483void afe_set_spk_initial_cal(int initial_cal)
484{
485 this_afe.initial_cal = initial_cal;
486}
487
488void afe_set_spk_v_vali_flag(int v_vali_flag)
489{
490 this_afe.v_vali_flag = v_vali_flag;
491}
492
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530493int afe_get_topology(int port_id)
494{
495 int topology;
496 int port_index = afe_get_port_index(port_id);
497
498 if ((port_index < 0) || (port_index >= AFE_MAX_PORTS)) {
499 pr_err("%s: Invalid port index %d\n", __func__, port_index);
500 topology = -EINVAL;
501 goto done;
502 }
503
504 topology = this_afe.topology[port_index];
505done:
506 return topology;
507}
508
Laxminath Kasam8b1366a2017-10-05 01:44:16 +0530509/**
510 * afe_set_aanc_info -
511 * Update AFE AANC info
512 *
513 * @q6_aanc_info: AFE AANC info params
514 *
515 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530516void afe_set_aanc_info(struct aanc_data *q6_aanc_info)
517{
518 this_afe.aanc_info.aanc_active = q6_aanc_info->aanc_active;
519 this_afe.aanc_info.aanc_rx_port = q6_aanc_info->aanc_rx_port;
520 this_afe.aanc_info.aanc_tx_port = q6_aanc_info->aanc_tx_port;
521
522 pr_debug("%s: aanc active is %d rx port is 0x%x, tx port is 0x%x\n",
523 __func__,
524 this_afe.aanc_info.aanc_active,
525 this_afe.aanc_info.aanc_rx_port,
526 this_afe.aanc_info.aanc_tx_port);
527}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +0530528EXPORT_SYMBOL(afe_set_aanc_info);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530529
530static void afe_callback_debug_print(struct apr_client_data *data)
531{
532 uint32_t *payload;
533
534 payload = data->payload;
535
536 if (data->payload_size >= 8)
537 pr_debug("%s: code = 0x%x PL#0[0x%x], PL#1[0x%x], size = %d\n",
538 __func__, data->opcode, payload[0], payload[1],
539 data->payload_size);
540 else if (data->payload_size >= 4)
541 pr_debug("%s: code = 0x%x PL#0[0x%x], size = %d\n",
542 __func__, data->opcode, payload[0],
543 data->payload_size);
544 else
545 pr_debug("%s: code = 0x%x, size = %d\n",
546 __func__, data->opcode, data->payload_size);
547}
548
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800549static void av_dev_drift_afe_cb_handler(uint32_t opcode, uint32_t *payload,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530550 uint32_t payload_size)
551{
552 u32 param_id;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800553 size_t expected_size =
554 sizeof(u32) + sizeof(struct afe_param_id_dev_timing_stats);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530555
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800556 /* Get param ID depending on command type */
557 param_id = (opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) ? payload[3] :
558 payload[2];
559 if (param_id != AFE_PARAM_ID_DEV_TIMING_STATS) {
560 pr_err("%s: Unrecognized param ID %d\n", __func__, param_id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530561 return;
562 }
563
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800564 switch (opcode) {
565 case AFE_PORT_CMDRSP_GET_PARAM_V2:
566 expected_size += sizeof(struct param_hdr_v1);
567 if (payload_size < expected_size) {
568 pr_err("%s: Error: received size %d, expected size %zu\n",
569 __func__, payload_size, expected_size);
570 return;
571 }
572 /* Repack response to add IID */
573 this_afe.av_dev_drift_resp.status = payload[0];
574 this_afe.av_dev_drift_resp.pdata.module_id = payload[1];
575 this_afe.av_dev_drift_resp.pdata.instance_id = INSTANCE_ID_0;
576 this_afe.av_dev_drift_resp.pdata.param_id = payload[2];
577 this_afe.av_dev_drift_resp.pdata.param_size = payload[3];
578 memcpy(&this_afe.av_dev_drift_resp.timing_stats, &payload[4],
579 sizeof(struct afe_param_id_dev_timing_stats));
580 break;
581 case AFE_PORT_CMDRSP_GET_PARAM_V3:
582 expected_size += sizeof(struct param_hdr_v3);
583 if (payload_size < expected_size) {
584 pr_err("%s: Error: received size %d, expected size %zu\n",
585 __func__, payload_size, expected_size);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530586 return;
587 }
588 memcpy(&this_afe.av_dev_drift_resp, payload,
589 sizeof(this_afe.av_dev_drift_resp));
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800590 break;
591 default:
592 pr_err("%s: Unrecognized command %d\n", __func__, opcode);
593 return;
594 }
595
596 if (!this_afe.av_dev_drift_resp.status) {
597 atomic_set(&this_afe.state, 0);
598 } else {
Chaithanya Krishna Bacharaju8c6a1842018-11-16 15:02:39 +0530599 pr_debug("%s: av_dev_drift_resp status: %d\n", __func__,
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800600 this_afe.av_dev_drift_resp.status);
601 atomic_set(&this_afe.state, -1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530602 }
603}
604
Chaithanya Krishna Bacharaju8c6a1842018-11-16 15:02:39 +0530605static void doa_tracking_mon_afe_cb_handler(uint32_t opcode, uint32_t *payload,
606 uint32_t payload_size)
607{
608 size_t expected_size =
609 sizeof(u32) + sizeof(struct doa_tracking_mon_param);
610
Surendar Karka7bc942b2019-02-22 17:21:13 +0530611 if (payload[0]) {
612 atomic_set(&this_afe.status, payload[0]);
613 atomic_set(&this_afe.state, 0);
614 pr_err("%s: doa_tracking_mon_resp status: %d payload size %d\n",
615 __func__, payload[0], payload_size);
616 return;
617 }
618
Chaithanya Krishna Bacharaju8c6a1842018-11-16 15:02:39 +0530619 switch (opcode) {
620 case AFE_PORT_CMDRSP_GET_PARAM_V2:
621 expected_size += sizeof(struct param_hdr_v1);
622 if (payload_size < expected_size) {
623 pr_err("%s: Error: received size %d, expected size %zu\n",
624 __func__, payload_size, expected_size);
625 return;
626 }
627 /* Repack response to add IID */
628 this_afe.doa_tracking_mon_resp.status = payload[0];
629 this_afe.doa_tracking_mon_resp.pdata.module_id = payload[1];
630 this_afe.doa_tracking_mon_resp.pdata.instance_id =
631 INSTANCE_ID_0;
632 this_afe.doa_tracking_mon_resp.pdata.param_id = payload[2];
633 this_afe.doa_tracking_mon_resp.pdata.param_size = payload[3];
634 memcpy(&this_afe.doa_tracking_mon_resp.doa, &payload[4],
635 sizeof(struct doa_tracking_mon_param));
636 break;
637 case AFE_PORT_CMDRSP_GET_PARAM_V3:
638 expected_size += sizeof(struct param_hdr_v3);
639 if (payload_size < expected_size) {
640 pr_err("%s: Error: received size %d, expected size %zu\n",
641 __func__, payload_size, expected_size);
642 return;
643 }
644 memcpy(&this_afe.doa_tracking_mon_resp, payload,
645 sizeof(this_afe.doa_tracking_mon_resp));
646 break;
647 default:
648 pr_err("%s: Unrecognized command %d\n", __func__, opcode);
649 return;
650 }
651
Surendar Karka7bc942b2019-02-22 17:21:13 +0530652 atomic_set(&this_afe.state, 0);
Chaithanya Krishna Bacharaju8c6a1842018-11-16 15:02:39 +0530653}
654
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800655static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload,
656 uint32_t payload_size)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530657{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800658 struct param_hdr_v3 param_hdr;
659 u32 *data_dest = NULL;
660 u32 *data_start = NULL;
661 size_t expected_size = sizeof(u32);
Vangala, Amarnath78732302020-04-09 03:57:14 +0530662 uint32_t num_ch = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530663
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800664 memset(&param_hdr, 0, sizeof(param_hdr));
665
666 /* Set command specific details */
667 switch (opcode) {
668 case AFE_PORT_CMDRSP_GET_PARAM_V2:
Karthikeyan Mani3325ee52019-01-18 16:50:58 -0800669 if (payload_size < (5 * sizeof(uint32_t))) {
670 pr_err("%s: Error: size %d is less than expected\n",
671 __func__, payload_size);
672 return -EINVAL;
673 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800674 expected_size += sizeof(struct param_hdr_v1);
675 param_hdr.module_id = payload[1];
676 param_hdr.instance_id = INSTANCE_ID_0;
677 param_hdr.param_id = payload[2];
678 param_hdr.param_size = payload[3];
679 data_start = &payload[4];
680 break;
681 case AFE_PORT_CMDRSP_GET_PARAM_V3:
Karthikeyan Mani3325ee52019-01-18 16:50:58 -0800682 if (payload_size < (6 * sizeof(uint32_t))) {
683 pr_err("%s: Error: size %d is less than expected\n",
684 __func__, payload_size);
685 return -EINVAL;
686 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800687 expected_size += sizeof(struct param_hdr_v3);
Karthikeyan Mani3325ee52019-01-18 16:50:58 -0800688 if (payload_size < expected_size) {
689 pr_err("%s: Error: size %d is less than expected\n",
690 __func__, payload_size);
691 return -EINVAL;
692 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800693 memcpy(&param_hdr, &payload[1], sizeof(struct param_hdr_v3));
694 data_start = &payload[5];
695 break;
696 default:
697 pr_err("%s: Unrecognized command %d\n", __func__, opcode);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530698 return -EINVAL;
699 }
700
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800701 switch (param_hdr.param_id) {
702 case AFE_PARAM_ID_CALIB_RES_CFG_V2:
703 expected_size += sizeof(struct asm_calib_res_cfg);
704 data_dest = (u32 *) &this_afe.calib_data;
705 break;
706 case AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS:
707 expected_size += sizeof(struct afe_sp_th_vi_ftm_params);
708 data_dest = (u32 *) &this_afe.th_vi_resp;
709 break;
Laxminath Kasam2e13d952019-02-20 15:05:39 +0530710 case AFE_PARAM_ID_SP_V2_TH_VI_V_VALI_PARAMS:
711 expected_size += sizeof(struct afe_sp_th_vi_v_vali_params);
712 data_dest = (u32 *) &this_afe.th_vi_v_vali_resp;
713 break;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800714 case AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS:
715 expected_size += sizeof(struct afe_sp_ex_vi_ftm_params);
716 data_dest = (u32 *) &this_afe.ex_vi_resp;
717 break;
Aditya Bavanari740b4832018-12-24 18:46:12 +0530718 case AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING:
719 expected_size += sizeof(
720 struct afe_sp_rx_tmax_xmax_logging_param);
721 data_dest = (u32 *) &this_afe.xt_logging_resp;
722 break;
Vangala, Amarnath78732302020-04-09 03:57:14 +0530723 case AFE_PARAM_ID_SP_V4_CALIB_RES_CFG:
724 expected_size += sizeof(
725 struct afe_sp_v4_param_th_vi_calib_res_cfg);
726 data_dest = (u32 *) &this_afe.spv4_calib_data;
727 break;
728 case AFE_PARAM_ID_SP_V4_TH_VI_FTM_PARAMS:
729 num_ch = data_start[0];
Vangala, Amarnathe1815842020-07-14 03:39:52 +0530730 this_afe.spv4_th_vi_ftm_rcvd_param_size = param_hdr.param_size;
731 data_dest = (u32 *)&this_afe.spv4_th_vi_ftm_resp;
Vangala, Amarnath78732302020-04-09 03:57:14 +0530732 expected_size +=
733 sizeof(struct afe_sp_v4_param_th_vi_ftm_params) +
734 (num_ch * sizeof(struct afe_sp_v4_channel_ftm_params));
735 break;
736 case AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_PARAMS:
737 num_ch = data_start[0];
Vangala, Amarnathe1815842020-07-14 03:39:52 +0530738 this_afe.spv4_v_vali_rcvd_param_size = param_hdr.param_size;
739 data_dest = (u32 *)&this_afe.spv4_v_vali_resp;
Vangala, Amarnath78732302020-04-09 03:57:14 +0530740 expected_size +=
741 sizeof(struct afe_sp_v4_param_th_vi_v_vali_params) +
742 (num_ch *
743 sizeof(struct afe_sp_v4_channel_v_vali_params));
744 break;
745 case AFE_PARAM_ID_SP_V4_EX_VI_FTM_PARAMS:
746 num_ch = data_start[0];
Vangala, Amarnathe1815842020-07-14 03:39:52 +0530747 this_afe.spv4_ex_vi_ftm_rcvd_param_size = param_hdr.param_size;
748 data_dest = (u32 *)&this_afe.spv4_ex_vi_ftm_resp;
Vangala, Amarnath78732302020-04-09 03:57:14 +0530749 expected_size +=
Vangala, Amarnathe1815842020-07-14 03:39:52 +0530750 sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) +
751 (num_ch * sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params));
Vangala, Amarnath78732302020-04-09 03:57:14 +0530752 break;
753 case AFE_PARAM_ID_SP_V4_RX_TMAX_XMAX_LOGGING:
754 num_ch = data_start[0];
Vangala, Amarnathe1815842020-07-14 03:39:52 +0530755 this_afe.spv4_max_log_rcvd_param_size = param_hdr.param_size;
756 data_dest = (u32 *)&this_afe.spv4_max_log_resp;
Vangala, Amarnath78732302020-04-09 03:57:14 +0530757 expected_size +=
Vangala, Amarnathe1815842020-07-14 03:39:52 +0530758 sizeof(struct afe_sp_v4_param_tmax_xmax_logging) +
759 (num_ch * sizeof(struct afe_sp_v4_channel_tmax_xmax_params));
Vangala, Amarnath78732302020-04-09 03:57:14 +0530760 break;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800761 default:
762 pr_err("%s: Unrecognized param ID %d\n", __func__,
763 param_hdr.param_id);
764 return -EINVAL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530765 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800766
Vangala, Amarnath78732302020-04-09 03:57:14 +0530767 if (!data_dest)
768 return -ENOMEM;
769
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800770 if (payload_size < expected_size) {
Vangala, Amarnath78732302020-04-09 03:57:14 +0530771 pr_err(
772 "%s: Error: received size %d, expected size %zu for param %d\n",
773 __func__, payload_size, expected_size,
774 param_hdr.param_id);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800775 return -EINVAL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530776 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800777
778 data_dest[0] = payload[0];
779 memcpy(&data_dest[1], &param_hdr, sizeof(struct param_hdr_v3));
780 memcpy(&data_dest[5], data_start, param_hdr.param_size);
781
782 if (!data_dest[0]) {
783 atomic_set(&this_afe.state, 0);
784 } else {
785 pr_debug("%s: status: %d", __func__, data_dest[0]);
786 atomic_set(&this_afe.state, -1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530787 }
788
789 return 0;
790}
791
Vidyakumar Athota94bd8732018-02-28 17:13:35 -0800792static void afe_notify_dc_presence(void)
793{
Vidyakumar Athota968be0a2018-07-12 16:39:44 -0700794 pr_debug("%s: DC detected\n", __func__);
Xiaoyu Yebaf28392018-06-22 15:22:27 -0700795 msm_aud_evt_notifier_call_chain(MSM_AUD_DC_EVENT, NULL);
796
797 schedule_work(&this_afe.afe_dc_work);
798}
799
800static void afe_notify_dc_presence_work_fn(struct work_struct *work)
801{
Vignesh Kulothunganc3f38982018-05-22 18:08:20 -0700802 int ret = 0;
803 char event[] = "DC_PRESENCE=TRUE";
804
Vignesh Kulothunganc3f38982018-05-22 18:08:20 -0700805 ret = q6core_send_uevent(this_afe.uevent_data, event);
806 if (ret)
Xiaoyu Yebaf28392018-06-22 15:22:27 -0700807 pr_err("%s: Send UEvent %s failed :%d\n",
808 __func__, event, ret);
Vidyakumar Athota94bd8732018-02-28 17:13:35 -0800809}
810
Ramprasad Katkam250075f2018-08-31 03:31:54 +0530811static int afe_aud_event_notify(struct notifier_block *self,
812 unsigned long action, void *data)
813{
814 switch (action) {
815 case SWR_WAKE_IRQ_REGISTER:
816 afe_send_cmd_wakeup_register(data, true);
817 break;
818 case SWR_WAKE_IRQ_DEREGISTER:
819 afe_send_cmd_wakeup_register(data, false);
820 break;
821 default:
822 pr_err("%s: invalid event type: %lu\n", __func__, action);
823 return -EINVAL;
824 }
825
826 return 0;
827}
Ralf Herzcc29b9e2018-07-17 20:19:04 +0530828
Ralf Herz044e4762018-09-10 11:04:16 +0200829static void afe_notify_spdif_fmt_update_work_fn(struct work_struct *work)
Ralf Herzcc29b9e2018-07-17 20:19:04 +0530830{
831 int ret = 0;
Ralf Herz044e4762018-09-10 11:04:16 +0200832 char event_pri[] = "PRI_SPDIF_TX=MEDIA_CONFIG_CHANGE";
833 char event_sec[] = "SEC_SPDIF_TX=MEDIA_CONFIG_CHANGE";
Ralf Herzcc29b9e2018-07-17 20:19:04 +0530834
Ralf Herz044e4762018-09-10 11:04:16 +0200835 if (this_afe.pri_spdif_config_change) {
836 this_afe.pri_spdif_config_change = 0;
837 ret = q6core_send_uevent(this_afe.uevent_data, event_pri);
838 if (ret)
839 pr_err("%s: Send UEvent %s failed :%d\n",
840 __func__, event_pri, ret);
Ralf Herzcc29b9e2018-07-17 20:19:04 +0530841 }
Ralf Herz044e4762018-09-10 11:04:16 +0200842 if (this_afe.sec_spdif_config_change) {
843 this_afe.sec_spdif_config_change = 0;
844 ret = q6core_send_uevent(this_afe.uevent_data, event_sec);
845 if (ret)
846 pr_err("%s: Send UEvent %s failed :%d\n",
847 __func__, event_sec, ret);
Ralf Herzcc29b9e2018-07-17 20:19:04 +0530848 }
Ralf Herzcc29b9e2018-07-17 20:19:04 +0530849}
850
851static void afe_notify_spdif_fmt_update(void *payload)
852{
853 struct afe_port_mod_evt_rsp_hdr *evt_pl;
854
855 evt_pl = (struct afe_port_mod_evt_rsp_hdr *)payload;
Ralf Herz044e4762018-09-10 11:04:16 +0200856 if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX)
857 this_afe.pri_spdif_config_change = 1;
858 else
859 this_afe.sec_spdif_config_change = 1;
860
861 schedule_work(&this_afe.afe_spdif_work);
Ralf Herzcc29b9e2018-07-17 20:19:04 +0530862}
863
Xiaojun Sangcf353ed2019-01-15 16:49:02 +0800864static bool afe_token_is_valid(uint32_t token)
865{
866 if (token >= AFE_MAX_PORTS) {
867 pr_err("%s: token %d is invalid.\n", __func__, token);
868 return false;
869 }
870 return true;
871}
872
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530873static int32_t afe_callback(struct apr_client_data *data, void *priv)
874{
Laxminath Kasam688db8a2019-11-05 13:11:30 +0530875 uint16_t i = 0;
876
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530877 if (!data) {
878 pr_err("%s: Invalid param data\n", __func__);
879 return -EINVAL;
880 }
881 if (data->opcode == RESET_EVENTS) {
882 pr_debug("%s: reset event = %d %d apr[%pK]\n",
883 __func__,
884 data->reset_event, data->reset_proc, this_afe.apr);
885
886 cal_utils_clear_cal_block_q6maps(MAX_AFE_CAL_TYPES,
887 this_afe.cal_data);
888
889 /* Reset the custom topology mode: to resend again to AFE. */
890 mutex_lock(&this_afe.cal_data[AFE_CUST_TOPOLOGY_CAL]->lock);
891 this_afe.set_custom_topology = 1;
892 mutex_unlock(&this_afe.cal_data[AFE_CUST_TOPOLOGY_CAL]->lock);
893 rtac_clear_mapping(AFE_RTAC_CAL);
894
895 if (this_afe.apr) {
896 apr_reset(this_afe.apr);
897 atomic_set(&this_afe.state, 0);
898 this_afe.apr = NULL;
899 rtac_set_afe_handle(this_afe.apr);
900 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530901
Aditya Bavanari81a54a22019-09-20 00:23:59 +0530902 /* Reset the core client handle in SSR/PDR use cases */
903 mutex_lock(&this_afe.afe_cmd_lock);
Laxminath Kasam688db8a2019-11-05 13:11:30 +0530904 for (i = 0; i < AFE_LPASS_CORE_HW_VOTE_MAX; i++)
905 this_afe.lpass_hw_core_client_hdl[i] = 0;
Aditya Bavanari81a54a22019-09-20 00:23:59 +0530906 mutex_unlock(&this_afe.afe_cmd_lock);
907
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530908 /*
909 * Pass reset events to proxy driver, if cb is registered
910 */
911 if (this_afe.tx_cb) {
912 this_afe.tx_cb(data->opcode, data->token,
913 data->payload,
914 this_afe.tx_private_data);
915 this_afe.tx_cb = NULL;
916 }
917 if (this_afe.rx_cb) {
918 this_afe.rx_cb(data->opcode, data->token,
919 data->payload,
920 this_afe.rx_private_data);
921 this_afe.rx_cb = NULL;
922 }
923
924 return 0;
925 }
926 afe_callback_debug_print(data);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800927 if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V2 ||
928 data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530929 uint32_t *payload = data->payload;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800930 uint32_t param_id;
Karthikeyan Mani3325ee52019-01-18 16:50:58 -0800931 uint32_t param_id_pos = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530932
933 if (!payload || (data->token >= AFE_MAX_PORTS)) {
934 pr_err("%s: Error: size %d payload %pK token %d\n",
935 __func__, data->payload_size,
936 payload, data->token);
937 return -EINVAL;
938 }
lintaopei746b0122021-03-16 19:35:42 +0800939#ifdef CONFIG_SND_SMARTPA_AW882XX
940 if (atomic_read(&this_afe.aw_state) == 1) {
941 if (!payload[0]) {
942 atomic_set(&this_afe.state, 0);
943 } else {
944 pr_debug("%s: status: %d", __func__, payload[0]);
945 atomic_set(&this_afe.state, -1);
946 }
947 atomic_set(&this_afe.aw_state, 0);
948 wake_up(&this_afe.wait[data->token]);
949 return 0;
950 }
951#endif /*CONFIG_SND_SMARTPA_AW882XX*/
Karthikeyan Mani3325ee52019-01-18 16:50:58 -0800952 if (rtac_make_afe_callback(data->payload,
953 data->payload_size))
954 return 0;
955
956 if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3)
957 param_id_pos = 4;
958 else
959 param_id_pos = 3;
960
961 if (data->payload_size >= param_id_pos * sizeof(uint32_t))
962 param_id = payload[param_id_pos - 1];
963 else {
964 pr_err("%s: Error: size %d is less than expected\n",
965 __func__, data->payload_size);
966 return -EINVAL;
967 }
968
Chaithanya Krishna Bacharaju8c6a1842018-11-16 15:02:39 +0530969 if (param_id == AUDPROC_PARAM_ID_FFV_DOA_TRACKING_MONITOR) {
970 doa_tracking_mon_afe_cb_handler(data->opcode,
971 data->payload, data->payload_size);
972 } else if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) {
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800973 av_dev_drift_afe_cb_handler(data->opcode, data->payload,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530974 data->payload_size);
975 } else {
Vignesh Kulothungan85073c02018-01-26 10:27:56 -0800976 if (sp_make_afe_callback(data->opcode, data->payload,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530977 data->payload_size))
978 return -EINVAL;
979 }
Xiaojun Sangcf353ed2019-01-15 16:49:02 +0800980 if (afe_token_is_valid(data->token))
981 wake_up(&this_afe.wait[data->token]);
982 else
983 return -EINVAL;
Ramprasad Katkam250075f2018-08-31 03:31:54 +0530984 } else if (data->opcode == AFE_EVENT_MBHC_DETECTION_SW_WA) {
985 msm_aud_evt_notifier_call_chain(SWR_WAKE_IRQ_EVENT, NULL);
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +0530986 } else if (data->opcode ==
987 AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST) {
988 uint32_t *payload = data->payload;
989
990 pr_debug("%s: AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST handle %d\n",
991 __func__, payload[0]);
Laxminath Kasam688db8a2019-11-05 13:11:30 +0530992 if (data->token < AFE_LPASS_CORE_HW_VOTE_MAX)
993 this_afe.lpass_hw_core_client_hdl[data->token] =
994 payload[0];
Meng Wang9eacb962019-11-19 09:16:55 +0800995 atomic_set(&this_afe.clk_state, 0);
996 atomic_set(&this_afe.clk_status, 0);
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +0530997 wake_up(&this_afe.lpass_core_hw_wait);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530998 } else if (data->payload_size) {
999 uint32_t *payload;
1000 uint16_t port_id = 0;
1001
1002 payload = data->payload;
1003 if (data->opcode == APR_BASIC_RSP_RESULT) {
Karthikeyan Mani3325ee52019-01-18 16:50:58 -08001004 if (data->payload_size < (2 * sizeof(uint32_t))) {
1005 pr_err("%s: Error: size %d is less than expected\n",
1006 __func__, data->payload_size);
1007 return -EINVAL;
1008 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301009 pr_debug("%s:opcode = 0x%x cmd = 0x%x status = 0x%x token=%d\n",
1010 __func__, data->opcode,
1011 payload[0], payload[1], data->token);
1012 /* payload[1] contains the error status for response */
1013 if (payload[1] != 0) {
Aditya Bavanari96210452019-12-23 18:56:39 +05301014 if(data->token == AFE_CLK_TOKEN)
1015 atomic_set(&this_afe.clk_status, payload[1]);
1016 else
1017 atomic_set(&this_afe.status, payload[1]);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301018 pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
1019 __func__, payload[0], payload[1]);
1020 }
1021 switch (payload[0]) {
1022 case AFE_PORT_CMD_SET_PARAM_V2:
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08001023 case AFE_PORT_CMD_SET_PARAM_V3:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301024 if (rtac_make_afe_callback(payload,
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08001025 data->payload_size))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301026 return 0;
1027 case AFE_PORT_CMD_DEVICE_STOP:
1028 case AFE_PORT_CMD_DEVICE_START:
1029 case AFE_PSEUDOPORT_CMD_START:
1030 case AFE_PSEUDOPORT_CMD_STOP:
1031 case AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS:
1032 case AFE_SERVICE_CMD_SHARED_MEM_UNMAP_REGIONS:
1033 case AFE_SERVICE_CMD_UNREGISTER_RT_PORT_DRIVER:
1034 case AFE_PORTS_CMD_DTMF_CTL:
1035 case AFE_SVC_CMD_SET_PARAM:
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08001036 case AFE_SVC_CMD_SET_PARAM_V2:
Vidyakumar Athota94bd8732018-02-28 17:13:35 -08001037 case AFE_PORT_CMD_MOD_EVENT_CFG:
Meng Wang9eacb962019-11-19 09:16:55 +08001038 if(data->token == AFE_CLK_TOKEN) {
1039 atomic_set(&this_afe.clk_state, 0);
1040 wake_up(&this_afe.clk_wait);
1041 } else {
1042 atomic_set(&this_afe.state, 0);
1043 if (afe_token_is_valid(data->token))
1044 wake_up(&this_afe.wait[data->token]);
1045 else
1046 return -EINVAL;
1047 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301048 break;
1049 case AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER:
1050 break;
1051 case AFE_PORT_DATA_CMD_RT_PROXY_PORT_WRITE_V2:
1052 port_id = RT_PROXY_PORT_001_TX;
1053 break;
1054 case AFE_PORT_DATA_CMD_RT_PROXY_PORT_READ_V2:
1055 port_id = RT_PROXY_PORT_001_RX;
1056 break;
1057 case AFE_CMD_ADD_TOPOLOGIES:
1058 atomic_set(&this_afe.state, 0);
Xiaojun Sangcf353ed2019-01-15 16:49:02 +08001059 if (afe_token_is_valid(data->token))
1060 wake_up(&this_afe.wait[data->token]);
1061 else
1062 return -EINVAL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301063 pr_debug("%s: AFE_CMD_ADD_TOPOLOGIES cmd 0x%x\n",
1064 __func__, payload[1]);
1065 break;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08001066 case AFE_PORT_CMD_GET_PARAM_V2:
1067 case AFE_PORT_CMD_GET_PARAM_V3:
1068 /*
1069 * Should only come here if there is an APR
1070 * error or malformed APR packet. Otherwise
1071 * response will be returned as
1072 * AFE_PORT_CMDRSP_GET_PARAM_V2/3
1073 */
1074 pr_debug("%s: AFE Get Param opcode 0x%x token 0x%x src %d dest %d\n",
1075 __func__, data->opcode, data->token,
1076 data->src_port, data->dest_port);
1077 if (payload[1] != 0) {
1078 pr_err("%s: AFE Get Param failed with error %d\n",
1079 __func__, payload[1]);
1080 if (rtac_make_afe_callback(
1081 payload,
1082 data->payload_size))
1083 return 0;
1084 }
1085 atomic_set(&this_afe.state, payload[1]);
Xiaojun Sangcf353ed2019-01-15 16:49:02 +08001086 if (afe_token_is_valid(data->token))
1087 wake_up(&this_afe.wait[data->token]);
1088 else
1089 return -EINVAL;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08001090 break;
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +05301091 case AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST:
1092 case AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST:
Meng Wang9eacb962019-11-19 09:16:55 +08001093 atomic_set(&this_afe.clk_state, 0);
Aditya Bavanari96210452019-12-23 18:56:39 +05301094 if (payload[1] != 0)
1095 atomic_set(&this_afe.clk_status,
1096 payload[1]);
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +05301097 wake_up(&this_afe.lpass_core_hw_wait);
1098 break;
Ramprasad Katkam250075f2018-08-31 03:31:54 +05301099 case AFE_SVC_CMD_EVENT_CFG:
1100 atomic_set(&this_afe.state, payload[1]);
1101 wake_up(&this_afe.wait_wakeup);
1102 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301103 default:
1104 pr_err("%s: Unknown cmd 0x%x\n", __func__,
1105 payload[0]);
1106 break;
1107 }
1108 } else if (data->opcode ==
1109 AFE_SERVICE_CMDRSP_SHARED_MEM_MAP_REGIONS) {
1110 pr_debug("%s: mmap_handle: 0x%x, cal index %d\n",
1111 __func__, payload[0],
1112 atomic_read(&this_afe.mem_map_cal_index));
1113 if (atomic_read(&this_afe.mem_map_cal_index) != -1)
1114 atomic_set(&this_afe.mem_map_cal_handles[
1115 atomic_read(
1116 &this_afe.mem_map_cal_index)],
1117 (uint32_t)payload[0]);
1118 else
1119 this_afe.mmap_handle = payload[0];
1120 atomic_set(&this_afe.state, 0);
Xiaojun Sangcf353ed2019-01-15 16:49:02 +08001121 if (afe_token_is_valid(data->token))
1122 wake_up(&this_afe.wait[data->token]);
1123 else
1124 return -EINVAL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301125 } else if (data->opcode == AFE_EVENT_RT_PROXY_PORT_STATUS) {
1126 port_id = (uint16_t)(0x0000FFFF & payload[0]);
Vidyakumar Athota94bd8732018-02-28 17:13:35 -08001127 } else if (data->opcode == AFE_PORT_MOD_EVENT) {
1128 u32 flag_dc_presence[2];
1129 uint32_t *payload = data->payload;
1130 struct afe_port_mod_evt_rsp_hdr *evt_pl =
1131 (struct afe_port_mod_evt_rsp_hdr *)payload;
1132
1133 if (!payload || (data->token >= AFE_MAX_PORTS)) {
1134 pr_err("%s: Error: size %d payload %pK token %d\n",
1135 __func__, data->payload_size,
1136 payload, data->token);
1137 return -EINVAL;
1138 }
1139 if ((evt_pl->module_id == AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI) &&
1140 (evt_pl->event_id == AFE_PORT_SP_DC_DETECTION_EVENT) &&
1141 (evt_pl->payload_size == sizeof(flag_dc_presence))) {
1142
1143 memcpy(&flag_dc_presence,
Vidyakumar Athota968be0a2018-07-12 16:39:44 -07001144 (uint8_t *)payload +
Vidyakumar Athota94bd8732018-02-28 17:13:35 -08001145 sizeof(struct afe_port_mod_evt_rsp_hdr),
1146 evt_pl->payload_size);
1147 if (flag_dc_presence[0] == 1 ||
1148 flag_dc_presence[1] == 1) {
1149 afe_notify_dc_presence();
1150 }
Vangala, Amarnath78732302020-04-09 03:57:14 +05301151 } else if ((evt_pl->module_id ==
1152 AFE_MODULE_SPEAKER_PROTECTION_V4_VI) &&
1153 (evt_pl->event_id ==
1154 AFE_PORT_SP_DC_DETECTION_EVENT)) {
1155 bool dc_detected = false;
1156 uint32_t *num_channels =
1157 (uint32_t *)((uint8_t *)payload +
1158 sizeof(struct afe_port_mod_evt_rsp_hdr));
1159 uint32_t *dc_presence_flag = num_channels + 1;
1160
1161 for (i = 0; i < *num_channels; i++) {
1162 if (dc_presence_flag[i] == 1)
1163 dc_detected = true;
1164 }
1165 if (dc_detected)
1166 afe_notify_dc_presence();
Ralf Herzcc29b9e2018-07-17 20:19:04 +05301167 } else if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) {
1168 if (this_afe.pri_spdif_tx_cb) {
1169 this_afe.pri_spdif_tx_cb(data->opcode,
1170 data->token, data->payload,
1171 this_afe.pri_spdif_tx_private_data);
1172 }
1173 afe_notify_spdif_fmt_update(data->payload);
1174 } else if (evt_pl->port_id == AFE_PORT_ID_SECONDARY_SPDIF_TX) {
1175 if (this_afe.sec_spdif_tx_cb) {
1176 this_afe.sec_spdif_tx_cb(data->opcode,
1177 data->token, data->payload,
1178 this_afe.sec_spdif_tx_private_data);
1179 }
1180 afe_notify_spdif_fmt_update(data->payload);
Vidyakumar Athota94bd8732018-02-28 17:13:35 -08001181 } else {
1182 pr_debug("%s: mod ID = 0x%x event_id = 0x%x\n",
1183 __func__, evt_pl->module_id,
1184 evt_pl->event_id);
1185 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301186 }
1187 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
1188 switch (port_id) {
1189 case RT_PROXY_PORT_001_TX: {
1190 if (this_afe.tx_cb) {
1191 this_afe.tx_cb(data->opcode, data->token,
1192 data->payload,
1193 this_afe.tx_private_data);
1194 }
1195 break;
1196 }
1197 case RT_PROXY_PORT_001_RX: {
1198 if (this_afe.rx_cb) {
1199 this_afe.rx_cb(data->opcode, data->token,
1200 data->payload,
1201 this_afe.rx_private_data);
1202 }
1203 break;
1204 }
1205 default:
1206 pr_debug("%s: default case 0x%x\n", __func__, port_id);
1207 break;
1208 }
1209 }
1210 return 0;
1211}
1212
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05301213/**
1214 * afe_get_port_type -
1215 * Retrieve AFE port type whether RX or TX
1216 *
1217 * @port_id: AFE Port ID number
1218 *
Mangesh Kunchamwar8c706ab2018-04-04 17:48:46 +05301219 * Returns RX/TX type.
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05301220 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301221int afe_get_port_type(u16 port_id)
1222{
Mangesh Kunchamwar8c706ab2018-04-04 17:48:46 +05301223 int ret = MSM_AFE_PORT_TYPE_RX;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301224
Vikram Pandurangadfae8ef2018-06-26 15:44:10 -07001225 switch (port_id) {
1226 case VOICE_RECORD_RX:
1227 case VOICE_RECORD_TX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301228 ret = MSM_AFE_PORT_TYPE_TX;
Vikram Pandurangadfae8ef2018-06-26 15:44:10 -07001229 break;
1230 case VOICE_PLAYBACK_TX:
1231 case VOICE2_PLAYBACK_TX:
Mangesh Kunchamwar8c706ab2018-04-04 17:48:46 +05301232 ret = MSM_AFE_PORT_TYPE_RX;
Vikram Pandurangadfae8ef2018-06-26 15:44:10 -07001233 break;
1234 default:
1235 /* Odd numbered ports are TX and Rx are Even numbered */
1236 if (port_id & 0x1)
1237 ret = MSM_AFE_PORT_TYPE_TX;
1238 else
1239 ret = MSM_AFE_PORT_TYPE_RX;
1240 break;
1241 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301242
1243 return ret;
1244}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05301245EXPORT_SYMBOL(afe_get_port_type);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301246
1247int afe_sizeof_cfg_cmd(u16 port_id)
1248{
1249 int ret_size;
1250
1251 switch (port_id) {
1252 case PRIMARY_I2S_RX:
1253 case PRIMARY_I2S_TX:
1254 case SECONDARY_I2S_RX:
1255 case SECONDARY_I2S_TX:
1256 case MI2S_RX:
1257 case MI2S_TX:
1258 case AFE_PORT_ID_PRIMARY_MI2S_RX:
1259 case AFE_PORT_ID_PRIMARY_MI2S_TX:
1260 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
1261 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
1262 case AFE_PORT_ID_QUINARY_MI2S_RX:
1263 case AFE_PORT_ID_QUINARY_MI2S_TX:
Karthikeyan Mani3bbd2ee2019-01-30 18:48:56 -08001264 case AFE_PORT_ID_SENARY_MI2S_RX:
1265 case AFE_PORT_ID_SENARY_MI2S_TX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301266 ret_size = SIZEOF_CFG_CMD(afe_param_id_i2s_cfg);
1267 break;
Ralf Herz43c0abd2019-07-26 15:12:48 +02001268 case AFE_PORT_ID_PRIMARY_META_MI2S_RX:
1269 case AFE_PORT_ID_SECONDARY_META_MI2S_RX:
1270 ret_size = SIZEOF_CFG_CMD(afe_param_id_meta_i2s_cfg);
1271 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301272 case HDMI_RX:
Sanjana B63bdc7b2020-01-20 19:31:18 +05301273 case HDMI_RX_MS:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301274 case DISPLAY_PORT_RX:
1275 ret_size =
1276 SIZEOF_CFG_CMD(afe_param_id_hdmi_multi_chan_audio_cfg);
1277 break;
Ralf Herzcc29b9e2018-07-17 20:19:04 +05301278 case AFE_PORT_ID_PRIMARY_SPDIF_RX:
1279 case AFE_PORT_ID_PRIMARY_SPDIF_TX:
1280 case AFE_PORT_ID_SECONDARY_SPDIF_RX:
1281 case AFE_PORT_ID_SECONDARY_SPDIF_TX:
1282 ret_size =
1283 SIZEOF_CFG_CMD(afe_param_id_spdif_cfg_v2);
1284 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301285 case SLIMBUS_0_RX:
1286 case SLIMBUS_0_TX:
1287 case SLIMBUS_1_RX:
1288 case SLIMBUS_1_TX:
1289 case SLIMBUS_2_RX:
1290 case SLIMBUS_2_TX:
1291 case SLIMBUS_3_RX:
1292 case SLIMBUS_3_TX:
1293 case SLIMBUS_4_RX:
1294 case SLIMBUS_4_TX:
1295 case SLIMBUS_5_RX:
1296 case SLIMBUS_5_TX:
1297 case SLIMBUS_6_RX:
1298 case SLIMBUS_6_TX:
1299 case SLIMBUS_7_RX:
1300 case SLIMBUS_7_TX:
1301 case SLIMBUS_8_RX:
1302 case SLIMBUS_8_TX:
Surendar Karkab0dd21f2018-09-28 18:53:50 +05301303 case SLIMBUS_9_RX:
1304 case SLIMBUS_9_TX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301305 ret_size = SIZEOF_CFG_CMD(afe_param_id_slimbus_cfg);
1306 break;
1307 case VOICE_PLAYBACK_TX:
1308 case VOICE2_PLAYBACK_TX:
1309 case VOICE_RECORD_RX:
1310 case VOICE_RECORD_TX:
1311 ret_size = SIZEOF_CFG_CMD(afe_param_id_pseudo_port_cfg);
1312 break;
1313 case RT_PROXY_PORT_001_RX:
1314 case RT_PROXY_PORT_001_TX:
Jaideep Sharma39932232020-03-11 22:24:14 +05301315 case RT_PROXY_PORT_002_RX:
1316 case RT_PROXY_PORT_002_TX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301317 ret_size = SIZEOF_CFG_CMD(afe_param_id_rt_proxy_port_cfg);
1318 break;
1319 case AFE_PORT_ID_USB_RX:
1320 case AFE_PORT_ID_USB_TX:
1321 ret_size = SIZEOF_CFG_CMD(afe_param_id_usb_audio_cfg);
1322 break;
Mangesh Kunchamwar8c706ab2018-04-04 17:48:46 +05301323 case AFE_PORT_ID_WSA_CODEC_DMA_RX_0:
1324 case AFE_PORT_ID_WSA_CODEC_DMA_TX_0:
1325 case AFE_PORT_ID_WSA_CODEC_DMA_RX_1:
1326 case AFE_PORT_ID_WSA_CODEC_DMA_TX_1:
1327 case AFE_PORT_ID_WSA_CODEC_DMA_TX_2:
1328 case AFE_PORT_ID_VA_CODEC_DMA_TX_0:
1329 case AFE_PORT_ID_VA_CODEC_DMA_TX_1:
Xiaoyu Ye8341eef2019-01-03 14:57:47 -08001330 case AFE_PORT_ID_VA_CODEC_DMA_TX_2:
Aditya Bavanari348a4a62018-05-16 21:48:45 +05301331 case AFE_PORT_ID_RX_CODEC_DMA_RX_0:
1332 case AFE_PORT_ID_TX_CODEC_DMA_TX_0:
1333 case AFE_PORT_ID_RX_CODEC_DMA_RX_1:
1334 case AFE_PORT_ID_TX_CODEC_DMA_TX_1:
1335 case AFE_PORT_ID_RX_CODEC_DMA_RX_2:
1336 case AFE_PORT_ID_TX_CODEC_DMA_TX_2:
1337 case AFE_PORT_ID_RX_CODEC_DMA_RX_3:
1338 case AFE_PORT_ID_TX_CODEC_DMA_TX_3:
1339 case AFE_PORT_ID_RX_CODEC_DMA_RX_4:
1340 case AFE_PORT_ID_TX_CODEC_DMA_TX_4:
1341 case AFE_PORT_ID_RX_CODEC_DMA_RX_5:
1342 case AFE_PORT_ID_TX_CODEC_DMA_TX_5:
1343 case AFE_PORT_ID_RX_CODEC_DMA_RX_6:
1344 case AFE_PORT_ID_RX_CODEC_DMA_RX_7:
Mangesh Kunchamwar8c706ab2018-04-04 17:48:46 +05301345 ret_size = SIZEOF_CFG_CMD(afe_param_id_cdc_dma_cfg_t);
1346 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301347 case AFE_PORT_ID_PRIMARY_PCM_RX:
1348 case AFE_PORT_ID_PRIMARY_PCM_TX:
1349 case AFE_PORT_ID_SECONDARY_PCM_RX:
1350 case AFE_PORT_ID_SECONDARY_PCM_TX:
1351 case AFE_PORT_ID_TERTIARY_PCM_RX:
1352 case AFE_PORT_ID_TERTIARY_PCM_TX:
1353 case AFE_PORT_ID_QUATERNARY_PCM_RX:
1354 case AFE_PORT_ID_QUATERNARY_PCM_TX:
Rohit Kumarc08b14f2017-10-06 10:52:17 +05301355 case AFE_PORT_ID_QUINARY_PCM_RX:
1356 case AFE_PORT_ID_QUINARY_PCM_TX:
Dieter Lueckingfa7687b2018-09-28 14:21:44 +02001357 case AFE_PORT_ID_SENARY_PCM_RX:
1358 case AFE_PORT_ID_SENARY_PCM_TX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301359 default:
1360 pr_debug("%s: default case 0x%x\n", __func__, port_id);
1361 ret_size = SIZEOF_CFG_CMD(afe_param_id_pcm_cfg);
1362 break;
1363 }
1364 return ret_size;
1365}
1366
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05301367/**
1368 * afe_q6_interface_prepare -
1369 * wrapper API to check Q6 AFE registered to APR otherwise registers
1370 *
1371 * Returns 0 on success or error on failure.
1372 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301373int afe_q6_interface_prepare(void)
1374{
1375 int ret = 0;
1376
1377 pr_debug("%s:\n", __func__);
1378
1379 if (this_afe.apr == NULL) {
1380 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
1381 0xFFFFFFFF, &this_afe);
1382 if (this_afe.apr == NULL) {
1383 pr_err("%s: Unable to register AFE\n", __func__);
Laxminath Kasamc910c022018-04-04 10:59:57 +05301384 ret = -ENETRESET;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301385 }
1386 rtac_set_afe_handle(this_afe.apr);
1387 }
1388 return ret;
1389}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05301390EXPORT_SYMBOL(afe_q6_interface_prepare);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301391
1392/*
1393 * afe_apr_send_pkt : returns 0 on success, negative otherwise.
1394 */
1395static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait)
1396{
1397 int ret;
1398
Aditya Bavanarid6546e32019-10-29 17:24:59 +05301399 mutex_lock(&this_afe.afe_apr_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301400 if (wait)
1401 atomic_set(&this_afe.state, 1);
1402 atomic_set(&this_afe.status, 0);
1403 ret = apr_send_pkt(this_afe.apr, data);
1404 if (ret > 0) {
1405 if (wait) {
1406 ret = wait_event_timeout(*wait,
1407 (atomic_read(&this_afe.state) == 0),
Vidyakumar Athotaaade87e2018-10-26 17:28:46 -07001408 msecs_to_jiffies(2 * TIMEOUT_MS));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301409 if (!ret) {
Aditya Bavanarid6546e32019-10-29 17:24:59 +05301410 pr_err_ratelimited("%s: request timedout\n",
1411 __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301412 ret = -ETIMEDOUT;
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07001413 trace_printk("%s: wait for ADSP response timed out\n",
1414 __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301415 } else if (atomic_read(&this_afe.status) > 0) {
1416 pr_err("%s: DSP returned error[%s]\n", __func__,
1417 adsp_err_get_err_str(atomic_read(
1418 &this_afe.status)));
1419 ret = adsp_err_get_lnx_err_code(
1420 atomic_read(&this_afe.status));
1421 } else {
1422 ret = 0;
1423 }
1424 } else {
1425 ret = 0;
1426 }
1427 } else if (ret == 0) {
1428 pr_err("%s: packet not transmitted\n", __func__);
1429 /* apr_send_pkt can return 0 when nothing is transmitted */
1430 ret = -EINVAL;
1431 }
1432
1433 pr_debug("%s: leave %d\n", __func__, ret);
Aditya Bavanarid6546e32019-10-29 17:24:59 +05301434 mutex_unlock(&this_afe.afe_apr_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301435 return ret;
1436}
Meng Wang9eacb962019-11-19 09:16:55 +08001437/*
1438 * afe_apr_send_clk_pkt : returns 0 on success, negative otherwise.
1439 */
1440static int afe_apr_send_clk_pkt(void *data, wait_queue_head_t *wait)
1441{
1442 int ret;
1443
1444 if (wait)
1445 atomic_set(&this_afe.clk_state, 1);
1446 atomic_set(&this_afe.clk_status, 0);
1447 ret = apr_send_pkt(this_afe.apr, data);
1448 if (ret > 0) {
1449 if (wait) {
1450 ret = wait_event_timeout(*wait,
1451 (atomic_read(&this_afe.clk_state) == 0),
1452 msecs_to_jiffies(2 * TIMEOUT_MS));
1453 if (!ret) {
1454 pr_err("%s: timeout\n", __func__);
1455 ret = -ETIMEDOUT;
1456 } else if (atomic_read(&this_afe.clk_status) > 0) {
1457 pr_err("%s: DSP returned error[%s]\n", __func__,
1458 adsp_err_get_err_str(atomic_read(
1459 &this_afe.clk_status)));
1460 ret = adsp_err_get_lnx_err_code(
1461 atomic_read(&this_afe.clk_status));
1462 } else {
1463 ret = 0;
1464 }
1465 } else {
1466 ret = 0;
1467 }
1468 } else if (ret == 0) {
1469 pr_err("%s: packet not transmitted\n", __func__);
1470 /* apr_send_pkt can return 0 when nothing is transmitted */
1471 ret = -EINVAL;
1472 }
1473
1474 pr_debug("%s: leave %d\n", __func__, ret);
1475 return ret;
1476}
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301477
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08001478/* This function shouldn't be called directly. Instead call q6afe_set_params. */
1479static int q6afe_set_params_v2(u16 port_id, int index,
1480 struct mem_mapping_hdr *mem_hdr,
1481 u8 *packed_param_data, u32 packed_data_size)
1482{
1483 struct afe_port_cmd_set_param_v2 *set_param = NULL;
1484 uint32_t size = sizeof(struct afe_port_cmd_set_param_v2);
1485 int rc = 0;
1486
1487 if (packed_param_data != NULL)
1488 size += packed_data_size;
1489 set_param = kzalloc(size, GFP_KERNEL);
1490 if (set_param == NULL)
1491 return -ENOMEM;
1492
1493 set_param->apr_hdr.hdr_field =
1494 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
1495 APR_PKT_VER);
1496 set_param->apr_hdr.pkt_size = size;
1497 set_param->apr_hdr.src_port = 0;
1498 set_param->apr_hdr.dest_port = 0;
1499 set_param->apr_hdr.token = index;
1500 set_param->apr_hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
1501 set_param->port_id = port_id;
1502 if (packed_data_size > U16_MAX) {
1503 pr_err("%s: Invalid data size for set params V2 %d\n", __func__,
1504 packed_data_size);
1505 rc = -EINVAL;
1506 goto done;
1507 }
1508 set_param->payload_size = packed_data_size;
1509 if (mem_hdr != NULL) {
1510 set_param->mem_hdr = *mem_hdr;
1511 } else if (packed_param_data != NULL) {
1512 memcpy(&set_param->param_data, packed_param_data,
1513 packed_data_size);
1514 } else {
1515 pr_err("%s: Both memory header and param data are NULL\n",
1516 __func__);
1517 rc = -EINVAL;
1518 goto done;
1519 }
1520
1521 rc = afe_apr_send_pkt(set_param, &this_afe.wait[index]);
1522done:
1523 kfree(set_param);
1524 return rc;
1525}
1526
1527/* This function shouldn't be called directly. Instead call q6afe_set_params. */
1528static int q6afe_set_params_v3(u16 port_id, int index,
1529 struct mem_mapping_hdr *mem_hdr,
1530 u8 *packed_param_data, u32 packed_data_size)
1531{
1532 struct afe_port_cmd_set_param_v3 *set_param = NULL;
1533 uint32_t size = sizeof(struct afe_port_cmd_set_param_v3);
1534 int rc = 0;
1535
1536 if (packed_param_data != NULL)
1537 size += packed_data_size;
1538 set_param = kzalloc(size, GFP_KERNEL);
1539 if (set_param == NULL)
1540 return -ENOMEM;
1541
1542 set_param->apr_hdr.hdr_field =
1543 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
1544 APR_PKT_VER);
1545 set_param->apr_hdr.pkt_size = size;
1546 set_param->apr_hdr.src_port = 0;
1547 set_param->apr_hdr.dest_port = 0;
1548 set_param->apr_hdr.token = index;
1549 set_param->apr_hdr.opcode = AFE_PORT_CMD_SET_PARAM_V3;
1550 set_param->port_id = port_id;
1551 set_param->payload_size = packed_data_size;
1552 if (mem_hdr != NULL) {
1553 set_param->mem_hdr = *mem_hdr;
1554 } else if (packed_param_data != NULL) {
1555 memcpy(&set_param->param_data, packed_param_data,
1556 packed_data_size);
1557 } else {
1558 pr_err("%s: Both memory header and param data are NULL\n",
1559 __func__);
1560 rc = -EINVAL;
1561 goto done;
1562 }
1563
1564 rc = afe_apr_send_pkt(set_param, &this_afe.wait[index]);
1565done:
1566 kfree(set_param);
1567 return rc;
1568}
1569
1570static int q6afe_set_params(u16 port_id, int index,
1571 struct mem_mapping_hdr *mem_hdr,
1572 u8 *packed_param_data, u32 packed_data_size)
1573{
1574 int ret = 0;
1575
1576 ret = afe_q6_interface_prepare();
1577 if (ret != 0) {
1578 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
1579 return ret;
1580 }
1581
1582 port_id = q6audio_get_port_id(port_id);
1583 ret = q6audio_validate_port(port_id);
1584 if (ret < 0) {
1585 pr_err("%s: Not a valid port id = 0x%x ret %d\n", __func__,
1586 port_id, ret);
1587 return -EINVAL;
1588 }
1589
1590 if (index < 0 || index >= AFE_MAX_PORTS) {
1591 pr_err("%s: AFE port index[%d] invalid\n", __func__, index);
1592 return -EINVAL;
1593 }
1594
1595 if (q6common_is_instance_id_supported())
1596 return q6afe_set_params_v3(port_id, index, mem_hdr,
1597 packed_param_data, packed_data_size);
1598 else
1599 return q6afe_set_params_v2(port_id, index, mem_hdr,
1600 packed_param_data, packed_data_size);
1601}
1602
1603static int q6afe_pack_and_set_param_in_band(u16 port_id, int index,
1604 struct param_hdr_v3 param_hdr,
1605 u8 *param_data)
1606{
1607 u8 *packed_param_data = NULL;
1608 int packed_data_size = sizeof(union param_hdrs) + param_hdr.param_size;
1609 int ret;
1610
1611 packed_param_data = kzalloc(packed_data_size, GFP_KERNEL);
1612 if (packed_param_data == NULL)
1613 return -ENOMEM;
1614
1615 ret = q6common_pack_pp_params(packed_param_data, &param_hdr, param_data,
1616 &packed_data_size);
1617 if (ret) {
1618 pr_err("%s: Failed to pack param header and data, error %d\n",
1619 __func__, ret);
1620 goto fail_cmd;
1621 }
1622
1623 ret = q6afe_set_params(port_id, index, NULL, packed_param_data,
1624 packed_data_size);
1625
1626fail_cmd:
1627 kfree(packed_param_data);
1628 return ret;
1629}
1630
Sudheer Papothiaf431ad2018-05-04 05:06:11 +05301631static int q6afe_set_aanc_level(void)
1632{
1633 struct param_hdr_v3 param_hdr;
1634 struct afe_param_id_aanc_noise_reduction aanc_noise_level;
1635 int ret = 0;
1636 uint16_t tx_port = 0;
1637
1638 if (!this_afe.aanc_info.aanc_active)
1639 return -EINVAL;
1640
1641 pr_debug("%s: level: %d\n", __func__, this_afe.aanc_info.level);
1642 memset(&aanc_noise_level, 0, sizeof(aanc_noise_level));
1643 aanc_noise_level.minor_version = 1;
1644 aanc_noise_level.ad_beta = this_afe.aanc_info.level;
1645
1646 memset(&param_hdr, 0, sizeof(param_hdr));
1647 param_hdr.module_id = AFE_MODULE_AANC;
1648 param_hdr.instance_id = INSTANCE_ID_0;
1649 param_hdr.param_id = AFE_PARAM_ID_AANC_NOISE_REDUCTION;
1650 param_hdr.param_size = sizeof(struct afe_param_id_aanc_noise_reduction);
1651
1652 tx_port = this_afe.aanc_info.aanc_tx_port;
1653 ret = q6afe_pack_and_set_param_in_band(tx_port,
1654 q6audio_get_port_index(tx_port),
1655 param_hdr,
1656 (u8 *) &aanc_noise_level);
1657 if (ret)
1658 pr_err("%s: AANC noise level enable failed for tx_port 0x%x ret %d\n",
1659 __func__, tx_port, ret);
1660 return ret;
1661}
1662
1663/**
1664 * afe_set_aanc_noise_level - controls aanc noise reduction strength
1665 *
1666 * @level: Noise level to be controlled
1667 *
1668 * Returns 0 on success or error on failure.
1669 */
1670int afe_set_aanc_noise_level(int level)
1671{
1672 int ret = 0;
1673
1674 if (this_afe.aanc_info.level == level)
1675 return ret;
1676
1677 mutex_lock(&this_afe.afe_cmd_lock);
1678 this_afe.aanc_info.level = level;
1679 ret = q6afe_set_aanc_level();
1680 mutex_unlock(&this_afe.afe_cmd_lock);
1681
1682 return ret;
1683}
1684EXPORT_SYMBOL(afe_set_aanc_noise_level);
1685
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08001686/* This function shouldn't be called directly. Instead call q6afe_get_param. */
1687static int q6afe_get_params_v2(u16 port_id, int index,
1688 struct mem_mapping_hdr *mem_hdr,
1689 struct param_hdr_v3 *param_hdr)
1690{
1691 struct afe_port_cmd_get_param_v2 afe_get_param;
1692 u32 param_size = param_hdr->param_size;
1693
1694 memset(&afe_get_param, 0, sizeof(afe_get_param));
1695 afe_get_param.apr_hdr.hdr_field =
1696 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
1697 APR_PKT_VER);
Aditya Bavanarib7788462019-07-02 20:08:14 +05301698 afe_get_param.apr_hdr.pkt_size = sizeof(afe_get_param);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08001699 afe_get_param.apr_hdr.src_port = 0;
1700 afe_get_param.apr_hdr.dest_port = 0;
1701 afe_get_param.apr_hdr.token = index;
1702 afe_get_param.apr_hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
1703 afe_get_param.port_id = port_id;
1704 afe_get_param.payload_size = sizeof(struct param_hdr_v1) + param_size;
1705 if (mem_hdr != NULL)
1706 afe_get_param.mem_hdr = *mem_hdr;
1707 /* Set MID and PID in command */
1708 afe_get_param.module_id = param_hdr->module_id;
1709 afe_get_param.param_id = param_hdr->param_id;
1710 /* Set param header in payload */
1711 afe_get_param.param_hdr.module_id = param_hdr->module_id;
1712 afe_get_param.param_hdr.param_id = param_hdr->param_id;
1713 afe_get_param.param_hdr.param_size = param_size;
1714
1715 return afe_apr_send_pkt(&afe_get_param, &this_afe.wait[index]);
1716}
1717
1718/* This function shouldn't be called directly. Instead call q6afe_get_param. */
1719static int q6afe_get_params_v3(u16 port_id, int index,
1720 struct mem_mapping_hdr *mem_hdr,
1721 struct param_hdr_v3 *param_hdr)
1722{
1723 struct afe_port_cmd_get_param_v3 afe_get_param;
1724
1725 memset(&afe_get_param, 0, sizeof(afe_get_param));
1726 afe_get_param.apr_hdr.hdr_field =
1727 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
1728 APR_PKT_VER);
1729 afe_get_param.apr_hdr.pkt_size = sizeof(afe_get_param);
1730 afe_get_param.apr_hdr.src_port = 0;
1731 afe_get_param.apr_hdr.dest_port = 0;
1732 afe_get_param.apr_hdr.token = index;
1733 afe_get_param.apr_hdr.opcode = AFE_PORT_CMD_GET_PARAM_V3;
1734 afe_get_param.port_id = port_id;
1735 if (mem_hdr != NULL)
1736 afe_get_param.mem_hdr = *mem_hdr;
1737 /* Set param header in command, no payload in V3 */
1738 afe_get_param.param_hdr = *param_hdr;
1739
1740 return afe_apr_send_pkt(&afe_get_param, &this_afe.wait[index]);
1741}
1742
1743/*
1744 * Calling functions copy param data directly from this_afe. Do not copy data
1745 * back to caller here.
1746 */
1747static int q6afe_get_params(u16 port_id, struct mem_mapping_hdr *mem_hdr,
1748 struct param_hdr_v3 *param_hdr)
1749{
1750 int index;
1751 int ret;
1752
1753 ret = afe_q6_interface_prepare();
1754 if (ret != 0) {
1755 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
1756 return ret;
1757 }
1758
1759 port_id = q6audio_get_port_id(port_id);
1760 ret = q6audio_validate_port(port_id);
1761 if (ret < 0) {
1762 pr_err("%s: Not a valid port id = 0x%x ret %d\n", __func__,
1763 port_id, ret);
1764 return -EINVAL;
1765 }
1766
1767 index = q6audio_get_port_index(port_id);
1768 if (index < 0 || index >= AFE_MAX_PORTS) {
1769 pr_err("%s: AFE port index[%d] invalid\n", __func__, index);
1770 return -EINVAL;
1771 }
1772
1773 if (q6common_is_instance_id_supported())
1774 return q6afe_get_params_v3(port_id, index, NULL, param_hdr);
1775 else
1776 return q6afe_get_params_v2(port_id, index, NULL, param_hdr);
1777}
1778
1779/*
1780 * This function shouldn't be called directly. Instead call
1781 * q6afe_svc_set_params.
1782 */
1783static int q6afe_svc_set_params_v1(int index, struct mem_mapping_hdr *mem_hdr,
1784 u8 *packed_param_data, u32 packed_data_size)
1785{
1786 struct afe_svc_cmd_set_param_v1 *svc_set_param = NULL;
1787 uint32_t size = sizeof(struct afe_svc_cmd_set_param_v1);
1788 int rc = 0;
1789
1790 if (packed_param_data != NULL)
1791 size += packed_data_size;
1792 svc_set_param = kzalloc(size, GFP_KERNEL);
1793 if (svc_set_param == NULL)
1794 return -ENOMEM;
1795
1796 svc_set_param->apr_hdr.hdr_field =
1797 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
1798 APR_PKT_VER);
1799 svc_set_param->apr_hdr.pkt_size = size;
1800 svc_set_param->apr_hdr.src_port = 0;
1801 svc_set_param->apr_hdr.dest_port = 0;
Vignesh Kulothungan87f926a2018-03-04 22:47:50 -08001802 svc_set_param->apr_hdr.token = index;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08001803 svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM;
1804 svc_set_param->payload_size = packed_data_size;
1805
1806 if (mem_hdr != NULL) {
1807 /* Out of band case. */
1808 svc_set_param->mem_hdr = *mem_hdr;
1809 } else if (packed_param_data != NULL) {
1810 /* In band case. */
1811 memcpy(&svc_set_param->param_data, packed_param_data,
1812 packed_data_size);
1813 } else {
1814 pr_err("%s: Both memory header and param data are NULL\n",
1815 __func__);
1816 rc = -EINVAL;
1817 goto done;
1818 }
1819
1820 rc = afe_apr_send_pkt(svc_set_param, &this_afe.wait[index]);
1821done:
1822 kfree(svc_set_param);
1823 return rc;
1824}
1825
1826/*
1827 * This function shouldn't be called directly. Instead call
1828 * q6afe_svc_set_params.
1829 */
1830static int q6afe_svc_set_params_v2(int index, struct mem_mapping_hdr *mem_hdr,
1831 u8 *packed_param_data, u32 packed_data_size)
1832{
1833 struct afe_svc_cmd_set_param_v2 *svc_set_param = NULL;
1834 uint16_t size = sizeof(struct afe_svc_cmd_set_param_v2);
1835 int rc = 0;
1836
1837 if (packed_param_data != NULL)
1838 size += packed_data_size;
1839 svc_set_param = kzalloc(size, GFP_KERNEL);
1840 if (svc_set_param == NULL)
1841 return -ENOMEM;
1842
1843 svc_set_param->apr_hdr.hdr_field =
1844 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
1845 APR_PKT_VER);
1846 svc_set_param->apr_hdr.pkt_size = size;
1847 svc_set_param->apr_hdr.src_port = 0;
1848 svc_set_param->apr_hdr.dest_port = 0;
Vignesh Kulothungan87f926a2018-03-04 22:47:50 -08001849 svc_set_param->apr_hdr.token = index;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08001850 svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM_V2;
1851 svc_set_param->payload_size = packed_data_size;
1852
1853 if (mem_hdr != NULL) {
1854 /* Out of band case. */
1855 svc_set_param->mem_hdr = *mem_hdr;
1856 } else if (packed_param_data != NULL) {
1857 /* In band case. */
1858 memcpy(&svc_set_param->param_data, packed_param_data,
1859 packed_data_size);
1860 } else {
1861 pr_err("%s: Both memory header and param data are NULL\n",
1862 __func__);
1863 rc = -EINVAL;
1864 goto done;
1865 }
1866
1867 rc = afe_apr_send_pkt(svc_set_param, &this_afe.wait[index]);
1868done:
1869 kfree(svc_set_param);
1870 return rc;
1871}
1872
Meng Wang9eacb962019-11-19 09:16:55 +08001873/*
1874 * This function shouldn't be called directly. Instead call
1875 * q6afe_clk_set_params.
1876 */
1877static int q6afe_clk_set_params_v1(int index, struct mem_mapping_hdr *mem_hdr,
1878 u8 *packed_param_data, u32 packed_data_size)
1879{
1880 struct afe_svc_cmd_set_param_v1 *svc_set_param = NULL;
1881 uint32_t size = sizeof(struct afe_svc_cmd_set_param_v1);
1882 int rc = 0;
1883
1884 if (packed_param_data != NULL)
1885 size += packed_data_size;
1886 svc_set_param = kzalloc(size, GFP_KERNEL);
1887 if (svc_set_param == NULL)
1888 return -ENOMEM;
1889
1890 svc_set_param->apr_hdr.hdr_field =
1891 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
1892 APR_PKT_VER);
1893 svc_set_param->apr_hdr.pkt_size = size;
1894 svc_set_param->apr_hdr.src_port = 0;
1895 svc_set_param->apr_hdr.dest_port = 0;
1896 svc_set_param->apr_hdr.token = AFE_CLK_TOKEN;
1897 svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM;
1898 svc_set_param->payload_size = packed_data_size;
1899
1900 if (mem_hdr != NULL) {
1901 /* Out of band case. */
1902 svc_set_param->mem_hdr = *mem_hdr;
1903 } else if (packed_param_data != NULL) {
1904 /* In band case. */
1905 memcpy(&svc_set_param->param_data, packed_param_data,
1906 packed_data_size);
1907 } else {
1908 pr_err("%s: Both memory header and param data are NULL\n",
1909 __func__);
1910 rc = -EINVAL;
1911 goto done;
1912 }
1913
1914 rc = afe_apr_send_clk_pkt(svc_set_param, &this_afe.clk_wait);
1915done:
1916 kfree(svc_set_param);
1917 return rc;
1918}
1919
1920/*
1921 * This function shouldn't be called directly. Instead call
1922 * q6afe_clk_set_params.
1923 */
1924static int q6afe_clk_set_params_v2(int index, struct mem_mapping_hdr *mem_hdr,
1925 u8 *packed_param_data, u32 packed_data_size)
1926{
1927 struct afe_svc_cmd_set_param_v2 *svc_set_param = NULL;
1928 uint16_t size = sizeof(struct afe_svc_cmd_set_param_v2);
1929 int rc = 0;
1930
1931 if (packed_param_data != NULL)
1932 size += packed_data_size;
1933 svc_set_param = kzalloc(size, GFP_KERNEL);
1934 if (svc_set_param == NULL)
1935 return -ENOMEM;
1936
1937 svc_set_param->apr_hdr.hdr_field =
1938 APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
1939 APR_PKT_VER);
1940 svc_set_param->apr_hdr.pkt_size = size;
1941 svc_set_param->apr_hdr.src_port = 0;
1942 svc_set_param->apr_hdr.dest_port = 0;
1943 svc_set_param->apr_hdr.token = AFE_CLK_TOKEN;
1944 svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM_V2;
1945 svc_set_param->payload_size = packed_data_size;
1946
1947 if (mem_hdr != NULL) {
1948 /* Out of band case. */
1949 svc_set_param->mem_hdr = *mem_hdr;
1950 } else if (packed_param_data != NULL) {
1951 /* In band case. */
1952 memcpy(&svc_set_param->param_data, packed_param_data,
1953 packed_data_size);
1954 } else {
1955 pr_err("%s: Both memory header and param data are NULL\n",
1956 __func__);
1957 rc = -EINVAL;
1958 goto done;
1959 }
1960
1961 rc = afe_apr_send_clk_pkt(svc_set_param, &this_afe.clk_wait);
1962done:
1963 kfree(svc_set_param);
1964 return rc;
1965}
1966
1967static int q6afe_clk_set_params(int index, struct mem_mapping_hdr *mem_hdr,
1968 u8 *packed_param_data, u32 packed_data_size,
1969 bool is_iid_supported)
1970{
1971 int ret;
1972
1973 ret = afe_q6_interface_prepare();
1974 if (ret != 0) {
1975 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
1976 return ret;
1977 }
1978
1979 if (is_iid_supported)
1980 return q6afe_clk_set_params_v2(index, mem_hdr,
1981 packed_param_data,
1982 packed_data_size);
1983 else
1984 return q6afe_clk_set_params_v1(index, mem_hdr,
1985 packed_param_data,
1986 packed_data_size);
1987}
1988
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08001989static int q6afe_svc_set_params(int index, struct mem_mapping_hdr *mem_hdr,
Aditya Bavanari23513e02019-02-28 11:06:41 +05301990 u8 *packed_param_data, u32 packed_data_size,
1991 bool is_iid_supported)
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08001992{
1993 int ret;
1994
1995 ret = afe_q6_interface_prepare();
1996 if (ret != 0) {
1997 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
1998 return ret;
1999 }
2000
Aditya Bavanari23513e02019-02-28 11:06:41 +05302001 if (is_iid_supported)
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002002 return q6afe_svc_set_params_v2(index, mem_hdr,
2003 packed_param_data,
2004 packed_data_size);
2005 else
2006 return q6afe_svc_set_params_v1(index, mem_hdr,
2007 packed_param_data,
2008 packed_data_size);
2009}
2010
2011static int q6afe_svc_pack_and_set_param_in_band(int index,
2012 struct param_hdr_v3 param_hdr,
2013 u8 *param_data)
2014{
2015 u8 *packed_param_data = NULL;
2016 u32 packed_data_size =
2017 sizeof(struct param_hdr_v3) + param_hdr.param_size;
2018 int ret = 0;
Aditya Bavanari23513e02019-02-28 11:06:41 +05302019 bool is_iid_supported = q6common_is_instance_id_supported();
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002020
2021 packed_param_data = kzalloc(packed_data_size, GFP_KERNEL);
2022 if (!packed_param_data)
2023 return -ENOMEM;
2024
Aditya Bavanari23513e02019-02-28 11:06:41 +05302025 ret = q6common_pack_pp_params_v2(packed_param_data, &param_hdr,
2026 param_data, &packed_data_size,
2027 is_iid_supported);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002028 if (ret) {
2029 pr_err("%s: Failed to pack parameter header and data, error %d\n",
2030 __func__, ret);
2031 goto done;
2032 }
Meng Wang9eacb962019-11-19 09:16:55 +08002033 if (param_hdr.module_id == AFE_MODULE_CLOCK_SET)
2034 ret = q6afe_clk_set_params(index, NULL, packed_param_data,
2035 packed_data_size, is_iid_supported);
2036 else
2037 ret = q6afe_svc_set_params(index, NULL, packed_param_data,
2038 packed_data_size, is_iid_supported);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002039
2040done:
2041 kfree(packed_param_data);
2042 return ret;
2043}
2044
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302045static int afe_send_cal_block(u16 port_id, struct cal_block_data *cal_block)
2046{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002047 struct mem_mapping_hdr mem_hdr;
2048 int payload_size = 0;
2049 int result = 0;
2050
2051 memset(&mem_hdr, 0, sizeof(mem_hdr));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302052
2053 if (!cal_block) {
2054 pr_debug("%s: No AFE cal to send!\n", __func__);
2055 result = -EINVAL;
2056 goto done;
2057 }
2058 if (cal_block->cal_data.size <= 0) {
2059 pr_debug("%s: AFE cal has invalid size!\n", __func__);
2060 result = -EINVAL;
2061 goto done;
2062 }
2063
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002064 payload_size = cal_block->cal_data.size;
2065 mem_hdr.data_payload_addr_lsw =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302066 lower_32_bits(cal_block->cal_data.paddr);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002067 mem_hdr.data_payload_addr_msw =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302068 msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002069 mem_hdr.mem_map_handle = cal_block->map_data.q6map_handle;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302070
2071 pr_debug("%s: AFE cal sent for device port = 0x%x, cal size = %zd, cal addr = 0x%pK\n",
2072 __func__, port_id,
2073 cal_block->cal_data.size, &cal_block->cal_data.paddr);
2074
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002075 result = q6afe_set_params(port_id, q6audio_get_port_index(port_id),
2076 &mem_hdr, NULL, payload_size);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302077 if (result)
2078 pr_err("%s: AFE cal for port 0x%x failed %d\n",
2079 __func__, port_id, result);
2080
2081done:
2082 return result;
2083}
2084
2085
2086static int afe_send_custom_topology_block(struct cal_block_data *cal_block)
2087{
2088 int result = 0;
2089 int index = 0;
2090 struct cmd_set_topologies afe_cal;
2091
2092 if (!cal_block) {
2093 pr_err("%s: No AFE SVC cal to send!\n", __func__);
2094 return -EINVAL;
2095 }
2096 if (cal_block->cal_data.size <= 0) {
2097 pr_err("%s: AFE SVC cal has invalid size: %zd!\n",
2098 __func__, cal_block->cal_data.size);
2099 return -EINVAL;
2100 }
2101
2102 afe_cal.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2103 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2104 afe_cal.hdr.pkt_size = sizeof(afe_cal);
2105 afe_cal.hdr.src_port = 0;
2106 afe_cal.hdr.dest_port = 0;
2107 afe_cal.hdr.token = index;
2108 afe_cal.hdr.opcode = AFE_CMD_ADD_TOPOLOGIES;
2109
2110 afe_cal.payload_size = cal_block->cal_data.size;
2111 afe_cal.payload_addr_lsw =
2112 lower_32_bits(cal_block->cal_data.paddr);
2113 afe_cal.payload_addr_msw =
2114 msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
2115 afe_cal.mem_map_handle = cal_block->map_data.q6map_handle;
2116
2117 pr_debug("%s:cmd_id:0x%x calsize:%zd memmap_hdl:0x%x caladdr:0x%pK",
2118 __func__, AFE_CMD_ADD_TOPOLOGIES, cal_block->cal_data.size,
2119 afe_cal.mem_map_handle, &cal_block->cal_data.paddr);
2120
2121 result = afe_apr_send_pkt(&afe_cal, &this_afe.wait[index]);
2122 if (result)
2123 pr_err("%s: AFE send topology for command 0x%x failed %d\n",
2124 __func__, AFE_CMD_ADD_TOPOLOGIES, result);
2125
2126 return result;
2127}
2128
2129static void afe_send_custom_topology(void)
2130{
2131 struct cal_block_data *cal_block = NULL;
2132 int cal_index = AFE_CUST_TOPOLOGY_CAL;
2133 int ret;
2134
2135 if (this_afe.cal_data[cal_index] == NULL) {
2136 pr_err("%s: cal_index %d not allocated!\n",
2137 __func__, cal_index);
2138 return;
2139 }
2140 mutex_lock(&this_afe.cal_data[cal_index]->lock);
2141
2142 if (!this_afe.set_custom_topology)
2143 goto unlock;
2144 this_afe.set_custom_topology = 0;
2145 cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]);
Vikram Panduranga770b8382017-09-27 12:17:36 -07002146 if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302147 pr_err("%s cal_block not found!!\n", __func__);
2148 goto unlock;
2149 }
2150
2151 pr_debug("%s: Sending cal_index cal %d\n", __func__, cal_index);
2152
2153 ret = remap_cal_data(cal_block, cal_index);
2154 if (ret) {
2155 pr_err("%s: Remap_cal_data failed for cal %d!\n",
2156 __func__, cal_index);
2157 goto unlock;
2158 }
2159 ret = afe_send_custom_topology_block(cal_block);
2160 if (ret < 0) {
2161 pr_err("%s: No cal sent for cal_index %d! ret %d\n",
2162 __func__, cal_index, ret);
2163 goto unlock;
2164 }
2165 pr_debug("%s:sent custom topology for AFE\n", __func__);
2166unlock:
2167 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
2168}
2169
2170static int afe_spk_ramp_dn_cfg(int port)
2171{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002172 struct param_hdr_v3 param_info;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302173 int ret = -EINVAL;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002174
2175 memset(&param_info, 0, sizeof(param_info));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302176
2177 if (afe_get_port_type(port) != MSM_AFE_PORT_TYPE_RX) {
2178 pr_debug("%s: port doesn't match 0x%x\n", __func__, port);
2179 return 0;
2180 }
2181 if (this_afe.prot_cfg.mode == MSM_SPKR_PROT_DISABLED ||
2182 (this_afe.vi_rx_port != port)) {
2183 pr_debug("%s: spkr protection disabled port 0x%x %d 0x%x\n",
2184 __func__, port, ret, this_afe.vi_rx_port);
2185 return 0;
2186 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002187 param_info.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX;
2188 param_info.instance_id = INSTANCE_ID_0;
2189 param_info.param_id = AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG;
2190 param_info.param_size = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302191
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002192 ret = q6afe_pack_and_set_param_in_band(port,
2193 q6audio_get_port_index(port),
2194 param_info, NULL);
2195 if (ret) {
2196 pr_err("%s: Failed to set speaker ramp duration param, err %d\n",
2197 __func__, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302198 goto fail_cmd;
2199 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002200
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302201 /* dsp needs atleast 15ms to ramp down pilot tone*/
2202 usleep_range(15000, 15010);
2203 ret = 0;
2204fail_cmd:
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002205 pr_debug("%s: config.pdata.param_id 0x%x status %d\n", __func__,
2206 param_info.param_id, ret);
2207 return ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302208}
2209
Faiz Nabi Kuchay29093022020-10-08 18:25:49 +05302210static int afe_send_cps_config(int src_port)
2211{
2212 int i = 0;
2213 struct param_hdr_v3 param_info;
2214 int ret = -EINVAL;
2215 u8 *packed_payload = NULL;
2216 int cpy_size = 0;
2217 int ch_copied = 0;
2218 size_t param_size = 0;
2219
2220 if ((-1 == this_afe.vi_tx_port) || (!this_afe.cps_ch_mask) ||
2221 (!this_afe.cps_config)) {
2222 pr_err("%s: speaker prot not configured for 0x%x\n", __func__,
2223 src_port);
2224 return -EINVAL;
2225 }
2226
2227 param_size = sizeof(struct afe_cps_hw_intf_cfg) -
2228 sizeof(this_afe.cps_config->spkr_dep_cfg) +
2229 (sizeof(struct lpass_swr_spkr_dep_cfg_t)
2230 * this_afe.num_spkrs);
2231
2232 this_afe.cps_config->hw_reg_cfg.num_spkr = this_afe.num_spkrs;
2233 packed_payload = kzalloc(param_size, GFP_KERNEL);
2234 if (packed_payload == NULL)
2235 return -ENOMEM;
2236
2237 cpy_size = sizeof(struct afe_cps_hw_intf_cfg) -
2238 sizeof(this_afe.cps_config->spkr_dep_cfg);
2239 memcpy(packed_payload, this_afe.cps_config, cpy_size);
2240
2241 while (ch_copied < this_afe.num_spkrs) {
2242 if (!(this_afe.cps_ch_mask & (1 << i))) {
2243 i++;
2244 continue;
2245 }
2246
2247 memcpy(packed_payload + cpy_size,
2248 &this_afe.cps_config->spkr_dep_cfg[i],
2249 sizeof(struct lpass_swr_spkr_dep_cfg_t));
2250 cpy_size += sizeof(struct lpass_swr_spkr_dep_cfg_t);
2251 ch_copied++;
2252 i++;
2253 }
2254
2255 memset(&param_info, 0, sizeof(param_info));
2256 param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_RX;
2257 param_info.instance_id = INSTANCE_ID_0;
2258 param_info.param_id = AFE_PARAM_ID_CPS_LPASS_HW_INTF_CFG;
2259 param_info.param_size = param_size;
2260
2261 ret = q6afe_pack_and_set_param_in_band(src_port,
2262 q6audio_get_port_index(src_port),
2263 param_info, packed_payload);
2264 if (ret)
2265 pr_err("%s: port = 0x%x param = 0x%x failed %d\n", __func__,
2266 src_port, param_info.param_id, ret);
2267
2268 pr_debug("%s: config.pdata.param_id 0x%x status %d 0x%x\n", __func__,
2269 param_info.param_id, ret, src_port);
2270 kfree(packed_payload);
2271 return ret;
2272}
2273
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302274static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id,
Vangala, Amarnath78732302020-04-09 03:57:14 +05302275 union afe_spkr_prot_config *prot_config, uint32_t param_size)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302276{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002277 struct param_hdr_v3 param_info;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302278 int ret = -EINVAL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302279
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002280 memset(&param_info, 0, sizeof(param_info));
2281
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302282 ret = q6audio_validate_port(src_port);
2283 if (ret < 0) {
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002284 pr_err("%s: Invalid src port 0x%x ret %d", __func__, src_port,
2285 ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302286 ret = -EINVAL;
2287 goto fail_cmd;
2288 }
2289 ret = q6audio_validate_port(dst_port);
2290 if (ret < 0) {
2291 pr_err("%s: Invalid dst port 0x%x ret %d", __func__,
2292 dst_port, ret);
2293 ret = -EINVAL;
2294 goto fail_cmd;
2295 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002296
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302297 switch (param_id) {
2298 case AFE_PARAM_ID_FBSP_MODE_RX_CFG:
Xiaojun Sang12120ab2017-09-28 18:21:21 +08002299 case AFE_PARAM_ID_SP_RX_LIMITER_TH:
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002300 param_info.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302301 break;
Vangala, Amarnath78732302020-04-09 03:57:14 +05302302 case AFE_PARAM_ID_SP_V4_OP_MODE:
2303 param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_RX;
2304 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302305 case AFE_PARAM_ID_FEEDBACK_PATH_CFG:
2306 this_afe.vi_tx_port = src_port;
2307 this_afe.vi_rx_port = dst_port;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002308 param_info.module_id = AFE_MODULE_FEEDBACK;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302309 break;
2310 /*
2311 * AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2 is same as
Laxminath Kasam2e13d952019-02-20 15:05:39 +05302312 * AFE_PARAM_ID_SP_V2_TH_VI_MODE_CFG. V_VALI_CFG uses
2313 * same module TH_VI.
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302314 */
2315 case AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2:
2316 case AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG:
Laxminath Kasam2e13d952019-02-20 15:05:39 +05302317 case AFE_PARAM_ID_SP_V2_TH_VI_V_VALI_CFG:
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002318 param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302319 break;
2320 case AFE_PARAM_ID_SP_V2_EX_VI_MODE_CFG:
2321 case AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG:
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002322 param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302323 break;
Vangala, Amarnath78732302020-04-09 03:57:14 +05302324 case AFE_PARAM_ID_SP_V4_VI_CHANNEL_MAP_CFG:
2325 case AFE_PARAM_ID_SP_V4_VI_OP_MODE_CFG:
2326 case AFE_PARAM_ID_SP_V4_VI_R0T0_CFG:
2327 case AFE_PARAM_ID_SP_V4_TH_VI_FTM_CFG:
2328 case AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_CFG:
2329 case AFE_PARAM_ID_SP_V4_EX_VI_MODE_CFG:
2330 case AFE_PARAM_ID_SP_V4_EX_VI_FTM_CFG:
2331 param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI;
2332 break;
lintaopei746b0122021-03-16 19:35:42 +08002333#ifdef CONFIG_SND_SMARTPA_AW882XX
2334 case AFE_PARAM_ID_AWDSP_RX_SET_ENABLE:
2335 case AFE_PARAM_ID_AWDSP_RX_PARAMS:
2336 param_info.module_id = AFE_MODULE_ID_AWDSP_RX;
2337 break;
2338 case AFE_PARAM_ID_AWDSP_TX_SET_ENABLE:
2339 param_info.module_id = AFE_MODULE_ID_AWDSP_TX;
2340 break;
2341#endif /*CONFIG_SND_SMARTPA_AW882XX*/
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302342 default:
2343 pr_err("%s: default case 0x%x\n", __func__, param_id);
2344 goto fail_cmd;
2345 }
2346
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002347 param_info.instance_id = INSTANCE_ID_0;
2348 param_info.param_id = param_id;
Vangala, Amarnath78732302020-04-09 03:57:14 +05302349 param_info.param_size = param_size;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302350
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002351 ret = q6afe_pack_and_set_param_in_band(src_port,
2352 q6audio_get_port_index(src_port),
2353 param_info, (u8 *) prot_config);
2354 if (ret)
2355 pr_err("%s: port = 0x%x param = 0x%x failed %d\n", __func__,
2356 src_port, param_id, ret);
2357
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302358fail_cmd:
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002359 pr_debug("%s: config.pdata.param_id 0x%x status %d 0x%x\n", __func__,
2360 param_info.param_id, ret, src_port);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302361 return ret;
2362}
2363
Vangala, Amarnath78732302020-04-09 03:57:14 +05302364static int afe_spkr_prot_reg_event_cfg(u16 port_id, uint32_t module_id)
Vidyakumar Athota94bd8732018-02-28 17:13:35 -08002365{
2366 struct afe_port_cmd_event_cfg *config;
2367 struct afe_port_cmd_mod_evt_cfg_payload pl;
2368 int index;
2369 int ret;
2370 int num_events = 1;
2371 int cmd_size = sizeof(struct afe_port_cmd_event_cfg) +
2372 (num_events * sizeof(struct afe_port_cmd_mod_evt_cfg_payload));
2373
2374 config = kzalloc(cmd_size, GFP_KERNEL);
2375 if (!config)
2376 return -ENOMEM;
2377
2378 index = q6audio_get_port_index(port_id);
2379 if (index < 0) {
2380 pr_err("%s: Invalid index number: %d\n", __func__, index);
2381 ret = -EINVAL;
2382 goto fail_idx;
2383 }
2384
2385 memset(&pl, 0, sizeof(pl));
Vangala, Amarnath78732302020-04-09 03:57:14 +05302386 pl.module_id = module_id;
Vidyakumar Athota94bd8732018-02-28 17:13:35 -08002387 pl.event_id = AFE_PORT_SP_DC_DETECTION_EVENT;
2388 pl.reg_flag = AFE_MODULE_REGISTER_EVENT_FLAG;
2389
2390
2391 config->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
2392 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
2393 config->hdr.pkt_size = cmd_size;
2394 config->hdr.src_port = 0;
2395 config->hdr.dest_port = 0;
2396 config->hdr.token = index;
2397
2398 config->hdr.opcode = AFE_PORT_CMD_MOD_EVENT_CFG;
2399 config->port_id = q6audio_get_port_id(port_id);
2400 config->num_events = num_events;
2401 config->version = 1;
2402 memcpy(config->payload, &pl, sizeof(pl));
Aditya Bavanarid6546e32019-10-29 17:24:59 +05302403 ret = afe_apr_send_pkt((uint32_t *) config, &this_afe.wait[index]);
Vidyakumar Athota94bd8732018-02-28 17:13:35 -08002404
2405fail_idx:
2406 kfree(config);
2407 return ret;
2408}
2409
Vangala, Amarnath78732302020-04-09 03:57:14 +05302410static void afe_send_cal_spv4_tx(int port_id)
2411{
2412 union afe_spkr_prot_config afe_spk_config;
2413 uint32_t size = 0;
2414 void *tmp_ptr = NULL;
2415 struct afe_sp_v4_param_th_vi_r0t0_cfg *th_vi_r0t0_cfg;
2416 struct afe_sp_v4_channel_r0t0 *ch_r0t0_cfg;
2417 struct afe_sp_v4_param_th_vi_ftm_cfg *th_vi_ftm_cfg;
2418 struct afe_sp_v4_channel_ftm_cfg *ch_ftm_cfg;
2419 struct afe_sp_v4_param_th_vi_v_vali_cfg *th_vi_v_vali_cfg;
2420 struct afe_sp_v4_channel_v_vali_cfg *ch_v_vali_cfg;
2421 struct afe_sp_v4_param_ex_vi_ftm_cfg *ex_vi_ftm_cfg;
2422 struct afe_sp_v4_channel_ex_vi_ftm *ch_ex_vi_ftm_cfg;
Vangala, Amarnath3e3537e2020-05-13 23:11:14 +05302423 uint32_t i = 0;
Vangala, Amarnath78732302020-04-09 03:57:14 +05302424
2425 pr_debug("%s: Entry.. port_id %d\n", __func__, port_id);
2426
2427 if (this_afe.vi_tx_port == port_id) {
2428 memcpy(&afe_spk_config.v4_ch_map_cfg, &this_afe.v4_ch_map_cfg,
2429 sizeof(struct afe_sp_v4_param_vi_channel_map_cfg));
lintaopeie994a2e2021-04-02 14:31:18 +08002430 /*if (afe_spk_prot_prepare(port_id, this_afe.vi_rx_port,
Vangala, Amarnath78732302020-04-09 03:57:14 +05302431 AFE_PARAM_ID_SP_V4_VI_CHANNEL_MAP_CFG, &afe_spk_config,
2432 sizeof(struct afe_sp_v4_param_vi_channel_map_cfg)))
2433 pr_info("%s: SPKR_CALIB_CHANNEL_MAP_CFG failed\n",
lintaopeie994a2e2021-04-02 14:31:18 +08002434 __func__);*/
Vangala, Amarnath78732302020-04-09 03:57:14 +05302435 }
2436
2437 if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL ||
2438 this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL ||
2439 this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL) {
2440 pr_info("%s: Returning as no cal data cached\n", __func__);
2441 return;
2442 }
2443
2444 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
2445 if ((this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED) &&
2446 (this_afe.vi_tx_port == port_id) &&
2447 (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9)) {
2448
2449 if (this_afe.prot_cfg.mode ==
2450 MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) {
2451 afe_spk_config.v4_vi_op_mode.th_operation_mode =
2452 Q6AFE_MSM_SPKR_CALIBRATION;
2453 afe_spk_config.v4_vi_op_mode.th_quick_calib_flag =
2454 this_afe.prot_cfg.quick_calib_flag;
2455 } else {
2456 afe_spk_config.v4_vi_op_mode.th_operation_mode =
2457 Q6AFE_MSM_SPKR_PROCESSING;
2458 }
2459
2460 if (this_afe.th_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE)
2461 afe_spk_config.v4_vi_op_mode.th_operation_mode =
2462 Q6AFE_MSM_SPKR_FTM_MODE;
2463 else if (this_afe.v_vali_cfg.mode ==
2464 MSM_SPKR_PROT_IN_V_VALI_MODE)
2465 afe_spk_config.v4_vi_op_mode.th_operation_mode =
2466 Q6AFE_MSM_SPKR_V_VALI_MODE;
2467 if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_NOT_CALIBRATED) {
2468 struct afe_sp_v4_param_vi_op_mode_cfg *v4_vi_op_mode;
2469
2470 v4_vi_op_mode = &afe_spk_config.v4_vi_op_mode;
2471 v4_vi_op_mode->th_r0t0_selection_flag[SP_V2_SPKR_1] =
2472 USE_CALIBRATED_R0TO;
2473 v4_vi_op_mode->th_r0t0_selection_flag[SP_V2_SPKR_2] =
2474 USE_CALIBRATED_R0TO;
2475 } else {
2476 struct afe_sp_v4_param_vi_op_mode_cfg *v4_vi_op_mode;
2477
2478 v4_vi_op_mode = &afe_spk_config.v4_vi_op_mode;
2479 v4_vi_op_mode->th_r0t0_selection_flag[SP_V2_SPKR_1] =
2480 USE_SAFE_R0TO;
2481 v4_vi_op_mode->th_r0t0_selection_flag[SP_V2_SPKR_2] =
2482 USE_SAFE_R0TO;
2483 }
Vangala, Amarnath3e3537e2020-05-13 23:11:14 +05302484 afe_spk_config.v4_vi_op_mode.num_speakers = this_afe.num_spkrs;
Vangala, Amarnath78732302020-04-09 03:57:14 +05302485 if (afe_spk_prot_prepare(port_id, 0,
2486 AFE_PARAM_ID_SP_V4_VI_OP_MODE_CFG,
2487 &afe_spk_config,
2488 sizeof(struct afe_sp_v4_param_vi_op_mode_cfg)))
2489 pr_info("%s: SPKR_CALIB_VI_PROC_CFG failed\n",
2490 __func__);
2491
2492 size = sizeof(struct afe_sp_v4_param_th_vi_r0t0_cfg) +
Vangala, Amarnath3e3537e2020-05-13 23:11:14 +05302493 (this_afe.num_spkrs * sizeof(struct afe_sp_v4_channel_r0t0));
Vangala, Amarnath78732302020-04-09 03:57:14 +05302494 tmp_ptr = kzalloc(size, GFP_KERNEL);
2495 if (!tmp_ptr) {
2496 mutex_unlock(
2497 &this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
2498 return;
2499 }
2500 memset(tmp_ptr, 0, size);
2501
2502 th_vi_r0t0_cfg =
2503 (struct afe_sp_v4_param_th_vi_r0t0_cfg *)tmp_ptr;
2504 ch_r0t0_cfg =
2505 (struct afe_sp_v4_channel_r0t0 *)(th_vi_r0t0_cfg + 1);
2506
Vangala, Amarnath3e3537e2020-05-13 23:11:14 +05302507 th_vi_r0t0_cfg->num_speakers = this_afe.num_spkrs;
2508 for (i = 0; i < this_afe.num_spkrs; i++) {
2509 ch_r0t0_cfg[i].r0_cali_q24 =
2510 (uint32_t) this_afe.prot_cfg.r0[i];
2511 ch_r0t0_cfg[i].t0_cali_q6 =
2512 (uint32_t) this_afe.prot_cfg.t0[i];
2513 }
Vangala, Amarnath78732302020-04-09 03:57:14 +05302514 if (afe_spk_prot_prepare(port_id, 0,
2515 AFE_PARAM_ID_SP_V4_VI_R0T0_CFG,
2516 (union afe_spkr_prot_config *)tmp_ptr, size))
2517 pr_info("%s: th vi ftm cfg failed\n", __func__);
2518
2519 kfree(tmp_ptr);
2520 }
2521 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
2522
2523 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
2524 if ((this_afe.th_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) &&
2525 (this_afe.vi_tx_port == port_id) &&
2526 (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9)) {
2527 size = sizeof(struct afe_sp_v4_param_th_vi_ftm_cfg) +
Vangala, Amarnath3e3537e2020-05-13 23:11:14 +05302528 (this_afe.num_spkrs * sizeof(struct afe_sp_v4_channel_ftm_cfg));
Vangala, Amarnath78732302020-04-09 03:57:14 +05302529 tmp_ptr = kzalloc(size, GFP_KERNEL);
2530 if (!tmp_ptr) {
2531 mutex_unlock(
2532 &this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
2533 return;
2534 }
2535 memset(tmp_ptr, 0, size);
2536
2537 th_vi_ftm_cfg = (struct afe_sp_v4_param_th_vi_ftm_cfg *)tmp_ptr;
2538 ch_ftm_cfg =
2539 (struct afe_sp_v4_channel_ftm_cfg *)(th_vi_ftm_cfg+1);
2540
Vangala, Amarnath3e3537e2020-05-13 23:11:14 +05302541 th_vi_ftm_cfg->num_ch = this_afe.num_spkrs;
2542 for (i = 0; i < this_afe.num_spkrs; i++) {
2543 ch_ftm_cfg[i].wait_time_ms =
2544 this_afe.th_ftm_cfg.wait_time[i];
2545 ch_ftm_cfg[i].ftm_time_ms =
2546 this_afe.th_ftm_cfg.ftm_time[i];
2547 }
Vangala, Amarnath78732302020-04-09 03:57:14 +05302548 if (afe_spk_prot_prepare(port_id, 0,
2549 AFE_PARAM_ID_SP_V4_TH_VI_FTM_CFG,
2550 (union afe_spkr_prot_config *)tmp_ptr, size))
2551 pr_info("%s: th vi ftm cfg failed\n", __func__);
2552
2553 kfree(tmp_ptr);
2554 this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED;
2555 } else if ((this_afe.v_vali_cfg.mode ==
2556 MSM_SPKR_PROT_IN_V_VALI_MODE) &&
2557 (this_afe.vi_tx_port == port_id)) {
2558 size = sizeof(struct afe_sp_v4_param_th_vi_v_vali_cfg) +
Vangala, Amarnath3e3537e2020-05-13 23:11:14 +05302559 (this_afe.num_spkrs *
2560 sizeof(struct afe_sp_v4_channel_v_vali_cfg));
Vangala, Amarnath78732302020-04-09 03:57:14 +05302561 tmp_ptr = kzalloc(size, GFP_KERNEL);
2562 if (!tmp_ptr) {
2563 mutex_unlock(
2564 &this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
2565 return;
2566 }
2567 memset(tmp_ptr, 0, size);
2568
2569 th_vi_v_vali_cfg =
2570 (struct afe_sp_v4_param_th_vi_v_vali_cfg *)tmp_ptr;
2571 ch_v_vali_cfg =
2572 (struct afe_sp_v4_channel_v_vali_cfg *)(th_vi_v_vali_cfg + 1);
2573
Vangala, Amarnath3e3537e2020-05-13 23:11:14 +05302574 th_vi_v_vali_cfg->num_ch = this_afe.num_spkrs;
2575 for (i = 0; i < this_afe.num_spkrs; i++) {
2576 ch_v_vali_cfg[i].wait_time_ms =
2577 this_afe.v_vali_cfg.wait_time[i];
2578 ch_v_vali_cfg[i].vali_time_ms =
2579 this_afe.v_vali_cfg.vali_time[i];
2580 }
Vangala, Amarnath78732302020-04-09 03:57:14 +05302581 if (afe_spk_prot_prepare(port_id, 0,
2582 AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_CFG,
2583 (union afe_spkr_prot_config *)tmp_ptr, size))
2584 pr_info("%s: th vi v-vali cfg failed\n", __func__);
2585
2586 kfree(tmp_ptr);
2587 this_afe.v_vali_cfg.mode = MSM_SPKR_PROT_DISABLED;
2588 }
2589 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
2590
2591 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
2592 if ((this_afe.ex_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) &&
2593 (this_afe.vi_tx_port == port_id) &&
2594 (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9)) {
2595 size = sizeof(struct afe_sp_v4_param_ex_vi_ftm_cfg) +
Vangala, Amarnath3e3537e2020-05-13 23:11:14 +05302596 (this_afe.num_spkrs *
Vangala, Amarnath78732302020-04-09 03:57:14 +05302597 sizeof(struct afe_sp_v4_channel_ex_vi_ftm));
2598 tmp_ptr = kzalloc(size, GFP_KERNEL);
2599 if (!tmp_ptr) {
2600 mutex_unlock(
2601 &this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
2602 return;
2603 }
2604 memset(tmp_ptr, 0, size);
2605
2606 ex_vi_ftm_cfg = (struct afe_sp_v4_param_ex_vi_ftm_cfg *)tmp_ptr;
2607 ch_ex_vi_ftm_cfg =
2608 (struct afe_sp_v4_channel_ex_vi_ftm *)(ex_vi_ftm_cfg + 1);
2609
2610 afe_spk_config.v4_ex_vi_mode_cfg.operation_mode =
2611 AFE_FBSP_V4_EX_VI_MODE_FTM;
2612 if (afe_spk_prot_prepare(port_id, 0,
2613 AFE_PARAM_ID_SP_V4_EX_VI_MODE_CFG,
2614 &afe_spk_config,
2615 sizeof(struct afe_sp_v4_param_ex_vi_mode_cfg)))
2616 pr_info("%s: ex vi mode cfg failed\n", __func__);
2617
Vangala, Amarnath3e3537e2020-05-13 23:11:14 +05302618 ex_vi_ftm_cfg->num_ch = this_afe.num_spkrs;
Vangala, Amarnath78732302020-04-09 03:57:14 +05302619
Vangala, Amarnath3e3537e2020-05-13 23:11:14 +05302620 for (i = 0; i < this_afe.num_spkrs; i++) {
2621 ch_ex_vi_ftm_cfg[i].wait_time_ms =
2622 this_afe.ex_ftm_cfg.wait_time[i];
2623 ch_ex_vi_ftm_cfg[i].ftm_time_ms =
2624 this_afe.ex_ftm_cfg.ftm_time[i];
2625 }
Vangala, Amarnath78732302020-04-09 03:57:14 +05302626 if (afe_spk_prot_prepare(port_id, 0,
2627 AFE_PARAM_ID_SP_V4_EX_VI_FTM_CFG,
2628 (union afe_spkr_prot_config *)tmp_ptr, size))
2629 pr_info("%s: ex vi ftm cfg failed\n", __func__);
2630 kfree(tmp_ptr);
2631 this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED;
2632 }
2633 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
2634
2635 /* Register for DC detection event if speaker protection is enabled */
2636 if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED &&
2637 (this_afe.vi_tx_port == port_id)) {
2638 afe_spkr_prot_reg_event_cfg(port_id,
2639 AFE_MODULE_SPEAKER_PROTECTION_V4_VI);
2640 }
2641
2642}
2643
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302644static void afe_send_cal_spkr_prot_tx(int port_id)
2645{
2646 union afe_spkr_prot_config afe_spk_config;
2647
Vangala, Amarnath78732302020-04-09 03:57:14 +05302648 if (q6core_get_avcs_api_version_per_service(
2649 APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) {
2650 afe_send_cal_spv4_tx(port_id);
2651 return;
2652 }
2653
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302654 if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL ||
2655 this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL ||
2656 this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL)
2657 return;
2658
2659 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
2660 if ((this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED) &&
2661 (this_afe.vi_tx_port == port_id)) {
2662 if (this_afe.prot_cfg.mode ==
2663 MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) {
2664 afe_spk_config.vi_proc_cfg.operation_mode =
2665 Q6AFE_MSM_SPKR_CALIBRATION;
2666 afe_spk_config.vi_proc_cfg.quick_calib_flag =
2667 this_afe.prot_cfg.quick_calib_flag;
2668 } else {
2669 afe_spk_config.vi_proc_cfg.operation_mode =
2670 Q6AFE_MSM_SPKR_PROCESSING;
2671 }
2672
2673 if (this_afe.th_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE)
2674 afe_spk_config.vi_proc_cfg.operation_mode =
2675 Q6AFE_MSM_SPKR_FTM_MODE;
Laxminath Kasam2e13d952019-02-20 15:05:39 +05302676 else if (this_afe.v_vali_cfg.mode ==
2677 MSM_SPKR_PROT_IN_V_VALI_MODE)
2678 afe_spk_config.vi_proc_cfg.operation_mode =
2679 Q6AFE_MSM_SPKR_V_VALI_MODE;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302680 afe_spk_config.vi_proc_cfg.minor_version = 1;
2681 afe_spk_config.vi_proc_cfg.r0_cali_q24[SP_V2_SPKR_1] =
2682 (uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_1];
2683 afe_spk_config.vi_proc_cfg.r0_cali_q24[SP_V2_SPKR_2] =
2684 (uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_2];
2685 afe_spk_config.vi_proc_cfg.t0_cali_q6[SP_V2_SPKR_1] =
2686 (uint32_t) this_afe.prot_cfg.t0[SP_V2_SPKR_1];
2687 afe_spk_config.vi_proc_cfg.t0_cali_q6[SP_V2_SPKR_2] =
2688 (uint32_t) this_afe.prot_cfg.t0[SP_V2_SPKR_2];
2689 if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_NOT_CALIBRATED) {
2690 struct asm_spkr_calib_vi_proc_cfg *vi_proc_cfg;
2691
2692 vi_proc_cfg = &afe_spk_config.vi_proc_cfg;
2693 vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_1] =
2694 USE_CALIBRATED_R0TO;
2695 vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_2] =
2696 USE_CALIBRATED_R0TO;
2697 } else {
2698 struct asm_spkr_calib_vi_proc_cfg *vi_proc_cfg;
2699
2700 vi_proc_cfg = &afe_spk_config.vi_proc_cfg;
2701 vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_1] =
2702 USE_SAFE_R0TO;
2703 vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_2] =
2704 USE_SAFE_R0TO;
2705 }
2706 if (afe_spk_prot_prepare(port_id, 0,
2707 AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2,
Vangala, Amarnath78732302020-04-09 03:57:14 +05302708 &afe_spk_config, sizeof(union afe_spkr_prot_config)))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302709 pr_err("%s: SPKR_CALIB_VI_PROC_CFG failed\n",
2710 __func__);
2711 }
2712 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
2713
2714 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
2715 if ((this_afe.th_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) &&
2716 (this_afe.vi_tx_port == port_id)) {
2717 afe_spk_config.th_vi_ftm_cfg.minor_version = 1;
2718 afe_spk_config.th_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_1] =
2719 this_afe.th_ftm_cfg.wait_time[SP_V2_SPKR_1];
2720 afe_spk_config.th_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_2] =
2721 this_afe.th_ftm_cfg.wait_time[SP_V2_SPKR_2];
2722 afe_spk_config.th_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_1] =
2723 this_afe.th_ftm_cfg.ftm_time[SP_V2_SPKR_1];
2724 afe_spk_config.th_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_2] =
2725 this_afe.th_ftm_cfg.ftm_time[SP_V2_SPKR_2];
2726
2727 if (afe_spk_prot_prepare(port_id, 0,
Vangala, Amarnath78732302020-04-09 03:57:14 +05302728 AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG,
2729 &afe_spk_config,
2730 sizeof(union afe_spkr_prot_config)))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302731 pr_err("%s: th vi ftm cfg failed\n", __func__);
2732 this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED;
Laxminath Kasam2e13d952019-02-20 15:05:39 +05302733 } else if ((this_afe.v_vali_cfg.mode ==
2734 MSM_SPKR_PROT_IN_V_VALI_MODE) &&
2735 (this_afe.vi_tx_port == port_id)) {
2736 afe_spk_config.th_vi_v_vali_cfg.minor_version = 1;
2737 afe_spk_config.th_vi_v_vali_cfg.wait_time_ms[SP_V2_SPKR_1] =
2738 this_afe.v_vali_cfg.wait_time[SP_V2_SPKR_1];
2739 afe_spk_config.th_vi_v_vali_cfg.wait_time_ms[SP_V2_SPKR_2] =
2740 this_afe.v_vali_cfg.wait_time[SP_V2_SPKR_2];
2741 afe_spk_config.th_vi_v_vali_cfg.vali_time_ms[SP_V2_SPKR_1] =
2742 this_afe.v_vali_cfg.vali_time[SP_V2_SPKR_1];
2743 afe_spk_config.th_vi_v_vali_cfg.vali_time_ms[SP_V2_SPKR_2] =
2744 this_afe.v_vali_cfg.vali_time[SP_V2_SPKR_2];
2745
2746 if (afe_spk_prot_prepare(port_id, 0,
2747 AFE_PARAM_ID_SP_V2_TH_VI_V_VALI_CFG,
Vangala, Amarnath78732302020-04-09 03:57:14 +05302748 &afe_spk_config,
2749 sizeof(union afe_spkr_prot_config)))
Laxminath Kasam2e13d952019-02-20 15:05:39 +05302750 pr_err("%s: th vi v-vali cfg failed\n", __func__);
2751
2752 this_afe.v_vali_cfg.mode = MSM_SPKR_PROT_DISABLED;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302753 }
2754 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
2755
2756 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
2757 if ((this_afe.ex_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) &&
2758 (this_afe.vi_tx_port == port_id)) {
2759 afe_spk_config.ex_vi_mode_cfg.minor_version = 1;
2760 afe_spk_config.ex_vi_mode_cfg.operation_mode =
2761 Q6AFE_MSM_SPKR_FTM_MODE;
2762 if (afe_spk_prot_prepare(port_id, 0,
2763 AFE_PARAM_ID_SP_V2_EX_VI_MODE_CFG,
Vangala, Amarnath78732302020-04-09 03:57:14 +05302764 &afe_spk_config,
2765 sizeof(union afe_spkr_prot_config)))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302766 pr_err("%s: ex vi mode cfg failed\n", __func__);
2767
2768 afe_spk_config.ex_vi_ftm_cfg.minor_version = 1;
2769 afe_spk_config.ex_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_1] =
2770 this_afe.ex_ftm_cfg.wait_time[SP_V2_SPKR_1];
2771 afe_spk_config.ex_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_2] =
2772 this_afe.ex_ftm_cfg.wait_time[SP_V2_SPKR_2];
2773 afe_spk_config.ex_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_1] =
2774 this_afe.ex_ftm_cfg.ftm_time[SP_V2_SPKR_1];
2775 afe_spk_config.ex_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_2] =
2776 this_afe.ex_ftm_cfg.ftm_time[SP_V2_SPKR_2];
2777
2778 if (afe_spk_prot_prepare(port_id, 0,
2779 AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG,
Vangala, Amarnath78732302020-04-09 03:57:14 +05302780 &afe_spk_config,
2781 sizeof(union afe_spkr_prot_config)))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302782 pr_err("%s: ex vi ftm cfg failed\n", __func__);
2783 this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED;
2784 }
2785 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
2786
Vignesh Kulothungan0ffc6082018-08-03 10:46:42 -07002787 /* Register for DC detection event if speaker protection is enabled */
2788 if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED &&
2789 (this_afe.vi_tx_port == port_id)) {
Vangala, Amarnath78732302020-04-09 03:57:14 +05302790 afe_spkr_prot_reg_event_cfg(port_id,
2791 AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI);
Vignesh Kulothungan0ffc6082018-08-03 10:46:42 -07002792 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302793}
2794
Vangala, Amarnath78732302020-04-09 03:57:14 +05302795static void afe_send_cal_spv4_rx(int port_id)
2796{
2797
2798 union afe_spkr_prot_config afe_spk_config;
2799
2800 if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL)
2801 return;
2802
2803 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
2804 if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED &&
2805 (this_afe.vi_rx_port == port_id) &&
2806 (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9)) {
2807 if (this_afe.prot_cfg.mode ==
2808 MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS)
2809 afe_spk_config.v4_op_mode.mode =
2810 Q6AFE_MSM_SPKR_CALIBRATION;
2811 else
2812 afe_spk_config.v4_op_mode.mode =
2813 Q6AFE_MSM_SPKR_PROCESSING;
2814 if (afe_spk_prot_prepare(port_id, 0,
2815 AFE_PARAM_ID_SP_V4_OP_MODE,
2816 &afe_spk_config, sizeof(union afe_spkr_prot_config)))
2817 pr_info("%s: RX MODE_VI_PROC_CFG failed\n",
2818 __func__);
2819 }
2820 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
2821}
2822
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302823static void afe_send_cal_spkr_prot_rx(int port_id)
2824{
2825 union afe_spkr_prot_config afe_spk_config;
Xiaojun Sang12120ab2017-09-28 18:21:21 +08002826 union afe_spkr_prot_config afe_spk_limiter_config;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302827
Vangala, Amarnath78732302020-04-09 03:57:14 +05302828 if (q6core_get_avcs_api_version_per_service(
2829 APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) {
2830 afe_send_cal_spv4_rx(port_id);
2831 return;
2832 }
2833
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302834 if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL)
2835 goto done;
2836
2837 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
2838
2839 if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED &&
2840 (this_afe.vi_rx_port == port_id)) {
2841 if (this_afe.prot_cfg.mode ==
2842 MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS)
2843 afe_spk_config.mode_rx_cfg.mode =
2844 Q6AFE_MSM_SPKR_CALIBRATION;
2845 else
2846 afe_spk_config.mode_rx_cfg.mode =
2847 Q6AFE_MSM_SPKR_PROCESSING;
2848 afe_spk_config.mode_rx_cfg.minor_version = 1;
2849 if (afe_spk_prot_prepare(port_id, 0,
2850 AFE_PARAM_ID_FBSP_MODE_RX_CFG,
Vangala, Amarnath78732302020-04-09 03:57:14 +05302851 &afe_spk_config, sizeof(union afe_spkr_prot_config)))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302852 pr_err("%s: RX MODE_VI_PROC_CFG failed\n",
Vangala, Amarnath78732302020-04-09 03:57:14 +05302853 __func__);
Xiaojun Sang12120ab2017-09-28 18:21:21 +08002854
2855 if (afe_spk_config.mode_rx_cfg.mode ==
2856 Q6AFE_MSM_SPKR_PROCESSING) {
2857 if (this_afe.prot_cfg.sp_version >=
2858 AFE_API_VERSION_SUPPORT_SPV3) {
2859 afe_spk_limiter_config.limiter_th_cfg.
2860 minor_version = 1;
2861 afe_spk_limiter_config.limiter_th_cfg.
2862 lim_thr_per_calib_q27[SP_V2_SPKR_1] =
2863 this_afe.prot_cfg.limiter_th[SP_V2_SPKR_1];
2864 afe_spk_limiter_config.limiter_th_cfg.
2865 lim_thr_per_calib_q27[SP_V2_SPKR_2] =
2866 this_afe.prot_cfg.limiter_th[SP_V2_SPKR_2];
2867 if (afe_spk_prot_prepare(port_id, 0,
2868 AFE_PARAM_ID_SP_RX_LIMITER_TH,
Vangala, Amarnath78732302020-04-09 03:57:14 +05302869 &afe_spk_limiter_config,
2870 sizeof(union afe_spkr_prot_config)))
Xiaojun Sang12120ab2017-09-28 18:21:21 +08002871 pr_err("%s: SP_RX_LIMITER_TH failed.\n",
2872 __func__);
2873 } else {
2874 pr_debug("%s: SPv3 failed to apply on AFE API version=%d.\n",
2875 __func__,
2876 this_afe.prot_cfg.sp_version);
2877 }
2878 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302879 }
2880 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
2881done:
2882 return;
2883}
2884
2885static int afe_send_hw_delay(u16 port_id, u32 rate)
2886{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002887 struct audio_cal_hw_delay_entry delay_entry;
2888 struct afe_param_id_device_hw_delay_cfg hw_delay;
2889 struct param_hdr_v3 param_info;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302890 int ret = -EINVAL;
2891
2892 pr_debug("%s:\n", __func__);
2893
2894 memset(&delay_entry, 0, sizeof(delay_entry));
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002895 memset(&param_info, 0, sizeof(param_info));
2896
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302897 delay_entry.sample_rate = rate;
2898 if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX)
2899 ret = afe_get_cal_hw_delay(TX_DEVICE, &delay_entry);
2900 else if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX)
2901 ret = afe_get_cal_hw_delay(RX_DEVICE, &delay_entry);
2902
2903 /*
2904 * HW delay is only used for IMS calls to sync audio with video
2905 * It is only needed for devices & sample rates used for IMS video
2906 * calls. Values are received from ACDB calbration files
2907 */
2908 if (ret != 0) {
2909 pr_debug("%s: debug: HW delay info not available %d\n",
2910 __func__, ret);
2911 goto fail_cmd;
2912 }
2913
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002914 param_info.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
2915 param_info.instance_id = INSTANCE_ID_0;
2916 param_info.param_id = AFE_PARAM_ID_DEVICE_HW_DELAY;
2917 param_info.param_size = sizeof(hw_delay);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302918
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002919 hw_delay.delay_in_us = delay_entry.delay_usec;
2920 hw_delay.device_hw_delay_minor_version =
2921 AFE_API_VERSION_DEVICE_HW_DELAY;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302922
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08002923 ret = q6afe_pack_and_set_param_in_band(port_id,
2924 q6audio_get_port_index(port_id),
2925 param_info, (u8 *) &hw_delay);
2926 if (ret)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302927 pr_err("%s: AFE hw delay for port 0x%x failed %d\n",
2928 __func__, port_id, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302929
2930fail_cmd:
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07002931 pr_info("%s: port_id 0x%x rate %u delay_usec %d status %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302932 __func__, port_id, rate, delay_entry.delay_usec, ret);
2933 return ret;
2934}
2935
2936static struct cal_block_data *afe_find_cal_topo_id_by_port(
2937 struct cal_type_data *cal_type, u16 port_id)
2938{
2939 struct list_head *ptr, *next;
2940 struct cal_block_data *cal_block = NULL;
2941 int32_t path;
2942 struct audio_cal_info_afe_top *afe_top;
2943 int afe_port_index = q6audio_get_port_index(port_id);
2944
2945 if (afe_port_index < 0)
2946 goto err_exit;
2947
2948 list_for_each_safe(ptr, next,
2949 &cal_type->cal_blocks) {
2950 cal_block = list_entry(ptr,
2951 struct cal_block_data, list);
Vikram Panduranga770b8382017-09-27 12:17:36 -07002952 /* Skip cal_block if it is already marked stale */
2953 if (cal_utils_is_cal_stale(cal_block))
2954 continue;
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07002955 pr_info("%s: port id: 0x%x, dev_acdb_id: %d\n", __func__,
2956 port_id, this_afe.dev_acdb_id[afe_port_index]);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302957 path = ((afe_get_port_type(port_id) ==
2958 MSM_AFE_PORT_TYPE_TX)?(TX_DEVICE):(RX_DEVICE));
2959 afe_top =
2960 (struct audio_cal_info_afe_top *)cal_block->cal_info;
2961 if (afe_top->path == path) {
2962 if (this_afe.dev_acdb_id[afe_port_index] > 0) {
2963 if (afe_top->acdb_id ==
2964 this_afe.dev_acdb_id[afe_port_index]) {
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07002965 pr_info("%s: top_id:%x acdb_id:%d afe_port_id:0x%x\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302966 __func__, afe_top->topology,
2967 afe_top->acdb_id,
2968 q6audio_get_port_id(port_id));
2969 return cal_block;
2970 }
2971 } else {
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07002972 pr_info("%s: top_id:%x acdb_id:%d afe_port:0x%x\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302973 __func__, afe_top->topology, afe_top->acdb_id,
2974 q6audio_get_port_id(port_id));
2975 return cal_block;
2976 }
2977 }
2978 }
2979
2980err_exit:
2981 return NULL;
2982}
2983
Vikram Panduranga770b8382017-09-27 12:17:36 -07002984/*
2985 * Retrieving cal_block will mark cal_block as stale.
2986 * Hence it cannot be reused or resent unless the flag
2987 * is reset.
2988 */
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05302989static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id,
2990 int cal_type_index)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302991{
2992 int ret = 0;
2993
2994 struct cal_block_data *cal_block = NULL;
2995 struct audio_cal_info_afe_top *afe_top_info = NULL;
2996
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05302997 if (this_afe.cal_data[cal_type_index] == NULL) {
Vikram Panduranga770b8382017-09-27 12:17:36 -07002998 pr_err("%s: cal_type %d not initialized\n", __func__,
2999 cal_type_index);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303000 return -EINVAL;
3001 }
3002 if (topology_id == NULL) {
3003 pr_err("%s: topology_id is NULL\n", __func__);
3004 return -EINVAL;
3005 }
3006 *topology_id = 0;
3007
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05303008 mutex_lock(&this_afe.cal_data[cal_type_index]->lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303009 cal_block = afe_find_cal_topo_id_by_port(
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05303010 this_afe.cal_data[cal_type_index], port_id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303011 if (cal_block == NULL) {
Vikram Panduranga770b8382017-09-27 12:17:36 -07003012 pr_err("%s: cal_type %d not initialized for this port %d\n",
3013 __func__, cal_type_index, port_id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303014 ret = -EINVAL;
3015 goto unlock;
3016 }
3017
3018 afe_top_info = ((struct audio_cal_info_afe_top *)
3019 cal_block->cal_info);
3020 if (!afe_top_info->topology) {
3021 pr_err("%s: invalid topology id : [%d, %d]\n",
3022 __func__, afe_top_info->acdb_id, afe_top_info->topology);
3023 ret = -EINVAL;
3024 goto unlock;
3025 }
3026 *topology_id = (u32)afe_top_info->topology;
Vikram Panduranga770b8382017-09-27 12:17:36 -07003027 cal_utils_mark_cal_used(cal_block);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303028
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07003029 pr_info("%s: port_id = 0x%x acdb_id = %d topology_id = 0x%x cal_type_index=%d ret=%d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303030 __func__, port_id, afe_top_info->acdb_id,
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07003031 afe_top_info->topology, cal_type_index, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303032unlock:
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05303033 mutex_unlock(&this_afe.cal_data[cal_type_index]->lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303034 return ret;
3035}
3036
3037static int afe_send_port_topology_id(u16 port_id)
3038{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003039 struct afe_param_id_set_topology_cfg topology;
3040 struct param_hdr_v3 param_info;
3041 u32 topology_id = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303042 int index = 0;
3043 int ret = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303044
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003045 memset(&topology, 0, sizeof(topology));
3046 memset(&param_info, 0, sizeof(param_info));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303047 index = q6audio_get_port_index(port_id);
3048 if (index < 0 || index >= AFE_MAX_PORTS) {
3049 pr_err("%s: AFE port index[%d] invalid!\n",
3050 __func__, index);
3051 return -EINVAL;
3052 }
3053
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05303054 ret = afe_get_cal_topology_id(port_id, &topology_id, AFE_TOPOLOGY_CAL);
Soumya Managoliadeb3312020-11-27 15:43:55 +05303055 if (ret < 0 && q6afe_is_afe_lsm_port(port_id)) {
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05303056 pr_debug("%s: Check for LSM topology\n", __func__);
3057 ret = afe_get_cal_topology_id(port_id, &topology_id,
3058 AFE_LSM_TOPOLOGY_CAL);
3059 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303060 if (ret || !topology_id) {
3061 pr_debug("%s: AFE port[%d] get_cal_topology[%d] invalid!\n",
3062 __func__, port_id, topology_id);
3063 goto done;
3064 }
3065
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003066 param_info.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
3067 param_info.instance_id = INSTANCE_ID_0;
3068 param_info.param_id = AFE_PARAM_ID_SET_TOPOLOGY;
3069 param_info.param_size = sizeof(topology);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303070
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003071 topology.minor_version = AFE_API_VERSION_TOPOLOGY_V1;
3072 topology.topology_id = topology_id;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303073
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003074 ret = q6afe_pack_and_set_param_in_band(port_id,
3075 q6audio_get_port_index(port_id),
3076 param_info, (u8 *) &topology);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303077 if (ret) {
3078 pr_err("%s: AFE set topology id enable for port 0x%x failed %d\n",
3079 __func__, port_id, ret);
3080 goto done;
3081 }
3082
3083 this_afe.topology[index] = topology_id;
3084 rtac_update_afe_topology(port_id);
3085done:
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07003086 pr_info("%s: AFE set topology id 0x%x enable for port 0x%x ret %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303087 __func__, topology_id, port_id, ret);
3088 return ret;
3089
3090}
3091
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05303092
3093static int afe_get_island_mode(u16 port_id, u32 *island_mode)
3094{
3095 int ret = 0;
3096 int index = 0;
3097 *island_mode = 0;
3098
3099 index = q6audio_get_port_index(port_id);
3100 if (index < 0 || index >= AFE_MAX_PORTS) {
3101 pr_err("%s: AFE port index[%d] invalid!\n",
3102 __func__, index);
3103 return -EINVAL;
3104 }
3105
3106 *island_mode = this_afe.island_mode[index];
3107 return ret;
3108}
3109
3110/*
3111 * afe_send_port_island_mode -
3112 * for sending island mode to AFE
3113 *
3114 * @port_id: AFE port id number
3115 *
3116 * Returns 0 on success or error on failure.
3117 */
3118int afe_send_port_island_mode(u16 port_id)
3119{
3120 struct afe_param_id_island_cfg_t island_cfg;
3121 struct param_hdr_v3 param_info;
3122 u32 island_mode = 0;
3123 int ret = 0;
3124
Mangesh Kunchamwar27baab02019-03-13 17:18:28 +05303125 if (!(q6core_get_avcs_api_version_per_service(
3126 APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4)) {
3127 pr_debug("%s: AFE port[%d] API version is invalid!\n",
3128 __func__, port_id);
3129 return 0;
3130 }
3131
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05303132 memset(&island_cfg, 0, sizeof(island_cfg));
3133 memset(&param_info, 0, sizeof(param_info));
3134
3135 ret = afe_get_island_mode(port_id, &island_mode);
3136 if (ret) {
3137 pr_err("%s: AFE port[%d] get island mode is invalid!\n",
3138 __func__, port_id);
3139 return ret;
3140 }
3141 param_info.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
3142 param_info.instance_id = INSTANCE_ID_0;
3143 param_info.param_id = AFE_PARAM_ID_ISLAND_CONFIG;
3144 param_info.param_size = sizeof(island_cfg);
3145
3146 island_cfg.island_cfg_minor_version = AFE_API_VERSION_ISLAND_CONFIG;
3147 island_cfg.island_enable = island_mode;
3148
3149 ret = q6afe_pack_and_set_param_in_band(port_id,
3150 q6audio_get_port_index(port_id),
3151 param_info, (u8 *) &island_cfg);
3152 if (ret) {
3153 pr_err("%s: AFE set island mode enable for port 0x%x failed %d\n",
3154 __func__, port_id, ret);
3155 return ret;
3156 }
3157 pr_debug("%s: AFE set island mode 0x%x enable for port 0x%x ret %d\n",
3158 __func__, island_mode, port_id, ret);
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07003159 trace_printk("%s: AFE set island mode 0x%x enable for port 0x%x ret %d\n",
3160 __func__, island_mode, port_id, ret);
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05303161 return ret;
3162}
3163EXPORT_SYMBOL(afe_send_port_island_mode);
3164
3165static int afe_get_vad_preroll_cfg(u16 port_id, u32 *preroll_cfg)
3166{
3167 int ret = 0;
3168 int index = 0;
3169 *preroll_cfg = 0;
3170
3171 index = q6audio_get_port_index(port_id);
3172 if (index < 0 || index >= AFE_MAX_PORTS) {
3173 pr_err("%s: AFE port index[%d] invalid!\n",
3174 __func__, index);
3175 return -EINVAL;
3176 }
3177
3178 *preroll_cfg = this_afe.vad_cfg[index].pre_roll;
3179 return ret;
3180}
3181
Mangesh Kunchamwar27baab02019-03-13 17:18:28 +05303182int afe_send_port_vad_cfg_params(u16 port_id)
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05303183{
3184 struct afe_param_id_vad_cfg_t vad_cfg;
Mangesh Kunchamwar27baab02019-03-13 17:18:28 +05303185 struct afe_mod_enable_param vad_enable;
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05303186 struct param_hdr_v3 param_info;
3187 u32 pre_roll_cfg = 0;
3188 struct firmware_cal *hwdep_cal = NULL;
3189 int ret = 0;
Mangesh Kunchamwar27baab02019-03-13 17:18:28 +05303190 uint16_t port_index = 0;
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05303191
Mangesh Kunchamwar27baab02019-03-13 17:18:28 +05303192 if (!(q6core_get_avcs_api_version_per_service(
3193 APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4)) {
3194 pr_err("%s: AFE port[%d]: AFE API version doesn't support VAD config\n",
3195 __func__, port_id);
3196 return 0;
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05303197 }
3198
Mangesh Kunchamwar27baab02019-03-13 17:18:28 +05303199 port_index = afe_get_port_index(port_id);
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05303200
Mangesh Kunchamwar27baab02019-03-13 17:18:28 +05303201 if (this_afe.vad_cfg[port_index].is_enable) {
3202 memset(&vad_cfg, 0, sizeof(vad_cfg));
3203 memset(&param_info, 0, sizeof(param_info));
3204
3205 ret = afe_get_vad_preroll_cfg(port_id, &pre_roll_cfg);
3206 if (ret) {
3207 pr_err("%s: AFE port[%d] get preroll cfg is invalid!\n",
3208 __func__, port_id);
3209 return ret;
3210 }
3211 param_info.module_id = AFE_MODULE_VAD;
3212 param_info.instance_id = INSTANCE_ID_0;
3213 param_info.param_id = AFE_PARAM_ID_VAD_CFG;
3214 param_info.param_size = sizeof(vad_cfg);
3215
3216 vad_cfg.vad_cfg_minor_version = AFE_API_VERSION_VAD_CFG;
3217 vad_cfg.pre_roll_in_ms = pre_roll_cfg;
3218
3219 ret = q6afe_pack_and_set_param_in_band(port_id,
3220 q6audio_get_port_index(port_id),
3221 param_info, (u8 *) &vad_cfg);
3222 if (ret) {
3223 pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n",
3224 __func__, port_id, ret);
3225 return ret;
3226 }
3227
3228 memset(&param_info, 0, sizeof(param_info));
3229
3230 hwdep_cal = q6afecal_get_fw_cal(this_afe.fw_data,
3231 Q6AFE_VAD_CORE_CAL);
3232 if (!hwdep_cal) {
3233 pr_err("%s: error in retrieving vad core calibration",
3234 __func__);
3235 return -EINVAL;
3236 }
3237
3238 param_info.module_id = AFE_MODULE_VAD;
3239 param_info.instance_id = INSTANCE_ID_0;
3240 param_info.param_id = AFE_PARAM_ID_VAD_CORE_CFG;
3241 param_info.param_size = hwdep_cal->size;
3242
3243 ret = q6afe_pack_and_set_param_in_band(port_id,
3244 q6audio_get_port_index(port_id),
3245 param_info,
3246 (u8 *) hwdep_cal->data);
3247 if (ret) {
3248 pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n",
3249 __func__, port_id, ret);
3250 return ret;
3251 }
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05303252 }
3253
Mangesh Kunchamwar27baab02019-03-13 17:18:28 +05303254 if (q6core_get_avcs_api_version_per_service(
3255 APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V6) {
3256 memset(&vad_enable, 0, sizeof(vad_enable));
3257 memset(&param_info, 0, sizeof(param_info));
3258 param_info.module_id = AFE_MODULE_VAD;
3259 param_info.instance_id = INSTANCE_ID_0;
3260 param_info.param_id = AFE_PARAM_ID_ENABLE;
3261 param_info.param_size = sizeof(vad_enable);
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05303262
Mangesh Kunchamwar27baab02019-03-13 17:18:28 +05303263 port_index = afe_get_port_index(port_id);
3264 vad_enable.enable = this_afe.vad_cfg[port_index].is_enable;
3265
3266 ret = q6afe_pack_and_set_param_in_band(port_id,
3267 q6audio_get_port_index(port_id),
3268 param_info, (u8 *) &vad_enable);
3269 if (ret) {
3270 pr_err("%s: AFE set vad enable for port 0x%x failed %d\n",
3271 __func__, port_id, ret);
3272 return ret;
3273 }
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05303274 }
Mangesh Kunchamwar27baab02019-03-13 17:18:28 +05303275
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05303276 pr_debug("%s: AFE set preroll cfg %d vad core cfg port 0x%x ret %d\n",
3277 __func__, pre_roll_cfg, port_id, ret);
3278 return ret;
3279}
Mangesh Kunchamwar27baab02019-03-13 17:18:28 +05303280EXPORT_SYMBOL(afe_send_port_vad_cfg_params);
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05303281
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303282static int remap_cal_data(struct cal_block_data *cal_block, int cal_index)
3283{
3284 int ret = 0;
3285
Banajit Goswami08bb7362017-11-03 22:48:23 -07003286 if (cal_block->map_data.dma_buf == NULL) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303287 pr_err("%s: No ION allocation for cal index %d!\n",
3288 __func__, cal_index);
3289 ret = -EINVAL;
3290 goto done;
3291 }
3292
3293 if ((cal_block->map_data.map_size > 0) &&
3294 (cal_block->map_data.q6map_handle == 0)) {
3295 atomic_set(&this_afe.mem_map_cal_index, cal_index);
3296 ret = afe_cmd_memory_map(cal_block->cal_data.paddr,
3297 cal_block->map_data.map_size);
3298 atomic_set(&this_afe.mem_map_cal_index, -1);
3299 if (ret < 0) {
3300 pr_err("%s: mmap did not work! size = %zd ret %d\n",
3301 __func__,
3302 cal_block->map_data.map_size, ret);
3303 pr_debug("%s: mmap did not work! addr = 0x%pK, size = %zd\n",
3304 __func__,
3305 &cal_block->cal_data.paddr,
3306 cal_block->map_data.map_size);
3307 goto done;
3308 }
3309 cal_block->map_data.q6map_handle = atomic_read(&this_afe.
3310 mem_map_cal_handles[cal_index]);
3311 }
3312done:
3313 return ret;
3314}
3315
3316static struct cal_block_data *afe_find_cal(int cal_index, int port_id)
3317{
3318 struct list_head *ptr, *next;
3319 struct cal_block_data *cal_block = NULL;
3320 struct audio_cal_info_afe *afe_cal_info = NULL;
3321 int afe_port_index = q6audio_get_port_index(port_id);
3322
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07003323 pr_info("%s: cal_index %d port_id 0x%x port_index %d\n", __func__,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303324 cal_index, port_id, afe_port_index);
3325 if (afe_port_index < 0) {
3326 pr_err("%s: Error getting AFE port index %d\n",
3327 __func__, afe_port_index);
3328 goto exit;
3329 }
3330
3331 list_for_each_safe(ptr, next,
3332 &this_afe.cal_data[cal_index]->cal_blocks) {
3333 cal_block = list_entry(ptr, struct cal_block_data, list);
3334 afe_cal_info = cal_block->cal_info;
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07003335 pr_info("%s: acdb_id %d dev_acdb_id %d sample_rate %d afe_sample_rates %d\n",
3336 __func__, afe_cal_info->acdb_id,
3337 this_afe.dev_acdb_id[afe_port_index],
3338 afe_cal_info->sample_rate,
3339 this_afe.afe_sample_rates[afe_port_index]);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303340 if ((afe_cal_info->acdb_id ==
3341 this_afe.dev_acdb_id[afe_port_index]) &&
3342 (afe_cal_info->sample_rate ==
3343 this_afe.afe_sample_rates[afe_port_index])) {
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07003344 pr_info("%s: cal block is a match, size is %zd\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303345 __func__, cal_block->cal_data.size);
3346 goto exit;
3347 }
3348 }
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07003349 pr_info("%s: no matching cal_block found\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303350 cal_block = NULL;
3351
3352exit:
3353 return cal_block;
3354}
3355
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05303356static int send_afe_cal_type(int cal_index, int port_id)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303357{
3358 struct cal_block_data *cal_block = NULL;
3359 int ret;
3360 int afe_port_index = q6audio_get_port_index(port_id);
3361
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07003362 pr_info("%s: cal_index is %d\n", __func__, cal_index);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303363
3364 if (this_afe.cal_data[cal_index] == NULL) {
3365 pr_warn("%s: cal_index %d not allocated!\n",
3366 __func__, cal_index);
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05303367 ret = -EINVAL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303368 goto done;
3369 }
3370
3371 if (afe_port_index < 0) {
3372 pr_err("%s: Error getting AFE port index %d\n",
3373 __func__, afe_port_index);
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05303374 ret = -EINVAL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303375 goto done;
3376 }
3377
3378 mutex_lock(&this_afe.cal_data[cal_index]->lock);
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07003379 pr_info("%s: dev_acdb_id[%d] is %d\n",
3380 __func__, afe_port_index,
3381 this_afe.dev_acdb_id[afe_port_index]);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303382 if (((cal_index == AFE_COMMON_RX_CAL) ||
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05303383 (cal_index == AFE_COMMON_TX_CAL) ||
3384 (cal_index == AFE_LSM_TX_CAL)) &&
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303385 (this_afe.dev_acdb_id[afe_port_index] > 0))
3386 cal_block = afe_find_cal(cal_index, port_id);
3387 else
3388 cal_block = cal_utils_get_only_cal_block(
3389 this_afe.cal_data[cal_index]);
3390
Vikram Panduranga770b8382017-09-27 12:17:36 -07003391 if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) {
Saurav Kumar1f3c09d2020-09-10 16:06:16 +05303392 pr_err_ratelimited("%s cal_block not found!!\n", __func__);
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05303393 ret = -EINVAL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303394 goto unlock;
3395 }
3396
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07003397 pr_info("%s: Sending cal_index cal %d\n", __func__, cal_index);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303398
3399 ret = remap_cal_data(cal_block, cal_index);
3400 if (ret) {
3401 pr_err("%s: Remap_cal_data failed for cal %d!\n",
3402 __func__, cal_index);
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05303403 ret = -EINVAL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303404 goto unlock;
3405 }
3406 ret = afe_send_cal_block(port_id, cal_block);
3407 if (ret < 0)
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07003408 pr_err("%s: No cal sent for cal_index %d, port_id = 0x%x! ret %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303409 __func__, cal_index, port_id, ret);
Vikram Panduranga770b8382017-09-27 12:17:36 -07003410
3411 cal_utils_mark_cal_used(cal_block);
3412
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303413unlock:
3414 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
3415done:
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05303416 return ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303417}
3418
3419void afe_send_cal(u16 port_id)
3420{
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05303421 int ret;
3422
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303423 pr_debug("%s: port_id=0x%x\n", __func__, port_id);
3424
3425 if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX) {
3426 afe_send_cal_spkr_prot_tx(port_id);
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05303427 ret = send_afe_cal_type(AFE_COMMON_TX_CAL, port_id);
Soumya Managoliadeb3312020-11-27 15:43:55 +05303428 if (ret < 0 && q6afe_is_afe_lsm_port(port_id))
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05303429 send_afe_cal_type(AFE_LSM_TX_CAL, port_id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303430 } else if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303431 send_afe_cal_type(AFE_COMMON_RX_CAL, port_id);
Xiaojun Sang092e0ed2017-12-11 16:13:32 +08003432 afe_send_cal_spkr_prot_rx(port_id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303433 }
3434}
3435
3436int afe_turn_onoff_hw_mad(u16 mad_type, u16 enable)
3437{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003438 struct afe_param_hw_mad_ctrl mad_enable_param;
3439 struct param_hdr_v3 param_info;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303440 int ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303441
3442 pr_debug("%s: enter\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303443
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003444 memset(&mad_enable_param, 0, sizeof(mad_enable_param));
3445 memset(&param_info, 0, sizeof(param_info));
3446 param_info.module_id = AFE_MODULE_HW_MAD;
3447 param_info.instance_id = INSTANCE_ID_0;
3448 param_info.param_id = AFE_PARAM_ID_HW_MAD_CTRL;
3449 param_info.param_size = sizeof(mad_enable_param);
3450
3451 mad_enable_param.minor_version = 1;
3452 mad_enable_param.mad_type = mad_type;
3453 mad_enable_param.mad_enable = enable;
3454
3455 ret = q6afe_pack_and_set_param_in_band(SLIMBUS_5_TX, IDX_GLOBAL_CFG,
3456 param_info,
3457 (u8 *) &mad_enable_param);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303458 if (ret)
3459 pr_err("%s: AFE_PARAM_ID_HW_MAD_CTRL failed %d\n", __func__,
3460 ret);
3461 return ret;
3462}
3463
3464static int afe_send_slimbus_slave_cfg(
3465 struct afe_param_cdc_slimbus_slave_cfg *sb_slave_cfg)
3466{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003467 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303468 int ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303469
3470 pr_debug("%s: enter\n", __func__);
3471
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003472 memset(&param_hdr, 0, sizeof(param_hdr));
3473 param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG;
3474 param_hdr.instance_id = INSTANCE_ID_0;
3475 param_hdr.param_id = AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG;
3476 param_hdr.param_size = sizeof(struct afe_param_cdc_slimbus_slave_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303477
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003478 ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
3479 (u8 *) sb_slave_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303480 if (ret)
3481 pr_err("%s: AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG failed %d\n",
3482 __func__, ret);
3483
3484 pr_debug("%s: leave %d\n", __func__, ret);
3485 return ret;
3486}
3487
3488static int afe_send_codec_reg_page_config(
3489 struct afe_param_cdc_reg_page_cfg *cdc_reg_page_cfg)
3490{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003491 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303492 int ret;
3493
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003494 memset(&param_hdr, 0, sizeof(param_hdr));
3495 param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG;
3496 param_hdr.instance_id = INSTANCE_ID_0;
3497 param_hdr.param_id = AFE_PARAM_ID_CDC_REG_PAGE_CFG;
3498 param_hdr.param_size = sizeof(struct afe_param_cdc_reg_page_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303499
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003500 ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
3501 (u8 *) cdc_reg_page_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303502 if (ret)
3503 pr_err("%s: AFE_PARAM_ID_CDC_REG_PAGE_CFG failed %d\n",
3504 __func__, ret);
3505
3506 return ret;
3507}
3508
3509static int afe_send_codec_reg_config(
3510 struct afe_param_cdc_reg_cfg_data *cdc_reg_cfg)
3511{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003512 u8 *packed_param_data = NULL;
3513 u32 packed_data_size = 0;
3514 u32 single_param_size = 0;
3515 u32 max_data_size = 0;
3516 u32 max_single_param = 0;
3517 struct param_hdr_v3 param_hdr;
3518 int idx = 0;
3519 int ret = -EINVAL;
Aditya Bavanari23513e02019-02-28 11:06:41 +05303520 bool is_iid_supported = q6common_is_instance_id_supported();
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303521
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003522 memset(&param_hdr, 0, sizeof(param_hdr));
3523 max_single_param = sizeof(struct param_hdr_v3) +
3524 sizeof(struct afe_param_cdc_reg_cfg);
3525 max_data_size = APR_MAX_BUF - sizeof(struct afe_svc_cmd_set_param_v2);
3526 packed_param_data = kzalloc(max_data_size, GFP_KERNEL);
3527 if (!packed_param_data)
3528 return -ENOMEM;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303529
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003530 /* param_hdr is the same for all params sent, set once at top */
3531 param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG;
3532 param_hdr.instance_id = INSTANCE_ID_0;
3533 param_hdr.param_id = AFE_PARAM_ID_CDC_REG_CFG;
3534 param_hdr.param_size = sizeof(struct afe_param_cdc_reg_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303535
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003536 while (idx < cdc_reg_cfg->num_registers) {
3537 memset(packed_param_data, 0, max_data_size);
3538 packed_data_size = 0;
3539 single_param_size = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303540
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003541 while (packed_data_size + max_single_param < max_data_size &&
3542 idx < cdc_reg_cfg->num_registers) {
Aditya Bavanari23513e02019-02-28 11:06:41 +05303543 ret = q6common_pack_pp_params_v2(
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003544 packed_param_data + packed_data_size,
3545 &param_hdr, (u8 *) &cdc_reg_cfg->reg_data[idx],
Aditya Bavanari23513e02019-02-28 11:06:41 +05303546 &single_param_size, is_iid_supported);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003547 if (ret) {
3548 pr_err("%s: Failed to pack parameters with error %d\n",
3549 __func__, ret);
3550 goto done;
3551 }
3552 packed_data_size += single_param_size;
3553 idx++;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303554 }
3555
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003556 ret = q6afe_svc_set_params(IDX_GLOBAL_CFG, NULL,
Aditya Bavanari23513e02019-02-28 11:06:41 +05303557 packed_param_data, packed_data_size,
3558 is_iid_supported);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303559 if (ret) {
3560 pr_err("%s: AFE_PARAM_ID_CDC_REG_CFG failed %d\n",
3561 __func__, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303562 break;
3563 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303564 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003565done:
3566 kfree(packed_param_data);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303567 return ret;
3568}
3569
lintaopei746b0122021-03-16 19:35:42 +08003570#ifdef CONFIG_SND_SMARTPA_AW882XX
3571int aw_send_afe_rx_module_enable(void *buf, int size)
3572{
3573 union afe_spkr_prot_config config;
3574 int32_t port_id = AFE_PORT_ID_AWDSP_RX;
3575
3576 if (size > sizeof(config))
3577 return -EINVAL;
3578
3579 memcpy(&config, buf, size);
3580
3581 if (afe_spk_prot_prepare(port_id, 0,
3582 AFE_PARAM_ID_AWDSP_RX_SET_ENABLE, &config,sizeof(union afe_spkr_prot_config))) {
3583 pr_err("%s: set bypass failed \n", __func__);
3584 return -EINVAL;
3585 }
3586 return 0;
3587}
3588EXPORT_SYMBOL(aw_send_afe_rx_module_enable);
3589int aw_send_afe_tx_module_enable(void *buf, int size)
3590{
3591 union afe_spkr_prot_config config;
3592 int32_t port_id = AFE_PORT_ID_AWDSP_TX;
3593
3594 if (size > sizeof(config))
3595 return -EINVAL;
3596
3597 memcpy(&config, buf, size);
3598
3599 if (afe_spk_prot_prepare(port_id, 0,
3600 AFE_PARAM_ID_AWDSP_TX_SET_ENABLE, &config,sizeof(union afe_spkr_prot_config))) {
3601 pr_err("%s: set bypass failed \n", __func__);
3602 return -EINVAL;
3603 }
3604 return 0;
3605}
3606EXPORT_SYMBOL(aw_send_afe_tx_module_enable);
3607
3608int aw_send_afe_cal_apr(uint32_t param_id, void *buf, int cmd_size, bool write)
3609{
3610 int32_t result = 0, port_id = AFE_PORT_ID_AWDSP_RX;
3611 int32_t module_id = AFE_MODULE_ID_AWDSP_RX;
3612 uint32_t port_index = 0;
3613 uint32_t payload_size = 0;
3614 size_t len;
3615 struct rtac_cal_block_data *aw_cal = &(this_afe.aw_cal);
3616 struct mem_mapping_hdr mem_hdr;
3617 struct param_hdr_v3 param_hdr;
3618
3619 pr_debug("%s: enter\n", __func__);
3620
3621 if (param_id == AFE_PARAM_ID_AWDSP_TX_SET_ENABLE) {
3622 port_id = AFE_PORT_ID_AWDSP_TX;
3623 module_id = AFE_MODULE_ID_AWDSP_TX;
3624 }
3625
3626 if (aw_cal->map_data.dma_buf == 0) {
3627 /*Minimal chunk size is 4K*/
3628 aw_cal->map_data.map_size = SZ_4K;
3629 result = msm_audio_ion_alloc(&(aw_cal->map_data.dma_buf),
3630 aw_cal->map_data.map_size,
3631 &(aw_cal->cal_data.paddr),&len,
3632 &(aw_cal->cal_data.kvaddr));
3633 if (result < 0) {
3634 pr_err("%s: allocate buffer failed! ret = %d\n",
3635 __func__, result);
3636 goto err;
3637 }
3638 }
3639
3640 if (aw_cal->map_data.map_handle == 0) {
3641 result = afe_map_rtac_block(aw_cal);
3642 if (result < 0) {
3643 pr_err("%s: map buffer failed! ret = %d\n",
3644 __func__, result);
3645 goto err;
3646 }
3647 }
3648
3649 port_index = q6audio_get_port_index(port_id);
3650 if (port_index >= AFE_MAX_PORTS) {
3651 pr_err("%s: Invalid AFE port = 0x%x\n", __func__, port_id);
3652 goto err;
3653 }
3654
3655 if (cmd_size > (SZ_4K - sizeof(struct param_hdr_v3))) {
3656 pr_err("%s: Invalid payload size = %d\n", __func__, cmd_size);
3657 result = -EINVAL;
3658 goto err;
3659 }
3660
3661 /* Pack message header with data */
3662 param_hdr.module_id = module_id;
3663 param_hdr.instance_id = INSTANCE_ID_0;
3664 param_hdr.param_size = cmd_size;
3665
3666 if (write) {
3667 param_hdr.param_id = param_id;
3668 q6common_pack_pp_params(aw_cal->cal_data.kvaddr,
3669 &param_hdr,
3670 buf,
3671 &payload_size);
3672 aw_cal->cal_data.size = payload_size;
3673 } else {
3674 param_hdr.param_id = param_id;
3675 aw_cal->cal_data.size = cmd_size + sizeof(struct param_hdr_v3);
3676 }
3677
3678 /*Send/Get package to/from ADSP*/
3679 mem_hdr.data_payload_addr_lsw =
3680 lower_32_bits(aw_cal->cal_data.paddr);
3681 mem_hdr.data_payload_addr_msw =
3682 msm_audio_populate_upper_32_bits(aw_cal->cal_data.paddr);
3683 mem_hdr.mem_map_handle =
3684 aw_cal->map_data.map_handle;
3685
3686 pr_debug("%s: Sending aw_cal port = 0x%x, cal size = %zd, cal addr = 0x%pK\n",
3687 __func__, port_id, aw_cal->cal_data.size, &aw_cal->cal_data.paddr);
3688
3689 result = afe_q6_interface_prepare();
3690 if (result != 0) {
3691 pr_err("%s: Q6 interface prepare failed %d\n", __func__, result);
3692 goto err;
3693 }
3694
3695 if (write) {
3696 if (q6common_is_instance_id_supported())
3697 result = q6afe_set_params_v3(port_id, port_index, &mem_hdr, NULL, payload_size);
3698 else
3699 result = q6afe_set_params_v2(port_id, port_index, &mem_hdr, NULL, payload_size);
3700 } else {
3701 int8_t *resp = (int8_t *)aw_cal->cal_data.kvaddr;
3702
3703 atomic_set(&this_afe.aw_state, 1);
3704 if (q6common_is_instance_id_supported()) {
3705 result = q6afe_get_params_v3(port_id, port_index, &mem_hdr, &param_hdr);
3706 resp += sizeof(struct param_hdr_v3);
3707 } else {
3708 result = q6afe_get_params_v2(port_id, port_index, &mem_hdr, &param_hdr);
3709 resp += sizeof(struct param_hdr_v1);
3710 }
3711
3712 if (result) {
3713 pr_err("%s: get response from port 0x%x failed %d\n",
3714 __func__, port_id, result);
3715 goto err;
3716 }
3717 else {
3718 /*Copy response data to command buffer*/
3719 memcpy(buf, resp, cmd_size);
3720 }
3721 }
3722err:
3723 return result;
3724}
3725EXPORT_SYMBOL(aw_send_afe_cal_apr);
3726void aw_cal_unmap_memory(void)
3727{
3728 int result = 0;
3729
3730 if (this_afe.aw_cal.map_data.map_handle) {
3731 result = afe_unmap_rtac_block(&this_afe.aw_cal.map_data.map_handle);
3732
3733 /*Force to remap after unmap failed*/
3734 if (result)
3735 this_afe.aw_cal.map_data.map_handle = 0;
3736 }
3737}
3738EXPORT_SYMBOL(aw_cal_unmap_memory);
3739#endif
3740
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303741static int afe_init_cdc_reg_config(void)
3742{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003743 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303744 int ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303745
3746 pr_debug("%s: enter\n", __func__);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003747 memset(&param_hdr, 0, sizeof(param_hdr));
3748 param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG;
3749 param_hdr.instance_id = INSTANCE_ID_0;
3750 param_hdr.param_id = AFE_PARAM_ID_CDC_REG_CFG_INIT;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303751
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003752 ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
3753 NULL);
3754 if (ret)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303755 pr_err("%s: AFE_PARAM_ID_CDC_INIT_REG_CFG failed %d\n",
3756 __func__, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303757
3758 return ret;
3759}
3760
3761static int afe_send_slimbus_slave_port_cfg(
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003762 struct afe_param_slimbus_slave_port_cfg *slim_slave_config, u16 port_id)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303763{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003764 struct param_hdr_v3 param_hdr;
3765 int ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303766
3767 pr_debug("%s: enter, port_id = 0x%x\n", __func__, port_id);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003768 memset(&param_hdr, 0, sizeof(param_hdr));
3769 param_hdr.module_id = AFE_MODULE_HW_MAD;
3770 param_hdr.instance_id = INSTANCE_ID_0;
3771 param_hdr.reserved = 0;
3772 param_hdr.param_id = AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG;
3773 param_hdr.param_size = sizeof(struct afe_param_slimbus_slave_port_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303774
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003775 ret = q6afe_pack_and_set_param_in_band(port_id,
3776 q6audio_get_port_index(port_id),
3777 param_hdr,
3778 (u8 *) slim_slave_config);
3779 if (ret)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303780 pr_err("%s: AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG failed %d\n",
3781 __func__, ret);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003782
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303783 pr_debug("%s: leave %d\n", __func__, ret);
3784 return ret;
3785}
3786static int afe_aanc_port_cfg(void *apr, uint16_t tx_port, uint16_t rx_port)
3787{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003788 struct afe_param_aanc_port_cfg aanc_port_cfg;
3789 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303790 int ret = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303791
3792 pr_debug("%s: tx_port 0x%x, rx_port 0x%x\n",
3793 __func__, tx_port, rx_port);
3794
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003795 pr_debug("%s: AANC sample rate tx rate: %d rx rate %d\n", __func__,
3796 this_afe.aanc_info.aanc_tx_port_sample_rate,
3797 this_afe.aanc_info.aanc_rx_port_sample_rate);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303798
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003799 memset(&aanc_port_cfg, 0, sizeof(aanc_port_cfg));
3800 memset(&param_hdr, 0, sizeof(param_hdr));
3801
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303802 /*
3803 * If aanc tx sample rate or rx sample rate is zero, skip aanc
3804 * configuration as AFE resampler will fail for invalid sample
3805 * rates.
3806 */
3807 if (!this_afe.aanc_info.aanc_tx_port_sample_rate ||
3808 !this_afe.aanc_info.aanc_rx_port_sample_rate) {
3809 return -EINVAL;
3810 }
3811
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003812 param_hdr.module_id = AFE_MODULE_AANC;
3813 param_hdr.instance_id = INSTANCE_ID_0;
3814 param_hdr.param_id = AFE_PARAM_ID_AANC_PORT_CONFIG;
3815 param_hdr.param_size = sizeof(struct afe_param_aanc_port_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303816
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003817 aanc_port_cfg.aanc_port_cfg_minor_version =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303818 AFE_API_VERSION_AANC_PORT_CONFIG;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003819 aanc_port_cfg.tx_port_sample_rate =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303820 this_afe.aanc_info.aanc_tx_port_sample_rate;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003821 aanc_port_cfg.tx_port_channel_map[0] = AANC_TX_VOICE_MIC;
3822 aanc_port_cfg.tx_port_channel_map[1] = AANC_TX_NOISE_MIC;
3823 aanc_port_cfg.tx_port_channel_map[2] = AANC_TX_ERROR_MIC;
3824 aanc_port_cfg.tx_port_channel_map[3] = AANC_TX_MIC_UNUSED;
3825 aanc_port_cfg.tx_port_channel_map[4] = AANC_TX_MIC_UNUSED;
3826 aanc_port_cfg.tx_port_channel_map[5] = AANC_TX_MIC_UNUSED;
3827 aanc_port_cfg.tx_port_channel_map[6] = AANC_TX_MIC_UNUSED;
3828 aanc_port_cfg.tx_port_channel_map[7] = AANC_TX_MIC_UNUSED;
3829 aanc_port_cfg.tx_port_num_channels = 3;
3830 aanc_port_cfg.rx_path_ref_port_id = rx_port;
3831 aanc_port_cfg.ref_port_sample_rate =
3832 this_afe.aanc_info.aanc_rx_port_sample_rate;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303833
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003834 ret = q6afe_pack_and_set_param_in_band(tx_port,
3835 q6audio_get_port_index(tx_port),
3836 param_hdr,
3837 (u8 *) &aanc_port_cfg);
3838 if (ret)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303839 pr_err("%s: AFE AANC port config failed for tx_port 0x%x, rx_port 0x%x ret %d\n",
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003840 __func__, tx_port, rx_port, ret);
Sudheer Papothiaf431ad2018-05-04 05:06:11 +05303841 else
3842 q6afe_set_aanc_level();
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303843
3844 return ret;
3845}
3846
3847static int afe_aanc_mod_enable(void *apr, uint16_t tx_port, uint16_t enable)
3848{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003849 struct afe_mod_enable_param mod_enable;
3850 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303851 int ret = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303852
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003853 pr_debug("%s: tx_port 0x%x\n", __func__, tx_port);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303854
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003855 memset(&mod_enable, 0, sizeof(mod_enable));
3856 memset(&param_hdr, 0, sizeof(param_hdr));
3857 param_hdr.module_id = AFE_MODULE_AANC;
3858 param_hdr.instance_id = INSTANCE_ID_0;
3859 param_hdr.param_id = AFE_PARAM_ID_ENABLE;
3860 param_hdr.param_size = sizeof(struct afe_mod_enable_param);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303861
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003862 mod_enable.enable = enable;
3863 mod_enable.reserved = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303864
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003865 ret = q6afe_pack_and_set_param_in_band(tx_port,
3866 q6audio_get_port_index(tx_port),
3867 param_hdr, (u8 *) &mod_enable);
3868 if (ret)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303869 pr_err("%s: AFE AANC enable failed for tx_port 0x%x ret %d\n",
3870 __func__, tx_port, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303871 return ret;
3872}
3873
3874static int afe_send_bank_selection_clip(
3875 struct afe_param_id_clip_bank_sel *param)
3876{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003877 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303878 int ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303879
3880 if (!param) {
3881 pr_err("%s: Invalid params", __func__);
3882 return -EINVAL;
3883 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003884 memset(&param_hdr, 0, sizeof(param_hdr));
3885 param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG;
3886 param_hdr.instance_id = INSTANCE_ID_0;
3887 param_hdr.param_id = AFE_PARAM_ID_CLIP_BANK_SEL_CFG;
3888 param_hdr.param_size = sizeof(struct afe_param_id_clip_bank_sel);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303889
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003890 ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
3891 (u8 *) param);
3892 if (ret)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303893 pr_err("%s: AFE_PARAM_ID_CLIP_BANK_SEL_CFG failed %d\n",
3894 __func__, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303895 return ret;
3896}
3897int afe_send_aanc_version(
3898 struct afe_param_id_cdc_aanc_version *version_cfg)
3899{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003900 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303901 int ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303902
3903 pr_debug("%s: enter\n", __func__);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003904 memset(&param_hdr, 0, sizeof(param_hdr));
3905 param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG;
3906 param_hdr.instance_id = INSTANCE_ID_0;
3907 param_hdr.param_id = AFE_PARAM_ID_CDC_AANC_VERSION;
3908 param_hdr.param_size = sizeof(struct afe_param_id_cdc_aanc_version);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303909
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08003910 ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
3911 (u8 *) version_cfg);
3912 if (ret)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303913 pr_err("%s: AFE_PARAM_ID_CDC_AANC_VERSION failed %d\n",
3914 __func__, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303915 return ret;
3916}
3917
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05303918/**
3919 * afe_port_set_mad_type -
3920 * to update mad type
3921 *
3922 * @port_id: AFE port id number
3923 * @mad_type: MAD type enum value
3924 *
3925 * Returns 0 on success or error on failure.
3926 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303927int afe_port_set_mad_type(u16 port_id, enum afe_mad_type mad_type)
3928{
3929 int i;
3930
3931 if (port_id == AFE_PORT_ID_TERTIARY_MI2S_TX ||
Aditya Bavanarie9454c62018-08-23 23:45:20 +05303932 port_id == AFE_PORT_ID_INT3_MI2S_TX ||
Guodong Hu395166b2019-10-10 16:56:28 +08003933 port_id == AFE_PORT_ID_TX_CODEC_DMA_TX_3 ||
3934 port_id == AFE_PORT_ID_TERTIARY_TDM_TX) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303935 mad_type = MAD_SW_AUDIO;
3936 return 0;
3937 }
3938
3939 i = port_id - SLIMBUS_0_RX;
3940 if (i < 0 || i >= ARRAY_SIZE(afe_ports_mad_type)) {
3941 pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
3942 return -EINVAL;
3943 }
3944 atomic_set(&afe_ports_mad_type[i], mad_type);
3945 return 0;
3946}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05303947EXPORT_SYMBOL(afe_port_set_mad_type);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303948
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05303949/**
3950 * afe_port_get_mad_type -
3951 * to retrieve mad type
3952 *
3953 * @port_id: AFE port id number
3954 *
3955 * Returns valid enum value on success or MAD_HW_NONE on failure.
3956 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303957enum afe_mad_type afe_port_get_mad_type(u16 port_id)
3958{
3959 int i;
3960
3961 if (port_id == AFE_PORT_ID_TERTIARY_MI2S_TX ||
Aditya Bavanarie9454c62018-08-23 23:45:20 +05303962 port_id == AFE_PORT_ID_INT3_MI2S_TX ||
Guodong Hu395166b2019-10-10 16:56:28 +08003963 port_id == AFE_PORT_ID_TX_CODEC_DMA_TX_3 ||
3964 port_id == AFE_PORT_ID_TERTIARY_TDM_TX)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303965 return MAD_SW_AUDIO;
3966
3967 i = port_id - SLIMBUS_0_RX;
3968 if (i < 0 || i >= ARRAY_SIZE(afe_ports_mad_type)) {
3969 pr_debug("%s: Non Slimbus port_id 0x%x\n", __func__, port_id);
3970 return MAD_HW_NONE;
3971 }
3972 return (enum afe_mad_type) atomic_read(&afe_ports_mad_type[i]);
3973}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05303974EXPORT_SYMBOL(afe_port_get_mad_type);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303975
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05303976/**
3977 * afe_set_config -
3978 * to configure AFE session with
3979 * specified configuration for given config type
3980 *
3981 * @config_type: config type
3982 * @config_data: configuration to pass to AFE session
3983 * @arg: argument used in specific config types
3984 *
3985 * Returns 0 on success or error value on port start failure.
3986 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303987int afe_set_config(enum afe_config_type config_type, void *config_data, int arg)
3988{
3989 int ret;
3990
3991 pr_debug("%s: enter config_type %d\n", __func__, config_type);
3992 ret = afe_q6_interface_prepare();
3993 if (ret) {
3994 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
3995 return ret;
3996 }
3997
3998 switch (config_type) {
3999 case AFE_SLIMBUS_SLAVE_CONFIG:
4000 ret = afe_send_slimbus_slave_cfg(config_data);
4001 if (!ret)
4002 ret = afe_init_cdc_reg_config();
4003 else
4004 pr_err("%s: Sending slimbus slave config failed %d\n",
4005 __func__, ret);
4006 break;
4007 case AFE_CDC_REGISTERS_CONFIG:
4008 ret = afe_send_codec_reg_config(config_data);
4009 break;
4010 case AFE_SLIMBUS_SLAVE_PORT_CONFIG:
4011 ret = afe_send_slimbus_slave_port_cfg(config_data, arg);
4012 break;
4013 case AFE_AANC_VERSION:
4014 ret = afe_send_aanc_version(config_data);
4015 break;
4016 case AFE_CLIP_BANK_SEL:
4017 ret = afe_send_bank_selection_clip(config_data);
4018 break;
4019 case AFE_CDC_CLIP_REGISTERS_CONFIG:
4020 ret = afe_send_codec_reg_config(config_data);
4021 break;
4022 case AFE_CDC_REGISTER_PAGE_CONFIG:
4023 ret = afe_send_codec_reg_page_config(config_data);
4024 break;
4025 default:
4026 pr_err("%s: unknown configuration type %d",
4027 __func__, config_type);
4028 ret = -EINVAL;
4029 }
4030
4031 if (!ret)
4032 set_bit(config_type, &afe_configured_cmd);
4033
4034 return ret;
4035}
4036EXPORT_SYMBOL(afe_set_config);
4037
4038/*
4039 * afe_clear_config - If SSR happens ADSP loses AFE configs, let AFE driver know
4040 * about the state so client driver can wait until AFE is
4041 * reconfigured.
4042 */
4043void afe_clear_config(enum afe_config_type config)
4044{
4045 clear_bit(config, &afe_configured_cmd);
4046}
4047EXPORT_SYMBOL(afe_clear_config);
4048
4049bool afe_has_config(enum afe_config_type config)
4050{
4051 return !!test_bit(config, &afe_configured_cmd);
4052}
4053
4054int afe_send_spdif_clk_cfg(struct afe_param_id_spdif_clk_cfg *cfg,
4055 u16 port_id)
4056{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004057 struct afe_param_id_spdif_clk_cfg clk_cfg;
4058 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304059 int ret = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304060
4061 if (!cfg) {
4062 pr_err("%s: Error, no configuration data\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304063 return -EINVAL;
4064 }
4065
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004066 memset(&clk_cfg, 0, sizeof(clk_cfg));
4067 memset(&param_hdr, 0, sizeof(param_hdr));
4068 param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
4069 param_hdr.instance_id = INSTANCE_ID_0;
4070 param_hdr.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG;
4071 param_hdr.param_size = sizeof(struct afe_param_id_spdif_clk_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304072
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004073 pr_debug("%s: Minor version = 0x%x clk val = %d clk root = 0x%x port id = 0x%x\n",
4074 __func__, clk_cfg.clk_cfg_minor_version, clk_cfg.clk_value,
4075 clk_cfg.clk_root, q6audio_get_port_id(port_id));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304076
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004077 ret = q6afe_pack_and_set_param_in_band(port_id,
4078 q6audio_get_port_index(port_id),
4079 param_hdr, (u8 *) &clk_cfg);
4080 if (ret < 0)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304081 pr_err("%s: AFE send clock config for port 0x%x failed ret = %d\n",
4082 __func__, port_id, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304083 return ret;
4084}
4085
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05304086/**
4087 * afe_send_spdif_ch_status_cfg -
4088 * to configure AFE session with
4089 * specified channel status configuration
4090 *
4091 * @ch_status_cfg: channel status configutation
4092 * @port_id: AFE port id number
4093 *
4094 * Returns 0 on success or error value on port start failure.
4095 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304096int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg
4097 *ch_status_cfg, u16 port_id)
4098{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004099 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304100 int ret = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304101
Karthikeyan Mani0253cb92018-11-30 11:14:36 -08004102 if (!ch_status_cfg) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304103 pr_err("%s: Error, no configuration data\n", __func__);
Karthikeyan Mani0253cb92018-11-30 11:14:36 -08004104 return -EINVAL;
4105 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304106
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004107 memset(&param_hdr, 0, sizeof(param_hdr));
4108 param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
4109 param_hdr.instance_id = INSTANCE_ID_0;
4110 param_hdr.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG;
4111 param_hdr.param_size = sizeof(struct afe_param_id_spdif_ch_status_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304112
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004113 ret = q6afe_pack_and_set_param_in_band(port_id,
4114 q6audio_get_port_index(port_id),
4115 param_hdr, (u8 *) ch_status_cfg);
4116 if (ret < 0)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304117 pr_err("%s: AFE send channel status for port 0x%x failed ret = %d\n",
4118 __func__, port_id, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304119 return ret;
4120}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05304121EXPORT_SYMBOL(afe_send_spdif_ch_status_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304122
Ramprasad Katkam250075f2018-08-31 03:31:54 +05304123int afe_send_cmd_wakeup_register(void *handle, bool enable)
4124{
4125 struct afe_svc_cmd_evt_cfg_payload wakeup_irq;
Aditya Bavanari91674b52018-11-23 17:02:49 +05304126 int ret = 0;
Ramprasad Katkam250075f2018-08-31 03:31:54 +05304127
4128 pr_debug("%s: enter\n", __func__);
4129
4130 wakeup_irq.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4131 APR_HDR_LEN(APR_HDR_SIZE),
4132 APR_PKT_VER);
4133 wakeup_irq.hdr.pkt_size = sizeof(wakeup_irq);
4134 wakeup_irq.hdr.src_port = 0;
4135 wakeup_irq.hdr.dest_port = 0;
4136 wakeup_irq.hdr.token = 0x0;
4137 wakeup_irq.hdr.opcode = AFE_SVC_CMD_EVENT_CFG;
4138 wakeup_irq.event_id = AFE_EVENT_ID_MBHC_DETECTION_SW_WA;
4139 wakeup_irq.reg_flag = enable;
Aditya Bavanari91674b52018-11-23 17:02:49 +05304140 pr_debug("%s: cmd wakeup register opcode[0x%x] register:%d\n",
Ramprasad Katkam250075f2018-08-31 03:31:54 +05304141 __func__, wakeup_irq.hdr.opcode, wakeup_irq.reg_flag);
4142
4143 ret = afe_apr_send_pkt(&wakeup_irq, &this_afe.wait_wakeup);
Aditya Bavanari91674b52018-11-23 17:02:49 +05304144 if (ret)
Ramprasad Katkam250075f2018-08-31 03:31:54 +05304145 pr_err("%s: AFE wakeup command register %d failed %d\n",
4146 __func__, enable, ret);
Ramprasad Katkam250075f2018-08-31 03:31:54 +05304147
4148 return ret;
4149}
4150EXPORT_SYMBOL(afe_send_cmd_wakeup_register);
4151
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304152static int afe_send_cmd_port_start(u16 port_id)
4153{
4154 struct afe_port_cmd_device_start start;
4155 int ret, index;
4156
4157 pr_debug("%s: enter\n", __func__);
4158 index = q6audio_get_port_index(port_id);
4159 if (index < 0 || index >= AFE_MAX_PORTS) {
4160 pr_err("%s: AFE port index[%d] invalid!\n",
4161 __func__, index);
4162 return -EINVAL;
4163 }
4164 ret = q6audio_validate_port(port_id);
4165 if (ret < 0) {
4166 pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
4167 return -EINVAL;
4168 }
4169
4170 start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4171 APR_HDR_LEN(APR_HDR_SIZE),
4172 APR_PKT_VER);
4173 start.hdr.pkt_size = sizeof(start);
4174 start.hdr.src_port = 0;
4175 start.hdr.dest_port = 0;
4176 start.hdr.token = index;
4177 start.hdr.opcode = AFE_PORT_CMD_DEVICE_START;
4178 start.port_id = q6audio_get_port_id(port_id);
4179 pr_debug("%s: cmd device start opcode[0x%x] port id[0x%x]\n",
4180 __func__, start.hdr.opcode, start.port_id);
4181
4182 ret = afe_apr_send_pkt(&start, &this_afe.wait[index]);
Aditya Bavanari91674b52018-11-23 17:02:49 +05304183 if (ret)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304184 pr_err("%s: AFE enable for port 0x%x failed %d\n", __func__,
4185 port_id, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304186
4187 return ret;
4188}
4189
4190static int afe_aanc_start(uint16_t tx_port_id, uint16_t rx_port_id)
4191{
4192 int ret;
4193
4194 pr_debug("%s: Tx port is 0x%x, Rx port is 0x%x\n",
4195 __func__, tx_port_id, rx_port_id);
4196 ret = afe_aanc_port_cfg(this_afe.apr, tx_port_id, rx_port_id);
4197 if (ret) {
4198 pr_err("%s: Send AANC Port Config failed %d\n",
4199 __func__, ret);
4200 goto fail_cmd;
4201 }
4202 send_afe_cal_type(AFE_AANC_CAL, tx_port_id);
4203
4204fail_cmd:
4205 return ret;
4206}
4207
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05304208/**
4209 * afe_spdif_port_start - to configure AFE session with
4210 * specified port configuration
4211 *
4212 * @port_id: AFE port id number
4213 * @spdif_port: spdif port configutation
4214 * @rate: sampling rate of port
4215 *
4216 * Returns 0 on success or error value on port start failure.
4217 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304218int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port,
4219 u32 rate)
4220{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004221 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304222 uint16_t port_index;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004223 int ret = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304224
4225 if (!spdif_port) {
4226 pr_err("%s: Error, no configuration data\n", __func__);
4227 ret = -EINVAL;
4228 return ret;
4229 }
4230
4231 pr_debug("%s: port id: 0x%x\n", __func__, port_id);
4232
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004233 memset(&param_hdr, 0, sizeof(param_hdr));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304234 ret = q6audio_validate_port(port_id);
4235 if (ret < 0) {
4236 pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
4237 return -EINVAL;
4238 }
4239
4240 afe_send_cal(port_id);
4241 afe_send_hw_delay(port_id, rate);
4242
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004243 param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
4244 param_hdr.instance_id = INSTANCE_ID_0;
4245 param_hdr.param_id = AFE_PARAM_ID_SPDIF_CONFIG;
4246 param_hdr.param_size = sizeof(struct afe_spdif_port_config);
4247
4248 ret = q6afe_pack_and_set_param_in_band(port_id,
4249 q6audio_get_port_index(port_id),
4250 param_hdr, (u8 *) spdif_port);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304251 if (ret) {
4252 pr_err("%s: AFE enable for port 0x%x failed ret = %d\n",
Ralf Herzcc29b9e2018-07-17 20:19:04 +05304253 __func__, port_id, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304254 goto fail_cmd;
4255 }
4256
4257 port_index = afe_get_port_index(port_id);
4258 if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
4259 this_afe.afe_sample_rates[port_index] = rate;
4260 } else {
4261 pr_err("%s: Invalid port index %d\n", __func__, port_index);
4262 ret = -EINVAL;
4263 goto fail_cmd;
4264 }
4265
Ralf Herzcc29b9e2018-07-17 20:19:04 +05304266 if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) {
4267 ret = afe_send_spdif_ch_status_cfg(&spdif_port->ch_status,
4268 port_id);
4269 if (ret < 0) {
4270 pr_err("%s: afe send failed %d\n", __func__, ret);
4271 goto fail_cmd;
4272 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304273 }
4274
4275 return afe_send_cmd_port_start(port_id);
4276
4277fail_cmd:
4278 return ret;
4279}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05304280EXPORT_SYMBOL(afe_spdif_port_start);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304281
Ralf Herzcc29b9e2018-07-17 20:19:04 +05304282/**
4283 * afe_spdif_reg_event_cfg -
4284 * register for event from AFE spdif port
4285 *
4286 * @port_id: Port ID to register event
4287 * @reg_flag: register or unregister
4288 * @cb: callback function to invoke for events from module
4289 * @private_data: private data to sent back in callback fn
4290 *
4291 * Returns 0 on success or error on failure
4292 */
4293int afe_spdif_reg_event_cfg(u16 port_id, u16 reg_flag,
4294 void (*cb)(uint32_t opcode,
4295 uint32_t token, uint32_t *payload, void *priv),
4296 void *private_data)
4297{
4298 struct afe_port_cmd_event_cfg *config;
4299 struct afe_port_cmd_mod_evt_cfg_payload pl;
4300 int index;
4301 int ret;
4302 int num_events = 1;
4303 int cmd_size = sizeof(struct afe_port_cmd_event_cfg) +
4304 (num_events * sizeof(struct afe_port_cmd_mod_evt_cfg_payload));
4305
4306 config = kzalloc(cmd_size, GFP_KERNEL);
4307 if (!config)
4308 return -ENOMEM;
4309
4310 if (port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) {
4311 this_afe.pri_spdif_tx_cb = cb;
4312 this_afe.pri_spdif_tx_private_data = private_data;
4313 } else if (port_id == AFE_PORT_ID_SECONDARY_SPDIF_TX) {
4314 this_afe.sec_spdif_tx_cb = cb;
4315 this_afe.sec_spdif_tx_private_data = private_data;
4316 } else {
4317 pr_err("%s: wrong port id 0x%x\n", __func__, port_id);
4318 ret = -EINVAL;
4319 goto fail_idx;
4320 }
4321
4322 index = q6audio_get_port_index(port_id);
4323 if (index < 0) {
4324 pr_err("%s: Invalid index number: %d\n", __func__, index);
4325 ret = -EINVAL;
4326 goto fail_idx;
4327 }
4328
4329 memset(&pl, 0, sizeof(pl));
4330 pl.module_id = AFE_MODULE_CUSTOM_EVENTS;
4331 pl.event_id = AFE_PORT_FMT_UPDATE_EVENT;
4332 pl.reg_flag = reg_flag;
4333
4334 config->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
4335 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
4336 config->hdr.pkt_size = cmd_size;
4337 config->hdr.src_port = 1;
4338 config->hdr.dest_port = 1;
4339 config->hdr.token = index;
4340
4341 config->hdr.opcode = AFE_PORT_CMD_MOD_EVENT_CFG;
4342 config->port_id = q6audio_get_port_id(port_id);
4343 config->num_events = num_events;
4344 config->version = 1;
4345 memcpy(config->payload, &pl, sizeof(pl));
Aditya Bavanarid6546e32019-10-29 17:24:59 +05304346 ret = afe_apr_send_pkt((uint32_t *) config, &this_afe.wait[index]);
Ralf Herzcc29b9e2018-07-17 20:19:04 +05304347
4348fail_idx:
4349 kfree(config);
4350 return ret;
4351}
4352EXPORT_SYMBOL(afe_spdif_reg_event_cfg);
4353
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304354int afe_send_slot_mapping_cfg(
4355 struct afe_param_id_slot_mapping_cfg *slot_mapping_cfg,
4356 u16 port_id)
4357{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004358 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304359 int ret = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304360
4361 if (!slot_mapping_cfg) {
4362 pr_err("%s: Error, no configuration data\n", __func__);
4363 return -EINVAL;
4364 }
4365
4366 pr_debug("%s: port id: 0x%x\n", __func__, port_id);
4367
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004368 memset(&param_hdr, 0, sizeof(param_hdr));
4369 param_hdr.module_id = AFE_MODULE_TDM;
4370 param_hdr.instance_id = INSTANCE_ID_0;
4371 param_hdr.param_id = AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG;
4372 param_hdr.param_size = sizeof(struct afe_param_id_slot_mapping_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304373
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004374 ret = q6afe_pack_and_set_param_in_band(port_id,
4375 q6audio_get_port_index(port_id),
4376 param_hdr,
4377 (u8 *) slot_mapping_cfg);
4378 if (ret < 0)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304379 pr_err("%s: AFE send slot mapping for port 0x%x failed ret = %d\n",
4380 __func__, port_id, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304381 return ret;
4382}
4383
Cong Tang04a6cfa2019-02-26 15:08:55 +08004384int afe_send_slot_mapping_cfg_v2(
4385 struct afe_param_id_slot_mapping_cfg_v2 *slot_mapping_cfg,
4386 u16 port_id)
4387{
4388 struct param_hdr_v3 param_hdr;
4389 int ret = 0;
4390
4391 if (!slot_mapping_cfg) {
4392 pr_err("%s: Error, no configuration data\n", __func__);
4393 return -EINVAL;
4394 }
4395
4396 pr_debug("%s: port id: 0x%x\n", __func__, port_id);
4397
4398 memset(&param_hdr, 0, sizeof(param_hdr));
4399 param_hdr.module_id = AFE_MODULE_TDM;
4400 param_hdr.instance_id = INSTANCE_ID_0;
4401 param_hdr.param_id = AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG;
4402 param_hdr.param_size = sizeof(struct afe_param_id_slot_mapping_cfg_v2);
4403
4404 ret = q6afe_pack_and_set_param_in_band(port_id,
4405 q6audio_get_port_index(port_id),
4406 param_hdr,
4407 (u8 *) slot_mapping_cfg);
4408 if (ret < 0)
4409 pr_err("%s: AFE send slot mapping for port 0x%x failed ret = %d\n",
4410 __func__, port_id, ret);
4411 return ret;
4412}
4413
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304414int afe_send_custom_tdm_header_cfg(
4415 struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header_cfg,
4416 u16 port_id)
4417{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004418 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304419 int ret = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304420
4421 if (!custom_tdm_header_cfg) {
4422 pr_err("%s: Error, no configuration data\n", __func__);
4423 return -EINVAL;
4424 }
4425
4426 pr_debug("%s: port id: 0x%x\n", __func__, port_id);
4427
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004428 memset(&param_hdr, 0, sizeof(param_hdr));
4429 param_hdr.module_id = AFE_MODULE_TDM;
4430 param_hdr.instance_id = INSTANCE_ID_0;
4431 param_hdr.param_id = AFE_PARAM_ID_CUSTOM_TDM_HEADER_CONFIG;
4432 param_hdr.param_size =
4433 sizeof(struct afe_param_id_custom_tdm_header_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304434
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004435 ret = q6afe_pack_and_set_param_in_band(port_id,
4436 q6audio_get_port_index(port_id),
4437 param_hdr,
4438 (u8 *) custom_tdm_header_cfg);
4439 if (ret < 0)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304440 pr_err("%s: AFE send custom tdm header for port 0x%x failed ret = %d\n",
4441 __func__, port_id, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304442 return ret;
4443}
4444
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05304445/**
4446 * afe_tdm_port_start - to configure AFE session with
4447 * specified port configuration
4448 *
4449 * @port_id: AFE port id number
4450 * @tdm_port: TDM port configutation
4451 * @rate: sampling rate of port
4452 * @num_groups: number of TDM groups
4453 *
4454 * Returns 0 on success or error value on port start failure.
4455 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304456int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port,
4457 u32 rate, u16 num_groups)
4458{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004459 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304460 int index = 0;
4461 uint16_t port_index = 0;
4462 enum afe_mad_type mad_type = MAD_HW_NONE;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004463 int ret = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304464
4465 if (!tdm_port) {
4466 pr_err("%s: Error, no configuration data\n", __func__);
4467 return -EINVAL;
4468 }
4469
4470 pr_debug("%s: port id: 0x%x\n", __func__, port_id);
4471
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004472 memset(&param_hdr, 0, sizeof(param_hdr));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304473 index = q6audio_get_port_index(port_id);
4474 if (index < 0 || index >= AFE_MAX_PORTS) {
4475 pr_err("%s: AFE port index[%d] invalid!\n",
4476 __func__, index);
4477 return -EINVAL;
4478 }
4479 ret = q6audio_validate_port(port_id);
4480 if (ret < 0) {
4481 pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
4482 return -EINVAL;
4483 }
4484
4485 ret = afe_q6_interface_prepare();
4486 if (ret != 0) {
4487 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
4488 return ret;
4489 }
4490
4491 if ((index >= 0) && (index < AFE_MAX_PORTS)) {
4492 this_afe.afe_sample_rates[index] = rate;
4493
4494 if (this_afe.rt_cb)
4495 this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id);
4496 }
4497
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304498 port_index = afe_get_port_index(port_id);
Mangesh Kunchamwarbc81e3a2018-10-09 11:38:02 +05304499
Mangesh Kunchamwarbc81e3a2018-10-09 11:38:02 +05304500 /* Also send the topology id here: */
Xiaoyu Ye13da4822017-09-18 17:46:30 -07004501 if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304502 /* One time call: only for first time */
4503 afe_send_custom_topology();
4504 afe_send_port_topology_id(port_id);
4505 afe_send_cal(port_id);
4506 afe_send_hw_delay(port_id, rate);
4507 }
4508
4509 /* Start SW MAD module */
4510 mad_type = afe_port_get_mad_type(port_id);
4511 pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id,
4512 mad_type);
4513 if (mad_type != MAD_HW_NONE && mad_type != MAD_SW_AUDIO) {
4514 if (!afe_has_config(AFE_CDC_REGISTERS_CONFIG) ||
4515 !afe_has_config(AFE_SLIMBUS_SLAVE_CONFIG)) {
4516 pr_err("%s: AFE isn't configured yet for\n"
4517 "HW MAD try Again\n", __func__);
4518 ret = -EAGAIN;
4519 goto fail_cmd;
4520 }
4521 ret = afe_turn_onoff_hw_mad(mad_type, true);
4522 if (ret) {
4523 pr_err("%s: afe_turn_onoff_hw_mad failed %d\n",
4524 __func__, ret);
4525 goto fail_cmd;
4526 }
4527 }
4528
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004529 param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
4530 param_hdr.instance_id = INSTANCE_ID_0;
4531 param_hdr.param_id = AFE_PARAM_ID_TDM_CONFIG;
4532 param_hdr.param_size = sizeof(struct afe_param_id_tdm_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304533
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004534 ret = q6afe_pack_and_set_param_in_band(port_id,
4535 q6audio_get_port_index(port_id),
4536 param_hdr,
4537 (u8 *) &tdm_port->tdm);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304538 if (ret) {
4539 pr_err("%s: AFE enable for port 0x%x failed ret = %d\n",
4540 __func__, port_id, ret);
4541 goto fail_cmd;
4542 }
4543
4544 port_index = afe_get_port_index(port_id);
4545 if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
4546 this_afe.afe_sample_rates[port_index] = rate;
4547 } else {
4548 pr_err("%s: Invalid port index %d\n", __func__, port_index);
4549 ret = -EINVAL;
4550 goto fail_cmd;
4551 }
Xiaoyu Ye13da4822017-09-18 17:46:30 -07004552
Cong Tang04a6cfa2019-02-26 15:08:55 +08004553 if (q6core_get_avcs_api_version_per_service(
4554 APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V3)
4555 ret = afe_send_slot_mapping_cfg_v2(
4556 &tdm_port->slot_mapping_v2, port_id);
4557 else
4558 ret = afe_send_slot_mapping_cfg(
4559 &tdm_port->slot_mapping,
4560 port_id);
4561
Xiaoyu Ye13da4822017-09-18 17:46:30 -07004562 if (ret < 0) {
4563 pr_err("%s: afe send failed %d\n", __func__, ret);
4564 goto fail_cmd;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304565 }
4566
4567 if (tdm_port->custom_tdm_header.header_type) {
4568 ret = afe_send_custom_tdm_header_cfg(
4569 &tdm_port->custom_tdm_header, port_id);
4570 if (ret < 0) {
4571 pr_err("%s: afe send failed %d\n", __func__, ret);
4572 goto fail_cmd;
4573 }
4574 }
4575
4576 ret = afe_send_cmd_port_start(port_id);
4577
4578fail_cmd:
4579 return ret;
4580}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05304581EXPORT_SYMBOL(afe_tdm_port_start);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304582
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05304583/**
4584 * afe_set_cal_mode -
4585 * set cal mode for AFE calibration
4586 *
4587 * @port_id: AFE port id number
4588 * @afe_cal_mode: AFE calib mode
4589 *
4590 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304591void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode)
4592{
4593 uint16_t port_index;
4594
4595 port_index = afe_get_port_index(port_id);
4596 this_afe.afe_cal_mode[port_index] = afe_cal_mode;
4597}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05304598EXPORT_SYMBOL(afe_set_cal_mode);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304599
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05304600/**
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05304601 * afe_set_vad_cfg -
4602 * set configuration for VAD
4603 *
4604 * @port_id: AFE port id number
4605 * @vad_enable: enable/disable vad
4606 * @preroll_config: Preroll configuration
4607 *
4608 */
4609void afe_set_vad_cfg(u32 vad_enable, u32 preroll_config,
4610 u32 port_id)
4611{
4612 uint16_t port_index;
4613
4614 port_index = afe_get_port_index(port_id);
4615 this_afe.vad_cfg[port_index].is_enable = vad_enable;
4616 this_afe.vad_cfg[port_index].pre_roll = preroll_config;
4617}
4618EXPORT_SYMBOL(afe_set_vad_cfg);
4619
4620/**
Mangesh Kunchamwar07b8dc92018-07-16 19:46:25 +05304621 * afe_get_island_mode_cfg -
4622 * get island mode configuration
4623 *
4624 * @port_id: AFE port id number
4625 * @enable_flag: Enable or Disable
4626 *
4627 */
4628void afe_get_island_mode_cfg(u16 port_id, u32 *enable_flag)
4629{
4630 uint16_t port_index;
4631
4632 if (enable_flag) {
4633 port_index = afe_get_port_index(port_id);
4634 *enable_flag = this_afe.island_mode[port_index];
4635 }
4636}
4637EXPORT_SYMBOL(afe_get_island_mode_cfg);
4638
4639/**
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05304640 * afe_set_island_mode_cfg -
4641 * set island mode configuration
4642 *
4643 * @port_id: AFE port id number
4644 * @enable_flag: Enable or Disable
4645 *
4646 */
4647void afe_set_island_mode_cfg(u16 port_id, u32 enable_flag)
4648{
4649 uint16_t port_index;
4650
4651 port_index = afe_get_port_index(port_id);
4652 this_afe.island_mode[port_index] = enable_flag;
4653
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07004654 trace_printk("%s: set island mode cfg 0x%x for port 0x%x\n",
4655 __func__, this_afe.island_mode[port_index], port_id);
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05304656}
4657EXPORT_SYMBOL(afe_set_island_mode_cfg);
4658
4659/**
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05304660 * afe_set_routing_callback -
4661 * Update callback function for routing
4662 *
4663 * @cb: callback function to update with
4664 *
4665 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304666void afe_set_routing_callback(routing_cb cb)
4667{
4668 this_afe.rt_cb = cb;
4669}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05304670EXPORT_SYMBOL(afe_set_routing_callback);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304671
4672int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config)
4673{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004674 struct afe_param_id_usb_audio_dev_params usb_dev;
4675 struct afe_param_id_usb_audio_dev_lpcm_fmt lpcm_fmt;
Garmond Leung6b3f4182018-05-11 12:29:34 -07004676 struct afe_param_id_usb_audio_svc_interval svc_int;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004677 struct param_hdr_v3 param_hdr;
Garmond Leung6b3f4182018-05-11 12:29:34 -07004678 int ret = 0, index = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304679
4680 if (!afe_config) {
4681 pr_err("%s: Error, no configuration data\n", __func__);
4682 ret = -EINVAL;
4683 goto exit;
4684 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304685
Garmond Leung6b3f4182018-05-11 12:29:34 -07004686 index = q6audio_get_port_index(port_id);
4687
4688 if (index < 0 || index >= AFE_MAX_PORTS) {
4689 pr_err("%s: AFE port index[%d] invalid!\n",
4690 __func__, index);
4691 return -EINVAL;
4692 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004693 memset(&usb_dev, 0, sizeof(usb_dev));
4694 memset(&lpcm_fmt, 0, sizeof(lpcm_fmt));
4695 memset(&param_hdr, 0, sizeof(param_hdr));
4696 param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
4697 param_hdr.instance_id = INSTANCE_ID_0;
4698
4699 param_hdr.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS;
4700 param_hdr.param_size = sizeof(usb_dev);
Garmond Leung6b3f4182018-05-11 12:29:34 -07004701 usb_dev.cfg_minor_version = AFE_API_MINOR_VERSION_USB_AUDIO_CONFIG;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004702 usb_dev.dev_token = afe_config->usb_audio.dev_token;
4703
4704 ret = q6afe_pack_and_set_param_in_band(port_id,
4705 q6audio_get_port_index(port_id),
4706 param_hdr, (u8 *) &usb_dev);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304707 if (ret) {
4708 pr_err("%s: AFE device param cmd failed %d\n",
4709 __func__, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304710 goto exit;
4711 }
4712
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004713 param_hdr.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_LPCM_FMT;
4714 param_hdr.param_size = sizeof(lpcm_fmt);
Garmond Leung6b3f4182018-05-11 12:29:34 -07004715 lpcm_fmt.cfg_minor_version = AFE_API_MINOR_VERSION_USB_AUDIO_CONFIG;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004716 lpcm_fmt.endian = afe_config->usb_audio.endian;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304717
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08004718 ret = q6afe_pack_and_set_param_in_band(port_id,
4719 q6audio_get_port_index(port_id),
4720 param_hdr, (u8 *) &lpcm_fmt);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304721 if (ret) {
4722 pr_err("%s: AFE device param cmd LPCM_FMT failed %d\n",
4723 __func__, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304724 goto exit;
4725 }
Garmond Leung6b3f4182018-05-11 12:29:34 -07004726 param_hdr.param_id = AFE_PARAM_ID_USB_AUDIO_SVC_INTERVAL;
4727 param_hdr.param_size = sizeof(svc_int);
4728 svc_int.cfg_minor_version =
4729 AFE_API_MINOR_VERSION_USB_AUDIO_CONFIG;
4730 svc_int.svc_interval = afe_config->usb_audio.service_interval;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304731
Garmond Leung6b3f4182018-05-11 12:29:34 -07004732 pr_debug("%s: AFE device param cmd sending SVC_INTERVAL %d\n",
4733 __func__, svc_int.svc_interval);
4734
4735 ret = q6afe_pack_and_set_param_in_band(port_id,
4736 q6audio_get_port_index(port_id),
4737 param_hdr, (u8 *) &svc_int);
4738
4739 if (ret) {
4740 pr_err("%s: AFE device param cmd svc_interval failed %d\n",
4741 __func__, ret);
4742 ret = -EINVAL;
4743 goto exit;
4744 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304745exit:
4746 return ret;
4747}
4748
Surendar Karkab50f4232019-02-12 12:46:05 +05304749static int q6afe_send_ttp_config(u16 port_id,
4750 union afe_port_config afe_config,
4751 struct afe_ttp_config *ttp_cfg)
4752{
4753 struct afe_ttp_gen_enable_t ttp_gen_enable;
4754 struct afe_ttp_gen_cfg_t ttp_gen_cfg;
4755 struct param_hdr_v3 param_hdr;
4756 int ret;
4757
4758 memset(&ttp_gen_enable, 0, sizeof(ttp_gen_enable));
4759 memset(&ttp_gen_cfg, 0, sizeof(ttp_gen_cfg));
4760 memset(&param_hdr, 0, sizeof(param_hdr));
4761
4762 param_hdr.module_id = AFE_MODULE_ID_DECODER;
4763 param_hdr.instance_id = INSTANCE_ID_0;
4764
4765 pr_debug("%s: Enable TTP generator\n", __func__);
4766 ttp_gen_enable = ttp_cfg->ttp_gen_enable;
4767 param_hdr.param_id = AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE;
4768 param_hdr.param_size = sizeof(struct afe_ttp_gen_enable_t);
4769 ret = q6afe_pack_and_set_param_in_band(port_id,
4770 q6audio_get_port_index(port_id),
4771 param_hdr,
4772 (u8 *) &ttp_gen_enable);
4773 if (ret) {
4774 pr_err("%s: AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE for port 0x%x failed %d\n",
4775 __func__, port_id, ret);
4776 goto exit;
4777 }
4778
4779 pr_debug("%s: sending TTP generator config\n", __func__);
4780 ttp_gen_cfg = ttp_cfg->ttp_gen_cfg;
4781 param_hdr.param_id = AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG;
4782 param_hdr.param_size = sizeof(struct afe_ttp_gen_cfg_t);
4783 ret = q6afe_pack_and_set_param_in_band(port_id,
4784 q6audio_get_port_index(port_id),
4785 param_hdr,
4786 (u8 *) &ttp_gen_cfg);
4787 if (ret)
4788 pr_err("%s: AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG for port 0x%x failed %d\n",
4789 __func__, port_id, ret);
4790exit:
4791 return ret;
4792}
4793
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08004794static int q6afe_send_dec_config(u16 port_id,
4795 union afe_port_config afe_config,
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02004796 struct afe_dec_config *cfg,
4797 u32 format,
4798 u16 afe_in_channels, u16 afe_in_bit_width)
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08004799{
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02004800 struct afe_dec_media_fmt_t dec_media_fmt;
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08004801 struct avs_dec_depacketizer_id_param_t dec_depkt_id_param;
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02004802 struct avs_dec_congestion_buffer_param_t dec_buffer_id_param;
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08004803 struct afe_enc_dec_imc_info_param_t imc_info_param;
4804 struct afe_port_media_type_t media_type;
Zhou Songcaa541d2019-02-19 18:37:47 +08004805 struct afe_matched_port_t matched_port_param;
4806 struct asm_aptx_ad_speech_mode_cfg_t speech_codec_init_param;
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08004807 struct param_hdr_v3 param_hdr;
4808 int ret;
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02004809 u32 dec_fmt;
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08004810
4811 memset(&dec_depkt_id_param, 0, sizeof(dec_depkt_id_param));
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02004812 memset(&dec_media_fmt, 0, sizeof(dec_media_fmt));
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08004813 memset(&imc_info_param, 0, sizeof(imc_info_param));
4814 memset(&media_type, 0, sizeof(media_type));
Zhou Songcaa541d2019-02-19 18:37:47 +08004815 memset(&matched_port_param, 0, sizeof(matched_port_param));
4816 memset(&speech_codec_init_param, 0, sizeof(speech_codec_init_param));
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08004817 memset(&param_hdr, 0, sizeof(param_hdr));
4818
4819 param_hdr.module_id = AFE_MODULE_ID_DECODER;
4820 param_hdr.instance_id = INSTANCE_ID_0;
4821
4822 pr_debug("%s: sending AFE_DECODER_PARAM_ID_DEPACKETIZER to DSP payload\n",
4823 __func__);
4824 param_hdr.param_id = AFE_DECODER_PARAM_ID_DEPACKETIZER_ID;
4825 param_hdr.param_size = sizeof(struct avs_dec_depacketizer_id_param_t);
4826 dec_depkt_id_param.dec_depacketizer_id =
Sharad Sangle82777e52018-06-20 19:06:08 +05304827 AFE_MODULE_ID_DEPACKETIZER_COP_V1;
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02004828 if (cfg->format == ENC_CODEC_TYPE_LDAC)
4829 dec_depkt_id_param.dec_depacketizer_id =
4830 AFE_MODULE_ID_DEPACKETIZER_COP;
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08004831 ret = q6afe_pack_and_set_param_in_band(port_id,
4832 q6audio_get_port_index(port_id),
4833 param_hdr,
4834 (u8 *) &dec_depkt_id_param);
4835 if (ret) {
4836 pr_err("%s: AFE_DECODER_PARAM_ID_DEPACKETIZER for port 0x%x failed %d\n",
4837 __func__, port_id, ret);
4838 goto exit;
4839 }
4840
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02004841 switch (cfg->format) {
4842 case ASM_MEDIA_FMT_SBC:
4843 case ASM_MEDIA_FMT_AAC_V2:
4844 case ASM_MEDIA_FMT_MP3:
4845 if (port_id == SLIMBUS_9_TX) {
4846 dec_buffer_id_param.max_nr_buffers = 200;
4847 dec_buffer_id_param.pre_buffer_size = 200;
4848 } else {
4849 dec_buffer_id_param.max_nr_buffers = 0;
4850 dec_buffer_id_param.pre_buffer_size = 0;
4851 }
4852 pr_debug("%s: sending AFE_DECODER_PARAM_ID_CONGESTION_BUFFER_SIZE to DSP payload\n",
4853 __func__);
4854 param_hdr.param_id =
4855 AFE_DECODER_PARAM_ID_CONGESTION_BUFFER_SIZE;
4856 param_hdr.param_size =
4857 sizeof(struct avs_dec_congestion_buffer_param_t);
4858 dec_buffer_id_param.version = 0;
4859 ret = q6afe_pack_and_set_param_in_band(port_id,
4860 q6audio_get_port_index(port_id),
4861 param_hdr,
4862 (u8 *) &dec_buffer_id_param);
4863 if (ret) {
4864 pr_err("%s: AFE_DECODER_PARAM_ID_CONGESTION_BUFFER_SIZE for port 0x%x failed %d\n",
4865 __func__, port_id, ret);
4866 goto exit;
4867 }
4868 break;
Chaithanya Krishna Bacharaju4a466532019-01-21 10:59:51 +05304869 case ASM_MEDIA_FMT_APTX_ADAPTIVE:
4870 if (!cfg->abr_dec_cfg.is_abr_enabled) {
4871 pr_debug("%s: sending aptx adaptive congestion buffer size to dsp\n",
4872 __func__);
4873 param_hdr.param_id =
4874 AFE_DECODER_PARAM_ID_CONGESTION_BUFFER_SIZE;
4875 param_hdr.param_size =
4876 sizeof(struct avs_dec_congestion_buffer_param_t);
4877 dec_buffer_id_param.version = 0;
4878 dec_buffer_id_param.max_nr_buffers = 226;
4879 dec_buffer_id_param.pre_buffer_size = 226;
4880 ret = q6afe_pack_and_set_param_in_band(port_id,
4881 q6audio_get_port_index(port_id),
4882 param_hdr,
4883 (u8 *) &dec_buffer_id_param);
4884 if (ret) {
4885 pr_err("%s: aptx adaptive congestion buffer size for port 0x%x failed %d\n",
4886 __func__, port_id, ret);
4887 goto exit;
4888 }
4889 break;
4890 }
4891 /* fall through for abr enabled case */
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02004892 default:
4893 pr_debug("%s:sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload\n",
4894 __func__);
4895 param_hdr.param_id =
4896 AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION;
4897 param_hdr.param_size =
4898 sizeof(struct afe_enc_dec_imc_info_param_t);
4899 imc_info_param.imc_info = cfg->abr_dec_cfg.imc_info;
4900 ret = q6afe_pack_and_set_param_in_band(port_id,
4901 q6audio_get_port_index(port_id),
4902 param_hdr,
4903 (u8 *) &imc_info_param);
4904 if (ret) {
4905 pr_err("%s: AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION for port 0x%x failed %d\n",
4906 __func__, port_id, ret);
4907 goto exit;
4908 }
4909 break;
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08004910 }
4911
Chaithanya Krishna Bacharaju4a466532019-01-21 10:59:51 +05304912 pr_debug("%s: Send AFE_API_VERSION_PORT_MEDIA_TYPE to DSP\n", __func__);
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08004913 param_hdr.module_id = AFE_MODULE_PORT;
4914 param_hdr.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE;
4915 param_hdr.param_size = sizeof(struct afe_port_media_type_t);
4916 media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE;
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02004917 switch (cfg->format) {
4918 case ASM_MEDIA_FMT_AAC_V2:
4919 media_type.sample_rate =
4920 cfg->data.aac_config.sample_rate;
4921 break;
Florian Pfisterf4fd5f32018-11-05 15:32:13 +01004922 case ASM_MEDIA_FMT_SBC:
4923 media_type.sample_rate =
4924 cfg->data.sbc_config.sample_rate;
4925 break;
Chaithanya Krishna Bacharaju4a466532019-01-21 10:59:51 +05304926 case ASM_MEDIA_FMT_APTX_ADAPTIVE:
4927 if (!cfg->abr_dec_cfg.is_abr_enabled) {
4928 media_type.sample_rate =
4929 (cfg->data.aptx_ad_config.sample_rate == APTX_AD_44_1) ?
4930 AFE_PORT_SAMPLE_RATE_44_1K :
4931 AFE_PORT_SAMPLE_RATE_48K;
4932 break;
4933 }
4934 /* fall through for abr enabled case */
Zhou Songcaa541d2019-02-19 18:37:47 +08004935 case ASM_MEDIA_FMT_APTX_AD_SPEECH:
4936 media_type.sample_rate = AFE_PORT_SAMPLE_RATE_32K;
4937 break;
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02004938 default:
4939 media_type.sample_rate =
4940 afe_config.slim_sch.sample_rate;
4941 }
4942 if (afe_in_bit_width)
4943 media_type.bit_width = afe_in_bit_width;
4944 else
4945 media_type.bit_width = afe_config.slim_sch.bit_width;
4946
4947 if (afe_in_channels)
4948 media_type.num_channels = afe_in_channels;
4949 else
4950 media_type.num_channels = afe_config.slim_sch.num_channels;
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08004951 media_type.data_format = AFE_PORT_DATA_FORMAT_PCM;
4952 media_type.reserved = 0;
4953
4954 ret = q6afe_pack_and_set_param_in_band(port_id,
4955 q6audio_get_port_index(port_id),
4956 param_hdr, (u8 *) &media_type);
4957 if (ret) {
4958 pr_err("%s: AFE_API_VERSION_PORT_MEDIA_TYPE for port 0x%x failed %d\n",
4959 __func__, port_id, ret);
4960 goto exit;
4961 }
4962
Chaithanya Krishna Bacharaju4a466532019-01-21 10:59:51 +05304963 if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 &&
Zhou Songcaa541d2019-02-19 18:37:47 +08004964 format != ASM_MEDIA_FMT_APTX_ADAPTIVE &&
4965 format != ASM_MEDIA_FMT_APTX_AD_SPEECH) {
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02004966 pr_debug("%s:Unsuppported dec format. Ignore AFE config %u\n",
4967 __func__, format);
4968 goto exit;
4969 }
Chaithanya Krishna Bacharaju4a466532019-01-21 10:59:51 +05304970
4971 if (format == ASM_MEDIA_FMT_APTX_ADAPTIVE &&
4972 cfg->abr_dec_cfg.is_abr_enabled) {
4973 pr_debug("%s: Ignore AFE config for abr case\n", __func__);
4974 goto exit;
4975 }
Zhou Songcaa541d2019-02-19 18:37:47 +08004976 if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH) {
4977 pr_debug("%s: sending AFE_PARAM_ID_RATE_MATCHED_PORT to DSP payload\n",
4978 __func__);
4979 param_hdr.param_id = AFE_PARAM_ID_RATE_MATCHED_PORT;
4980 param_hdr.param_size =
4981 sizeof(struct afe_matched_port_t);
4982 matched_port_param.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE;
4983 matched_port_param.enable = AFE_MATCHED_PORT_ENABLE;
4984 ret = q6afe_pack_and_set_param_in_band(port_id,
4985 q6audio_get_port_index(port_id),
4986 param_hdr,
4987 (u8 *) &matched_port_param);
4988 if (ret) {
4989 pr_err("%s: AFE_PARAM_ID_RATE_MATCHED_PORT for port 0x%x failed %d\n",
4990 __func__, port_id, ret);
4991 goto exit;
4992 }
4993 }
Chaithanya Krishna Bacharaju4a466532019-01-21 10:59:51 +05304994
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02004995 pr_debug("%s: sending AFE_DECODER_PARAM_ID_DEC_MEDIA_FMT to DSP payload\n",
4996 __func__);
4997 param_hdr.module_id = AFE_MODULE_ID_DECODER;
4998 param_hdr.instance_id = INSTANCE_ID_0;
4999 param_hdr.param_id = AFE_DECODER_PARAM_ID_DEC_FMT_ID;
5000 param_hdr.param_size = sizeof(dec_fmt);
5001 dec_fmt = format;
5002 ret = q6afe_pack_and_set_param_in_band(port_id,
5003 q6audio_get_port_index(port_id),
5004 param_hdr, (u8 *) &dec_fmt);
5005 if (ret) {
5006 pr_err("%s: AFE_DECODER_PARAM_ID_DEC_MEDIA_FMT for port 0x%x failed %d\n",
5007 __func__, port_id, ret);
5008 goto exit;
5009 }
5010
5011 switch (cfg->format) {
5012 case ASM_MEDIA_FMT_AAC_V2:
Chaithanya Krishna Bacharaju4a466532019-01-21 10:59:51 +05305013 case ASM_MEDIA_FMT_APTX_ADAPTIVE:
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02005014 param_hdr.param_size = sizeof(struct afe_dec_media_fmt_t);
5015
Chaithanya Krishna Bacharaju4a466532019-01-21 10:59:51 +05305016 pr_debug("%s:send AVS_DECODER_PARAM_ID DEC_MEDIA_FMT to DSP payload\n",
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02005017 __func__);
5018 param_hdr.param_id = AVS_DECODER_PARAM_ID_DEC_MEDIA_FMT;
5019 dec_media_fmt.dec_media_config = cfg->data;
5020 ret = q6afe_pack_and_set_param_in_band(port_id,
5021 q6audio_get_port_index(port_id),
5022 param_hdr,
5023 (u8 *) &dec_media_fmt);
5024 if (ret) {
Chaithanya Krishna Bacharaju4a466532019-01-21 10:59:51 +05305025 pr_err("%s: AVS_DECODER_PARAM_ID DEC_MEDIA_FMT for port 0x%x failed %d\n",
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02005026 __func__, port_id, ret);
5027 goto exit;
5028 }
5029 break;
Zhou Songcaa541d2019-02-19 18:37:47 +08005030 case ASM_MEDIA_FMT_APTX_AD_SPEECH:
5031 param_hdr.param_size =
5032 sizeof(struct asm_aptx_ad_speech_dec_cfg_t);
5033
5034 pr_debug("%s: send AVS_DECODER_PARAM_ID_APTX_AD_SPEECH_DEC_INIT to DSP payload\n",
5035 __func__);
5036 param_hdr.param_id =
5037 AVS_DECODER_PARAM_ID_APTX_AD_SPEECH_DEC_INIT;
5038 speech_codec_init_param =
5039 cfg->data.aptx_ad_speech_config.speech_mode;
5040 ret = q6afe_pack_and_set_param_in_band(port_id,
5041 q6audio_get_port_index(port_id),
5042 param_hdr,
5043 (u8 *) &speech_codec_init_param);
5044 if (ret) {
5045 pr_err("%s: AVS_DECODER_PARAM_ID_APTX_ADAPTIVE_SPEECH_DEC_INIT for port 0x%x failed %d\n",
5046 __func__, port_id, ret);
5047 goto exit;
5048 }
5049 break;
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02005050 default:
5051 pr_debug("%s:No need to send DEC_MEDIA_FMT to DSP payload\n",
5052 __func__);
5053 }
5054
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005055exit:
5056 return ret;
5057}
5058
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305059static int q6afe_send_enc_config(u16 port_id,
5060 union afe_enc_config_data *cfg, u32 format,
5061 union afe_port_config afe_config,
Preetam Singh Ranawatf746a872017-10-20 18:13:14 +05305062 u16 afe_in_channels, u16 afe_in_bit_width,
Manisha Agarwald99fac02018-11-04 15:46:02 +05305063 u32 scrambler_mode, u32 mono_mode)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305064{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005065 u32 enc_fmt;
5066 struct afe_enc_cfg_blk_param_t enc_blk_param;
5067 struct afe_param_id_aptx_sync_mode sync_mode_param;
Sharad Sangle82777e52018-06-20 19:06:08 +05305068 struct afe_id_aptx_adaptive_enc_init aptx_adaptive_enc_init;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005069 struct avs_enc_packetizer_id_param_t enc_pkt_id_param;
5070 struct avs_enc_set_scrambler_param_t enc_set_scrambler_param;
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005071 struct afe_enc_level_to_bitrate_map_param_t map_param;
5072 struct afe_enc_dec_imc_info_param_t imc_info_param;
Aniket Kumar Latabe837352018-06-20 14:57:05 -07005073 struct asm_aac_frame_size_control_t frame_ctl_param;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005074 struct afe_port_media_type_t media_type;
Manisha Agarwald99fac02018-11-04 15:46:02 +05305075 struct aptx_channel_mode_param_t channel_mode_param;
Zhou Songcaa541d2019-02-19 18:37:47 +08005076 struct afe_matched_port_t matched_port_param;
5077 struct asm_aptx_ad_speech_mode_cfg_t speech_codec_init_param;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005078 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305079 int ret;
Manisha Agarwale87c0b12020-01-30 16:33:37 +05305080 uint32_t frame_size_ctl_value_v2;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305081
5082 pr_debug("%s:update DSP for enc format = %d\n", __func__, format);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005083
5084 memset(&enc_blk_param, 0, sizeof(enc_blk_param));
5085 memset(&sync_mode_param, 0, sizeof(sync_mode_param));
Sharad Sangle82777e52018-06-20 19:06:08 +05305086 memset(&aptx_adaptive_enc_init, 0, sizeof(aptx_adaptive_enc_init));
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005087 memset(&enc_pkt_id_param, 0, sizeof(enc_pkt_id_param));
5088 memset(&enc_set_scrambler_param, 0, sizeof(enc_set_scrambler_param));
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005089 memset(&map_param, 0, sizeof(map_param));
5090 memset(&imc_info_param, 0, sizeof(imc_info_param));
Aniket Kumar Latabe837352018-06-20 14:57:05 -07005091 memset(&frame_ctl_param, 0, sizeof(frame_ctl_param));
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005092 memset(&media_type, 0, sizeof(media_type));
Zhou Songcaa541d2019-02-19 18:37:47 +08005093 memset(&matched_port_param, 0, sizeof(matched_port_param));
5094 memset(&speech_codec_init_param, 0, sizeof(speech_codec_init_param));
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005095 memset(&param_hdr, 0, sizeof(param_hdr));
5096
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305097 if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 &&
Sharad Sangle82777e52018-06-20 19:06:08 +05305098 format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD &&
5099 format != ASM_MEDIA_FMT_CELT && format != ASM_MEDIA_FMT_LDAC &&
Zhou Songcaa541d2019-02-19 18:37:47 +08005100 format != ASM_MEDIA_FMT_APTX_ADAPTIVE &&
5101 format != ASM_MEDIA_FMT_APTX_AD_SPEECH) {
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02005102 pr_err("%s:Unsuppported enc format. Ignore AFE config\n",
5103 __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305104 return 0;
5105 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305106
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005107 param_hdr.module_id = AFE_MODULE_ID_ENCODER;
5108 param_hdr.instance_id = INSTANCE_ID_0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305109
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005110 param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENC_FMT_ID;
5111 param_hdr.param_size = sizeof(enc_fmt);
5112 enc_fmt = format;
5113 pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENC_FMT_ID payload\n",
5114 __func__);
5115 ret = q6afe_pack_and_set_param_in_band(port_id,
5116 q6audio_get_port_index(port_id),
5117 param_hdr, (u8 *) &enc_fmt);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305118 if (ret) {
5119 pr_err("%s:unable to send AFE_ENCODER_PARAM_ID_ENC_FMT_ID",
5120 __func__);
5121 goto exit;
5122 }
5123
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005124 if (format == ASM_MEDIA_FMT_LDAC) {
5125 param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t)
5126 - sizeof(struct afe_abr_enc_cfg_t);
5127 enc_blk_param.enc_cfg_blk_size =
5128 sizeof(union afe_enc_config_data)
5129 - sizeof(struct afe_abr_enc_cfg_t);
Aniket Kumar Latabe837352018-06-20 14:57:05 -07005130 } else if (format == ASM_MEDIA_FMT_AAC_V2) {
5131 param_hdr.param_size = sizeof(enc_blk_param)
5132 - sizeof(struct asm_aac_frame_size_control_t);
5133 enc_blk_param.enc_cfg_blk_size =
5134 sizeof(enc_blk_param.enc_blk_config)
5135 - sizeof(struct asm_aac_frame_size_control_t);
Zhou Songcaa541d2019-02-19 18:37:47 +08005136 } else if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH) {
5137 param_hdr.param_size = sizeof(struct afe_enc_aptx_ad_speech_cfg_blk_param_t);
5138 enc_blk_param.enc_cfg_blk_size = sizeof(struct asm_custom_enc_cfg_t);
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005139 } else {
5140 param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t);
5141 enc_blk_param.enc_cfg_blk_size =
5142 sizeof(union afe_enc_config_data);
5143 }
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02005144 pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payload\n",
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005145 __func__);
5146 param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005147 enc_blk_param.enc_blk_config = *cfg;
5148 ret = q6afe_pack_and_set_param_in_band(port_id,
5149 q6audio_get_port_index(port_id),
5150 param_hdr,
5151 (u8 *) &enc_blk_param);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305152 if (ret) {
5153 pr_err("%s: AFE_ENCODER_PARAM_ID_ENC_CFG_BLK for port 0x%x failed %d\n",
5154 __func__, port_id, ret);
5155 goto exit;
5156 }
5157
Aniket Kumar Latabe837352018-06-20 14:57:05 -07005158 if (format == ASM_MEDIA_FMT_AAC_V2) {
5159 uint32_t frame_size_ctl_value = enc_blk_param.enc_blk_config.
5160 aac_config.frame_ctl.ctl_value;
5161 if (frame_size_ctl_value > 0) {
5162 param_hdr.param_id =
5163 AFE_PARAM_ID_AAC_FRM_SIZE_CONTROL;
5164 param_hdr.param_size = sizeof(frame_ctl_param);
5165 frame_ctl_param.ctl_type = enc_blk_param.
5166 enc_blk_config.aac_config.frame_ctl.ctl_type;
5167 frame_ctl_param.ctl_value = frame_size_ctl_value;
Manisha Agarwale87c0b12020-01-30 16:33:37 +05305168
Aniket Kumar Latabe837352018-06-20 14:57:05 -07005169 pr_debug("%s: send AFE_PARAM_ID_AAC_FRM_SIZE_CONTROL\n",
Manisha Agarwale87c0b12020-01-30 16:33:37 +05305170 __func__);
Aniket Kumar Latabe837352018-06-20 14:57:05 -07005171 ret = q6afe_pack_and_set_param_in_band(port_id,
5172 q6audio_get_port_index(port_id),
5173 param_hdr,
5174 (u8 *) &frame_ctl_param);
5175 if (ret) {
5176 pr_err("%s: AAC_FRM_SIZE_CONTROL failed %d\n",
5177 __func__, ret);
5178 goto exit;
5179 }
5180 }
Manisha Agarwale87c0b12020-01-30 16:33:37 +05305181 frame_size_ctl_value_v2 = enc_blk_param.enc_blk_config.
5182 aac_config.frame_ctl_v2.ctl_value;
5183 if (frame_size_ctl_value_v2 > 0) {
5184 param_hdr.param_id =
5185 AFE_PARAM_ID_AAC_FRM_SIZE_CONTROL;
5186 param_hdr.param_size = sizeof(frame_ctl_param);
5187 frame_ctl_param.ctl_type = enc_blk_param.
5188 enc_blk_config.aac_config.frame_ctl_v2.ctl_type;
5189 frame_ctl_param.ctl_value = enc_blk_param.
5190 enc_blk_config.aac_config.frame_ctl_v2.ctl_value;
5191
5192 pr_debug("%s: send AFE_PARAM_ID_AAC_FRM_SIZE_CONTROL V2\n",
5193 __func__);
5194 ret = q6afe_pack_and_set_param_in_band(port_id,
5195 q6audio_get_port_index(port_id),
5196 param_hdr,
5197 (u8 *) &frame_ctl_param);
5198 if (ret) {
5199 pr_err("%s: AAC_FRM_SIZE_CONTROL with VBR support failed %d\n",
5200 __func__, ret);
5201 goto exit;
5202 }
5203 }
Aniket Kumar Latabe837352018-06-20 14:57:05 -07005204 }
5205
Preetam Singh Ranawat899b78b2017-09-07 12:36:06 -07005206 if (format == ASM_MEDIA_FMT_APTX) {
Preetam Singh Ranawat899b78b2017-09-07 12:36:06 -07005207 pr_debug("%s: sending AFE_PARAM_ID_APTX_SYNC_MODE to DSP",
5208 __func__);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005209 param_hdr.param_id = AFE_PARAM_ID_APTX_SYNC_MODE;
5210 param_hdr.param_size =
5211 sizeof(struct afe_param_id_aptx_sync_mode);
5212 sync_mode_param.sync_mode =
5213 enc_blk_param.enc_blk_config.aptx_config.
Preetam Singh Ranawat899b78b2017-09-07 12:36:06 -07005214 aptx_v2_cfg.sync_mode;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005215 ret = q6afe_pack_and_set_param_in_band(port_id,
5216 q6audio_get_port_index(port_id),
5217 param_hdr,
5218 (u8 *) &sync_mode_param);
Preetam Singh Ranawat899b78b2017-09-07 12:36:06 -07005219 if (ret) {
5220 pr_err("%s: AFE_PARAM_ID_APTX_SYNC_MODE for port 0x%x failed %d\n",
5221 __func__, port_id, ret);
5222 goto exit;
5223 }
5224 }
Sharad Sangle82777e52018-06-20 19:06:08 +05305225 if (format == ASM_MEDIA_FMT_APTX_ADAPTIVE) {
5226 pr_debug("%s: sending AFE_ID_APTX_ADAPTIVE_ENC_INIT to DSP\n",
5227 __func__);
5228 param_hdr.param_id = AFE_ID_APTX_ADAPTIVE_ENC_INIT;
5229 param_hdr.param_size =
5230 sizeof(struct afe_id_aptx_adaptive_enc_init);
5231 aptx_adaptive_enc_init =
5232 enc_blk_param.enc_blk_config.aptx_ad_config.
5233 aptx_ad_cfg;
5234 ret = q6afe_pack_and_set_param_in_band(port_id,
5235 q6audio_get_port_index(port_id),
5236 param_hdr,
5237 (u8 *) &aptx_adaptive_enc_init);
5238 if (ret) {
5239 pr_err("%s: AFE_ID_APTX_ADAPTIVE_ENC_INIT for port 0x%x failed %d\n",
5240 __func__, port_id, ret);
5241 goto exit;
5242 }
5243 }
Zhou Songcaa541d2019-02-19 18:37:47 +08005244 if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH) {
5245 pr_debug("%s: sending AVS_DECODER_PARAM_ID_APTX_AD_SPEECH_ENC_INIT to DSP\n",
5246 __func__);
5247 param_hdr.param_id = AVS_DECODER_PARAM_ID_APTX_AD_SPEECH_ENC_INIT;
5248 param_hdr.param_size =
5249 sizeof(struct asm_aptx_ad_speech_dec_cfg_t);
5250 speech_codec_init_param = cfg->aptx_ad_speech_config.speech_mode;
5251 ret = q6afe_pack_and_set_param_in_band(port_id,
5252 q6audio_get_port_index(port_id),
5253 param_hdr,
5254 (u8 *) &speech_codec_init_param);
5255 if (ret) {
5256 pr_err("%s: AFE_ID_APTX_ADAPTIVE_ENC_INIT for port 0x%x failed %d\n",
5257 __func__, port_id, ret);
5258 goto exit;
5259 }
5260 }
5261
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005262 pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP\n",
5263 __func__);
5264 param_hdr.param_id = AFE_ENCODER_PARAM_ID_PACKETIZER_ID;
5265 param_hdr.param_size = sizeof(struct avs_enc_packetizer_id_param_t);
5266 enc_pkt_id_param.enc_packetizer_id = AFE_MODULE_ID_PACKETIZER_COP;
5267 ret = q6afe_pack_and_set_param_in_band(port_id,
5268 q6audio_get_port_index(port_id),
5269 param_hdr,
5270 (u8 *) &enc_pkt_id_param);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305271 if (ret) {
5272 pr_err("%s: AFE_ENCODER_PARAM_ID_PACKETIZER for port 0x%x failed %d\n",
5273 __func__, port_id, ret);
5274 goto exit;
5275 }
5276
Zhou Songcaa541d2019-02-19 18:37:47 +08005277 if (format != ASM_MEDIA_FMT_APTX_AD_SPEECH) {
5278 pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING mode= %d to DSP payload\n",
5279 __func__, scrambler_mode);
5280 param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING;
5281 param_hdr.param_size = sizeof(struct avs_enc_set_scrambler_param_t);
5282 enc_set_scrambler_param.enable_scrambler = scrambler_mode;
5283 ret = q6afe_pack_and_set_param_in_band(port_id,
5284 q6audio_get_port_index(port_id),
5285 param_hdr,
5286 (u8 *) &enc_set_scrambler_param);
5287 if (ret) {
5288 pr_err("%s: AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING for port 0x%x failed %d\n",
5289 __func__, port_id, ret);
5290 goto exit;
5291 }
Preetam Singh Ranawatf746a872017-10-20 18:13:14 +05305292 }
5293
Manisha Agarwald99fac02018-11-04 15:46:02 +05305294 if (format == ASM_MEDIA_FMT_APTX) {
5295 pr_debug("%s:sending CAPI_V2_PARAM_ID_APTX_ENC_SWITCH_TO_MONO mode= %d to DSP payload\n",
5296 __func__, mono_mode);
5297 param_hdr.param_id = CAPI_V2_PARAM_ID_APTX_ENC_SWITCH_TO_MONO;
5298 param_hdr.param_size = sizeof(channel_mode_param);
5299 channel_mode_param.channel_mode = mono_mode;
5300 ret = q6afe_pack_and_set_param_in_band(port_id,
5301 q6audio_get_port_index(port_id),
5302 param_hdr,
5303 (u8 *) &channel_mode_param);
5304
5305 if (ret) {
5306 pr_err("%s: CAPI_V2_PARAM_ID_APTX_ENC_SWITCH_TO_MONO for port 0x%x failed %d\n",
5307 __func__, port_id, ret);
5308 }
5309 }
5310
Aniket Kumar Lata9dce5042018-08-16 16:23:46 -07005311 if ((format == ASM_MEDIA_FMT_LDAC &&
5312 cfg->ldac_config.abr_config.is_abr_enabled) ||
Zhou Songcaa541d2019-02-19 18:37:47 +08005313 format == ASM_MEDIA_FMT_APTX_ADAPTIVE ||
5314 format == ASM_MEDIA_FMT_APTX_AD_SPEECH) {
5315 if (format != ASM_MEDIA_FMT_APTX_AD_SPEECH) {
5316 pr_debug("%s:sending AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP to DSP payload",
5317 __func__);
5318 param_hdr.param_id = AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP;
5319 param_hdr.param_size =
5320 sizeof(struct afe_enc_level_to_bitrate_map_param_t);
5321 map_param.mapping_table =
5322 cfg->ldac_config.abr_config.mapping_info;
5323 ret = q6afe_pack_and_set_param_in_band(port_id,
5324 q6audio_get_port_index(port_id),
5325 param_hdr,
5326 (u8 *) &map_param);
5327 if (ret) {
5328 pr_err("%s: AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP for port 0x%x failed %d\n",
5329 __func__, port_id, ret);
5330 goto exit;
5331 }
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005332 }
5333
5334 pr_debug("%s: sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload",
5335 __func__);
5336 param_hdr.param_id =
5337 AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION;
5338 param_hdr.param_size =
5339 sizeof(struct afe_enc_dec_imc_info_param_t);
Sharad Sangle82777e52018-06-20 19:06:08 +05305340 if (format == ASM_MEDIA_FMT_APTX_ADAPTIVE)
5341 imc_info_param.imc_info =
5342 cfg->aptx_ad_config.abr_cfg.imc_info;
Zhou Songcaa541d2019-02-19 18:37:47 +08005343 else if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH)
5344 imc_info_param.imc_info =
5345 cfg->aptx_ad_speech_config.imc_info;
Sharad Sangle82777e52018-06-20 19:06:08 +05305346 else
5347 imc_info_param.imc_info =
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005348 cfg->ldac_config.abr_config.imc_info;
5349 ret = q6afe_pack_and_set_param_in_band(port_id,
5350 q6audio_get_port_index(port_id),
5351 param_hdr,
5352 (u8 *) &imc_info_param);
5353 if (ret) {
5354 pr_err("%s: AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION for port 0x%x failed %d\n",
5355 __func__, port_id, ret);
5356 goto exit;
5357 }
5358 }
5359
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305360 pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005361 param_hdr.module_id = AFE_MODULE_PORT;
5362 param_hdr.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE;
5363 param_hdr.param_size = sizeof(struct afe_port_media_type_t);
5364 media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE;
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005365 if (format == ASM_MEDIA_FMT_LDAC)
5366 media_type.sample_rate =
5367 cfg->ldac_config.custom_config.sample_rate;
Aniket Kumar Lata1c9ae8f2018-10-10 18:22:04 -07005368 else if (format == ASM_MEDIA_FMT_APTX_ADAPTIVE)
5369 media_type.sample_rate =
5370 cfg->aptx_ad_config.custom_cfg.sample_rate;
Zhou Songcaa541d2019-02-19 18:37:47 +08005371 else if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH)
5372 media_type.sample_rate =
5373 cfg->aptx_ad_speech_config.custom_cfg.sample_rate;
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005374 else
5375 media_type.sample_rate =
5376 afe_config.slim_sch.sample_rate;
5377
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305378 if (afe_in_bit_width)
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005379 media_type.bit_width = afe_in_bit_width;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305380 else
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005381 media_type.bit_width = afe_config.slim_sch.bit_width;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305382
5383 if (afe_in_channels)
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005384 media_type.num_channels = afe_in_channels;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305385 else
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005386 media_type.num_channels = afe_config.slim_sch.num_channels;
5387 media_type.data_format = AFE_PORT_DATA_FORMAT_PCM;
5388 media_type.reserved = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305389
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005390 ret = q6afe_pack_and_set_param_in_band(port_id,
5391 q6audio_get_port_index(port_id),
5392 param_hdr, (u8 *) &media_type);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305393 if (ret) {
5394 pr_err("%s: AFE_API_VERSION_PORT_MEDIA_TYPE for port 0x%x failed %d\n",
5395 __func__, port_id, ret);
5396 goto exit;
5397 }
5398
Zhou Songcaa541d2019-02-19 18:37:47 +08005399 if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH) {
5400 pr_debug("%s: sending AFE_PARAM_ID_RATE_MATCHED_PORT to DSP payload",
5401 __func__);
5402 param_hdr.param_id = AFE_PARAM_ID_RATE_MATCHED_PORT;
5403 param_hdr.param_size =
5404 sizeof(struct afe_matched_port_t);
5405 matched_port_param.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE;
5406 matched_port_param.enable = AFE_MATCHED_PORT_ENABLE;
5407 ret = q6afe_pack_and_set_param_in_band(port_id,
5408 q6audio_get_port_index(port_id),
5409 param_hdr,
5410 (u8 *) &matched_port_param);
5411 if (ret) {
5412 pr_err("%s: AFE_PARAM_ID_RATE_MATCHED_PORT for port 0x%x failed %d\n",
5413 __func__, port_id, ret);
5414 goto exit;
5415 }
5416 }
5417
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305418exit:
5419 return ret;
5420}
5421
Zhou Song450ee1b2019-08-02 11:06:01 +08005422int afe_set_tws_channel_mode(u32 format, u16 port_id, u32 channel_mode)
Manisha Agarwald99fac02018-11-04 15:46:02 +05305423{
5424 struct aptx_channel_mode_param_t channel_mode_param;
5425 struct param_hdr_v3 param_info;
5426 int ret = 0;
Zhou Song450ee1b2019-08-02 11:06:01 +08005427 u32 param_id = 0;
5428
5429 if (format == ASM_MEDIA_FMT_APTX) {
5430 param_id = CAPI_V2_PARAM_ID_APTX_ENC_SWITCH_TO_MONO;
5431 } else if (format == ASM_MEDIA_FMT_APTX_ADAPTIVE) {
5432 param_id = CAPI_V2_PARAM_ID_APTX_AD_ENC_SWITCH_TO_MONO;
5433 } else {
5434 pr_err("%s: Not supported format 0x%x\n", __func__, format);
5435 return -EINVAL;
5436 }
Manisha Agarwald99fac02018-11-04 15:46:02 +05305437
5438 memset(&param_info, 0, sizeof(param_info));
5439 memset(&channel_mode_param, 0, sizeof(channel_mode_param));
5440
5441 param_info.module_id = AFE_MODULE_ID_ENCODER;
5442 param_info.instance_id = INSTANCE_ID_0;
Zhou Song450ee1b2019-08-02 11:06:01 +08005443 param_info.param_id = param_id;
Manisha Agarwald99fac02018-11-04 15:46:02 +05305444 param_info.param_size = sizeof(channel_mode_param);
5445
5446 channel_mode_param.channel_mode = channel_mode;
5447
5448 ret = q6afe_pack_and_set_param_in_band(port_id,
5449 q6audio_get_port_index(port_id),
5450 param_info,
5451 (u8 *) &channel_mode_param);
5452 if (ret)
5453 pr_err("%s: AFE set channel mode cfg for port 0x%x failed %d\n",
5454 __func__, port_id, ret);
5455
5456 return ret;
5457}
5458EXPORT_SYMBOL(afe_set_tws_channel_mode);
5459
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305460static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
5461 u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005462 union afe_enc_config_data *enc_cfg,
Manisha Agarwald99fac02018-11-04 15:46:02 +05305463 u32 codec_format, u32 scrambler_mode, u32 mono_mode,
Surendar Karkab50f4232019-02-12 12:46:05 +05305464 struct afe_dec_config *dec_cfg,
5465 struct afe_ttp_config *ttp_cfg)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305466{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005467 union afe_port_config port_cfg;
5468 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305469 int ret = 0;
5470 int cfg_type;
5471 int index = 0;
5472 enum afe_mad_type mad_type;
5473 uint16_t port_index;
5474
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005475 memset(&param_hdr, 0, sizeof(param_hdr));
5476 memset(&port_cfg, 0, sizeof(port_cfg));
5477
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305478 if (!afe_config) {
5479 pr_err("%s: Error, no configuration data\n", __func__);
5480 ret = -EINVAL;
5481 return ret;
5482 }
5483
5484 if ((port_id == RT_PROXY_DAI_001_RX) ||
5485 (port_id == RT_PROXY_DAI_002_TX)) {
5486 pr_debug("%s: before incrementing pcm_afe_instance %d port_id 0x%x\n",
5487 __func__,
5488 pcm_afe_instance[port_id & 0x1], port_id);
5489 port_id = VIRTUAL_ID_TO_PORTID(port_id);
5490 pcm_afe_instance[port_id & 0x1]++;
5491 return 0;
5492 }
5493 if ((port_id == RT_PROXY_DAI_002_RX) ||
5494 (port_id == RT_PROXY_DAI_001_TX)) {
5495 pr_debug("%s: before incrementing proxy_afe_instance %d port_id 0x%x\n",
5496 __func__,
5497 proxy_afe_instance[port_id & 0x1], port_id);
5498
5499 if (!afe_close_done[port_id & 0x1]) {
5500 /*close pcm dai corresponding to the proxy dai*/
5501 afe_close(port_id - 0x10);
5502 pcm_afe_instance[port_id & 0x1]++;
5503 pr_debug("%s: reconfigure afe port again\n", __func__);
5504 }
5505 proxy_afe_instance[port_id & 0x1]++;
5506 afe_close_done[port_id & 0x1] = false;
5507 port_id = VIRTUAL_ID_TO_PORTID(port_id);
5508 }
5509
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07005510 pr_info("%s: port id: 0x%x\n", __func__, port_id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305511
5512 index = q6audio_get_port_index(port_id);
5513 if (index < 0 || index >= AFE_MAX_PORTS) {
5514 pr_err("%s: AFE port index[%d] invalid!\n",
5515 __func__, index);
5516 return -EINVAL;
5517 }
5518 ret = q6audio_validate_port(port_id);
5519 if (ret < 0) {
5520 pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
5521 return -EINVAL;
5522 }
5523
5524 ret = afe_q6_interface_prepare();
5525 if (ret != 0) {
5526 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
5527 return ret;
5528 }
5529
5530 if ((index >= 0) && (index < AFE_MAX_PORTS)) {
5531 this_afe.afe_sample_rates[index] = rate;
5532
5533 if (this_afe.rt_cb)
5534 this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id);
5535 }
5536
5537 mutex_lock(&this_afe.afe_cmd_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305538 port_index = afe_get_port_index(port_id);
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05305539
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +05305540 /* Also send the topology id here: */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305541 if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) {
5542 /* One time call: only for first time */
5543 afe_send_custom_topology();
5544 afe_send_port_topology_id(port_id);
5545 afe_send_cal(port_id);
5546 afe_send_hw_delay(port_id, rate);
5547 }
5548
Faiz Nabi Kuchay29093022020-10-08 18:25:49 +05305549 if ((this_afe.cps_config) &&
5550 (this_afe.vi_rx_port == port_id)) {
5551 afe_send_cps_config(port_id);
5552 }
5553
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305554 /* Start SW MAD module */
5555 mad_type = afe_port_get_mad_type(port_id);
5556 pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id,
5557 mad_type);
5558 if (mad_type != MAD_HW_NONE && mad_type != MAD_SW_AUDIO) {
5559 if (!afe_has_config(AFE_CDC_REGISTERS_CONFIG) ||
5560 !afe_has_config(AFE_SLIMBUS_SLAVE_CONFIG)) {
5561 pr_err("%s: AFE isn't configured yet for\n"
5562 "HW MAD try Again\n", __func__);
5563 ret = -EAGAIN;
5564 goto fail_cmd;
5565 }
5566 ret = afe_turn_onoff_hw_mad(mad_type, true);
5567 if (ret) {
5568 pr_err("%s: afe_turn_onoff_hw_mad failed %d\n",
5569 __func__, ret);
5570 goto fail_cmd;
5571 }
5572 }
5573
5574 if ((this_afe.aanc_info.aanc_active) &&
5575 (this_afe.aanc_info.aanc_tx_port == port_id)) {
5576 this_afe.aanc_info.aanc_tx_port_sample_rate = rate;
5577 port_index =
5578 afe_get_port_index(this_afe.aanc_info.aanc_rx_port);
5579 if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
5580 this_afe.aanc_info.aanc_rx_port_sample_rate =
5581 this_afe.afe_sample_rates[port_index];
5582 } else {
5583 pr_err("%s: Invalid port index %d\n",
5584 __func__, port_index);
5585 ret = -EINVAL;
5586 goto fail_cmd;
5587 }
5588 ret = afe_aanc_start(this_afe.aanc_info.aanc_tx_port,
5589 this_afe.aanc_info.aanc_rx_port);
5590 pr_debug("%s: afe_aanc_start ret %d\n", __func__, ret);
5591 }
5592
5593 if ((port_id == AFE_PORT_ID_USB_RX) ||
5594 (port_id == AFE_PORT_ID_USB_TX)) {
5595 ret = afe_port_send_usb_dev_param(port_id, afe_config);
5596 if (ret) {
5597 pr_err("%s: AFE device param for port 0x%x failed %d\n",
5598 __func__, port_id, ret);
5599 ret = -EINVAL;
5600 goto fail_cmd;
5601 }
5602 }
5603
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305604 switch (port_id) {
5605 case AFE_PORT_ID_PRIMARY_PCM_RX:
5606 case AFE_PORT_ID_PRIMARY_PCM_TX:
5607 case AFE_PORT_ID_SECONDARY_PCM_RX:
5608 case AFE_PORT_ID_SECONDARY_PCM_TX:
5609 case AFE_PORT_ID_TERTIARY_PCM_RX:
5610 case AFE_PORT_ID_TERTIARY_PCM_TX:
5611 case AFE_PORT_ID_QUATERNARY_PCM_RX:
5612 case AFE_PORT_ID_QUATERNARY_PCM_TX:
Rohit Kumarc08b14f2017-10-06 10:52:17 +05305613 case AFE_PORT_ID_QUINARY_PCM_RX:
5614 case AFE_PORT_ID_QUINARY_PCM_TX:
Dieter Lueckingfa7687b2018-09-28 14:21:44 +02005615 case AFE_PORT_ID_SENARY_PCM_RX:
5616 case AFE_PORT_ID_SENARY_PCM_TX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305617 cfg_type = AFE_PARAM_ID_PCM_CONFIG;
5618 break;
5619 case PRIMARY_I2S_RX:
5620 case PRIMARY_I2S_TX:
5621 case SECONDARY_I2S_RX:
5622 case SECONDARY_I2S_TX:
5623 case MI2S_RX:
5624 case MI2S_TX:
5625 case AFE_PORT_ID_PRIMARY_MI2S_RX:
5626 case AFE_PORT_ID_PRIMARY_MI2S_TX:
5627 case AFE_PORT_ID_SECONDARY_MI2S_RX:
5628 case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1:
5629 case AFE_PORT_ID_SECONDARY_MI2S_TX:
5630 case AFE_PORT_ID_TERTIARY_MI2S_RX:
5631 case AFE_PORT_ID_TERTIARY_MI2S_TX:
5632 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
5633 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
5634 case AFE_PORT_ID_QUINARY_MI2S_RX:
5635 case AFE_PORT_ID_QUINARY_MI2S_TX:
Karthikeyan Mani3bbd2ee2019-01-30 18:48:56 -08005636 case AFE_PORT_ID_SENARY_MI2S_RX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305637 case AFE_PORT_ID_SENARY_MI2S_TX:
5638 case AFE_PORT_ID_INT0_MI2S_RX:
5639 case AFE_PORT_ID_INT0_MI2S_TX:
5640 case AFE_PORT_ID_INT1_MI2S_RX:
5641 case AFE_PORT_ID_INT1_MI2S_TX:
5642 case AFE_PORT_ID_INT2_MI2S_RX:
5643 case AFE_PORT_ID_INT2_MI2S_TX:
5644 case AFE_PORT_ID_INT3_MI2S_RX:
5645 case AFE_PORT_ID_INT3_MI2S_TX:
5646 case AFE_PORT_ID_INT4_MI2S_RX:
5647 case AFE_PORT_ID_INT4_MI2S_TX:
5648 case AFE_PORT_ID_INT5_MI2S_RX:
5649 case AFE_PORT_ID_INT5_MI2S_TX:
5650 case AFE_PORT_ID_INT6_MI2S_RX:
5651 case AFE_PORT_ID_INT6_MI2S_TX:
5652 cfg_type = AFE_PARAM_ID_I2S_CONFIG;
5653 break;
Ralf Herz43c0abd2019-07-26 15:12:48 +02005654 case AFE_PORT_ID_PRIMARY_META_MI2S_RX:
5655 case AFE_PORT_ID_SECONDARY_META_MI2S_RX:
5656 cfg_type = AFE_PARAM_ID_META_I2S_CONFIG;
5657 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305658 case HDMI_RX:
Sanjana B63bdc7b2020-01-20 19:31:18 +05305659 case HDMI_RX_MS:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305660 case DISPLAY_PORT_RX:
5661 cfg_type = AFE_PARAM_ID_HDMI_CONFIG;
5662 break;
5663 case VOICE_PLAYBACK_TX:
5664 case VOICE2_PLAYBACK_TX:
5665 case VOICE_RECORD_RX:
5666 case VOICE_RECORD_TX:
5667 cfg_type = AFE_PARAM_ID_PSEUDO_PORT_CONFIG;
5668 break;
5669 case SLIMBUS_0_RX:
5670 case SLIMBUS_0_TX:
5671 case SLIMBUS_1_RX:
5672 case SLIMBUS_1_TX:
5673 case SLIMBUS_2_RX:
5674 case SLIMBUS_2_TX:
5675 case SLIMBUS_3_RX:
5676 case SLIMBUS_3_TX:
5677 case SLIMBUS_4_RX:
5678 case SLIMBUS_4_TX:
5679 case SLIMBUS_5_RX:
5680 case SLIMBUS_5_TX:
5681 case SLIMBUS_6_RX:
5682 case SLIMBUS_6_TX:
5683 case SLIMBUS_7_RX:
5684 case SLIMBUS_7_TX:
5685 case SLIMBUS_8_RX:
5686 case SLIMBUS_8_TX:
Surendar Karkab0dd21f2018-09-28 18:53:50 +05305687 case SLIMBUS_9_RX:
5688 case SLIMBUS_9_TX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305689 cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG;
5690 break;
5691 case AFE_PORT_ID_USB_RX:
5692 case AFE_PORT_ID_USB_TX:
5693 cfg_type = AFE_PARAM_ID_USB_AUDIO_CONFIG;
5694 break;
5695 case RT_PROXY_PORT_001_RX:
5696 case RT_PROXY_PORT_001_TX:
Jaideep Sharma39932232020-03-11 22:24:14 +05305697 case RT_PROXY_PORT_002_RX:
5698 case RT_PROXY_PORT_002_TX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305699 cfg_type = AFE_PARAM_ID_RT_PROXY_CONFIG;
5700 break;
5701 case INT_BT_SCO_RX:
5702 case INT_BT_A2DP_RX:
5703 case INT_BT_SCO_TX:
5704 case INT_FM_RX:
5705 case INT_FM_TX:
5706 cfg_type = AFE_PARAM_ID_INTERNAL_BT_FM_CONFIG;
5707 break;
Mangesh Kunchamwar8c706ab2018-04-04 17:48:46 +05305708 case AFE_PORT_ID_WSA_CODEC_DMA_RX_0:
5709 case AFE_PORT_ID_WSA_CODEC_DMA_TX_0:
5710 case AFE_PORT_ID_WSA_CODEC_DMA_RX_1:
5711 case AFE_PORT_ID_WSA_CODEC_DMA_TX_1:
5712 case AFE_PORT_ID_WSA_CODEC_DMA_TX_2:
5713 case AFE_PORT_ID_VA_CODEC_DMA_TX_0:
5714 case AFE_PORT_ID_VA_CODEC_DMA_TX_1:
Xiaoyu Ye8341eef2019-01-03 14:57:47 -08005715 case AFE_PORT_ID_VA_CODEC_DMA_TX_2:
Aditya Bavanari348a4a62018-05-16 21:48:45 +05305716 case AFE_PORT_ID_RX_CODEC_DMA_RX_0:
5717 case AFE_PORT_ID_TX_CODEC_DMA_TX_0:
5718 case AFE_PORT_ID_RX_CODEC_DMA_RX_1:
5719 case AFE_PORT_ID_TX_CODEC_DMA_TX_1:
5720 case AFE_PORT_ID_RX_CODEC_DMA_RX_2:
5721 case AFE_PORT_ID_TX_CODEC_DMA_TX_2:
5722 case AFE_PORT_ID_RX_CODEC_DMA_RX_3:
5723 case AFE_PORT_ID_TX_CODEC_DMA_TX_3:
5724 case AFE_PORT_ID_RX_CODEC_DMA_RX_4:
5725 case AFE_PORT_ID_TX_CODEC_DMA_TX_4:
5726 case AFE_PORT_ID_RX_CODEC_DMA_RX_5:
5727 case AFE_PORT_ID_TX_CODEC_DMA_TX_5:
5728 case AFE_PORT_ID_RX_CODEC_DMA_RX_6:
5729 case AFE_PORT_ID_RX_CODEC_DMA_RX_7:
Mangesh Kunchamwar8c706ab2018-04-04 17:48:46 +05305730 cfg_type = AFE_PARAM_ID_CODEC_DMA_CONFIG;
5731 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305732 default:
5733 pr_err("%s: Invalid port id 0x%x\n", __func__, port_id);
5734 ret = -EINVAL;
5735 goto fail_cmd;
5736 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305737
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005738 param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
5739 param_hdr.instance_id = INSTANCE_ID_0;
5740 param_hdr.param_id = cfg_type;
5741 param_hdr.param_size = sizeof(union afe_port_config);
5742
5743 port_cfg = *afe_config;
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005744 if (((enc_cfg != NULL) || (dec_cfg != NULL)) &&
5745 (codec_format != ASM_MEDIA_FMT_NONE) &&
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305746 (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) {
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005747 port_cfg.slim_sch.data_format =
5748 AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305749 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08005750 ret = q6afe_pack_and_set_param_in_band(port_id,
5751 q6audio_get_port_index(port_id),
5752 param_hdr, (u8 *) &port_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305753 if (ret) {
5754 pr_err("%s: AFE enable for port 0x%x failed %d\n",
5755 __func__, port_id, ret);
5756 goto fail_cmd;
5757 }
5758
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005759 if ((codec_format != ASM_MEDIA_FMT_NONE) &&
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305760 (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) {
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005761 if (enc_cfg != NULL) {
Harshal Ahire10e83842020-03-27 04:37:23 +05305762 pr_debug("%s: Found AFE encoder support for SLIMBUS format = %d\n",
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005763 __func__, codec_format);
Harshal Ahire10e83842020-03-27 04:37:23 +05305764
5765 if ((q6core_get_avcs_api_version_per_service(
5766 APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >=
5767 AVCS_API_VERSION_V5)) {
5768 ret = q6afe_load_avcs_modules(2, port_id,
5769 ENCODER_CASE, codec_format);
5770 if (ret < 0) {
5771 pr_err("%s:encoder load for port 0x%x failed %d\n",
5772 __func__, port_id, ret);
5773 goto fail_cmd;
5774 }
5775 }
5776
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005777 ret = q6afe_send_enc_config(port_id, enc_cfg,
5778 codec_format, *afe_config,
5779 afe_in_channels,
5780 afe_in_bit_width,
Manisha Agarwald99fac02018-11-04 15:46:02 +05305781 scrambler_mode, mono_mode);
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005782 if (ret) {
5783 pr_err("%s: AFE encoder config for port 0x%x failed %d\n",
5784 __func__, port_id, ret);
5785 goto fail_cmd;
5786 }
5787 }
5788 if (dec_cfg != NULL) {
5789 pr_debug("%s: Found AFE decoder support for SLIMBUS format = %d\n",
Harshal Ahire10e83842020-03-27 04:37:23 +05305790 __func__, codec_format);
5791
5792 if ((q6core_get_avcs_api_version_per_service(
5793 APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >=
5794 AVCS_API_VERSION_V5)) {
Harshal Ahire9f083ad2020-07-13 14:53:02 +05305795 /*
5796 * LDAC and APTX_ADAPTIVE don't require loading decoder module
5797 * Only loading de-packetizer module.
5798 */
5799 if (codec_format == ENC_CODEC_TYPE_LDAC ||
5800 codec_format == ASM_MEDIA_FMT_APTX_ADAPTIVE)
Harshal Ahire10e83842020-03-27 04:37:23 +05305801 ret = q6afe_load_avcs_modules(1, port_id,
5802 DECODER_CASE, codec_format);
5803 else
5804 ret = q6afe_load_avcs_modules(2, port_id,
5805 DECODER_CASE, codec_format);
5806 if (ret < 0) {
5807 pr_err("%s:decoder load for port 0x%x failed %d\n",
5808 __func__, port_id, ret);
5809 goto fail_cmd;
5810 }
5811 }
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005812 ret = q6afe_send_dec_config(port_id, *afe_config,
Florian Pfisterf1b8d5b2018-09-26 15:45:18 +02005813 dec_cfg, codec_format,
5814 afe_in_channels,
5815 afe_in_bit_width);
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005816 if (ret) {
5817 pr_err("%s: AFE decoder config for port 0x%x failed %d\n",
5818 __func__, port_id, ret);
5819 goto fail_cmd;
5820 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305821 }
Surendar Karkab50f4232019-02-12 12:46:05 +05305822 if (ttp_cfg != NULL) {
5823 ret = q6afe_send_ttp_config(port_id, *afe_config,
5824 ttp_cfg);
5825 if (ret) {
5826 pr_err("%s: AFE TTP config for port 0x%x failed %d\n",
5827 __func__, port_id, ret);
5828 goto fail_cmd;
5829 }
5830 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305831 }
5832
5833 port_index = afe_get_port_index(port_id);
5834 if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
5835 /*
5836 * If afe_port_start() for tx port called before
5837 * rx port, then aanc rx sample rate is zero. So,
5838 * AANC state machine in AFE will not get triggered.
5839 * Make sure to check whether aanc is active during
5840 * afe_port_start() for rx port and if aanc rx
5841 * sample rate is zero, call afe_aanc_start to configure
5842 * aanc with valid sample rates.
5843 */
5844 if (this_afe.aanc_info.aanc_active &&
5845 !this_afe.aanc_info.aanc_rx_port_sample_rate) {
5846 this_afe.aanc_info.aanc_rx_port_sample_rate =
5847 this_afe.afe_sample_rates[port_index];
5848 ret = afe_aanc_start(this_afe.aanc_info.aanc_tx_port,
5849 this_afe.aanc_info.aanc_rx_port);
5850 pr_debug("%s: afe_aanc_start ret %d\n", __func__, ret);
5851 }
5852 } else {
5853 pr_err("%s: Invalid port index %d\n", __func__, port_index);
5854 ret = -EINVAL;
5855 goto fail_cmd;
5856 }
5857 ret = afe_send_cmd_port_start(port_id);
5858
5859fail_cmd:
5860 mutex_unlock(&this_afe.afe_cmd_lock);
5861 return ret;
5862}
5863
5864/**
5865 * afe_port_start - to configure AFE session with
5866 * specified port configuration
5867 *
5868 * @port_id: AFE port id number
5869 * @afe_config: port configutation
5870 * @rate: sampling rate of port
5871 *
5872 * Returns 0 on success or error value on port start failure.
5873 */
5874int afe_port_start(u16 port_id, union afe_port_config *afe_config,
5875 u32 rate)
5876{
Surendar Karkab50f4232019-02-12 12:46:05 +05305877 return __afe_port_start(port_id, afe_config, rate, 0, 0, NULL,
5878 ASM_MEDIA_FMT_NONE, 0, 0, NULL, NULL);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305879}
5880EXPORT_SYMBOL(afe_port_start);
5881
5882/**
5883 * afe_port_start_v2 - to configure AFE session with
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005884 * specified port configuration and encoder /decoder params
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305885 *
5886 * @port_id: AFE port id number
5887 * @afe_config: port configutation
5888 * @rate: sampling rate of port
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005889 * @enc_cfg: AFE enc configuration information to setup encoder
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305890 * @afe_in_channels: AFE input channel configuration, this needs
5891 * update only if input channel is differ from AFE output
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005892 * @dec_cfg: AFE dec configuration information to set up decoder
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305893 *
5894 * Returns 0 on success or error value on port start failure.
5895 */
5896int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config,
5897 u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005898 struct afe_enc_config *enc_cfg,
5899 struct afe_dec_config *dec_cfg)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305900{
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005901 int ret = 0;
5902
5903 if (enc_cfg != NULL)
5904 ret = __afe_port_start(port_id, afe_config, rate,
5905 afe_in_channels, afe_in_bit_width,
5906 &enc_cfg->data, enc_cfg->format,
Manisha Agarwald99fac02018-11-04 15:46:02 +05305907 enc_cfg->scrambler_mode,
Surendar Karkab50f4232019-02-12 12:46:05 +05305908 enc_cfg->mono_mode, dec_cfg, NULL);
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005909 else if (dec_cfg != NULL)
5910 ret = __afe_port_start(port_id, afe_config, rate,
5911 afe_in_channels, afe_in_bit_width,
Surendar Karkab50f4232019-02-12 12:46:05 +05305912 NULL, dec_cfg->format, 0, 0,
5913 dec_cfg, NULL);
Aniket Kumar Latac0c31472018-02-22 14:46:09 -08005914
5915 return ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305916}
5917EXPORT_SYMBOL(afe_port_start_v2);
5918
Surendar Karkab50f4232019-02-12 12:46:05 +05305919/**
5920 * afe_port_start_v3 - to configure AFE session with
5921 * specified port configuration and encoder /decoder params
5922 *
5923 * @port_id: AFE port id number
5924 * @afe_config: port configuration
5925 * @rate: sampling rate of port
5926 * @enc_cfg: AFE enc configuration information to setup encoder
5927 * @afe_in_channels: AFE input channel configuration, this needs
5928 * update only if input channel is differ from AFE output
5929 * @dec_cfg: AFE dec configuration information to set up decoder
5930 * @ttp_cfg: TTP generator configuration to enable TTP in AFE
5931 *
5932 * Returns 0 on success or error value on port start failure.
5933 */
5934int afe_port_start_v3(u16 port_id, union afe_port_config *afe_config,
5935 u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
5936 struct afe_enc_config *enc_cfg,
5937 struct afe_dec_config *dec_cfg,
5938 struct afe_ttp_config *ttp_cfg)
5939{
5940 int ret = 0;
5941
5942 if (dec_cfg != NULL && ttp_cfg != NULL)
5943 ret = __afe_port_start(port_id, afe_config, rate,
5944 afe_in_channels, afe_in_bit_width,
5945 NULL, dec_cfg->format, 0, 0,
5946 dec_cfg, ttp_cfg);
5947
5948 return ret;
5949}
5950EXPORT_SYMBOL(afe_port_start_v3);
5951
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305952int afe_get_port_index(u16 port_id)
5953{
5954 switch (port_id) {
5955 case PRIMARY_I2S_RX: return IDX_PRIMARY_I2S_RX;
5956 case PRIMARY_I2S_TX: return IDX_PRIMARY_I2S_TX;
5957 case AFE_PORT_ID_PRIMARY_PCM_RX:
5958 return IDX_AFE_PORT_ID_PRIMARY_PCM_RX;
5959 case AFE_PORT_ID_PRIMARY_PCM_TX:
5960 return IDX_AFE_PORT_ID_PRIMARY_PCM_TX;
5961 case AFE_PORT_ID_SECONDARY_PCM_RX:
5962 return IDX_AFE_PORT_ID_SECONDARY_PCM_RX;
5963 case AFE_PORT_ID_SECONDARY_PCM_TX:
5964 return IDX_AFE_PORT_ID_SECONDARY_PCM_TX;
5965 case AFE_PORT_ID_TERTIARY_PCM_RX:
5966 return IDX_AFE_PORT_ID_TERTIARY_PCM_RX;
5967 case AFE_PORT_ID_TERTIARY_PCM_TX:
5968 return IDX_AFE_PORT_ID_TERTIARY_PCM_TX;
5969 case AFE_PORT_ID_QUATERNARY_PCM_RX:
5970 return IDX_AFE_PORT_ID_QUATERNARY_PCM_RX;
5971 case AFE_PORT_ID_QUATERNARY_PCM_TX:
5972 return IDX_AFE_PORT_ID_QUATERNARY_PCM_TX;
Rohit Kumarc08b14f2017-10-06 10:52:17 +05305973 case AFE_PORT_ID_QUINARY_PCM_RX:
5974 return IDX_AFE_PORT_ID_QUINARY_PCM_RX;
5975 case AFE_PORT_ID_QUINARY_PCM_TX:
5976 return IDX_AFE_PORT_ID_QUINARY_PCM_TX;
Dieter Lueckingfa7687b2018-09-28 14:21:44 +02005977 case AFE_PORT_ID_SENARY_PCM_RX:
5978 return IDX_AFE_PORT_ID_SENARY_PCM_RX;
5979 case AFE_PORT_ID_SENARY_PCM_TX:
5980 return IDX_AFE_PORT_ID_SENARY_PCM_TX;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305981 case SECONDARY_I2S_RX: return IDX_SECONDARY_I2S_RX;
5982 case SECONDARY_I2S_TX: return IDX_SECONDARY_I2S_TX;
5983 case MI2S_RX: return IDX_MI2S_RX;
5984 case MI2S_TX: return IDX_MI2S_TX;
5985 case HDMI_RX: return IDX_HDMI_RX;
Sanjana B63bdc7b2020-01-20 19:31:18 +05305986 case HDMI_RX_MS: return IDX_HDMI_RX_MS;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305987 case DISPLAY_PORT_RX: return IDX_DISPLAY_PORT_RX;
Ralf Herzcc29b9e2018-07-17 20:19:04 +05305988 case AFE_PORT_ID_PRIMARY_SPDIF_RX: return IDX_PRIMARY_SPDIF_RX;
5989 case AFE_PORT_ID_PRIMARY_SPDIF_TX: return IDX_PRIMARY_SPDIF_TX;
5990 case AFE_PORT_ID_SECONDARY_SPDIF_RX: return IDX_SECONDARY_SPDIF_RX;
5991 case AFE_PORT_ID_SECONDARY_SPDIF_TX: return IDX_SECONDARY_SPDIF_TX;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305992 case RSVD_2: return IDX_RSVD_2;
5993 case RSVD_3: return IDX_RSVD_3;
5994 case DIGI_MIC_TX: return IDX_DIGI_MIC_TX;
5995 case VOICE_RECORD_RX: return IDX_VOICE_RECORD_RX;
5996 case VOICE_RECORD_TX: return IDX_VOICE_RECORD_TX;
5997 case VOICE_PLAYBACK_TX: return IDX_VOICE_PLAYBACK_TX;
5998 case VOICE2_PLAYBACK_TX: return IDX_VOICE2_PLAYBACK_TX;
5999 case SLIMBUS_0_RX: return IDX_SLIMBUS_0_RX;
6000 case SLIMBUS_0_TX: return IDX_SLIMBUS_0_TX;
6001 case SLIMBUS_1_RX: return IDX_SLIMBUS_1_RX;
6002 case SLIMBUS_1_TX: return IDX_SLIMBUS_1_TX;
6003 case SLIMBUS_2_RX: return IDX_SLIMBUS_2_RX;
6004 case SLIMBUS_2_TX: return IDX_SLIMBUS_2_TX;
6005 case SLIMBUS_3_RX: return IDX_SLIMBUS_3_RX;
6006 case SLIMBUS_3_TX: return IDX_SLIMBUS_3_TX;
6007 case INT_BT_SCO_RX: return IDX_INT_BT_SCO_RX;
6008 case INT_BT_SCO_TX: return IDX_INT_BT_SCO_TX;
6009 case INT_BT_A2DP_RX: return IDX_INT_BT_A2DP_RX;
6010 case INT_FM_RX: return IDX_INT_FM_RX;
6011 case INT_FM_TX: return IDX_INT_FM_TX;
6012 case RT_PROXY_PORT_001_RX: return IDX_RT_PROXY_PORT_001_RX;
6013 case RT_PROXY_PORT_001_TX: return IDX_RT_PROXY_PORT_001_TX;
6014 case SLIMBUS_4_RX: return IDX_SLIMBUS_4_RX;
6015 case SLIMBUS_4_TX: return IDX_SLIMBUS_4_TX;
6016 case SLIMBUS_5_RX: return IDX_SLIMBUS_5_RX;
6017 case SLIMBUS_5_TX: return IDX_SLIMBUS_5_TX;
6018 case SLIMBUS_6_RX: return IDX_SLIMBUS_6_RX;
6019 case SLIMBUS_6_TX: return IDX_SLIMBUS_6_TX;
6020 case SLIMBUS_7_RX: return IDX_SLIMBUS_7_RX;
6021 case SLIMBUS_7_TX: return IDX_SLIMBUS_7_TX;
6022 case SLIMBUS_8_RX: return IDX_SLIMBUS_8_RX;
6023 case SLIMBUS_8_TX: return IDX_SLIMBUS_8_TX;
Surendar Karkab0dd21f2018-09-28 18:53:50 +05306024 case SLIMBUS_9_RX: return IDX_SLIMBUS_9_RX;
6025 case SLIMBUS_9_TX: return IDX_SLIMBUS_9_TX;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306026 case AFE_PORT_ID_USB_RX: return IDX_AFE_PORT_ID_USB_RX;
6027 case AFE_PORT_ID_USB_TX: return IDX_AFE_PORT_ID_USB_TX;
6028 case AFE_PORT_ID_PRIMARY_MI2S_RX:
6029 return IDX_AFE_PORT_ID_PRIMARY_MI2S_RX;
6030 case AFE_PORT_ID_PRIMARY_MI2S_TX:
6031 return IDX_AFE_PORT_ID_PRIMARY_MI2S_TX;
6032 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
6033 return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX;
6034 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
6035 return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX;
6036 case AFE_PORT_ID_SECONDARY_MI2S_RX:
6037 return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX;
6038 case AFE_PORT_ID_SECONDARY_MI2S_TX:
6039 return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX;
6040 case AFE_PORT_ID_TERTIARY_MI2S_RX:
6041 return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX;
6042 case AFE_PORT_ID_TERTIARY_MI2S_TX:
6043 return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX;
6044 case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1:
6045 return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_SD1;
6046 case AFE_PORT_ID_QUINARY_MI2S_RX:
6047 return IDX_AFE_PORT_ID_QUINARY_MI2S_RX;
6048 case AFE_PORT_ID_QUINARY_MI2S_TX:
6049 return IDX_AFE_PORT_ID_QUINARY_MI2S_TX;
Karthikeyan Mani3bbd2ee2019-01-30 18:48:56 -08006050 case AFE_PORT_ID_SENARY_MI2S_RX:
6051 return IDX_AFE_PORT_ID_SENARY_MI2S_RX;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306052 case AFE_PORT_ID_SENARY_MI2S_TX:
6053 return IDX_AFE_PORT_ID_SENARY_MI2S_TX;
6054 case AFE_PORT_ID_PRIMARY_TDM_RX:
6055 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_0;
6056 case AFE_PORT_ID_PRIMARY_TDM_TX:
6057 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_0;
6058 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
6059 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_1;
6060 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
6061 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_1;
6062 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
6063 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_2;
6064 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
6065 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_2;
6066 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
6067 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_3;
6068 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
6069 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_3;
6070 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
6071 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_4;
6072 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
6073 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_4;
6074 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
6075 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_5;
6076 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
6077 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_5;
6078 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
6079 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_6;
6080 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
6081 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_6;
6082 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
6083 return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_7;
6084 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
6085 return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_7;
6086 case AFE_PORT_ID_SECONDARY_TDM_RX:
6087 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_0;
6088 case AFE_PORT_ID_SECONDARY_TDM_TX:
6089 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_0;
6090 case AFE_PORT_ID_SECONDARY_TDM_RX_1:
6091 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_1;
6092 case AFE_PORT_ID_SECONDARY_TDM_TX_1:
6093 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_1;
6094 case AFE_PORT_ID_SECONDARY_TDM_RX_2:
6095 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_2;
6096 case AFE_PORT_ID_SECONDARY_TDM_TX_2:
6097 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_2;
6098 case AFE_PORT_ID_SECONDARY_TDM_RX_3:
6099 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_3;
6100 case AFE_PORT_ID_SECONDARY_TDM_TX_3:
6101 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_3;
6102 case AFE_PORT_ID_SECONDARY_TDM_RX_4:
6103 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_4;
6104 case AFE_PORT_ID_SECONDARY_TDM_TX_4:
6105 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_4;
6106 case AFE_PORT_ID_SECONDARY_TDM_RX_5:
6107 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_5;
6108 case AFE_PORT_ID_SECONDARY_TDM_TX_5:
6109 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_5;
6110 case AFE_PORT_ID_SECONDARY_TDM_RX_6:
6111 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_6;
6112 case AFE_PORT_ID_SECONDARY_TDM_TX_6:
6113 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_6;
6114 case AFE_PORT_ID_SECONDARY_TDM_RX_7:
6115 return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_7;
6116 case AFE_PORT_ID_SECONDARY_TDM_TX_7:
6117 return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_7;
6118 case AFE_PORT_ID_TERTIARY_TDM_RX:
6119 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_0;
6120 case AFE_PORT_ID_TERTIARY_TDM_TX:
6121 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_0;
6122 case AFE_PORT_ID_TERTIARY_TDM_RX_1:
6123 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_1;
6124 case AFE_PORT_ID_TERTIARY_TDM_TX_1:
6125 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_1;
6126 case AFE_PORT_ID_TERTIARY_TDM_RX_2:
6127 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_2;
6128 case AFE_PORT_ID_TERTIARY_TDM_TX_2:
6129 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_2;
6130 case AFE_PORT_ID_TERTIARY_TDM_RX_3:
6131 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_3;
6132 case AFE_PORT_ID_TERTIARY_TDM_TX_3:
6133 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_3;
6134 case AFE_PORT_ID_TERTIARY_TDM_RX_4:
6135 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_4;
6136 case AFE_PORT_ID_TERTIARY_TDM_TX_4:
6137 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_4;
6138 case AFE_PORT_ID_TERTIARY_TDM_RX_5:
6139 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_5;
6140 case AFE_PORT_ID_TERTIARY_TDM_TX_5:
6141 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_5;
6142 case AFE_PORT_ID_TERTIARY_TDM_RX_6:
6143 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_6;
6144 case AFE_PORT_ID_TERTIARY_TDM_TX_6:
6145 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_6;
6146 case AFE_PORT_ID_TERTIARY_TDM_RX_7:
6147 return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_7;
6148 case AFE_PORT_ID_TERTIARY_TDM_TX_7:
6149 return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_7;
6150 case AFE_PORT_ID_QUATERNARY_TDM_RX:
6151 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_0;
6152 case AFE_PORT_ID_QUATERNARY_TDM_TX:
6153 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_0;
6154 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
6155 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_1;
6156 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
6157 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_1;
6158 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
6159 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_2;
6160 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
6161 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_2;
6162 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
6163 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_3;
6164 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
6165 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_3;
6166 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
6167 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_4;
6168 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
6169 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_4;
6170 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
6171 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_5;
6172 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
6173 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_5;
6174 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
6175 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_6;
6176 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
6177 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_6;
6178 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
6179 return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_7;
6180 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
6181 return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_7;
Rohit Kumarc08b14f2017-10-06 10:52:17 +05306182 case AFE_PORT_ID_QUINARY_TDM_RX:
6183 return IDX_AFE_PORT_ID_QUINARY_TDM_RX_0;
6184 case AFE_PORT_ID_QUINARY_TDM_TX:
6185 return IDX_AFE_PORT_ID_QUINARY_TDM_TX_0;
6186 case AFE_PORT_ID_QUINARY_TDM_RX_1:
6187 return IDX_AFE_PORT_ID_QUINARY_TDM_RX_1;
6188 case AFE_PORT_ID_QUINARY_TDM_TX_1:
6189 return IDX_AFE_PORT_ID_QUINARY_TDM_TX_1;
6190 case AFE_PORT_ID_QUINARY_TDM_RX_2:
6191 return IDX_AFE_PORT_ID_QUINARY_TDM_RX_2;
6192 case AFE_PORT_ID_QUINARY_TDM_TX_2:
6193 return IDX_AFE_PORT_ID_QUINARY_TDM_TX_2;
6194 case AFE_PORT_ID_QUINARY_TDM_RX_3:
6195 return IDX_AFE_PORT_ID_QUINARY_TDM_RX_3;
6196 case AFE_PORT_ID_QUINARY_TDM_TX_3:
6197 return IDX_AFE_PORT_ID_QUINARY_TDM_TX_3;
6198 case AFE_PORT_ID_QUINARY_TDM_RX_4:
6199 return IDX_AFE_PORT_ID_QUINARY_TDM_RX_4;
6200 case AFE_PORT_ID_QUINARY_TDM_TX_4:
6201 return IDX_AFE_PORT_ID_QUINARY_TDM_TX_4;
6202 case AFE_PORT_ID_QUINARY_TDM_RX_5:
6203 return IDX_AFE_PORT_ID_QUINARY_TDM_RX_5;
6204 case AFE_PORT_ID_QUINARY_TDM_TX_5:
6205 return IDX_AFE_PORT_ID_QUINARY_TDM_TX_5;
6206 case AFE_PORT_ID_QUINARY_TDM_RX_6:
6207 return IDX_AFE_PORT_ID_QUINARY_TDM_RX_6;
6208 case AFE_PORT_ID_QUINARY_TDM_TX_6:
6209 return IDX_AFE_PORT_ID_QUINARY_TDM_TX_6;
6210 case AFE_PORT_ID_QUINARY_TDM_RX_7:
6211 return IDX_AFE_PORT_ID_QUINARY_TDM_RX_7;
6212 case AFE_PORT_ID_QUINARY_TDM_TX_7:
6213 return IDX_AFE_PORT_ID_QUINARY_TDM_TX_7;
Karthikeyan Mani3bbd2ee2019-01-30 18:48:56 -08006214 case AFE_PORT_ID_SENARY_TDM_RX:
6215 return IDX_AFE_PORT_ID_SENARY_TDM_RX_0;
6216 case AFE_PORT_ID_SENARY_TDM_TX:
6217 return IDX_AFE_PORT_ID_SENARY_TDM_TX_0;
6218 case AFE_PORT_ID_SENARY_TDM_RX_1:
6219 return IDX_AFE_PORT_ID_SENARY_TDM_RX_1;
6220 case AFE_PORT_ID_SENARY_TDM_TX_1:
6221 return IDX_AFE_PORT_ID_SENARY_TDM_TX_1;
6222 case AFE_PORT_ID_SENARY_TDM_RX_2:
6223 return IDX_AFE_PORT_ID_SENARY_TDM_RX_2;
6224 case AFE_PORT_ID_SENARY_TDM_TX_2:
6225 return IDX_AFE_PORT_ID_SENARY_TDM_TX_2;
6226 case AFE_PORT_ID_SENARY_TDM_RX_3:
6227 return IDX_AFE_PORT_ID_SENARY_TDM_RX_3;
6228 case AFE_PORT_ID_SENARY_TDM_TX_3:
6229 return IDX_AFE_PORT_ID_SENARY_TDM_TX_3;
6230 case AFE_PORT_ID_SENARY_TDM_RX_4:
6231 return IDX_AFE_PORT_ID_SENARY_TDM_RX_4;
6232 case AFE_PORT_ID_SENARY_TDM_TX_4:
6233 return IDX_AFE_PORT_ID_SENARY_TDM_TX_4;
6234 case AFE_PORT_ID_SENARY_TDM_RX_5:
6235 return IDX_AFE_PORT_ID_SENARY_TDM_RX_5;
6236 case AFE_PORT_ID_SENARY_TDM_TX_5:
6237 return IDX_AFE_PORT_ID_SENARY_TDM_TX_5;
6238 case AFE_PORT_ID_SENARY_TDM_RX_6:
6239 return IDX_AFE_PORT_ID_SENARY_TDM_RX_6;
6240 case AFE_PORT_ID_SENARY_TDM_TX_6:
6241 return IDX_AFE_PORT_ID_SENARY_TDM_TX_6;
6242 case AFE_PORT_ID_SENARY_TDM_RX_7:
6243 return IDX_AFE_PORT_ID_SENARY_TDM_RX_7;
6244 case AFE_PORT_ID_SENARY_TDM_TX_7:
6245 return IDX_AFE_PORT_ID_SENARY_TDM_TX_7;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306246 case AFE_PORT_ID_INT0_MI2S_RX:
6247 return IDX_AFE_PORT_ID_INT0_MI2S_RX;
6248 case AFE_PORT_ID_INT0_MI2S_TX:
6249 return IDX_AFE_PORT_ID_INT0_MI2S_TX;
6250 case AFE_PORT_ID_INT1_MI2S_RX:
6251 return IDX_AFE_PORT_ID_INT1_MI2S_RX;
6252 case AFE_PORT_ID_INT1_MI2S_TX:
6253 return IDX_AFE_PORT_ID_INT1_MI2S_TX;
6254 case AFE_PORT_ID_INT2_MI2S_RX:
6255 return IDX_AFE_PORT_ID_INT2_MI2S_RX;
6256 case AFE_PORT_ID_INT2_MI2S_TX:
6257 return IDX_AFE_PORT_ID_INT2_MI2S_TX;
6258 case AFE_PORT_ID_INT3_MI2S_RX:
6259 return IDX_AFE_PORT_ID_INT3_MI2S_RX;
6260 case AFE_PORT_ID_INT3_MI2S_TX:
6261 return IDX_AFE_PORT_ID_INT3_MI2S_TX;
6262 case AFE_PORT_ID_INT4_MI2S_RX:
6263 return IDX_AFE_PORT_ID_INT4_MI2S_RX;
6264 case AFE_PORT_ID_INT4_MI2S_TX:
6265 return IDX_AFE_PORT_ID_INT4_MI2S_TX;
6266 case AFE_PORT_ID_INT5_MI2S_RX:
6267 return IDX_AFE_PORT_ID_INT5_MI2S_RX;
6268 case AFE_PORT_ID_INT5_MI2S_TX:
6269 return IDX_AFE_PORT_ID_INT5_MI2S_TX;
6270 case AFE_PORT_ID_INT6_MI2S_RX:
6271 return IDX_AFE_PORT_ID_INT6_MI2S_RX;
6272 case AFE_PORT_ID_INT6_MI2S_TX:
6273 return IDX_AFE_PORT_ID_INT6_MI2S_TX;
Ralf Herz43c0abd2019-07-26 15:12:48 +02006274 case AFE_PORT_ID_PRIMARY_META_MI2S_RX:
6275 return IDX_AFE_PORT_ID_PRIMARY_META_MI2S_RX;
6276 case AFE_PORT_ID_SECONDARY_META_MI2S_RX:
6277 return IDX_AFE_PORT_ID_SECONDARY_META_MI2S_RX;
Mangesh Kunchamwar1274b762018-06-28 15:40:57 +05306278 case AFE_PORT_ID_VA_CODEC_DMA_TX_0:
6279 return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_0;
6280 case AFE_PORT_ID_VA_CODEC_DMA_TX_1:
6281 return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_1;
Xiaoyu Ye8341eef2019-01-03 14:57:47 -08006282 case AFE_PORT_ID_VA_CODEC_DMA_TX_2:
6283 return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_2;
Mangesh Kunchamwar1274b762018-06-28 15:40:57 +05306284 case AFE_PORT_ID_WSA_CODEC_DMA_RX_0:
6285 return IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_0;
6286 case AFE_PORT_ID_WSA_CODEC_DMA_TX_0:
6287 return IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_0;
6288 case AFE_PORT_ID_WSA_CODEC_DMA_RX_1:
6289 return IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_1;
6290 case AFE_PORT_ID_WSA_CODEC_DMA_TX_1:
6291 return IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_1;
6292 case AFE_PORT_ID_WSA_CODEC_DMA_TX_2:
6293 return IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_2;
Aditya Bavanari54ca7d12018-08-08 13:59:54 +05306294 case AFE_PORT_ID_RX_CODEC_DMA_RX_0:
6295 return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_0;
6296 case AFE_PORT_ID_TX_CODEC_DMA_TX_0:
6297 return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_0;
6298 case AFE_PORT_ID_RX_CODEC_DMA_RX_1:
6299 return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_1;
6300 case AFE_PORT_ID_TX_CODEC_DMA_TX_1:
6301 return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_1;
6302 case AFE_PORT_ID_RX_CODEC_DMA_RX_2:
6303 return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_2;
6304 case AFE_PORT_ID_TX_CODEC_DMA_TX_2:
6305 return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_2;
6306 case AFE_PORT_ID_RX_CODEC_DMA_RX_3:
6307 return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_3;
6308 case AFE_PORT_ID_TX_CODEC_DMA_TX_3:
6309 return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_3;
6310 case AFE_PORT_ID_RX_CODEC_DMA_RX_4:
6311 return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_4;
6312 case AFE_PORT_ID_TX_CODEC_DMA_TX_4:
6313 return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_4;
6314 case AFE_PORT_ID_RX_CODEC_DMA_RX_5:
6315 return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_5;
6316 case AFE_PORT_ID_TX_CODEC_DMA_TX_5:
6317 return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_5;
6318 case AFE_PORT_ID_RX_CODEC_DMA_RX_6:
6319 return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_6;
6320 case AFE_PORT_ID_RX_CODEC_DMA_RX_7:
6321 return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_7;
Surendar Karkad47fda42018-05-20 19:21:10 +05306322 case AFE_LOOPBACK_TX:
6323 return IDX_AFE_LOOPBACK_TX;
Jaideep Sharma39932232020-03-11 22:24:14 +05306324 case RT_PROXY_PORT_002_RX:
6325 return IDX_RT_PROXY_PORT_002_RX;
6326 case RT_PROXY_PORT_002_TX:
6327 return IDX_RT_PROXY_PORT_002_TX;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306328 default:
6329 pr_err("%s: port 0x%x\n", __func__, port_id);
6330 return -EINVAL;
6331 }
6332}
6333
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05306334/**
6335 * afe_open -
6336 * command to open AFE port
6337 *
6338 * @port_id: AFE port id
6339 * @afe_config: AFE port config to pass
6340 * @rate: sample rate
6341 *
6342 * Returns 0 on success or error on failure
6343 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306344int afe_open(u16 port_id,
6345 union afe_port_config *afe_config, int rate)
6346{
6347 struct afe_port_cmd_device_start start;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006348 union afe_port_config port_cfg;
6349 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306350 int ret = 0;
6351 int cfg_type;
6352 int index = 0;
6353
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006354 memset(&param_hdr, 0, sizeof(param_hdr));
6355 memset(&start, 0, sizeof(start));
6356 memset(&port_cfg, 0, sizeof(port_cfg));
6357
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306358 if (!afe_config) {
6359 pr_err("%s: Error, no configuration data\n", __func__);
6360 ret = -EINVAL;
6361 return ret;
6362 }
6363
6364 pr_err("%s: port_id 0x%x rate %d\n", __func__, port_id, rate);
6365
6366 index = q6audio_get_port_index(port_id);
6367 if (index < 0 || index >= AFE_MAX_PORTS) {
6368 pr_err("%s: AFE port index[%d] invalid!\n",
6369 __func__, index);
6370 return -EINVAL;
6371 }
6372 ret = q6audio_validate_port(port_id);
6373 if (ret < 0) {
6374 pr_err("%s: Invalid port 0x%x ret %d", __func__, port_id, ret);
6375 return -EINVAL;
6376 }
6377
6378 if ((port_id == RT_PROXY_DAI_001_RX) ||
6379 (port_id == RT_PROXY_DAI_002_TX)) {
6380 pr_err("%s: wrong port 0x%x\n", __func__, port_id);
6381 return -EINVAL;
6382 }
6383 if ((port_id == RT_PROXY_DAI_002_RX) ||
6384 (port_id == RT_PROXY_DAI_001_TX))
6385 port_id = VIRTUAL_ID_TO_PORTID(port_id);
6386
6387 ret = afe_q6_interface_prepare();
6388 if (ret != 0) {
6389 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
6390 return -EINVAL;
6391 }
6392
6393 if ((index >= 0) && (index < AFE_MAX_PORTS)) {
6394 this_afe.afe_sample_rates[index] = rate;
6395
6396 if (this_afe.rt_cb)
6397 this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id);
6398 }
6399
6400 /* Also send the topology id here: */
6401 afe_send_custom_topology(); /* One time call: only for first time */
6402 afe_send_port_topology_id(port_id);
6403
6404 ret = q6audio_validate_port(port_id);
6405 if (ret < 0) {
6406 pr_err("%s: Failed : Invalid Port id = 0x%x ret %d\n",
6407 __func__, port_id, ret);
6408 return -EINVAL;
6409 }
6410 mutex_lock(&this_afe.afe_cmd_lock);
6411
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306412 switch (port_id) {
6413 case PRIMARY_I2S_RX:
6414 case PRIMARY_I2S_TX:
6415 cfg_type = AFE_PARAM_ID_I2S_CONFIG;
6416 break;
6417 case AFE_PORT_ID_PRIMARY_PCM_RX:
6418 case AFE_PORT_ID_PRIMARY_PCM_TX:
6419 case AFE_PORT_ID_SECONDARY_PCM_RX:
6420 case AFE_PORT_ID_SECONDARY_PCM_TX:
6421 case AFE_PORT_ID_TERTIARY_PCM_RX:
6422 case AFE_PORT_ID_TERTIARY_PCM_TX:
6423 case AFE_PORT_ID_QUATERNARY_PCM_RX:
6424 case AFE_PORT_ID_QUATERNARY_PCM_TX:
Rohit Kumarc08b14f2017-10-06 10:52:17 +05306425 case AFE_PORT_ID_QUINARY_PCM_RX:
6426 case AFE_PORT_ID_QUINARY_PCM_TX:
Dieter Lueckingfa7687b2018-09-28 14:21:44 +02006427 case AFE_PORT_ID_SENARY_PCM_RX:
6428 case AFE_PORT_ID_SENARY_PCM_TX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306429 cfg_type = AFE_PARAM_ID_PCM_CONFIG;
6430 break;
6431 case SECONDARY_I2S_RX:
6432 case SECONDARY_I2S_TX:
6433 case AFE_PORT_ID_PRIMARY_MI2S_RX:
6434 case AFE_PORT_ID_PRIMARY_MI2S_TX:
6435 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
6436 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
6437 case MI2S_RX:
6438 case MI2S_TX:
6439 case AFE_PORT_ID_QUINARY_MI2S_RX:
6440 case AFE_PORT_ID_QUINARY_MI2S_TX:
Karthikeyan Mani3bbd2ee2019-01-30 18:48:56 -08006441 case AFE_PORT_ID_SENARY_MI2S_RX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306442 case AFE_PORT_ID_SENARY_MI2S_TX:
6443 cfg_type = AFE_PARAM_ID_I2S_CONFIG;
6444 break;
Ralf Herz43c0abd2019-07-26 15:12:48 +02006445 case AFE_PORT_ID_PRIMARY_META_MI2S_RX:
6446 case AFE_PORT_ID_SECONDARY_META_MI2S_RX:
6447 cfg_type = AFE_PARAM_ID_META_I2S_CONFIG;
6448 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306449 case HDMI_RX:
Sanjana B63bdc7b2020-01-20 19:31:18 +05306450 case HDMI_RX_MS:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306451 case DISPLAY_PORT_RX:
6452 cfg_type = AFE_PARAM_ID_HDMI_CONFIG;
6453 break;
Ralf Herzcc29b9e2018-07-17 20:19:04 +05306454 case AFE_PORT_ID_PRIMARY_SPDIF_RX:
6455 case AFE_PORT_ID_PRIMARY_SPDIF_TX:
6456 case AFE_PORT_ID_SECONDARY_SPDIF_RX:
6457 case AFE_PORT_ID_SECONDARY_SPDIF_TX:
6458 cfg_type = AFE_PARAM_ID_SPDIF_CONFIG;
6459 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306460 case SLIMBUS_0_RX:
6461 case SLIMBUS_0_TX:
6462 case SLIMBUS_1_RX:
6463 case SLIMBUS_1_TX:
6464 case SLIMBUS_2_RX:
6465 case SLIMBUS_2_TX:
6466 case SLIMBUS_3_RX:
6467 case SLIMBUS_3_TX:
6468 case SLIMBUS_4_RX:
6469 case SLIMBUS_4_TX:
6470 case SLIMBUS_5_RX:
6471 case SLIMBUS_6_RX:
6472 case SLIMBUS_6_TX:
6473 case SLIMBUS_7_RX:
6474 case SLIMBUS_7_TX:
6475 case SLIMBUS_8_RX:
6476 case SLIMBUS_8_TX:
Surendar Karkab0dd21f2018-09-28 18:53:50 +05306477 case SLIMBUS_9_RX:
6478 case SLIMBUS_9_TX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306479 cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG;
6480 break;
6481 case AFE_PORT_ID_USB_RX:
6482 case AFE_PORT_ID_USB_TX:
6483 cfg_type = AFE_PARAM_ID_USB_AUDIO_CONFIG;
6484 break;
Mangesh Kunchamwar8c706ab2018-04-04 17:48:46 +05306485 case AFE_PORT_ID_WSA_CODEC_DMA_RX_0:
6486 case AFE_PORT_ID_WSA_CODEC_DMA_TX_0:
6487 case AFE_PORT_ID_WSA_CODEC_DMA_RX_1:
6488 case AFE_PORT_ID_WSA_CODEC_DMA_TX_1:
6489 case AFE_PORT_ID_WSA_CODEC_DMA_TX_2:
6490 case AFE_PORT_ID_VA_CODEC_DMA_TX_0:
6491 case AFE_PORT_ID_VA_CODEC_DMA_TX_1:
Xiaoyu Ye8341eef2019-01-03 14:57:47 -08006492 case AFE_PORT_ID_VA_CODEC_DMA_TX_2:
Aditya Bavanari348a4a62018-05-16 21:48:45 +05306493 case AFE_PORT_ID_RX_CODEC_DMA_RX_0:
6494 case AFE_PORT_ID_TX_CODEC_DMA_TX_0:
6495 case AFE_PORT_ID_RX_CODEC_DMA_RX_1:
6496 case AFE_PORT_ID_TX_CODEC_DMA_TX_1:
6497 case AFE_PORT_ID_RX_CODEC_DMA_RX_2:
6498 case AFE_PORT_ID_TX_CODEC_DMA_TX_2:
6499 case AFE_PORT_ID_RX_CODEC_DMA_RX_3:
6500 case AFE_PORT_ID_TX_CODEC_DMA_TX_3:
6501 case AFE_PORT_ID_RX_CODEC_DMA_RX_4:
6502 case AFE_PORT_ID_TX_CODEC_DMA_TX_4:
6503 case AFE_PORT_ID_RX_CODEC_DMA_RX_5:
6504 case AFE_PORT_ID_TX_CODEC_DMA_TX_5:
6505 case AFE_PORT_ID_RX_CODEC_DMA_RX_6:
6506 case AFE_PORT_ID_RX_CODEC_DMA_RX_7:
Mangesh Kunchamwar8c706ab2018-04-04 17:48:46 +05306507 cfg_type = AFE_PARAM_ID_CODEC_DMA_CONFIG;
6508 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306509 default:
6510 pr_err("%s: Invalid port id 0x%x\n",
6511 __func__, port_id);
6512 ret = -EINVAL;
6513 goto fail_cmd;
6514 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306515
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006516 param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
6517 param_hdr.instance_id = INSTANCE_ID_0;
6518 param_hdr.param_id = cfg_type;
6519 param_hdr.param_size = sizeof(union afe_port_config);
6520 port_cfg = *afe_config;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306521
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006522 ret = q6afe_pack_and_set_param_in_band(port_id,
6523 q6audio_get_port_index(port_id),
6524 param_hdr, (u8 *) &port_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306525 if (ret) {
6526 pr_err("%s: AFE enable for port 0x%x opcode[0x%x]failed %d\n",
6527 __func__, port_id, cfg_type, ret);
6528 goto fail_cmd;
6529 }
6530 start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
6531 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
6532 start.hdr.pkt_size = sizeof(start);
6533 start.hdr.src_port = 0;
6534 start.hdr.dest_port = 0;
6535 start.hdr.token = index;
6536 start.hdr.opcode = AFE_PORT_CMD_DEVICE_START;
6537 start.port_id = q6audio_get_port_id(port_id);
6538 pr_debug("%s: cmd device start opcode[0x%x] port id[0x%x]\n",
6539 __func__, start.hdr.opcode, start.port_id);
6540
6541 ret = afe_apr_send_pkt(&start, &this_afe.wait[index]);
6542 if (ret) {
6543 pr_err("%s: AFE enable for port 0x%x failed %d\n", __func__,
6544 port_id, ret);
6545 goto fail_cmd;
6546 }
6547
6548fail_cmd:
6549 mutex_unlock(&this_afe.afe_cmd_lock);
6550 return ret;
6551}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05306552EXPORT_SYMBOL(afe_open);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306553
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05306554/**
6555 * afe_loopback -
6556 * command to set loopback between AFE ports
6557 *
6558 * @enable: enable or disable loopback
6559 * @rx_port: AFE RX port ID
6560 * @tx_port: AFE TX port ID
6561 *
6562 * Returns 0 on success or error on failure
6563 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306564int afe_loopback(u16 enable, u16 rx_port, u16 tx_port)
6565{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006566 struct afe_loopback_cfg_v1 lb_param;
6567 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306568 int ret = 0;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006569
6570 memset(&lb_param, 0, sizeof(lb_param));
6571 memset(&param_hdr, 0, sizeof(param_hdr));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306572
6573 if (rx_port == MI2S_RX)
6574 rx_port = AFE_PORT_ID_PRIMARY_MI2S_RX;
6575 if (tx_port == MI2S_TX)
6576 tx_port = AFE_PORT_ID_PRIMARY_MI2S_TX;
6577
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006578 param_hdr.module_id = AFE_MODULE_LOOPBACK;
6579 param_hdr.instance_id = INSTANCE_ID_0;
6580 param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG;
6581 param_hdr.param_size = sizeof(struct afe_loopback_cfg_v1);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306582
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006583 lb_param.dst_port_id = rx_port;
6584 lb_param.routing_mode = LB_MODE_DEFAULT;
6585 lb_param.enable = (enable ? 1 : 0);
6586 lb_param.loopback_cfg_minor_version = AFE_API_VERSION_LOOPBACK_CONFIG;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306587
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006588 ret = q6afe_pack_and_set_param_in_band(tx_port,
6589 q6audio_get_port_index(tx_port),
6590 param_hdr, (u8 *) &lb_param);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306591 if (ret)
6592 pr_err("%s: AFE loopback failed %d\n", __func__, ret);
6593 return ret;
6594}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05306595EXPORT_SYMBOL(afe_loopback);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306596
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05306597/**
6598 * afe_loopback_gain -
6599 * command to set gain for AFE loopback
6600 *
6601 * @port_id: AFE port id
6602 * @volume: gain value to set
6603 *
6604 * Returns 0 on success or error on failure
6605 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306606int afe_loopback_gain(u16 port_id, u16 volume)
6607{
6608 struct afe_loopback_gain_per_path_param set_param;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006609 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306610 int ret = 0;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006611
6612 memset(&set_param, 0, sizeof(set_param));
6613 memset(&param_hdr, 0, sizeof(param_hdr));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306614
6615 if (this_afe.apr == NULL) {
6616 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
6617 0xFFFFFFFF, &this_afe);
6618 pr_debug("%s: Register AFE\n", __func__);
6619 if (this_afe.apr == NULL) {
6620 pr_err("%s: Unable to register AFE\n", __func__);
6621 ret = -ENODEV;
6622 return ret;
6623 }
6624 rtac_set_afe_handle(this_afe.apr);
6625 }
6626
6627 ret = q6audio_validate_port(port_id);
6628 if (ret < 0) {
6629 pr_err("%s: Failed : Invalid Port id = 0x%x ret %d\n",
6630 __func__, port_id, ret);
6631 ret = -EINVAL;
6632 goto fail_cmd;
6633 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306634
6635 /* RX ports numbers are even .TX ports numbers are odd. */
6636 if (port_id % 2 == 0) {
6637 pr_err("%s: Failed : afe loopback gain only for TX ports. port_id %d\n",
6638 __func__, port_id);
6639 ret = -EINVAL;
6640 goto fail_cmd;
6641 }
6642
6643 pr_debug("%s: port 0x%x volume %d\n", __func__, port_id, volume);
6644
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006645 param_hdr.module_id = AFE_MODULE_LOOPBACK;
6646 param_hdr.instance_id = INSTANCE_ID_0;
6647 param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH;
6648 param_hdr.param_size = sizeof(struct afe_loopback_gain_per_path_param);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306649 set_param.rx_port_id = port_id;
6650 set_param.gain = volume;
6651
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006652 ret = q6afe_pack_and_set_param_in_band(port_id,
6653 q6audio_get_port_index(port_id),
6654 param_hdr, (u8 *) &set_param);
6655 if (ret)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306656 pr_err("%s: AFE param set failed for port 0x%x ret %d\n",
6657 __func__, port_id, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306658
6659fail_cmd:
6660 return ret;
6661}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05306662EXPORT_SYMBOL(afe_loopback_gain);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306663
6664int afe_pseudo_port_start_nowait(u16 port_id)
6665{
6666 struct afe_pseudoport_start_command start;
6667 int ret = 0;
6668
6669 pr_debug("%s: port_id=0x%x\n", __func__, port_id);
6670 if (this_afe.apr == NULL) {
6671 pr_err("%s: AFE APR is not registered\n", __func__);
6672 return -ENODEV;
6673 }
6674
6675
6676 start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
6677 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
6678 start.hdr.pkt_size = sizeof(start);
6679 start.hdr.src_port = 0;
6680 start.hdr.dest_port = 0;
6681 start.hdr.token = 0;
6682 start.hdr.opcode = AFE_PSEUDOPORT_CMD_START;
6683 start.port_id = port_id;
6684 start.timing = 1;
6685
6686 ret = afe_apr_send_pkt(&start, NULL);
6687 if (ret) {
6688 pr_err("%s: AFE enable for port 0x%x failed %d\n",
6689 __func__, port_id, ret);
6690 return ret;
6691 }
6692 return 0;
6693}
6694
6695int afe_start_pseudo_port(u16 port_id)
6696{
6697 int ret = 0;
6698 struct afe_pseudoport_start_command start;
6699 int index = 0;
6700
6701 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
6702
6703 ret = afe_q6_interface_prepare();
6704 if (ret != 0) {
6705 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
6706 return ret;
6707 }
6708
6709 index = q6audio_get_port_index(port_id);
6710 if (index < 0 || index >= AFE_MAX_PORTS) {
6711 pr_err("%s: AFE port index[%d] invalid!\n",
6712 __func__, index);
6713 return -EINVAL;
6714 }
6715 ret = q6audio_validate_port(port_id);
6716 if (ret < 0) {
6717 pr_err("%s: Invalid port 0x%x ret %d",
6718 __func__, port_id, ret);
6719 return -EINVAL;
6720 }
6721
6722 start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
6723 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
6724 start.hdr.pkt_size = sizeof(start);
6725 start.hdr.src_port = 0;
6726 start.hdr.dest_port = 0;
6727 start.hdr.token = 0;
6728 start.hdr.opcode = AFE_PSEUDOPORT_CMD_START;
6729 start.port_id = port_id;
6730 start.timing = 1;
6731 start.hdr.token = index;
6732
6733 ret = afe_apr_send_pkt(&start, &this_afe.wait[index]);
6734 if (ret)
6735 pr_err("%s: AFE enable for port 0x%x failed %d\n",
6736 __func__, port_id, ret);
6737 return ret;
6738}
6739
6740int afe_pseudo_port_stop_nowait(u16 port_id)
6741{
6742 int ret = 0;
6743 struct afe_pseudoport_stop_command stop;
6744 int index = 0;
6745
6746 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
6747
6748 if (this_afe.apr == NULL) {
6749 pr_err("%s: AFE is already closed\n", __func__);
6750 return -EINVAL;
6751 }
6752 index = q6audio_get_port_index(port_id);
6753 if (index < 0 || index >= AFE_MAX_PORTS) {
6754 pr_err("%s: AFE port index[%d] invalid!\n",
6755 __func__, index);
6756 return -EINVAL;
6757 }
6758 ret = q6audio_validate_port(port_id);
6759 if (ret < 0) {
6760 pr_err("%s: Invalid port 0x%x ret %d",
6761 __func__, port_id, ret);
6762 return -EINVAL;
6763 }
6764
6765 stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
6766 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
6767 stop.hdr.pkt_size = sizeof(stop);
6768 stop.hdr.src_port = 0;
6769 stop.hdr.dest_port = 0;
6770 stop.hdr.token = 0;
6771 stop.hdr.opcode = AFE_PSEUDOPORT_CMD_STOP;
6772 stop.port_id = port_id;
6773 stop.reserved = 0;
6774 stop.hdr.token = index;
6775
6776 ret = afe_apr_send_pkt(&stop, NULL);
6777 if (ret)
6778 pr_err("%s: AFE close failed %d\n", __func__, ret);
6779
6780 return ret;
6781}
6782
6783int afe_port_group_set_param(u16 group_id,
6784 union afe_port_group_config *afe_group_config)
6785{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006786 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306787 int cfg_type;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006788 int ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306789
6790 if (!afe_group_config) {
6791 pr_err("%s: Error, no configuration data\n", __func__);
6792 return -EINVAL;
6793 }
6794
6795 pr_debug("%s: group id: 0x%x\n", __func__, group_id);
6796
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006797 memset(&param_hdr, 0, sizeof(param_hdr));
6798
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306799 ret = afe_q6_interface_prepare();
6800 if (ret != 0) {
6801 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
6802 return ret;
6803 }
6804
6805 switch (group_id) {
6806 case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX:
6807 case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX:
6808 case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_RX:
6809 case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_TX:
6810 case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_RX:
6811 case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_TX:
6812 case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_RX:
6813 case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_TX:
Rohit Kumarc08b14f2017-10-06 10:52:17 +05306814 case AFE_GROUP_DEVICE_ID_QUINARY_TDM_RX:
6815 case AFE_GROUP_DEVICE_ID_QUINARY_TDM_TX:
Karthikeyan Mani3bbd2ee2019-01-30 18:48:56 -08006816 case AFE_GROUP_DEVICE_ID_SENARY_TDM_RX:
6817 case AFE_GROUP_DEVICE_ID_SENARY_TDM_TX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306818 cfg_type = AFE_PARAM_ID_GROUP_DEVICE_TDM_CONFIG;
6819 break;
6820 default:
6821 pr_err("%s: Invalid group id 0x%x\n", __func__, group_id);
6822 return -EINVAL;
6823 }
6824
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006825 param_hdr.module_id = AFE_MODULE_GROUP_DEVICE;
6826 param_hdr.instance_id = INSTANCE_ID_0;
6827 param_hdr.param_id = cfg_type;
6828 param_hdr.param_size = sizeof(union afe_port_group_config);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306829
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006830 ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
6831 (u8 *) afe_group_config);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306832 if (ret)
6833 pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_CFG failed %d\n",
6834 __func__, ret);
6835
6836 return ret;
6837}
6838
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05306839/**
Cong Tangb84eea32019-02-26 15:14:28 +08006840 * afe_port_tdm_lane_config -
6841 * to configure group TDM lane mask with specified configuration
6842 *
6843 * @group_id: AFE group id number
6844 * @lane_cfg: TDM lane mask configutation
6845 *
6846 * Returns 0 on success or error value on failure.
6847 */
6848static int afe_port_tdm_lane_config(u16 group_id,
6849 struct afe_param_id_tdm_lane_cfg *lane_cfg)
6850{
6851 struct param_hdr_v3 param_hdr;
6852 int ret = 0;
6853
6854 if (lane_cfg == NULL ||
6855 lane_cfg->lane_mask == AFE_LANE_MASK_INVALID) {
6856 pr_debug("%s: lane cfg not supported for group id: 0x%x\n",
6857 __func__, group_id);
6858 return ret;
6859 }
6860
6861 pr_debug("%s: group id: 0x%x lane mask 0x%x\n", __func__,
6862 group_id, lane_cfg->lane_mask);
6863
6864 memset(&param_hdr, 0, sizeof(param_hdr));
6865
6866 ret = afe_q6_interface_prepare();
6867 if (ret != 0) {
6868 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
6869 return ret;
6870 }
6871
6872 param_hdr.module_id = AFE_MODULE_GROUP_DEVICE;
6873 param_hdr.instance_id = INSTANCE_ID_0;
6874 param_hdr.param_id = AFE_PARAM_ID_TDM_LANE_CONFIG;
6875 param_hdr.param_size = sizeof(struct afe_param_id_tdm_lane_cfg);
6876
6877 ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
6878 (u8 *)lane_cfg);
6879 if (ret)
6880 pr_err("%s: AFE_PARAM_ID_TDM_LANE_CONFIG failed %d\n",
6881 __func__, ret);
6882
6883 return ret;
6884}
6885
6886/**
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05306887 * afe_port_group_enable -
6888 * command to enable AFE port group
6889 *
6890 * @group_id: group ID for AFE port group
6891 * @afe_group_config: config for AFE group
6892 * @enable: flag to indicate enable or disable
Cong Tangb84eea32019-02-26 15:14:28 +08006893 * @lane_cfg: TDM lane mask configutation
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05306894 *
6895 * Returns 0 on success or error on failure
6896 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306897int afe_port_group_enable(u16 group_id,
6898 union afe_port_group_config *afe_group_config,
Cong Tangb84eea32019-02-26 15:14:28 +08006899 u16 enable,
6900 struct afe_param_id_tdm_lane_cfg *lane_cfg)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306901{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006902 struct afe_group_device_enable group_enable;
6903 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306904 int ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306905
6906 pr_debug("%s: group id: 0x%x enable: %d\n", __func__,
6907 group_id, enable);
6908
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006909 memset(&group_enable, 0, sizeof(group_enable));
6910 memset(&param_hdr, 0, sizeof(param_hdr));
6911
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306912 ret = afe_q6_interface_prepare();
6913 if (ret != 0) {
6914 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
6915 return ret;
6916 }
6917
6918 if (enable) {
6919 ret = afe_port_group_set_param(group_id, afe_group_config);
6920 if (ret < 0) {
6921 pr_err("%s: afe send failed %d\n", __func__, ret);
6922 return ret;
6923 }
Cong Tangb84eea32019-02-26 15:14:28 +08006924 ret = afe_port_tdm_lane_config(group_id, lane_cfg);
6925 if (ret < 0) {
6926 pr_err("%s: afe send lane config failed %d\n",
6927 __func__, ret);
6928 return ret;
6929 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306930 }
6931
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006932 param_hdr.module_id = AFE_MODULE_GROUP_DEVICE;
6933 param_hdr.instance_id = INSTANCE_ID_0;
6934 param_hdr.param_id = AFE_PARAM_ID_GROUP_DEVICE_ENABLE;
6935 param_hdr.param_size = sizeof(struct afe_group_device_enable);
6936 group_enable.group_id = group_id;
6937 group_enable.enable = enable;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306938
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08006939 ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
6940 (u8 *) &group_enable);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306941 if (ret)
6942 pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_ENABLE failed %d\n",
6943 __func__, ret);
6944
6945 return ret;
6946}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05306947EXPORT_SYMBOL(afe_port_group_enable);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306948
6949int afe_stop_pseudo_port(u16 port_id)
6950{
6951 int ret = 0;
6952 struct afe_pseudoport_stop_command stop;
6953 int index = 0;
6954
6955 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
6956
6957 if (this_afe.apr == NULL) {
6958 pr_err("%s: AFE is already closed\n", __func__);
6959 return -EINVAL;
6960 }
6961
6962 index = q6audio_get_port_index(port_id);
6963 if (index < 0 || index >= AFE_MAX_PORTS) {
6964 pr_err("%s: AFE port index[%d] invalid!\n",
6965 __func__, index);
6966 return -EINVAL;
6967 }
6968 ret = q6audio_validate_port(port_id);
6969 if (ret < 0) {
6970 pr_err("%s: Invalid port 0x%x ret %d\n",
6971 __func__, port_id, ret);
6972 return -EINVAL;
6973 }
6974
6975 stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
6976 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
6977 stop.hdr.pkt_size = sizeof(stop);
6978 stop.hdr.src_port = 0;
6979 stop.hdr.dest_port = 0;
6980 stop.hdr.token = 0;
6981 stop.hdr.opcode = AFE_PSEUDOPORT_CMD_STOP;
6982 stop.port_id = port_id;
6983 stop.reserved = 0;
6984 stop.hdr.token = index;
6985
6986 ret = afe_apr_send_pkt(&stop, &this_afe.wait[index]);
6987 if (ret)
6988 pr_err("%s: AFE close failed %d\n", __func__, ret);
6989
6990 return ret;
6991}
6992
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05306993/**
6994 * afe_req_mmap_handle -
6995 * Retrieve AFE memory map handle
6996 *
6997 * @ac: AFE audio client
6998 *
6999 * Returns memory map handle
7000 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307001uint32_t afe_req_mmap_handle(struct afe_audio_client *ac)
7002{
7003 return ac->mem_map_handle;
7004}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307005EXPORT_SYMBOL(afe_req_mmap_handle);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307006
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307007/**
7008 * q6afe_audio_client_alloc -
7009 * Assign new AFE audio client
7010 *
7011 * @priv: privata data to hold for audio client
7012 *
7013 * Returns ac pointer on success or NULL on failure
7014 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307015struct afe_audio_client *q6afe_audio_client_alloc(void *priv)
7016{
7017 struct afe_audio_client *ac;
7018 int lcnt = 0;
7019
7020 ac = kzalloc(sizeof(struct afe_audio_client), GFP_KERNEL);
7021 if (!ac)
7022 return NULL;
7023
7024 ac->priv = priv;
7025
7026 init_waitqueue_head(&ac->cmd_wait);
7027 INIT_LIST_HEAD(&ac->port[0].mem_map_handle);
7028 INIT_LIST_HEAD(&ac->port[1].mem_map_handle);
7029 pr_debug("%s: mem_map_handle list init'ed\n", __func__);
7030 mutex_init(&ac->cmd_lock);
7031 for (lcnt = 0; lcnt <= OUT; lcnt++) {
7032 mutex_init(&ac->port[lcnt].lock);
7033 spin_lock_init(&ac->port[lcnt].dsp_lock);
7034 }
7035 atomic_set(&ac->cmd_state, 0);
7036
7037 return ac;
7038}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307039EXPORT_SYMBOL(q6afe_audio_client_alloc);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307040
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307041/**
7042 * q6afe_audio_client_buf_alloc_contiguous -
7043 * Allocate contiguous shared buffers
7044 *
7045 * @dir: RX or TX direction of AFE port
7046 * @ac: AFE audio client handle
7047 * @bufsz: size of each shared buffer
7048 * @bufcnt: number of buffers
7049 *
7050 * Returns 0 on success or error on failure
7051 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307052int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir,
7053 struct afe_audio_client *ac,
7054 unsigned int bufsz,
7055 unsigned int bufcnt)
7056{
7057 int cnt = 0;
7058 int rc = 0;
7059 struct afe_audio_buffer *buf;
7060 size_t len;
7061
7062 if (!(ac) || ((dir != IN) && (dir != OUT))) {
7063 pr_err("%s: ac %pK dir %d\n", __func__, ac, dir);
7064 return -EINVAL;
7065 }
7066
7067 pr_debug("%s: bufsz[%d]bufcnt[%d]\n",
7068 __func__,
7069 bufsz, bufcnt);
7070
7071 if (ac->port[dir].buf) {
7072 pr_debug("%s: buffer already allocated\n", __func__);
7073 return 0;
7074 }
7075 mutex_lock(&ac->cmd_lock);
7076 buf = kzalloc(((sizeof(struct afe_audio_buffer))*bufcnt),
7077 GFP_KERNEL);
7078
7079 if (!buf) {
7080 pr_err("%s: null buf\n", __func__);
7081 mutex_unlock(&ac->cmd_lock);
7082 goto fail;
7083 }
7084
7085 ac->port[dir].buf = buf;
7086
Banajit Goswami08bb7362017-11-03 22:48:23 -07007087 rc = msm_audio_ion_alloc(&buf[0].dma_buf,
7088 bufsz * bufcnt,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307089 &buf[0].phys, &len,
7090 &buf[0].data);
7091 if (rc) {
7092 pr_err("%s: audio ION alloc failed, rc = %d\n",
7093 __func__, rc);
7094 mutex_unlock(&ac->cmd_lock);
7095 goto fail;
7096 }
7097
7098 buf[0].used = dir ^ 1;
7099 buf[0].size = bufsz;
7100 buf[0].actual_size = bufsz;
7101 cnt = 1;
7102 while (cnt < bufcnt) {
7103 if (bufsz > 0) {
7104 buf[cnt].data = buf[0].data + (cnt * bufsz);
7105 buf[cnt].phys = buf[0].phys + (cnt * bufsz);
7106 if (!buf[cnt].data) {
7107 pr_err("%s: Buf alloc failed\n",
7108 __func__);
7109 mutex_unlock(&ac->cmd_lock);
7110 goto fail;
7111 }
7112 buf[cnt].used = dir ^ 1;
7113 buf[cnt].size = bufsz;
7114 buf[cnt].actual_size = bufsz;
7115 pr_debug("%s: data[%pK]phys[%pK][%pK]\n", __func__,
7116 buf[cnt].data,
7117 &buf[cnt].phys,
7118 &buf[cnt].phys);
7119 }
7120 cnt++;
7121 }
7122 ac->port[dir].max_buf_cnt = cnt;
7123 mutex_unlock(&ac->cmd_lock);
7124 return 0;
7125fail:
7126 pr_err("%s: jump fail\n", __func__);
7127 q6afe_audio_client_buf_free_contiguous(dir, ac);
7128 return -EINVAL;
7129}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307130EXPORT_SYMBOL(q6afe_audio_client_buf_alloc_contiguous);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307131
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307132/**
7133 * afe_memory_map -
7134 * command to map shared buffers to AFE
7135 *
7136 * @dma_addr_p: DMA physical address
7137 * @dma_buf_sz: shared DMA buffer size
7138 * @ac: AFE audio client handle
7139 *
7140 * Returns 0 on success or error on failure
7141 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307142int afe_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz,
7143 struct afe_audio_client *ac)
7144{
7145 int ret = 0;
7146
7147 mutex_lock(&this_afe.afe_cmd_lock);
7148 ac->mem_map_handle = 0;
7149 ret = afe_cmd_memory_map(dma_addr_p, dma_buf_sz);
7150 if (ret < 0) {
7151 pr_err("%s: afe_cmd_memory_map failed %d\n",
7152 __func__, ret);
7153
7154 mutex_unlock(&this_afe.afe_cmd_lock);
7155 return ret;
7156 }
7157 ac->mem_map_handle = this_afe.mmap_handle;
7158 mutex_unlock(&this_afe.afe_cmd_lock);
7159
7160 return ret;
7161}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307162EXPORT_SYMBOL(afe_memory_map);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307163
7164int afe_cmd_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz)
7165{
7166 int ret = 0;
7167 int cmd_size = 0;
7168 void *payload = NULL;
7169 void *mmap_region_cmd = NULL;
7170 struct afe_service_cmd_shared_mem_map_regions *mregion = NULL;
7171 struct afe_service_shared_map_region_payload *mregion_pl = NULL;
7172 int index = 0;
7173
7174 pr_debug("%s:\n", __func__);
7175
7176 if (this_afe.apr == NULL) {
7177 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
7178 0xFFFFFFFF, &this_afe);
7179 pr_debug("%s: Register AFE\n", __func__);
7180 if (this_afe.apr == NULL) {
7181 pr_err("%s: Unable to register AFE\n", __func__);
7182 ret = -ENODEV;
7183 return ret;
7184 }
7185 rtac_set_afe_handle(this_afe.apr);
7186 }
7187 if (dma_buf_sz % SZ_4K != 0) {
7188 /*
7189 * The memory allocated by msm_audio_ion_alloc is always 4kB
7190 * aligned, ADSP expects the size to be 4kB aligned as well
7191 * so re-adjusts the buffer size before passing to ADSP.
7192 */
7193 dma_buf_sz = PAGE_ALIGN(dma_buf_sz);
7194 }
7195
7196 cmd_size = sizeof(struct afe_service_cmd_shared_mem_map_regions)
7197 + sizeof(struct afe_service_shared_map_region_payload);
7198
7199 mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL);
7200 if (!mmap_region_cmd)
7201 return -ENOMEM;
7202
7203 mregion = (struct afe_service_cmd_shared_mem_map_regions *)
7204 mmap_region_cmd;
7205 mregion->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7206 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
7207 mregion->hdr.pkt_size = cmd_size;
7208 mregion->hdr.src_port = 0;
7209 mregion->hdr.dest_port = 0;
7210 mregion->hdr.token = 0;
7211 mregion->hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS;
7212 mregion->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL;
7213 mregion->num_regions = 1;
7214 mregion->property_flag = 0x00;
7215 /* Todo */
7216 index = mregion->hdr.token = IDX_RSVD_2;
7217
7218 payload = ((u8 *) mmap_region_cmd +
7219 sizeof(struct afe_service_cmd_shared_mem_map_regions));
7220
7221 mregion_pl = (struct afe_service_shared_map_region_payload *)payload;
7222
7223 mregion_pl->shm_addr_lsw = lower_32_bits(dma_addr_p);
7224 mregion_pl->shm_addr_msw = msm_audio_populate_upper_32_bits(dma_addr_p);
7225 mregion_pl->mem_size_bytes = dma_buf_sz;
7226
7227 pr_debug("%s: dma_addr_p 0x%pK , size %d\n", __func__,
7228 &dma_addr_p, dma_buf_sz);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307229 this_afe.mmap_handle = 0;
Aditya Bavanarid6546e32019-10-29 17:24:59 +05307230 ret = afe_apr_send_pkt((uint32_t *) mmap_region_cmd,
7231 &this_afe.wait[index]);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307232 kfree(mmap_region_cmd);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307233 return ret;
7234}
7235
7236int afe_cmd_memory_map_nowait(int port_id, phys_addr_t dma_addr_p,
7237 u32 dma_buf_sz)
7238{
7239 int ret = 0;
7240 int cmd_size = 0;
7241 void *payload = NULL;
7242 void *mmap_region_cmd = NULL;
7243 struct afe_service_cmd_shared_mem_map_regions *mregion = NULL;
7244 struct afe_service_shared_map_region_payload *mregion_pl = NULL;
7245 int index = 0;
7246
7247 pr_debug("%s:\n", __func__);
7248
7249 if (this_afe.apr == NULL) {
7250 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
7251 0xFFFFFFFF, &this_afe);
7252 pr_debug("%s: Register AFE\n", __func__);
7253 if (this_afe.apr == NULL) {
7254 pr_err("%s: Unable to register AFE\n", __func__);
7255 ret = -ENODEV;
7256 return ret;
7257 }
7258 rtac_set_afe_handle(this_afe.apr);
7259 }
7260 index = q6audio_get_port_index(port_id);
7261 if (index < 0 || index >= AFE_MAX_PORTS) {
7262 pr_err("%s: AFE port index[%d] invalid!\n",
7263 __func__, index);
7264 return -EINVAL;
7265 }
7266 ret = q6audio_validate_port(port_id);
7267 if (ret < 0) {
7268 pr_err("%s: Invalid port 0x%x ret %d",
7269 __func__, port_id, ret);
7270 return -EINVAL;
7271 }
7272
7273 cmd_size = sizeof(struct afe_service_cmd_shared_mem_map_regions)
7274 + sizeof(struct afe_service_shared_map_region_payload);
7275
7276 mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL);
7277 if (!mmap_region_cmd)
7278 return -ENOMEM;
7279
7280 mregion = (struct afe_service_cmd_shared_mem_map_regions *)
7281 mmap_region_cmd;
7282 mregion->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7283 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
7284 mregion->hdr.pkt_size = sizeof(mregion);
7285 mregion->hdr.src_port = 0;
7286 mregion->hdr.dest_port = 0;
7287 mregion->hdr.token = 0;
7288 mregion->hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS;
7289 mregion->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL;
7290 mregion->num_regions = 1;
7291 mregion->property_flag = 0x00;
7292
7293 payload = ((u8 *) mmap_region_cmd +
7294 sizeof(struct afe_service_cmd_shared_mem_map_regions));
7295 mregion_pl = (struct afe_service_shared_map_region_payload *)payload;
7296
7297 mregion_pl->shm_addr_lsw = lower_32_bits(dma_addr_p);
7298 mregion_pl->shm_addr_msw = msm_audio_populate_upper_32_bits(dma_addr_p);
7299 mregion_pl->mem_size_bytes = dma_buf_sz;
7300
7301 ret = afe_apr_send_pkt(mmap_region_cmd, NULL);
7302 if (ret)
7303 pr_err("%s: AFE memory map cmd failed %d\n",
7304 __func__, ret);
7305 kfree(mmap_region_cmd);
7306 return ret;
7307}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307308
7309/**
7310 * q6afe_audio_client_buf_free_contiguous -
7311 * frees the shared contiguous memory
7312 *
7313 * @dir: RX or TX direction of port
7314 * @ac: AFE audio client handle
7315 *
7316 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307317int q6afe_audio_client_buf_free_contiguous(unsigned int dir,
7318 struct afe_audio_client *ac)
7319{
7320 struct afe_audio_port_data *port;
7321 int cnt = 0;
7322
7323 mutex_lock(&ac->cmd_lock);
7324 port = &ac->port[dir];
7325 if (!port->buf) {
7326 pr_err("%s: buf is null\n", __func__);
7327 mutex_unlock(&ac->cmd_lock);
7328 return 0;
7329 }
7330 cnt = port->max_buf_cnt - 1;
7331
7332 if (port->buf[0].data) {
Banajit Goswami08bb7362017-11-03 22:48:23 -07007333 pr_debug("%s: data[%pK], phys[%pK], dma_buf[%pK]\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307334 __func__,
7335 port->buf[0].data,
7336 &port->buf[0].phys,
Banajit Goswami08bb7362017-11-03 22:48:23 -07007337 port->buf[0].dma_buf);
7338 msm_audio_ion_free(port->buf[0].dma_buf);
7339 port->buf[0].dma_buf = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307340 }
7341
7342 while (cnt >= 0) {
7343 port->buf[cnt].data = NULL;
7344 port->buf[cnt].phys = 0;
7345 cnt--;
7346 }
7347 port->max_buf_cnt = 0;
7348 kfree(port->buf);
7349 port->buf = NULL;
7350 mutex_unlock(&ac->cmd_lock);
7351 return 0;
7352}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307353EXPORT_SYMBOL(q6afe_audio_client_buf_free_contiguous);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307354
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307355/**
7356 * q6afe_audio_client_free -
7357 * frees the audio client from AFE
7358 *
7359 * @ac: AFE audio client handle
7360 *
7361 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307362void q6afe_audio_client_free(struct afe_audio_client *ac)
7363{
7364 int loopcnt;
7365 struct afe_audio_port_data *port;
7366
7367 if (!ac) {
7368 pr_err("%s: audio client is NULL\n", __func__);
7369 return;
7370 }
7371 for (loopcnt = 0; loopcnt <= OUT; loopcnt++) {
7372 port = &ac->port[loopcnt];
7373 if (!port->buf)
7374 continue;
7375 pr_debug("%s: loopcnt = %d\n", __func__, loopcnt);
7376 q6afe_audio_client_buf_free_contiguous(loopcnt, ac);
7377 }
7378 kfree(ac);
7379}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307380EXPORT_SYMBOL(q6afe_audio_client_free);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307381
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307382/**
7383 * afe_cmd_memory_unmap -
7384 * command to unmap memory for AFE shared buffer
7385 *
7386 * @mem_map_handle: memory map handle to be unmapped
7387 *
7388 * Returns 0 on success or error on failure
7389 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307390int afe_cmd_memory_unmap(u32 mem_map_handle)
7391{
7392 int ret = 0;
7393 struct afe_service_cmd_shared_mem_unmap_regions mregion;
7394 int index = 0;
7395
7396 pr_debug("%s: handle 0x%x\n", __func__, mem_map_handle);
7397
7398 if (this_afe.apr == NULL) {
7399 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
7400 0xFFFFFFFF, &this_afe);
7401 pr_debug("%s: Register AFE\n", __func__);
7402 if (this_afe.apr == NULL) {
7403 pr_err("%s: Unable to register AFE\n", __func__);
7404 ret = -ENODEV;
7405 return ret;
7406 }
7407 rtac_set_afe_handle(this_afe.apr);
7408 }
7409
7410 mregion.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7411 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
7412 mregion.hdr.pkt_size = sizeof(mregion);
7413 mregion.hdr.src_port = 0;
7414 mregion.hdr.dest_port = 0;
7415 mregion.hdr.token = 0;
7416 mregion.hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_UNMAP_REGIONS;
7417 mregion.mem_map_handle = mem_map_handle;
7418
7419 /* Todo */
7420 index = mregion.hdr.token = IDX_RSVD_2;
7421
7422 atomic_set(&this_afe.status, 0);
7423 ret = afe_apr_send_pkt(&mregion, &this_afe.wait[index]);
7424 if (ret)
7425 pr_err("%s: AFE memory unmap cmd failed %d\n",
7426 __func__, ret);
7427
7428 return ret;
7429}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307430EXPORT_SYMBOL(afe_cmd_memory_unmap);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307431
7432int afe_cmd_memory_unmap_nowait(u32 mem_map_handle)
7433{
7434 int ret = 0;
7435 struct afe_service_cmd_shared_mem_unmap_regions mregion;
7436
7437 pr_debug("%s: handle 0x%x\n", __func__, mem_map_handle);
7438
7439 if (this_afe.apr == NULL) {
7440 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
7441 0xFFFFFFFF, &this_afe);
7442 pr_debug("%s: Register AFE\n", __func__);
7443 if (this_afe.apr == NULL) {
7444 pr_err("%s: Unable to register AFE\n", __func__);
7445 ret = -ENODEV;
7446 return ret;
7447 }
7448 rtac_set_afe_handle(this_afe.apr);
7449 }
7450
7451 mregion.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7452 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
7453 mregion.hdr.pkt_size = sizeof(mregion);
7454 mregion.hdr.src_port = 0;
7455 mregion.hdr.dest_port = 0;
7456 mregion.hdr.token = 0;
7457 mregion.hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_UNMAP_REGIONS;
7458 mregion.mem_map_handle = mem_map_handle;
7459
7460 ret = afe_apr_send_pkt(&mregion, NULL);
7461 if (ret)
7462 pr_err("%s: AFE memory unmap cmd failed %d\n",
7463 __func__, ret);
7464 return ret;
7465}
7466
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307467/**
7468 * afe_register_get_events -
7469 * register for events from proxy port
7470 *
7471 * @port_id: Port ID to register events
7472 * @cb: callback function to invoke for events from proxy port
7473 * @private_data: private data to sent back in callback fn
7474 *
7475 * Returns 0 on success or error on failure
7476 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307477int afe_register_get_events(u16 port_id,
7478 void (*cb)(uint32_t opcode,
7479 uint32_t token, uint32_t *payload, void *priv),
7480 void *private_data)
7481{
7482 int ret = 0;
7483 struct afe_service_cmd_register_rt_port_driver rtproxy;
7484
7485 pr_debug("%s: port_id: 0x%x\n", __func__, port_id);
7486
7487 if (this_afe.apr == NULL) {
7488 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
7489 0xFFFFFFFF, &this_afe);
7490 pr_debug("%s: Register AFE\n", __func__);
7491 if (this_afe.apr == NULL) {
7492 pr_err("%s: Unable to register AFE\n", __func__);
7493 ret = -ENODEV;
7494 return ret;
7495 }
7496 rtac_set_afe_handle(this_afe.apr);
7497 }
7498 if ((port_id == RT_PROXY_DAI_002_RX) ||
7499 (port_id == RT_PROXY_DAI_001_TX)) {
7500 port_id = VIRTUAL_ID_TO_PORTID(port_id);
7501 } else {
7502 pr_err("%s: wrong port id 0x%x\n", __func__, port_id);
7503 return -EINVAL;
7504 }
7505
7506 if (port_id == RT_PROXY_PORT_001_TX) {
7507 this_afe.tx_cb = cb;
7508 this_afe.tx_private_data = private_data;
7509 } else if (port_id == RT_PROXY_PORT_001_RX) {
7510 this_afe.rx_cb = cb;
7511 this_afe.rx_private_data = private_data;
7512 }
7513
7514 rtproxy.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7515 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
7516 rtproxy.hdr.pkt_size = sizeof(rtproxy);
7517 rtproxy.hdr.src_port = 1;
7518 rtproxy.hdr.dest_port = 1;
7519 rtproxy.hdr.opcode = AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER;
7520 rtproxy.port_id = port_id;
7521 rtproxy.reserved = 0;
7522
7523 ret = afe_apr_send_pkt(&rtproxy, NULL);
7524 if (ret)
7525 pr_err("%s: AFE reg. rtproxy_event failed %d\n",
7526 __func__, ret);
7527 return ret;
7528}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307529EXPORT_SYMBOL(afe_register_get_events);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307530
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307531/**
7532 * afe_unregister_get_events -
7533 * unregister for events from proxy port
7534 *
7535 * @port_id: Port ID to unregister events
7536 *
7537 * Returns 0 on success or error on failure
7538 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307539int afe_unregister_get_events(u16 port_id)
7540{
7541 int ret = 0;
7542 struct afe_service_cmd_unregister_rt_port_driver rtproxy;
7543 int index = 0;
7544
7545 pr_debug("%s:\n", __func__);
7546
7547 if (this_afe.apr == NULL) {
7548 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
7549 0xFFFFFFFF, &this_afe);
7550 pr_debug("%s: Register AFE\n", __func__);
7551 if (this_afe.apr == NULL) {
7552 pr_err("%s: Unable to register AFE\n", __func__);
7553 ret = -ENODEV;
7554 return ret;
7555 }
7556 rtac_set_afe_handle(this_afe.apr);
7557 }
7558
7559 if ((port_id == RT_PROXY_DAI_002_RX) ||
7560 (port_id == RT_PROXY_DAI_001_TX)) {
7561 port_id = VIRTUAL_ID_TO_PORTID(port_id);
7562 } else {
7563 pr_err("%s: wrong port id 0x%x\n", __func__, port_id);
7564 return -EINVAL;
7565 }
7566
7567 index = q6audio_get_port_index(port_id);
7568 if (index < 0 || index >= AFE_MAX_PORTS) {
7569 pr_err("%s: AFE port index[%d] invalid!\n",
7570 __func__, index);
7571 return -EINVAL;
7572 }
7573 ret = q6audio_validate_port(port_id);
7574 if (ret < 0) {
7575 pr_err("%s: Invalid port 0x%x ret %d", __func__, port_id, ret);
7576 return -EINVAL;
7577 }
7578
7579 rtproxy.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7580 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
7581 rtproxy.hdr.pkt_size = sizeof(rtproxy);
7582 rtproxy.hdr.src_port = 0;
7583 rtproxy.hdr.dest_port = 0;
7584 rtproxy.hdr.token = 0;
7585 rtproxy.hdr.opcode = AFE_SERVICE_CMD_UNREGISTER_RT_PORT_DRIVER;
7586 rtproxy.port_id = port_id;
7587 rtproxy.reserved = 0;
7588
7589 rtproxy.hdr.token = index;
7590
7591 if (port_id == RT_PROXY_PORT_001_TX) {
7592 this_afe.tx_cb = NULL;
7593 this_afe.tx_private_data = NULL;
7594 } else if (port_id == RT_PROXY_PORT_001_RX) {
7595 this_afe.rx_cb = NULL;
7596 this_afe.rx_private_data = NULL;
7597 }
7598
7599 ret = afe_apr_send_pkt(&rtproxy, &this_afe.wait[index]);
7600 if (ret)
7601 pr_err("%s: AFE enable Unreg. rtproxy_event failed %d\n",
7602 __func__, ret);
7603 return ret;
7604}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307605EXPORT_SYMBOL(afe_unregister_get_events);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307606
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307607/**
7608 * afe_rt_proxy_port_write -
7609 * command for AFE RT proxy port write
7610 *
7611 * @buf_addr_p: Physical buffer address with
7612 * playback data to proxy port
7613 * @mem_map_handle: memory map handle of write buffer
7614 * @bytes: number of bytes to write
7615 *
7616 * Returns 0 on success or error on failure
7617 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307618int afe_rt_proxy_port_write(phys_addr_t buf_addr_p,
7619 u32 mem_map_handle, int bytes)
7620{
7621 int ret = 0;
7622 struct afe_port_data_cmd_rt_proxy_port_write_v2 afecmd_wr;
7623
7624 if (this_afe.apr == NULL) {
7625 pr_err("%s: register to AFE is not done\n", __func__);
7626 ret = -ENODEV;
7627 return ret;
7628 }
7629 pr_debug("%s: buf_addr_p = 0x%pK bytes = %d\n", __func__,
7630 &buf_addr_p, bytes);
7631
7632 afecmd_wr.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7633 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
7634 afecmd_wr.hdr.pkt_size = sizeof(afecmd_wr);
7635 afecmd_wr.hdr.src_port = 0;
7636 afecmd_wr.hdr.dest_port = 0;
7637 afecmd_wr.hdr.token = 0;
7638 afecmd_wr.hdr.opcode = AFE_PORT_DATA_CMD_RT_PROXY_PORT_WRITE_V2;
7639 afecmd_wr.port_id = RT_PROXY_PORT_001_TX;
7640 afecmd_wr.buffer_address_lsw = lower_32_bits(buf_addr_p);
7641 afecmd_wr.buffer_address_msw =
7642 msm_audio_populate_upper_32_bits(buf_addr_p);
7643 afecmd_wr.mem_map_handle = mem_map_handle;
7644 afecmd_wr.available_bytes = bytes;
7645 afecmd_wr.reserved = 0;
7646
Aditya Bavanarid6546e32019-10-29 17:24:59 +05307647 /*
7648 * Do not call afe_apr_send_pkt() here as it acquires
7649 * a mutex lock inside and this function gets called in
7650 * interrupt context leading to scheduler crash
7651 */
7652 atomic_set(&this_afe.status, 0);
7653 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &afecmd_wr);
7654 if (ret < 0) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307655 pr_err("%s: AFE rtproxy write to port 0x%x failed %d\n",
Aditya Bavanarid6546e32019-10-29 17:24:59 +05307656 __func__, afecmd_wr.port_id, ret);
7657 ret = -EINVAL;
7658 }
7659
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307660 return ret;
7661
7662}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307663EXPORT_SYMBOL(afe_rt_proxy_port_write);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307664
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307665/**
7666 * afe_rt_proxy_port_read -
7667 * command for AFE RT proxy port read
7668 *
7669 * @buf_addr_p: Physical buffer address to fill read data
7670 * @mem_map_handle: memory map handle for buffer read
7671 * @bytes: number of bytes to read
7672 *
7673 * Returns 0 on success or error on failure
7674 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307675int afe_rt_proxy_port_read(phys_addr_t buf_addr_p,
7676 u32 mem_map_handle, int bytes)
7677{
7678 int ret = 0;
7679 struct afe_port_data_cmd_rt_proxy_port_read_v2 afecmd_rd;
7680
7681 if (this_afe.apr == NULL) {
7682 pr_err("%s: register to AFE is not done\n", __func__);
7683 ret = -ENODEV;
7684 return ret;
7685 }
7686 pr_debug("%s: buf_addr_p = 0x%pK bytes = %d\n", __func__,
7687 &buf_addr_p, bytes);
7688
7689 afecmd_rd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7690 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
7691 afecmd_rd.hdr.pkt_size = sizeof(afecmd_rd);
7692 afecmd_rd.hdr.src_port = 0;
7693 afecmd_rd.hdr.dest_port = 0;
7694 afecmd_rd.hdr.token = 0;
7695 afecmd_rd.hdr.opcode = AFE_PORT_DATA_CMD_RT_PROXY_PORT_READ_V2;
7696 afecmd_rd.port_id = RT_PROXY_PORT_001_RX;
7697 afecmd_rd.buffer_address_lsw = lower_32_bits(buf_addr_p);
7698 afecmd_rd.buffer_address_msw =
7699 msm_audio_populate_upper_32_bits(buf_addr_p);
7700 afecmd_rd.available_bytes = bytes;
7701 afecmd_rd.mem_map_handle = mem_map_handle;
7702
Aditya Bavanarid6546e32019-10-29 17:24:59 +05307703 /*
7704 * Do not call afe_apr_send_pkt() here as it acquires
7705 * a mutex lock inside and this function gets called in
7706 * interrupt context leading to scheduler crash
7707 */
7708 atomic_set(&this_afe.status, 0);
7709 ret = apr_send_pkt(this_afe.apr, (uint32_t *) &afecmd_rd);
7710 if (ret < 0) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307711 pr_err("%s: AFE rtproxy read cmd to port 0x%x failed %d\n",
Aditya Bavanarid6546e32019-10-29 17:24:59 +05307712 __func__, afecmd_rd.port_id, ret);
7713 ret = -EINVAL;
7714 }
7715
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307716 return ret;
7717}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307718EXPORT_SYMBOL(afe_rt_proxy_port_read);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307719
7720#ifdef CONFIG_DEBUG_FS
7721static struct dentry *debugfs_afelb;
7722static struct dentry *debugfs_afelb_gain;
7723
7724static int afe_debug_open(struct inode *inode, struct file *file)
7725{
7726 file->private_data = inode->i_private;
7727 pr_info("%s: debug intf %s\n", __func__, (char *) file->private_data);
7728 return 0;
7729}
7730
7731static int afe_get_parameters(char *buf, long int *param1, int num_of_par)
7732{
7733 char *token;
7734 int base, cnt;
7735
7736 token = strsep(&buf, " ");
7737
7738 for (cnt = 0; cnt < num_of_par; cnt++) {
7739 if (token != NULL) {
7740 if ((token[1] == 'x') || (token[1] == 'X'))
7741 base = 16;
7742 else
7743 base = 10;
7744
7745 if (kstrtoul(token, base, &param1[cnt]) != 0) {
7746 pr_err("%s: kstrtoul failed\n",
7747 __func__);
7748 return -EINVAL;
7749 }
7750
7751 token = strsep(&buf, " ");
7752 } else {
7753 pr_err("%s: token NULL\n", __func__);
7754 return -EINVAL;
7755 }
7756 }
7757 return 0;
7758}
7759#define AFE_LOOPBACK_ON (1)
7760#define AFE_LOOPBACK_OFF (0)
7761static ssize_t afe_debug_write(struct file *filp,
7762 const char __user *ubuf, size_t cnt, loff_t *ppos)
7763{
7764 char *lb_str = filp->private_data;
7765 char lbuf[32];
7766 int rc;
7767 unsigned long param[5];
7768
7769 if (cnt > sizeof(lbuf) - 1) {
7770 pr_err("%s: cnt %zd size %zd\n", __func__, cnt, sizeof(lbuf)-1);
7771 return -EINVAL;
7772 }
7773
7774 rc = copy_from_user(lbuf, ubuf, cnt);
7775 if (rc) {
7776 pr_err("%s: copy from user failed %d\n", __func__, rc);
7777 return -EFAULT;
7778 }
7779
7780 lbuf[cnt] = '\0';
7781
7782 if (!strcmp(lb_str, "afe_loopback")) {
7783 rc = afe_get_parameters(lbuf, param, 3);
7784 if (!rc) {
7785 pr_info("%s: %lu %lu %lu\n", lb_str, param[0], param[1],
7786 param[2]);
7787
7788 if ((param[0] != AFE_LOOPBACK_ON) && (param[0] !=
7789 AFE_LOOPBACK_OFF)) {
7790 pr_err("%s: Error, parameter 0 incorrect\n",
7791 __func__);
7792 rc = -EINVAL;
7793 goto afe_error;
7794 }
7795 if ((q6audio_validate_port(param[1]) < 0) ||
7796 (q6audio_validate_port(param[2])) < 0) {
7797 pr_err("%s: Error, invalid afe port\n",
7798 __func__);
7799 }
7800 if (this_afe.apr == NULL) {
7801 pr_err("%s: Error, AFE not opened\n", __func__);
7802 rc = -EINVAL;
7803 } else {
7804 rc = afe_loopback(param[0], param[1], param[2]);
7805 }
7806 } else {
7807 pr_err("%s: Error, invalid parameters\n", __func__);
7808 rc = -EINVAL;
7809 }
7810
7811 } else if (!strcmp(lb_str, "afe_loopback_gain")) {
7812 rc = afe_get_parameters(lbuf, param, 2);
7813 if (!rc) {
7814 pr_info("%s: %s %lu %lu\n",
7815 __func__, lb_str, param[0], param[1]);
7816
7817 rc = q6audio_validate_port(param[0]);
7818 if (rc < 0) {
7819 pr_err("%s: Error, invalid afe port %d %lu\n",
7820 __func__, rc, param[0]);
7821 rc = -EINVAL;
7822 goto afe_error;
7823 }
7824
7825 if (param[1] > 100) {
7826 pr_err("%s: Error, volume should be 0 to 100 percentage param = %lu\n",
7827 __func__, param[1]);
7828 rc = -EINVAL;
7829 goto afe_error;
7830 }
7831
7832 param[1] = (Q6AFE_MAX_VOLUME * param[1]) / 100;
7833
7834 if (this_afe.apr == NULL) {
7835 pr_err("%s: Error, AFE not opened\n", __func__);
7836 rc = -EINVAL;
7837 } else {
7838 rc = afe_loopback_gain(param[0], param[1]);
7839 }
7840 } else {
7841 pr_err("%s: Error, invalid parameters\n", __func__);
7842 rc = -EINVAL;
7843 }
7844 }
7845
7846afe_error:
7847 if (rc == 0)
7848 rc = cnt;
7849 else
7850 pr_err("%s: rc = %d\n", __func__, rc);
7851
7852 return rc;
7853}
7854
7855static const struct file_operations afe_debug_fops = {
7856 .open = afe_debug_open,
7857 .write = afe_debug_write
7858};
7859
7860static void config_debug_fs_init(void)
7861{
7862 debugfs_afelb = debugfs_create_file("afe_loopback",
7863 0664, NULL, (void *) "afe_loopback",
7864 &afe_debug_fops);
7865
7866 debugfs_afelb_gain = debugfs_create_file("afe_loopback_gain",
7867 0664, NULL, (void *) "afe_loopback_gain",
7868 &afe_debug_fops);
7869}
7870static void config_debug_fs_exit(void)
7871{
7872 debugfs_remove(debugfs_afelb);
7873 debugfs_remove(debugfs_afelb_gain);
7874}
7875#else
7876static void config_debug_fs_init(void)
7877{
7878}
7879static void config_debug_fs_exit(void)
7880{
7881}
7882#endif
7883
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307884/**
7885 * afe_set_dtmf_gen_rx_portid -
7886 * Set port_id for DTMF tone generation
7887 *
7888 * @port_id: AFE port id
7889 * @set: set or reset port id value for dtmf gen
7890 *
7891 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307892void afe_set_dtmf_gen_rx_portid(u16 port_id, int set)
7893{
7894 if (set)
7895 this_afe.dtmf_gen_rx_portid = port_id;
7896 else if (this_afe.dtmf_gen_rx_portid == port_id)
7897 this_afe.dtmf_gen_rx_portid = -1;
7898}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307899EXPORT_SYMBOL(afe_set_dtmf_gen_rx_portid);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307900
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307901/**
7902 * afe_dtmf_generate_rx - command to generate AFE DTMF RX
7903 *
7904 * @duration_in_ms: Duration in ms for dtmf tone
7905 * @high_freq: Higher frequency for dtmf
7906 * @low_freq: lower frequency for dtmf
7907 * @gain: Gain value for DTMF tone
7908 *
7909 * Returns 0 on success, appropriate error code otherwise
7910 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307911int afe_dtmf_generate_rx(int64_t duration_in_ms,
7912 uint16_t high_freq,
7913 uint16_t low_freq, uint16_t gain)
7914{
7915 int ret = 0;
7916 int index = 0;
7917 struct afe_dtmf_generation_command cmd_dtmf;
7918
7919 pr_debug("%s: DTMF AFE Gen\n", __func__);
7920
7921 if (afe_validate_port(this_afe.dtmf_gen_rx_portid) < 0) {
7922 pr_err("%s: Failed : Invalid Port id = 0x%x\n",
7923 __func__, this_afe.dtmf_gen_rx_portid);
7924 ret = -EINVAL;
7925 goto fail_cmd;
7926 }
7927
7928 if (this_afe.apr == NULL) {
7929 this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
7930 0xFFFFFFFF, &this_afe);
7931 pr_debug("%s: Register AFE\n", __func__);
7932 if (this_afe.apr == NULL) {
7933 pr_err("%s: Unable to register AFE\n", __func__);
7934 ret = -ENODEV;
7935 return ret;
7936 }
7937 rtac_set_afe_handle(this_afe.apr);
7938 }
7939
7940 pr_debug("%s: dur=%lld: hfreq=%d lfreq=%d gain=%d portid=0x%x\n",
7941 __func__,
7942 duration_in_ms, high_freq, low_freq, gain,
7943 this_afe.dtmf_gen_rx_portid);
7944
7945 cmd_dtmf.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
7946 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
7947 cmd_dtmf.hdr.pkt_size = sizeof(cmd_dtmf);
7948 cmd_dtmf.hdr.src_port = 0;
7949 cmd_dtmf.hdr.dest_port = 0;
7950 cmd_dtmf.hdr.token = 0;
7951 cmd_dtmf.hdr.opcode = AFE_PORTS_CMD_DTMF_CTL;
7952 cmd_dtmf.duration_in_ms = duration_in_ms;
7953 cmd_dtmf.high_freq = high_freq;
7954 cmd_dtmf.low_freq = low_freq;
7955 cmd_dtmf.gain = gain;
7956 cmd_dtmf.num_ports = 1;
7957 cmd_dtmf.port_ids = q6audio_get_port_id(this_afe.dtmf_gen_rx_portid);
7958
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307959 index = q6audio_get_port_index(this_afe.dtmf_gen_rx_portid);
7960 if (index < 0 || index >= AFE_MAX_PORTS) {
7961 pr_err("%s: AFE port index[%d] invalid!\n",
7962 __func__, index);
7963 ret = -EINVAL;
7964 goto fail_cmd;
7965 }
Aditya Bavanarid6546e32019-10-29 17:24:59 +05307966 ret = afe_apr_send_pkt((uint32_t *) &cmd_dtmf,
7967 &this_afe.wait[index]);
7968 return ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307969fail_cmd:
7970 pr_err("%s: failed %d\n", __func__, ret);
7971 return ret;
7972}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05307973EXPORT_SYMBOL(afe_dtmf_generate_rx);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307974
7975static int afe_sidetone_iir(u16 tx_port_id)
7976{
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307977 int ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307978 uint16_t size = 0;
7979 int cal_index = AFE_SIDETONE_IIR_CAL;
7980 int iir_pregain = 0;
7981 int iir_num_biquad_stages = 0;
7982 int iir_enable;
7983 struct cal_block_data *cal_block;
7984 int mid;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08007985 struct afe_mod_enable_param enable;
7986 struct afe_sidetone_iir_filter_config_params filter_data;
7987 struct param_hdr_v3 param_hdr;
7988 u8 *packed_param_data = NULL;
7989 u32 packed_param_size = 0;
7990 u32 single_param_size = 0;
7991 struct audio_cal_info_sidetone_iir *st_iir_cal_info = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307992
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08007993 memset(&enable, 0, sizeof(enable));
7994 memset(&filter_data, 0, sizeof(filter_data));
7995 memset(&param_hdr, 0, sizeof(param_hdr));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307996
7997 if (this_afe.cal_data[cal_index] == NULL) {
7998 pr_err("%s: cal data is NULL\n", __func__);
7999 ret = -EINVAL;
8000 goto done;
8001 }
8002 mutex_lock(&this_afe.cal_data[cal_index]->lock);
8003 cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]);
Vikram Panduranga770b8382017-09-27 12:17:36 -07008004 if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308005 pr_err("%s: cal_block not found\n ", __func__);
8006 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
8007 ret = -EINVAL;
8008 goto done;
8009 }
8010
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008011 /* Cache data from cal block while inside lock to reduce locked time */
8012 st_iir_cal_info =
8013 (struct audio_cal_info_sidetone_iir *) cal_block->cal_info;
8014 iir_pregain = st_iir_cal_info->pregain;
8015 iir_enable = st_iir_cal_info->iir_enable;
8016 iir_num_biquad_stages = st_iir_cal_info->num_biquad_stages;
8017 mid = st_iir_cal_info->mid;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308018
8019 /*
8020 * calculate the actual size of payload based on no of stages
8021 * enabled in calibration
8022 */
8023 size = (MAX_SIDETONE_IIR_DATA_SIZE / MAX_NO_IIR_FILTER_STAGE) *
8024 iir_num_biquad_stages;
8025 /*
8026 * For an odd number of stages, 2 bytes of padding are
8027 * required at the end of the payload.
8028 */
8029 if (iir_num_biquad_stages % 2) {
8030 pr_debug("%s: adding 2 to size:%d\n", __func__, size);
8031 size = size + 2;
8032 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008033 memcpy(&filter_data.iir_config, &st_iir_cal_info->iir_config, size);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308034 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
8035
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008036 packed_param_size =
8037 sizeof(param_hdr) * 2 + sizeof(enable) + sizeof(filter_data);
8038 packed_param_data = kzalloc(packed_param_size, GFP_KERNEL);
8039 if (!packed_param_data)
8040 return -ENOMEM;
8041 packed_param_size = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308042
8043 /*
8044 * Set IIR enable params
8045 */
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008046 param_hdr.module_id = mid;
Aditya Bavanari1c53d882020-02-13 11:14:58 +05308047 param_hdr.instance_id = INSTANCE_ID_0;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008048 param_hdr.param_id = AFE_PARAM_ID_ENABLE;
8049 param_hdr.param_size = sizeof(enable);
8050 enable.enable = iir_enable;
8051 ret = q6common_pack_pp_params(packed_param_data, &param_hdr,
8052 (u8 *) &enable, &single_param_size);
8053 if (ret) {
8054 pr_err("%s: Failed to pack param data, error %d\n", __func__,
8055 ret);
8056 goto done;
8057 }
8058 packed_param_size += single_param_size;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308059
8060 /*
8061 * Set IIR filter config params
8062 */
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008063 param_hdr.module_id = mid;
8064 param_hdr.instance_id = INSTANCE_ID_0;
8065 param_hdr.param_id = AFE_PARAM_ID_SIDETONE_IIR_FILTER_CONFIG;
8066 param_hdr.param_size = sizeof(filter_data.num_biquad_stages) +
8067 sizeof(filter_data.pregain) + size;
8068 filter_data.num_biquad_stages = iir_num_biquad_stages;
8069 filter_data.pregain = iir_pregain;
8070 ret = q6common_pack_pp_params(packed_param_data + packed_param_size,
8071 &param_hdr, (u8 *) &filter_data,
8072 &single_param_size);
8073 if (ret) {
8074 pr_err("%s: Failed to pack param data, error %d\n", __func__,
8075 ret);
8076 goto done;
8077 }
8078 packed_param_size += single_param_size;
8079
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308080 pr_debug("%s: tx(0x%x)mid(0x%x)iir_en(%d)stg(%d)gain(0x%x)size(%d)\n",
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008081 __func__, tx_port_id, mid, enable.enable,
8082 filter_data.num_biquad_stages, filter_data.pregain,
8083 param_hdr.param_size);
8084
8085 ret = q6afe_set_params(tx_port_id, q6audio_get_port_index(tx_port_id),
8086 NULL, packed_param_data, packed_param_size);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308087 if (ret)
8088 pr_err("%s: AFE sidetone failed for tx_port(0x%x)\n",
8089 __func__, tx_port_id);
8090
8091done:
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008092 kfree(packed_param_data);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308093 return ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308094}
8095
8096static int afe_sidetone(u16 tx_port_id, u16 rx_port_id, bool enable)
8097{
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308098 int ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308099 int cal_index = AFE_SIDETONE_CAL;
8100 int sidetone_gain;
8101 int sidetone_enable;
8102 struct cal_block_data *cal_block;
8103 int mid = 0;
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008104 struct afe_loopback_sidetone_gain gain_data;
8105 struct loopback_cfg_data cfg_data;
8106 struct param_hdr_v3 param_hdr;
8107 u8 *packed_param_data = NULL;
8108 u32 packed_param_size = 0;
8109 u32 single_param_size = 0;
8110 struct audio_cal_info_sidetone *st_cal_info = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308111
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308112 if (this_afe.cal_data[cal_index] == NULL) {
8113 pr_err("%s: cal data is NULL\n", __func__);
8114 ret = -EINVAL;
8115 goto done;
8116 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008117
8118 memset(&gain_data, 0, sizeof(gain_data));
8119 memset(&cfg_data, 0, sizeof(cfg_data));
8120 memset(&param_hdr, 0, sizeof(param_hdr));
8121
8122 packed_param_size =
8123 sizeof(param_hdr) * 2 + sizeof(gain_data) + sizeof(cfg_data);
8124 packed_param_data = kzalloc(packed_param_size, GFP_KERNEL);
8125 if (!packed_param_data)
8126 return -ENOMEM;
8127 packed_param_size = 0;
8128
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308129 mutex_lock(&this_afe.cal_data[cal_index]->lock);
8130 cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]);
Vikram Panduranga770b8382017-09-27 12:17:36 -07008131 if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308132 pr_err("%s: cal_block not found\n", __func__);
8133 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
8134 ret = -EINVAL;
8135 goto done;
8136 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008137
8138 /* Cache data from cal block while inside lock to reduce locked time */
8139 st_cal_info = (struct audio_cal_info_sidetone *) cal_block->cal_info;
8140 sidetone_gain = st_cal_info->gain;
8141 sidetone_enable = st_cal_info->enable;
8142 mid = st_cal_info->mid;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308143 mutex_unlock(&this_afe.cal_data[cal_index]->lock);
8144
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008145 /* Set gain data. */
8146 param_hdr.module_id = AFE_MODULE_LOOPBACK;
8147 param_hdr.instance_id = INSTANCE_ID_0;
8148 param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH;
8149 param_hdr.param_size = sizeof(struct afe_loopback_sidetone_gain);
8150 gain_data.rx_port_id = rx_port_id;
8151 gain_data.gain = sidetone_gain;
8152 ret = q6common_pack_pp_params(packed_param_data, &param_hdr,
8153 (u8 *) &gain_data, &single_param_size);
8154 if (ret) {
8155 pr_err("%s: Failed to pack param data, error %d\n", __func__,
8156 ret);
8157 goto done;
8158 }
8159 packed_param_size += single_param_size;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308160
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008161 /* Set configuration data. */
8162 param_hdr.module_id = AFE_MODULE_LOOPBACK;
8163 param_hdr.instance_id = INSTANCE_ID_0;
8164 param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG;
8165 param_hdr.param_size = sizeof(struct loopback_cfg_data);
8166 cfg_data.loopback_cfg_minor_version = AFE_API_VERSION_LOOPBACK_CONFIG;
8167 cfg_data.dst_port_id = rx_port_id;
8168 cfg_data.routing_mode = LB_MODE_SIDETONE;
8169 cfg_data.enable = enable;
8170 ret = q6common_pack_pp_params(packed_param_data + packed_param_size,
8171 &param_hdr, (u8 *) &cfg_data,
8172 &single_param_size);
8173 if (ret) {
8174 pr_err("%s: Failed to pack param data, error %d\n", __func__,
8175 ret);
8176 goto done;
8177 }
8178 packed_param_size += single_param_size;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308179
8180 pr_debug("%s rx(0x%x) tx(0x%x) enable(%d) mid(0x%x) gain(%d) sidetone_enable(%d)\n",
8181 __func__, rx_port_id, tx_port_id,
8182 enable, mid, sidetone_gain, sidetone_enable);
8183
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008184 ret = q6afe_set_params(tx_port_id, q6audio_get_port_index(tx_port_id),
8185 NULL, packed_param_data, packed_param_size);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308186 if (ret)
8187 pr_err("%s: AFE sidetone send failed for tx_port:%d rx_port:%d ret:%d\n",
8188 __func__, tx_port_id, rx_port_id, ret);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008189
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308190done:
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008191 kfree(packed_param_data);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308192 return ret;
8193}
8194
8195int afe_sidetone_enable(u16 tx_port_id, u16 rx_port_id, bool enable)
8196{
8197 int ret;
8198 int index;
8199
8200 index = q6audio_get_port_index(rx_port_id);
8201 if (index < 0 || index >= AFE_MAX_PORTS) {
8202 pr_err("%s: AFE port index[%d] invalid!\n",
8203 __func__, index);
8204 ret = -EINVAL;
8205 goto done;
8206 }
8207 if (q6audio_validate_port(rx_port_id) < 0) {
8208 pr_err("%s: Invalid port 0x%x\n",
8209 __func__, rx_port_id);
8210 ret = -EINVAL;
8211 goto done;
8212 }
8213 index = q6audio_get_port_index(tx_port_id);
8214 if (index < 0 || index >= AFE_MAX_PORTS) {
8215 pr_err("%s: AFE port index[%d] invalid!\n",
8216 __func__, index);
8217 ret = -EINVAL;
8218 goto done;
8219 }
8220 if (q6audio_validate_port(tx_port_id) < 0) {
8221 pr_err("%s: Invalid port 0x%x\n",
8222 __func__, tx_port_id);
8223 ret = -EINVAL;
8224 goto done;
8225 }
8226 if (enable) {
8227 ret = afe_sidetone_iir(tx_port_id);
8228 if (ret)
8229 goto done;
8230 }
8231
8232 ret = afe_sidetone(tx_port_id, rx_port_id, enable);
8233
8234done:
8235 return ret;
8236}
8237
Karthikeyan Mani16b69722018-05-03 18:26:21 -07008238/**
8239 * afe_set_display_stream - command to update AFE dp port params
8240 *
8241 * @rx_port_id: AFE port id
8242 * @stream_idx: dp controller stream index
8243 * @ctl_idx: dp controller index
8244 *
8245 * Returns 0 on success, appropriate error code otherwise
8246 */
8247int afe_set_display_stream(u16 rx_port_id, u32 stream_idx, u32 ctl_idx)
8248{
8249 int ret;
8250 struct param_hdr_v3 param_hdr;
8251 u32 packed_param_size = 0;
8252 u8 *packed_param_data = NULL;
8253 struct afe_display_stream_idx stream_data;
8254 struct afe_display_ctl_idx ctl_data;
8255 u32 single_param_size = 0;
8256
8257 memset(&param_hdr, 0, sizeof(param_hdr));
8258 memset(&stream_data, 0, sizeof(stream_data));
8259 memset(&ctl_data, 0, sizeof(ctl_data));
8260
8261 packed_param_size =
8262 sizeof(param_hdr) * 2 + sizeof(stream_data) + sizeof(ctl_data);
8263 packed_param_data = kzalloc(packed_param_size, GFP_KERNEL);
8264 if (!packed_param_data)
8265 return -ENOMEM;
8266 packed_param_size = 0;
8267
8268 /* Set stream index */
8269 param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
8270 param_hdr.instance_id = INSTANCE_ID_0;
8271 param_hdr.param_id = AFE_PARAM_ID_HDMI_DP_MST_VID_IDX_CFG;
8272 param_hdr.param_size = sizeof(struct afe_display_stream_idx);
8273 stream_data.minor_version = 1;
8274 stream_data.stream_idx = stream_idx;
8275 ret = q6common_pack_pp_params(packed_param_data, &param_hdr,
8276 (u8 *) &stream_data, &single_param_size);
8277 if (ret) {
8278 pr_err("%s: Failed to pack param data, error %d\n", __func__,
8279 ret);
8280 goto done;
8281 }
8282 packed_param_size += single_param_size;
8283
8284 /* Set controller dptx index */
8285 param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
8286 param_hdr.instance_id = INSTANCE_ID_0;
8287 param_hdr.param_id = AFE_PARAM_ID_HDMI_DPTX_IDX_CFG;
8288 param_hdr.param_size = sizeof(struct afe_display_ctl_idx);
8289 ctl_data.minor_version = 1;
8290 ctl_data.ctl_idx = ctl_idx;
8291 ret = q6common_pack_pp_params(packed_param_data + packed_param_size,
8292 &param_hdr, (u8 *) &ctl_data,
8293 &single_param_size);
8294 if (ret) {
8295 pr_err("%s: Failed to pack param data, error %d\n", __func__,
8296 ret);
8297 goto done;
8298 }
8299 packed_param_size += single_param_size;
8300
8301 pr_debug("%s: rx(0x%x) stream(%d) controller(%d)\n",
8302 __func__, rx_port_id, stream_idx, ctl_idx);
8303
8304 ret = q6afe_set_params(rx_port_id, q6audio_get_port_index(rx_port_id),
8305 NULL, packed_param_data, packed_param_size);
8306 if (ret)
8307 pr_err("%s: AFE display stream send failed for rx_port:%d ret:%d\n",
8308 __func__, rx_port_id, ret);
8309
8310done:
8311 kfree(packed_param_data);
8312 return ret;
8313
8314}
8315EXPORT_SYMBOL(afe_set_display_stream);
8316
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308317int afe_validate_port(u16 port_id)
8318{
8319 int ret;
8320
8321 switch (port_id) {
8322 case PRIMARY_I2S_RX:
8323 case PRIMARY_I2S_TX:
8324 case AFE_PORT_ID_PRIMARY_PCM_RX:
8325 case AFE_PORT_ID_PRIMARY_PCM_TX:
8326 case AFE_PORT_ID_SECONDARY_PCM_RX:
8327 case AFE_PORT_ID_SECONDARY_PCM_TX:
8328 case AFE_PORT_ID_TERTIARY_PCM_RX:
8329 case AFE_PORT_ID_TERTIARY_PCM_TX:
8330 case AFE_PORT_ID_QUATERNARY_PCM_RX:
8331 case AFE_PORT_ID_QUATERNARY_PCM_TX:
Rohit Kumarc08b14f2017-10-06 10:52:17 +05308332 case AFE_PORT_ID_QUINARY_PCM_RX:
8333 case AFE_PORT_ID_QUINARY_PCM_TX:
Karthikeyan Mani3bbd2ee2019-01-30 18:48:56 -08008334 case AFE_PORT_ID_SENARY_PCM_RX:
8335 case AFE_PORT_ID_SENARY_PCM_TX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308336 case SECONDARY_I2S_RX:
8337 case SECONDARY_I2S_TX:
8338 case MI2S_RX:
8339 case MI2S_TX:
8340 case HDMI_RX:
Sanjana B63bdc7b2020-01-20 19:31:18 +05308341 case HDMI_RX_MS:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308342 case DISPLAY_PORT_RX:
Ralf Herzcc29b9e2018-07-17 20:19:04 +05308343 case AFE_PORT_ID_PRIMARY_SPDIF_RX:
8344 case AFE_PORT_ID_PRIMARY_SPDIF_TX:
8345 case AFE_PORT_ID_SECONDARY_SPDIF_RX:
8346 case AFE_PORT_ID_SECONDARY_SPDIF_TX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308347 case RSVD_2:
8348 case RSVD_3:
8349 case DIGI_MIC_TX:
8350 case VOICE_RECORD_RX:
8351 case VOICE_RECORD_TX:
8352 case VOICE_PLAYBACK_TX:
8353 case VOICE2_PLAYBACK_TX:
8354 case SLIMBUS_0_RX:
8355 case SLIMBUS_0_TX:
8356 case SLIMBUS_1_RX:
8357 case SLIMBUS_1_TX:
8358 case SLIMBUS_2_RX:
8359 case SLIMBUS_2_TX:
8360 case SLIMBUS_3_RX:
8361 case INT_BT_SCO_RX:
8362 case INT_BT_SCO_TX:
8363 case INT_BT_A2DP_RX:
8364 case INT_FM_RX:
8365 case INT_FM_TX:
8366 case RT_PROXY_PORT_001_RX:
8367 case RT_PROXY_PORT_001_TX:
8368 case SLIMBUS_4_RX:
8369 case SLIMBUS_4_TX:
8370 case SLIMBUS_5_RX:
8371 case SLIMBUS_6_RX:
8372 case SLIMBUS_6_TX:
8373 case SLIMBUS_7_RX:
8374 case SLIMBUS_7_TX:
8375 case SLIMBUS_8_RX:
8376 case SLIMBUS_8_TX:
Surendar Karkab0dd21f2018-09-28 18:53:50 +05308377 case SLIMBUS_9_RX:
8378 case SLIMBUS_9_TX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308379 case AFE_PORT_ID_USB_RX:
8380 case AFE_PORT_ID_USB_TX:
8381 case AFE_PORT_ID_PRIMARY_MI2S_RX:
8382 case AFE_PORT_ID_PRIMARY_MI2S_TX:
8383 case AFE_PORT_ID_SECONDARY_MI2S_RX:
8384 case AFE_PORT_ID_SECONDARY_MI2S_TX:
8385 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
8386 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
8387 case AFE_PORT_ID_TERTIARY_MI2S_RX:
8388 case AFE_PORT_ID_TERTIARY_MI2S_TX:
8389 case AFE_PORT_ID_QUINARY_MI2S_RX:
8390 case AFE_PORT_ID_QUINARY_MI2S_TX:
Karthikeyan Mani3bbd2ee2019-01-30 18:48:56 -08008391 case AFE_PORT_ID_SENARY_MI2S_RX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308392 case AFE_PORT_ID_SENARY_MI2S_TX:
Ralf Herz43c0abd2019-07-26 15:12:48 +02008393 case AFE_PORT_ID_PRIMARY_META_MI2S_RX:
8394 case AFE_PORT_ID_SECONDARY_META_MI2S_RX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308395 case AFE_PORT_ID_PRIMARY_TDM_RX:
8396 case AFE_PORT_ID_PRIMARY_TDM_TX:
8397 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
8398 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
8399 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
8400 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
8401 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
8402 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
8403 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
8404 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
8405 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
8406 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
8407 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
8408 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
8409 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
8410 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
8411 case AFE_PORT_ID_SECONDARY_TDM_RX:
8412 case AFE_PORT_ID_SECONDARY_TDM_TX:
8413 case AFE_PORT_ID_SECONDARY_TDM_RX_1:
8414 case AFE_PORT_ID_SECONDARY_TDM_TX_1:
8415 case AFE_PORT_ID_SECONDARY_TDM_RX_2:
8416 case AFE_PORT_ID_SECONDARY_TDM_TX_2:
8417 case AFE_PORT_ID_SECONDARY_TDM_RX_3:
8418 case AFE_PORT_ID_SECONDARY_TDM_TX_3:
8419 case AFE_PORT_ID_SECONDARY_TDM_RX_4:
8420 case AFE_PORT_ID_SECONDARY_TDM_TX_4:
8421 case AFE_PORT_ID_SECONDARY_TDM_RX_5:
8422 case AFE_PORT_ID_SECONDARY_TDM_TX_5:
8423 case AFE_PORT_ID_SECONDARY_TDM_RX_6:
8424 case AFE_PORT_ID_SECONDARY_TDM_TX_6:
8425 case AFE_PORT_ID_SECONDARY_TDM_RX_7:
8426 case AFE_PORT_ID_SECONDARY_TDM_TX_7:
8427 case AFE_PORT_ID_TERTIARY_TDM_RX:
8428 case AFE_PORT_ID_TERTIARY_TDM_TX:
8429 case AFE_PORT_ID_TERTIARY_TDM_RX_1:
8430 case AFE_PORT_ID_TERTIARY_TDM_TX_1:
8431 case AFE_PORT_ID_TERTIARY_TDM_RX_2:
8432 case AFE_PORT_ID_TERTIARY_TDM_TX_2:
8433 case AFE_PORT_ID_TERTIARY_TDM_RX_3:
8434 case AFE_PORT_ID_TERTIARY_TDM_TX_3:
8435 case AFE_PORT_ID_TERTIARY_TDM_RX_4:
8436 case AFE_PORT_ID_TERTIARY_TDM_TX_4:
8437 case AFE_PORT_ID_TERTIARY_TDM_RX_5:
8438 case AFE_PORT_ID_TERTIARY_TDM_TX_5:
8439 case AFE_PORT_ID_TERTIARY_TDM_RX_6:
8440 case AFE_PORT_ID_TERTIARY_TDM_TX_6:
8441 case AFE_PORT_ID_TERTIARY_TDM_RX_7:
8442 case AFE_PORT_ID_TERTIARY_TDM_TX_7:
8443 case AFE_PORT_ID_QUATERNARY_TDM_RX:
8444 case AFE_PORT_ID_QUATERNARY_TDM_TX:
8445 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
8446 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
8447 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
8448 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
8449 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
8450 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
8451 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
8452 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
8453 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
8454 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
8455 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
8456 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
8457 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
8458 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
Rohit Kumarc08b14f2017-10-06 10:52:17 +05308459 case AFE_PORT_ID_QUINARY_TDM_RX:
8460 case AFE_PORT_ID_QUINARY_TDM_TX:
8461 case AFE_PORT_ID_QUINARY_TDM_RX_1:
8462 case AFE_PORT_ID_QUINARY_TDM_TX_1:
8463 case AFE_PORT_ID_QUINARY_TDM_RX_2:
8464 case AFE_PORT_ID_QUINARY_TDM_TX_2:
8465 case AFE_PORT_ID_QUINARY_TDM_RX_3:
8466 case AFE_PORT_ID_QUINARY_TDM_TX_3:
8467 case AFE_PORT_ID_QUINARY_TDM_RX_4:
8468 case AFE_PORT_ID_QUINARY_TDM_TX_4:
8469 case AFE_PORT_ID_QUINARY_TDM_RX_5:
8470 case AFE_PORT_ID_QUINARY_TDM_TX_5:
8471 case AFE_PORT_ID_QUINARY_TDM_RX_6:
8472 case AFE_PORT_ID_QUINARY_TDM_TX_6:
8473 case AFE_PORT_ID_QUINARY_TDM_RX_7:
8474 case AFE_PORT_ID_QUINARY_TDM_TX_7:
Karthikeyan Mani3bbd2ee2019-01-30 18:48:56 -08008475 case AFE_PORT_ID_SENARY_TDM_RX:
8476 case AFE_PORT_ID_SENARY_TDM_TX:
8477 case AFE_PORT_ID_SENARY_TDM_RX_1:
8478 case AFE_PORT_ID_SENARY_TDM_TX_1:
8479 case AFE_PORT_ID_SENARY_TDM_RX_2:
8480 case AFE_PORT_ID_SENARY_TDM_TX_2:
8481 case AFE_PORT_ID_SENARY_TDM_RX_3:
8482 case AFE_PORT_ID_SENARY_TDM_TX_3:
8483 case AFE_PORT_ID_SENARY_TDM_RX_4:
8484 case AFE_PORT_ID_SENARY_TDM_TX_4:
8485 case AFE_PORT_ID_SENARY_TDM_RX_5:
8486 case AFE_PORT_ID_SENARY_TDM_TX_5:
8487 case AFE_PORT_ID_SENARY_TDM_RX_6:
8488 case AFE_PORT_ID_SENARY_TDM_TX_6:
8489 case AFE_PORT_ID_SENARY_TDM_RX_7:
8490 case AFE_PORT_ID_SENARY_TDM_TX_7:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308491 case AFE_PORT_ID_INT0_MI2S_RX:
8492 case AFE_PORT_ID_INT1_MI2S_RX:
8493 case AFE_PORT_ID_INT2_MI2S_RX:
8494 case AFE_PORT_ID_INT3_MI2S_RX:
8495 case AFE_PORT_ID_INT4_MI2S_RX:
8496 case AFE_PORT_ID_INT5_MI2S_RX:
8497 case AFE_PORT_ID_INT6_MI2S_RX:
8498 case AFE_PORT_ID_INT0_MI2S_TX:
8499 case AFE_PORT_ID_INT1_MI2S_TX:
8500 case AFE_PORT_ID_INT2_MI2S_TX:
8501 case AFE_PORT_ID_INT3_MI2S_TX:
8502 case AFE_PORT_ID_INT4_MI2S_TX:
8503 case AFE_PORT_ID_INT5_MI2S_TX:
8504 case AFE_PORT_ID_INT6_MI2S_TX:
Mangesh Kunchamwar07b8dc92018-07-16 19:46:25 +05308505 case AFE_PORT_ID_WSA_CODEC_DMA_RX_0:
8506 case AFE_PORT_ID_WSA_CODEC_DMA_TX_0:
8507 case AFE_PORT_ID_WSA_CODEC_DMA_RX_1:
8508 case AFE_PORT_ID_WSA_CODEC_DMA_TX_1:
8509 case AFE_PORT_ID_WSA_CODEC_DMA_TX_2:
8510 case AFE_PORT_ID_VA_CODEC_DMA_TX_0:
8511 case AFE_PORT_ID_VA_CODEC_DMA_TX_1:
Xiaoyu Ye8341eef2019-01-03 14:57:47 -08008512 case AFE_PORT_ID_VA_CODEC_DMA_TX_2:
Aditya Bavanari54ca7d12018-08-08 13:59:54 +05308513 case AFE_PORT_ID_RX_CODEC_DMA_RX_0:
8514 case AFE_PORT_ID_TX_CODEC_DMA_TX_0:
8515 case AFE_PORT_ID_RX_CODEC_DMA_RX_1:
8516 case AFE_PORT_ID_TX_CODEC_DMA_TX_1:
8517 case AFE_PORT_ID_RX_CODEC_DMA_RX_2:
8518 case AFE_PORT_ID_TX_CODEC_DMA_TX_2:
8519 case AFE_PORT_ID_RX_CODEC_DMA_RX_3:
8520 case AFE_PORT_ID_TX_CODEC_DMA_TX_3:
8521 case AFE_PORT_ID_RX_CODEC_DMA_RX_4:
8522 case AFE_PORT_ID_TX_CODEC_DMA_TX_4:
8523 case AFE_PORT_ID_RX_CODEC_DMA_RX_5:
8524 case AFE_PORT_ID_TX_CODEC_DMA_TX_5:
8525 case AFE_PORT_ID_RX_CODEC_DMA_RX_6:
8526 case AFE_PORT_ID_RX_CODEC_DMA_RX_7:
Jaideep Sharma39932232020-03-11 22:24:14 +05308527 case RT_PROXY_PORT_002_RX:
8528 case RT_PROXY_PORT_002_TX:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308529 {
8530 ret = 0;
8531 break;
8532 }
8533
8534 default:
8535 pr_err("%s: default ret 0x%x\n", __func__, port_id);
8536 ret = -EINVAL;
8537 }
8538
8539 return ret;
8540}
8541
8542int afe_convert_virtual_to_portid(u16 port_id)
8543{
8544 int ret;
8545
8546 /*
8547 * if port_id is virtual, convert to physical..
8548 * if port_id is already physical, return physical
8549 */
8550 if (afe_validate_port(port_id) < 0) {
8551 if (port_id == RT_PROXY_DAI_001_RX ||
8552 port_id == RT_PROXY_DAI_001_TX ||
8553 port_id == RT_PROXY_DAI_002_RX ||
8554 port_id == RT_PROXY_DAI_002_TX) {
8555 ret = VIRTUAL_ID_TO_PORTID(port_id);
8556 } else {
8557 pr_err("%s: wrong port 0x%x\n",
8558 __func__, port_id);
8559 ret = -EINVAL;
8560 }
8561 } else
8562 ret = port_id;
8563
8564 return ret;
8565}
8566int afe_port_stop_nowait(int port_id)
8567{
8568 struct afe_port_cmd_device_stop stop;
8569 int ret = 0;
8570
8571 if (this_afe.apr == NULL) {
8572 pr_err("%s: AFE is already closed\n", __func__);
8573 ret = -EINVAL;
8574 goto fail_cmd;
8575 }
8576 pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
8577 port_id = q6audio_convert_virtual_to_portid(port_id);
8578
8579 stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
8580 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
8581 stop.hdr.pkt_size = sizeof(stop);
8582 stop.hdr.src_port = 0;
8583 stop.hdr.dest_port = 0;
8584 stop.hdr.token = 0;
8585 stop.hdr.opcode = AFE_PORT_CMD_DEVICE_STOP;
8586 stop.port_id = port_id;
8587 stop.reserved = 0;
8588
8589 ret = afe_apr_send_pkt(&stop, NULL);
8590 if (ret)
8591 pr_err("%s: AFE close failed %d\n", __func__, ret);
8592
8593fail_cmd:
8594 return ret;
8595
8596}
8597
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05308598/**
8599 * afe_close - command to close AFE port
8600 *
8601 * @port_id: AFE port id
8602 *
8603 * Returns 0 on success, appropriate error code otherwise
8604 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308605int afe_close(int port_id)
8606{
8607 struct afe_port_cmd_device_stop stop;
8608 enum afe_mad_type mad_type;
8609 int ret = 0;
Harshal Ahire10e83842020-03-27 04:37:23 +05308610 u16 i;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308611 int index = 0;
8612 uint16_t port_index;
8613
8614 if (this_afe.apr == NULL) {
8615 pr_err("%s: AFE is already closed\n", __func__);
8616 if ((port_id == RT_PROXY_DAI_001_RX) ||
8617 (port_id == RT_PROXY_DAI_002_TX))
8618 pcm_afe_instance[port_id & 0x1] = 0;
8619 if ((port_id == RT_PROXY_DAI_002_RX) ||
8620 (port_id == RT_PROXY_DAI_001_TX))
8621 proxy_afe_instance[port_id & 0x1] = 0;
8622 afe_close_done[port_id & 0x1] = true;
8623 ret = -EINVAL;
8624 goto fail_cmd;
8625 }
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07008626 pr_info("%s: port_id = 0x%x\n", __func__, port_id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308627 if ((port_id == RT_PROXY_DAI_001_RX) ||
8628 (port_id == RT_PROXY_DAI_002_TX)) {
8629 pr_debug("%s: before decrementing pcm_afe_instance %d\n",
8630 __func__, pcm_afe_instance[port_id & 0x1]);
8631 port_id = VIRTUAL_ID_TO_PORTID(port_id);
8632 pcm_afe_instance[port_id & 0x1]--;
8633 if ((!(pcm_afe_instance[port_id & 0x1] == 0 &&
8634 proxy_afe_instance[port_id & 0x1] == 0)) ||
8635 afe_close_done[port_id & 0x1] == true)
8636 return 0;
8637
8638 afe_close_done[port_id & 0x1] = true;
8639 }
8640
8641 if ((port_id == RT_PROXY_DAI_002_RX) ||
8642 (port_id == RT_PROXY_DAI_001_TX)) {
8643 pr_debug("%s: before decrementing proxy_afe_instance %d\n",
8644 __func__, proxy_afe_instance[port_id & 0x1]);
8645 port_id = VIRTUAL_ID_TO_PORTID(port_id);
8646 proxy_afe_instance[port_id & 0x1]--;
8647 if ((!(pcm_afe_instance[port_id & 0x1] == 0 &&
8648 proxy_afe_instance[port_id & 0x1] == 0)) ||
8649 afe_close_done[port_id & 0x1] == true)
8650 return 0;
8651
8652 afe_close_done[port_id & 0x1] = true;
8653 }
8654
8655 port_id = q6audio_convert_virtual_to_portid(port_id);
8656 index = q6audio_get_port_index(port_id);
8657 if (index < 0 || index >= AFE_MAX_PORTS) {
8658 pr_err("%s: AFE port index[%d] invalid!\n",
8659 __func__, index);
8660 return -EINVAL;
8661 }
8662 ret = q6audio_validate_port(port_id);
8663 if (ret < 0) {
8664 pr_warn("%s: Not a valid port id 0x%x ret %d\n",
8665 __func__, port_id, ret);
8666 return -EINVAL;
8667 }
8668
8669 mad_type = afe_port_get_mad_type(port_id);
8670 pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id,
8671 mad_type);
8672 if (mad_type != MAD_HW_NONE && mad_type != MAD_SW_AUDIO) {
8673 pr_debug("%s: Turn off MAD\n", __func__);
8674 ret = afe_turn_onoff_hw_mad(mad_type, false);
8675 if (ret) {
8676 pr_err("%s: afe_turn_onoff_hw_mad failed %d\n",
8677 __func__, ret);
8678 return ret;
8679 }
8680 } else {
8681 pr_debug("%s: Not a MAD port\n", __func__);
8682 }
8683
Soumya Managolic89e6fb2019-10-14 14:30:17 +05308684 mutex_lock(&this_afe.afe_cmd_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308685 port_index = afe_get_port_index(port_id);
8686 if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
8687 this_afe.afe_sample_rates[port_index] = 0;
8688 this_afe.topology[port_index] = 0;
8689 this_afe.dev_acdb_id[port_index] = 0;
8690 } else {
8691 pr_err("%s: port %d\n", __func__, port_index);
8692 ret = -EINVAL;
8693 goto fail_cmd;
8694 }
8695
8696 if ((port_id == this_afe.aanc_info.aanc_tx_port) &&
8697 (this_afe.aanc_info.aanc_active)) {
8698 memset(&this_afe.aanc_info, 0x00, sizeof(this_afe.aanc_info));
8699 ret = afe_aanc_mod_enable(this_afe.apr, port_id, 0);
8700 if (ret)
8701 pr_err("%s: AFE mod disable failed %d\n",
8702 __func__, ret);
8703 }
8704
8705 /*
8706 * even if ramp down configuration failed it is not serious enough to
8707 * warrant bailaing out.
8708 */
Vangala, Amarnath3e3537e2020-05-13 23:11:14 +05308709 if (q6core_get_avcs_api_version_per_service(
8710 APRV2_IDS_SERVICE_ID_ADSP_AFE_V) < AFE_API_VERSION_V9) {
8711 if (afe_spk_ramp_dn_cfg(port_id) < 0)
8712 pr_err("%s: ramp down config failed\n", __func__);
8713 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308714
8715 stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
8716 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
8717 stop.hdr.pkt_size = sizeof(stop);
8718 stop.hdr.src_port = 0;
8719 stop.hdr.dest_port = 0;
8720 stop.hdr.token = index;
8721 stop.hdr.opcode = AFE_PORT_CMD_DEVICE_STOP;
8722 stop.port_id = q6audio_get_port_id(port_id);
8723 stop.reserved = 0;
8724
8725 ret = afe_apr_send_pkt(&stop, &this_afe.wait[index]);
8726 if (ret)
8727 pr_err("%s: AFE close failed %d\n", __func__, ret);
8728
8729fail_cmd:
Harshal Ahire10e83842020-03-27 04:37:23 +05308730 if ((q6core_get_avcs_api_version_per_service(
8731 APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= AVCS_API_VERSION_V5)) {
8732 for (i = 0; i < MAX_ALLOWED_USE_CASES; i++) {
8733 if (pm[i] && pm[i]->port_id == port_id) {
8734 q6afe_unload_avcs_modules(port_id, i);
8735 break;
8736 }
8737 }
8738 }
Soumya Managolic89e6fb2019-10-14 14:30:17 +05308739 mutex_unlock(&this_afe.afe_cmd_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308740 return ret;
8741}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05308742EXPORT_SYMBOL(afe_close);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308743
8744int afe_set_digital_codec_core_clock(u16 port_id,
8745 struct afe_digital_clk_cfg *cfg)
8746{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008747 struct afe_digital_clk_cfg clk_cfg;
8748 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308749 int ret = 0;
8750
8751 if (!cfg) {
8752 pr_err("%s: clock cfg is NULL\n", __func__);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008753 return -EINVAL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308754 }
8755
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008756 memset(&clk_cfg, 0, sizeof(clk_cfg));
8757 memset(&param_hdr, 0, sizeof(param_hdr));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308758
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308759 /*default rx port is taken to enable the codec digital clock*/
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008760 param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
8761 param_hdr.instance_id = INSTANCE_ID_0;
8762 param_hdr.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG;
8763 param_hdr.param_size = sizeof(struct afe_digital_clk_cfg);
8764 clk_cfg = *cfg;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308765
8766 pr_debug("%s: Minor version =0x%x clk val = %d\n"
8767 "clk root = 0x%x resrv = 0x%x\n",
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008768 __func__, cfg->i2s_cfg_minor_version, cfg->clk_val,
8769 cfg->clk_root, cfg->reserved);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308770
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008771 ret = q6afe_pack_and_set_param_in_band(port_id,
8772 q6audio_get_port_index(port_id),
8773 param_hdr, (u8 *) &clk_cfg);
8774 if (ret < 0)
8775 pr_err("%s: AFE enable for port 0x%x ret %d\n", __func__,
8776 port_id, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308777 return ret;
8778}
8779
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05308780/**
8781 * afe_set_lpass_clock - Enable AFE lpass clock
8782 *
8783 * @port_id: AFE port id
8784 * @cfg: pointer to clk set struct
8785 *
8786 * Returns 0 on success, appropriate error code otherwise
8787 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308788int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg)
8789{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008790 struct afe_clk_cfg clk_cfg;
8791 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308792 int ret = 0;
8793
8794 if (!cfg) {
8795 pr_err("%s: clock cfg is NULL\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308796 return -EINVAL;
8797 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008798
8799 memset(&clk_cfg, 0, sizeof(clk_cfg));
8800 memset(&param_hdr, 0, sizeof(param_hdr));
8801
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308802 ret = q6audio_is_digital_pcm_interface(port_id);
8803 if (ret < 0) {
8804 pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n",
8805 __func__, ret);
8806 return -EINVAL;
8807 }
8808
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308809 mutex_lock(&this_afe.afe_cmd_lock);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008810 param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
8811 param_hdr.instance_id = INSTANCE_ID_0;
8812 param_hdr.param_id = AFE_PARAM_ID_LPAIF_CLK_CONFIG;
8813 param_hdr.param_size = sizeof(clk_cfg);
8814 clk_cfg = *cfg;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308815
8816 pr_debug("%s: Minor version =0x%x clk val1 = %d\n"
8817 "clk val2 = %d, clk src = 0x%x\n"
8818 "clk root = 0x%x clk mode = 0x%x resrv = 0x%x\n"
8819 "port id = 0x%x\n",
8820 __func__, cfg->i2s_cfg_minor_version,
8821 cfg->clk_val1, cfg->clk_val2, cfg->clk_src,
8822 cfg->clk_root, cfg->clk_set_mode,
8823 cfg->reserved, q6audio_get_port_id(port_id));
8824
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07008825 trace_printk("%s: Minor version =0x%x clk val1 = %d\n"
8826 "clk val2 = %d, clk src = 0x%x\n"
8827 "clk root = 0x%x clk mode = 0x%x resrv = 0x%x\n"
8828 "port id = 0x%x\n",
8829 __func__, cfg->i2s_cfg_minor_version,
8830 cfg->clk_val1, cfg->clk_val2, cfg->clk_src,
8831 cfg->clk_root, cfg->clk_set_mode,
8832 cfg->reserved, q6audio_get_port_id(port_id));
8833
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08008834 ret = q6afe_pack_and_set_param_in_band(port_id,
8835 q6audio_get_port_index(port_id),
8836 param_hdr, (u8 *) &clk_cfg);
8837 if (ret < 0)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308838 pr_err("%s: AFE enable for port 0x%x ret %d\n",
8839 __func__, port_id, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308840
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308841 mutex_unlock(&this_afe.afe_cmd_lock);
8842 return ret;
8843}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05308844EXPORT_SYMBOL(afe_set_lpass_clock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308845
Surendar Karkacf3f8e62020-01-24 14:35:07 +05308846static int afe_get_port_idx(u16 port_id)
8847{
8848 u16 afe_port = 0;
8849 int i = -EINVAL;
8850
8851 pr_debug("%s: port id 0x%x\n", __func__, port_id);
8852
8853 if ((port_id >= AFE_PORT_ID_TDM_PORT_RANGE_START) &&
8854 (port_id <= AFE_PORT_ID_TDM_PORT_RANGE_END))
8855 afe_port = port_id & 0xFFF0;
8856 else if ((port_id == AFE_PORT_ID_PRIMARY_SPDIF_RX) ||
8857 (port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) ||
8858 (port_id == AFE_PORT_ID_SECONDARY_SPDIF_RX) ||
8859 (port_id == AFE_PORT_ID_SECONDARY_SPDIF_TX))
8860 afe_port = port_id;
8861 else
8862 afe_port = port_id & 0xFFFE;
8863
8864 for (i = 0; i < ARRAY_SIZE(clkinfo_per_port); i++) {
8865 if (afe_port == clkinfo_per_port[i].port_id) {
8866 pr_debug("%s: idx 0x%x port id 0x%x\n", __func__,
8867 i, afe_port);
8868 return i;
8869 }
8870 }
8871
8872 pr_debug("%s: cannot get idx for port id 0x%x\n", __func__,
8873 afe_port);
8874
8875 return -EINVAL;
8876}
8877
8878static int afe_get_clk_id(u16 port_id)
8879{
8880 u16 afe_port = 0;
8881 uint32_t clk_id = -EINVAL;
8882 int idx = 0;
8883
8884 idx = afe_get_port_idx(port_id);
8885 if (idx < 0) {
8886 pr_err("%s: cannot get clock id for port id 0x%x\n", __func__,
8887 afe_port);
8888 return -EINVAL;
8889 }
8890
8891 clk_id = clkinfo_per_port[idx].clk_id;
8892 pr_debug("%s: clk id 0x%x port id 0x%x\n", __func__, clk_id,
8893 afe_port);
8894
8895 return clk_id;
8896}
8897
8898/**
8899 * afe_set_clk_id - Update clock id for AFE port
8900 *
8901 * @port_id: AFE port id
8902 * @clk_id: CLock ID
8903 *
8904 * Returns 0 on success, appropriate error code otherwise
8905 */
8906int afe_set_clk_id(u16 port_id, uint32_t clk_id)
8907{
8908 u16 afe_port = 0;
8909 int idx = 0;
8910
8911 idx = afe_get_port_idx(port_id);
8912 if (idx < 0) {
8913 pr_debug("%s: cannot set clock id for port id 0x%x\n", __func__,
8914 afe_port);
8915 return -EINVAL;
8916 }
8917
8918 clkinfo_per_port[idx].clk_id = clk_id;
8919 pr_debug("%s: updated clk id 0x%x port id 0x%x\n", __func__,
8920 clkinfo_per_port[idx].clk_id, afe_port);
8921
8922 return 0;
8923}
8924EXPORT_SYMBOL(afe_set_clk_id);
8925
8926/**
8927 * afe_set_pll_clk_drift - Set audio interface PLL clock drift
8928 *
8929 * @port_id: AFE port id
8930 * @set_clk_drift: clk drift to adjust PLL
8931 * @clk_reset: reset Interface clock to original value
8932 *
8933 * Returns 0 on success, appropriate error code otherwise
8934 */
8935int afe_set_pll_clk_drift(u16 port_id, int32_t set_clk_drift,
8936 uint32_t clk_reset)
8937{
8938 struct afe_set_clk_drift clk_drift;
8939 struct param_hdr_v3 param_hdr;
8940 uint32_t clk_id;
8941 int index = 0, ret = 0;
8942
8943 memset(&param_hdr, 0, sizeof(param_hdr));
8944 memset(&clk_drift, 0, sizeof(clk_drift));
8945
8946 index = q6audio_get_port_index(port_id);
8947 if (index < 0 || index >= AFE_MAX_PORTS) {
8948 pr_err("%s: index[%d] invalid!\n", __func__, index);
8949 return -EINVAL;
8950 }
8951
8952 ret = afe_q6_interface_prepare();
8953 if (ret != 0) {
8954 pr_err_ratelimited("%s: Q6 interface prepare failed %d\n",
8955 __func__, ret);
8956 return ret;
8957 }
8958
8959 clk_id = afe_get_clk_id(port_id);
8960 if (clk_id < 0) {
8961 pr_err("%s: cannot get clk id for port id 0x%x\n",
8962 __func__, port_id);
8963 return -EINVAL;
8964 }
8965
8966 if (clk_id & 0x01) {
8967 pr_err("%s: cannot adjust clock drift for external clock id 0x%x\n",
8968 __func__, clk_id);
8969 return -EINVAL;
8970 }
8971
8972 clk_drift.clk_drift = set_clk_drift;
8973 clk_drift.clk_reset = clk_reset;
8974 clk_drift.clk_id = clk_id;
8975 pr_debug("%s: clk id = 0x%x clk drift = %d clk reset = %d port id 0x%x\n",
8976 __func__, clk_drift.clk_id, clk_drift.clk_drift,
8977 clk_drift.clk_reset, port_id);
8978
8979 mutex_lock(&this_afe.afe_clk_lock);
8980 param_hdr.module_id = AFE_MODULE_CLOCK_SET;
8981 param_hdr.instance_id = INSTANCE_ID_0;
8982 param_hdr.param_id = AFE_PARAM_ID_CLOCK_ADJUST;
8983 param_hdr.param_size = sizeof(struct afe_set_clk_drift);
8984
8985 ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr,
8986 (u8 *) &clk_drift);
8987 if (ret < 0)
8988 pr_err_ratelimited("%s: AFE PLL clk drift failed with ret %d\n",
8989 __func__, ret);
8990
8991 mutex_unlock(&this_afe.afe_clk_lock);
8992 return ret;
8993}
8994EXPORT_SYMBOL(afe_set_pll_clk_drift);
8995
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308996/**
8997 * afe_set_lpass_clk_cfg - Set AFE clk config
8998 *
8999 * @index: port index
9000 * @cfg: pointer to clk set struct
9001 *
9002 * Returns 0 on success, appropriate error code otherwise
9003 */
9004int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg)
9005{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009006 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309007 int ret = 0;
9008
9009 if (!cfg) {
9010 pr_err("%s: clock cfg is NULL\n", __func__);
9011 ret = -EINVAL;
9012 return ret;
9013 }
9014
9015 if (index < 0 || index >= AFE_MAX_PORTS) {
9016 pr_err("%s: index[%d] invalid!\n", __func__, index);
9017 return -EINVAL;
9018 }
9019
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009020 memset(&param_hdr, 0, sizeof(param_hdr));
9021
Meng Wang9eacb962019-11-19 09:16:55 +08009022 mutex_lock(&this_afe.afe_clk_lock);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009023 param_hdr.module_id = AFE_MODULE_CLOCK_SET;
9024 param_hdr.instance_id = INSTANCE_ID_0;
9025 param_hdr.param_id = AFE_PARAM_ID_CLOCK_SET;
9026 param_hdr.param_size = sizeof(struct afe_clk_set);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309027
9028
9029 pr_debug("%s: Minor version =0x%x clk id = %d\n"
9030 "clk freq (Hz) = %d, clk attri = 0x%x\n"
9031 "clk root = 0x%x clk enable = 0x%x\n",
9032 __func__, cfg->clk_set_minor_version,
9033 cfg->clk_id, cfg->clk_freq_in_hz, cfg->clk_attri,
9034 cfg->clk_root, cfg->enable);
9035
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07009036 trace_printk("%s: Minor version =0x%x clk id = %d\n"
9037 "clk freq (Hz) = %d, clk attri = 0x%x\n"
9038 "clk root = 0x%x clk enable = 0x%x\n",
9039 __func__, cfg->clk_set_minor_version,
9040 cfg->clk_id, cfg->clk_freq_in_hz, cfg->clk_attri,
9041 cfg->clk_root, cfg->enable);
9042
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009043 ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr,
9044 (u8 *) cfg);
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07009045 if (ret < 0) {
Ramprasad Katkam14efed62019-03-07 13:16:50 +05309046 pr_err_ratelimited("%s: AFE clk cfg failed with ret %d\n",
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07009047 __func__, ret);
9048 trace_printk("%s: AFE clk cfg failed with ret %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309049 __func__, ret);
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07009050 }
Meng Wang9eacb962019-11-19 09:16:55 +08009051 mutex_unlock(&this_afe.afe_clk_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309052 return ret;
9053}
9054EXPORT_SYMBOL(afe_set_lpass_clk_cfg);
9055
9056/**
9057 * afe_set_lpass_clock_v2 - Enable AFE lpass clock
9058 *
9059 * @port_id: AFE port id
9060 * @cfg: pointer to clk set struct
9061 *
9062 * Returns 0 on success, appropriate error code otherwise
9063 */
9064int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg)
9065{
9066 int index = 0;
9067 int ret = 0;
9068
9069 index = q6audio_get_port_index(port_id);
9070 if (index < 0 || index >= AFE_MAX_PORTS) {
9071 pr_err("%s: AFE port index[%d] invalid!\n",
9072 __func__, index);
9073 return -EINVAL;
9074 }
9075 ret = q6audio_is_digital_pcm_interface(port_id);
9076 if (ret < 0) {
9077 pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n",
9078 __func__, ret);
9079 return -EINVAL;
9080 }
9081
Surendar Karkacf3f8e62020-01-24 14:35:07 +05309082 ret = afe_set_clk_id(port_id, cfg->clk_id);
9083 if (ret < 0)
9084 pr_debug("%s: afe_set_clk_id fail %d\n", __func__, ret);
9085
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309086 ret = afe_set_lpass_clk_cfg(index, cfg);
9087 if (ret)
9088 pr_err("%s: afe_set_lpass_clk_cfg_v2 failed %d\n",
9089 __func__, ret);
9090
9091 return ret;
9092}
9093EXPORT_SYMBOL(afe_set_lpass_clock_v2);
9094
9095int afe_set_lpass_internal_digital_codec_clock(u16 port_id,
9096 struct afe_digital_clk_cfg *cfg)
9097{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009098 struct afe_digital_clk_cfg clk_cfg;
9099 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309100 int ret = 0;
9101
9102 if (!cfg) {
9103 pr_err("%s: clock cfg is NULL\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309104 return -EINVAL;
9105 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009106
9107 memset(&clk_cfg, 0, sizeof(clk_cfg));
9108 memset(&param_hdr, 0, sizeof(param_hdr));
9109
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309110 ret = q6audio_is_digital_pcm_interface(port_id);
9111 if (ret < 0) {
9112 pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n",
9113 __func__, ret);
9114 return -EINVAL;
9115 }
9116
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009117 param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
9118 param_hdr.instance_id = INSTANCE_ID_0;
9119 param_hdr.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG;
9120 param_hdr.param_size = sizeof(clk_cfg);
9121 clk_cfg = *cfg;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309122
9123 pr_debug("%s: Minor version =0x%x clk val = %d\n"
9124 "clk root = 0x%x resrv = 0x%x port id = 0x%x\n",
9125 __func__, cfg->i2s_cfg_minor_version,
9126 cfg->clk_val, cfg->clk_root, cfg->reserved,
9127 q6audio_get_port_id(port_id));
9128
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009129 ret = q6afe_pack_and_set_param_in_band(port_id,
9130 q6audio_get_port_index(port_id),
9131 param_hdr, (u8 *) &clk_cfg);
9132 if (ret < 0)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309133 pr_err("%s: AFE enable for port 0x0x%x ret %d\n",
9134 __func__, port_id, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309135
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309136 return ret;
9137}
Josh Kirsch22533092019-01-17 16:01:08 -08009138/**
9139 * afe_enable_lpass_core_shared_clock -
9140 * Configures the core clk on LPASS.
9141 * Need on targets where lpass provides
9142 * clocks
9143 * @port_id: afe port id
9144 * @enable: enable or disable clk
9145 *
9146 * Returns success or failure of call.
9147 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309148int afe_enable_lpass_core_shared_clock(u16 port_id, u32 enable)
9149{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009150 struct afe_param_id_lpass_core_shared_clk_cfg clk_cfg;
9151 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309152 int ret = 0;
9153
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009154 memset(&clk_cfg, 0, sizeof(clk_cfg));
9155 memset(&param_hdr, 0, sizeof(param_hdr));
9156
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309157 ret = q6audio_is_digital_pcm_interface(port_id);
9158 if (ret < 0) {
9159 pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n",
9160 __func__, ret);
9161 return -EINVAL;
9162 }
9163
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309164 mutex_lock(&this_afe.afe_cmd_lock);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009165 param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
9166 param_hdr.instance_id = INSTANCE_ID_0;
9167 param_hdr.param_id = AFE_PARAM_ID_LPASS_CORE_SHARED_CLOCK_CONFIG;
9168 param_hdr.param_size = sizeof(clk_cfg);
9169 clk_cfg.lpass_core_shared_clk_cfg_minor_version =
9170 AFE_API_VERSION_LPASS_CORE_SHARED_CLK_CONFIG;
9171 clk_cfg.enable = enable;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309172
9173 pr_debug("%s: port id = %d, enable = %d\n",
9174 __func__, q6audio_get_port_id(port_id), enable);
9175
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009176 ret = q6afe_pack_and_set_param_in_band(port_id,
9177 q6audio_get_port_index(port_id),
9178 param_hdr, (u8 *) &clk_cfg);
9179 if (ret < 0)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309180 pr_err("%s: AFE enable for port 0x%x ret %d\n",
9181 __func__, port_id, ret);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309182
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309183 mutex_unlock(&this_afe.afe_cmd_lock);
9184 return ret;
9185}
Josh Kirsch22533092019-01-17 16:01:08 -08009186EXPORT_SYMBOL(afe_enable_lpass_core_shared_clock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309187
Josh Kirsch22533092019-01-17 16:01:08 -08009188/**
9189 * q6afe_check_osr_clk_freq -
9190 * Gets supported OSR CLK frequencies
9191 *
9192 * @freq: frequency to check
9193 *
9194 * Returns success if freq is supported.
9195 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309196int q6afe_check_osr_clk_freq(u32 freq)
9197{
9198 int ret = 0;
9199
9200 switch (freq) {
9201 case Q6AFE_LPASS_OSR_CLK_12_P288_MHZ:
Karthikeyan Mani0575b672017-12-10 23:50:37 -08009202 case Q6AFE_LPASS_OSR_CLK_9_P600_MHZ:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309203 case Q6AFE_LPASS_OSR_CLK_8_P192_MHZ:
9204 case Q6AFE_LPASS_OSR_CLK_6_P144_MHZ:
9205 case Q6AFE_LPASS_OSR_CLK_4_P096_MHZ:
9206 case Q6AFE_LPASS_OSR_CLK_3_P072_MHZ:
9207 case Q6AFE_LPASS_OSR_CLK_2_P048_MHZ:
9208 case Q6AFE_LPASS_OSR_CLK_1_P536_MHZ:
9209 case Q6AFE_LPASS_OSR_CLK_1_P024_MHZ:
9210 case Q6AFE_LPASS_OSR_CLK_768_kHZ:
9211 case Q6AFE_LPASS_OSR_CLK_512_kHZ:
9212 break;
9213 default:
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009214 pr_err("%s: default freq 0x%x\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309215 __func__, freq);
9216 ret = -EINVAL;
9217 }
9218 return ret;
9219}
Josh Kirsch22533092019-01-17 16:01:08 -08009220EXPORT_SYMBOL(q6afe_check_osr_clk_freq);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309221
Vangala, Amarnath78732302020-04-09 03:57:14 +05309222static int afe_get_spv4_th_vi_v_vali_data(void *params, uint32_t size)
9223{
9224 struct param_hdr_v3 param_hdr;
9225 int port = SLIMBUS_4_TX;
9226 int ret = -EINVAL;
Vangala, Amarnathe1815842020-07-14 03:39:52 +05309227 uint32_t min_size = 0;
9228 struct afe_sp_v4_channel_v_vali_params *v_vali_params = NULL;
Vangala, Amarnath78732302020-04-09 03:57:14 +05309229
9230 if (!params) {
9231 pr_err("%s: Invalid params\n", __func__);
9232 goto done;
9233 }
9234 if (this_afe.vi_tx_port != -1)
9235 port = this_afe.vi_tx_port;
9236
9237 mutex_lock(&this_afe.afe_cmd_lock);
9238 memset(&param_hdr, 0, sizeof(param_hdr));
9239
9240 param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI;
9241 param_hdr.instance_id = INSTANCE_ID_0;
9242 param_hdr.param_id = AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_PARAMS;
9243 param_hdr.param_size = size;
9244
9245 ret = q6afe_get_params(port, NULL, &param_hdr);
9246 if (ret) {
9247 pr_err("%s: Failed to get TH VI V-Vali data\n", __func__);
9248 goto get_params_fail;
9249 }
9250
Vangala, Amarnathe1815842020-07-14 03:39:52 +05309251 min_size = (size < this_afe.spv4_v_vali_rcvd_param_size) ?
9252 size : this_afe.spv4_v_vali_rcvd_param_size;
9253 memcpy(params, (void*)&this_afe.spv4_v_vali_resp.num_ch, min_size);
Vangala, Amarnath78732302020-04-09 03:57:14 +05309254
Vangala, Amarnathe1815842020-07-14 03:39:52 +05309255 v_vali_params = &this_afe.spv4_v_vali_resp.ch_v_vali_params[0];
Vangala, Amarnath78732302020-04-09 03:57:14 +05309256
Vangala, Amarnathe1815842020-07-14 03:39:52 +05309257 pr_debug("%s: num_ch %d Vrms %d %d status %d %d\n", __func__,
9258 this_afe.spv4_v_vali_resp.num_ch,
Vangala, Amarnath78732302020-04-09 03:57:14 +05309259 v_vali_params[SP_V2_SPKR_1].vrms_q24,
9260 v_vali_params[SP_V2_SPKR_2].vrms_q24,
9261 v_vali_params[SP_V2_SPKR_1].status,
9262 v_vali_params[SP_V2_SPKR_2].status);
9263
9264 /*using the non-spv4 status varaible to support v_vali debug app. */
9265 this_afe.th_vi_v_vali_resp.param.status[SP_V2_SPKR_1] =
9266 v_vali_params[SP_V2_SPKR_1].status;
9267 this_afe.th_vi_v_vali_resp.param.status[SP_V2_SPKR_2] =
9268 v_vali_params[SP_V2_SPKR_2].status;
9269
9270 ret = 0;
9271get_params_fail:
Vangala, Amarnath78732302020-04-09 03:57:14 +05309272 mutex_unlock(&this_afe.afe_cmd_lock);
9273done:
9274 return ret;
9275}
9276
Laxminath Kasam2e13d952019-02-20 15:05:39 +05309277static int afe_get_sp_th_vi_v_vali_data(
9278 struct afe_sp_th_vi_v_vali_get_param *th_vi_v_vali)
9279{
9280 struct param_hdr_v3 param_hdr;
9281 int port = SLIMBUS_4_TX;
9282 int ret = -EINVAL;
9283
9284 if (!th_vi_v_vali) {
9285 pr_err("%s: Invalid params\n", __func__);
9286 goto done;
9287 }
9288 if (this_afe.vi_tx_port != -1)
9289 port = this_afe.vi_tx_port;
9290
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009291 mutex_lock(&this_afe.afe_cmd_lock);
Laxminath Kasam2e13d952019-02-20 15:05:39 +05309292 memset(&param_hdr, 0, sizeof(param_hdr));
9293
9294 param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI;
9295 param_hdr.instance_id = INSTANCE_ID_0;
9296 param_hdr.param_id = AFE_PARAM_ID_SP_V2_TH_VI_V_VALI_PARAMS;
9297 param_hdr.param_size = sizeof(struct afe_sp_th_vi_v_vali_params);
9298
9299 ret = q6afe_get_params(port, NULL, &param_hdr);
9300 if (ret) {
9301 pr_err("%s: Failed to get TH VI V-Vali data\n", __func__);
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009302 goto get_params_fail;
Laxminath Kasam2e13d952019-02-20 15:05:39 +05309303 }
9304
9305 th_vi_v_vali->pdata = param_hdr;
9306 memcpy(&th_vi_v_vali->param, &this_afe.th_vi_v_vali_resp.param,
9307 sizeof(this_afe.th_vi_v_vali_resp.param));
9308 pr_debug("%s: Vrms %d %d status %d %d\n", __func__,
9309 th_vi_v_vali->param.vrms_q24[SP_V2_SPKR_1],
9310 th_vi_v_vali->param.vrms_q24[SP_V2_SPKR_2],
9311 th_vi_v_vali->param.status[SP_V2_SPKR_1],
9312 th_vi_v_vali->param.status[SP_V2_SPKR_2]);
9313 ret = 0;
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009314get_params_fail:
9315 mutex_unlock(&this_afe.afe_cmd_lock);
Laxminath Kasam2e13d952019-02-20 15:05:39 +05309316done:
9317 return ret;
9318}
9319
Vangala, Amarnath78732302020-04-09 03:57:14 +05309320static int afe_get_spv4_th_vi_ftm_data(void *params, uint32_t size)
9321{
9322 struct param_hdr_v3 param_hdr;
9323 int port = SLIMBUS_4_TX;
9324 int ret = -EINVAL;
Vangala, Amarnathe1815842020-07-14 03:39:52 +05309325 uint32_t min_size = 0;
Vangala, Amarnath78732302020-04-09 03:57:14 +05309326 struct afe_sp_v4_channel_ftm_params *th_vi_params;
9327
9328 if (!params) {
9329 pr_err("%s: Invalid params\n", __func__);
9330 goto done;
9331 }
9332 if (this_afe.vi_tx_port != -1)
9333 port = this_afe.vi_tx_port;
9334
9335 mutex_lock(&this_afe.afe_cmd_lock);
9336 memset(&param_hdr, 0, sizeof(param_hdr));
9337
9338 param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI;
9339 param_hdr.instance_id = INSTANCE_ID_0;
9340 param_hdr.param_id = AFE_PARAM_ID_SP_V4_TH_VI_FTM_PARAMS;
9341 param_hdr.param_size = size;
9342
9343 ret = q6afe_get_params(port, NULL, &param_hdr);
9344 if (ret) {
9345 pr_err("%s: Failed to get TH VI FTM data\n", __func__);
9346 goto get_params_fail;
9347 }
9348
Vangala, Amarnathe1815842020-07-14 03:39:52 +05309349 min_size = (size < this_afe.spv4_th_vi_ftm_rcvd_param_size) ?
9350 size : this_afe.spv4_th_vi_ftm_rcvd_param_size;
9351 memcpy(params, (void*)&this_afe.spv4_th_vi_ftm_resp.num_ch, min_size);
Vangala, Amarnath78732302020-04-09 03:57:14 +05309352
Vangala, Amarnathe1815842020-07-14 03:39:52 +05309353 th_vi_params = &this_afe.spv4_th_vi_ftm_resp.ch_ftm_params[0];
9354 pr_debug("%s:num_ch %d, DC resistance %d %d temp %d %d status %d %d\n",
9355 __func__, this_afe.spv4_th_vi_ftm_resp.num_ch,
9356 th_vi_params[SP_V2_SPKR_1].dc_res_q24,
9357 th_vi_params[SP_V2_SPKR_2].dc_res_q24,
9358 th_vi_params[SP_V2_SPKR_1].temp_q22,
9359 th_vi_params[SP_V2_SPKR_2].temp_q22,
9360 th_vi_params[SP_V2_SPKR_1].status,
9361 th_vi_params[SP_V2_SPKR_2].status);
Vangala, Amarnath78732302020-04-09 03:57:14 +05309362 ret = 0;
9363get_params_fail:
Vangala, Amarnath78732302020-04-09 03:57:14 +05309364 mutex_unlock(&this_afe.afe_cmd_lock);
9365done:
9366 return ret;
9367}
9368
9369static int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309370{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009371 struct param_hdr_v3 param_hdr;
9372 int port = SLIMBUS_4_TX;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309373 int ret = -EINVAL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309374
9375 if (!th_vi) {
9376 pr_err("%s: Invalid params\n", __func__);
9377 goto done;
9378 }
9379 if (this_afe.vi_tx_port != -1)
9380 port = this_afe.vi_tx_port;
9381
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009382 mutex_lock(&this_afe.afe_cmd_lock);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009383 memset(&param_hdr, 0, sizeof(param_hdr));
9384
9385 param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI;
9386 param_hdr.instance_id = INSTANCE_ID_0;
9387 param_hdr.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS;
9388 param_hdr.param_size = sizeof(struct afe_sp_th_vi_ftm_params);
9389
9390 ret = q6afe_get_params(port, NULL, &param_hdr);
9391 if (ret) {
9392 pr_err("%s: Failed to get TH VI FTM data\n", __func__);
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009393 goto get_params_fail;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309394 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009395
9396 th_vi->pdata = param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309397 memcpy(&th_vi->param, &this_afe.th_vi_resp.param,
9398 sizeof(this_afe.th_vi_resp.param));
9399 pr_debug("%s: DC resistance %d %d temp %d %d status %d %d\n",
9400 __func__, th_vi->param.dc_res_q24[SP_V2_SPKR_1],
9401 th_vi->param.dc_res_q24[SP_V2_SPKR_2],
9402 th_vi->param.temp_q22[SP_V2_SPKR_1],
9403 th_vi->param.temp_q22[SP_V2_SPKR_2],
9404 th_vi->param.status[SP_V2_SPKR_1],
9405 th_vi->param.status[SP_V2_SPKR_2]);
9406 ret = 0;
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009407get_params_fail:
9408 mutex_unlock(&this_afe.afe_cmd_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309409done:
9410 return ret;
9411}
9412
Vangala, Amarnath78732302020-04-09 03:57:14 +05309413static int afe_get_spv4_ex_vi_ftm_data(void *params, uint32_t size)
9414{
9415 struct param_hdr_v3 param_hdr;
9416 int port = SLIMBUS_4_TX;
9417 int ret = -EINVAL;
Vangala, Amarnathe1815842020-07-14 03:39:52 +05309418 uint32_t min_size = 0;
Vangala, Amarnath78732302020-04-09 03:57:14 +05309419 struct afe_sp_v4_channel_ex_vi_ftm_params *ex_vi_ftm_param;
9420
9421 if (!params) {
9422 pr_err("%s: Invalid params\n", __func__);
9423 goto done;
9424 }
9425 if (this_afe.vi_tx_port != -1)
9426 port = this_afe.vi_tx_port;
9427
9428 mutex_lock(&this_afe.afe_cmd_lock);
9429 memset(&param_hdr, 0, sizeof(param_hdr));
9430
9431 param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI;
9432 param_hdr.instance_id = INSTANCE_ID_0;
9433 param_hdr.param_id = AFE_PARAM_ID_SP_V4_EX_VI_FTM_PARAMS;
9434 param_hdr.param_size = size;
9435
9436 ret = q6afe_get_params(port, NULL, &param_hdr);
9437 if (ret < 0) {
9438 pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n",
9439 __func__, port, param_hdr.param_id, ret);
9440 goto get_params_fail;
9441 }
9442
Vangala, Amarnathe1815842020-07-14 03:39:52 +05309443 min_size = (size < this_afe.spv4_ex_vi_ftm_rcvd_param_size) ?
9444 size : this_afe.spv4_ex_vi_ftm_rcvd_param_size;
9445 memcpy(params, (void*)&this_afe.spv4_ex_vi_ftm_resp.num_ch, min_size);
Vangala, Amarnath78732302020-04-09 03:57:14 +05309446
Vangala, Amarnathe1815842020-07-14 03:39:52 +05309447 ex_vi_ftm_param = &this_afe.spv4_ex_vi_ftm_resp.ch_ex_vi_ftm_params[0];
Vangala, Amarnath78732302020-04-09 03:57:14 +05309448
Vangala, Amarnathe1815842020-07-14 03:39:52 +05309449 pr_debug("%s:num_ch %d, res %d %d forcefactor %d %d Dmping kg/s %d %d\n"
Vangala, Amarnath78732302020-04-09 03:57:14 +05309450 "stiffness N/mm %d %d freq %d %d Qfactor %d %d status %d %d",
Vangala, Amarnathe1815842020-07-14 03:39:52 +05309451 __func__, this_afe.spv4_ex_vi_ftm_resp.num_ch,
9452 ex_vi_ftm_param[SP_V2_SPKR_1].ftm_re_q24,
Vangala, Amarnath78732302020-04-09 03:57:14 +05309453 ex_vi_ftm_param[SP_V2_SPKR_2].ftm_re_q24,
9454 ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Bl_q24,
9455 ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Bl_q24,
9456 ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Rms_q24,
9457 ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Rms_q24,
9458 ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Kms_q24,
9459 ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Kms_q24,
9460 ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Fres_q20,
9461 ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Fres_q20,
9462 ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Qms_q24,
9463 ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Qms_q24,
9464 ex_vi_ftm_param[SP_V2_SPKR_1].status,
9465 ex_vi_ftm_param[SP_V2_SPKR_2].status);
9466 ret = 0;
9467get_params_fail:
Vangala, Amarnath78732302020-04-09 03:57:14 +05309468 mutex_unlock(&this_afe.afe_cmd_lock);
9469done:
9470 return ret;
9471}
9472
9473static int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309474{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009475 struct param_hdr_v3 param_hdr;
9476 int port = SLIMBUS_4_TX;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309477 int ret = -EINVAL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309478
9479 if (!ex_vi) {
9480 pr_err("%s: Invalid params\n", __func__);
9481 goto done;
9482 }
9483 if (this_afe.vi_tx_port != -1)
9484 port = this_afe.vi_tx_port;
9485
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009486 mutex_lock(&this_afe.afe_cmd_lock);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009487 memset(&param_hdr, 0, sizeof(param_hdr));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309488
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009489 param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI;
9490 param_hdr.instance_id = INSTANCE_ID_0;
9491 param_hdr.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS;
9492 param_hdr.param_size = sizeof(struct afe_sp_ex_vi_ftm_params);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309493
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009494 ret = q6afe_get_params(port, NULL, &param_hdr);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309495 if (ret < 0) {
9496 pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n",
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009497 __func__, port, param_hdr.param_id, ret);
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009498 goto get_params_fail;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309499 }
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009500
9501 ex_vi->pdata = param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309502 memcpy(&ex_vi->param, &this_afe.ex_vi_resp.param,
9503 sizeof(this_afe.ex_vi_resp.param));
9504 pr_debug("%s: freq %d %d resistance %d %d qfactor %d %d state %d %d\n",
9505 __func__, ex_vi->param.freq_q20[SP_V2_SPKR_1],
9506 ex_vi->param.freq_q20[SP_V2_SPKR_2],
9507 ex_vi->param.resis_q24[SP_V2_SPKR_1],
9508 ex_vi->param.resis_q24[SP_V2_SPKR_2],
9509 ex_vi->param.qmct_q24[SP_V2_SPKR_1],
9510 ex_vi->param.qmct_q24[SP_V2_SPKR_2],
9511 ex_vi->param.status[SP_V2_SPKR_1],
9512 ex_vi->param.status[SP_V2_SPKR_2]);
9513 ret = 0;
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009514get_params_fail:
9515 mutex_unlock(&this_afe.afe_cmd_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309516done:
9517 return ret;
9518}
9519
Vangala, Amarnath78732302020-04-09 03:57:14 +05309520int afe_get_sp_v4_rx_tmax_xmax_logging_data(
9521 struct afe_sp_rx_tmax_xmax_logging_param *xt_logging,
9522 u16 port_id)
9523{
9524 struct param_hdr_v3 param_hdr;
9525 int ret = -EINVAL;
Vangala, Amarnath78732302020-04-09 03:57:14 +05309526 struct afe_sp_v4_channel_tmax_xmax_params *tx_channel_params;
9527 uint32_t i, size = 0;
9528
9529 if (!xt_logging) {
9530 pr_err("%s: Invalid params\n", __func__);
9531 goto done;
9532 }
9533
9534 size = sizeof(struct afe_sp_v4_param_tmax_xmax_logging) +
9535 (SP_V2_NUM_MAX_SPKRS *
9536 sizeof(struct afe_sp_v4_channel_tmax_xmax_params));
9537 memset(&param_hdr, 0, sizeof(param_hdr));
9538
9539 param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_RX;
9540 param_hdr.instance_id = INSTANCE_ID_0;
9541 param_hdr.param_id = AFE_PARAM_ID_SP_V4_RX_TMAX_XMAX_LOGGING;
9542 param_hdr.param_size = size;
9543
9544 ret = q6afe_get_params(port_id, NULL, &param_hdr);
9545 if (ret) {
9546 pr_err("%s: Failed to get Tmax Xmax logging data\n", __func__);
9547 goto get_params_fail;
9548 }
9549
Vangala, Amarnathe1815842020-07-14 03:39:52 +05309550 tx_channel_params = &this_afe.spv4_max_log_resp.ch_max_params[0];
9551 for (i = 0; i < this_afe.spv4_max_log_resp.num_ch; i++) {
9552
Vangala, Amarnath78732302020-04-09 03:57:14 +05309553 xt_logging->max_excursion[i] =
9554 tx_channel_params[i].max_excursion;
9555 xt_logging->count_exceeded_excursion[i] =
9556 tx_channel_params[i].count_exceeded_excursion;
9557 xt_logging->max_temperature[i] =
9558 tx_channel_params[i].max_temperature;
9559 xt_logging->count_exceeded_temperature[i] =
9560 tx_channel_params[i].count_exceeded_temperature;
9561 }
9562
9563 ret = 0;
9564get_params_fail:
Vangala, Amarnath78732302020-04-09 03:57:14 +05309565done:
9566 return ret;
9567}
9568
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05309569/**
Aditya Bavanari740b4832018-12-24 18:46:12 +05309570 * afe_get_sp_rx_tmax_xmax_logging_data -
9571 * command to get excursion logging data from DSP
9572 *
9573 * @xt_logging: excursion logging params
9574 * @port: AFE port ID
9575 *
9576 * Returns 0 on success or error on failure
9577 */
9578int afe_get_sp_rx_tmax_xmax_logging_data(
9579 struct afe_sp_rx_tmax_xmax_logging_param *xt_logging,
9580 u16 port_id)
9581{
9582 struct param_hdr_v3 param_hdr;
9583 int ret = -EINVAL;
9584
9585 if (!xt_logging) {
9586 pr_err("%s: Invalid params\n", __func__);
9587 goto done;
9588 }
9589
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009590 mutex_lock(&this_afe.afe_cmd_lock);
Vangala, Amarnath78732302020-04-09 03:57:14 +05309591 if (q6core_get_avcs_api_version_per_service(
9592 APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) {
9593 ret = afe_get_sp_v4_rx_tmax_xmax_logging_data(xt_logging,
9594 port_id);
9595 } else {
9596 memset(&param_hdr, 0, sizeof(param_hdr));
Aditya Bavanari740b4832018-12-24 18:46:12 +05309597
Vangala, Amarnath78732302020-04-09 03:57:14 +05309598 param_hdr.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX;
9599 param_hdr.instance_id = INSTANCE_ID_0;
9600 param_hdr.param_id = AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING;
9601 param_hdr.param_size =
9602 sizeof(struct afe_sp_rx_tmax_xmax_logging_param);
Aditya Bavanari740b4832018-12-24 18:46:12 +05309603
Vangala, Amarnath78732302020-04-09 03:57:14 +05309604 ret = q6afe_get_params(port_id, NULL, &param_hdr);
9605 if (ret < 0) {
9606 pr_err(
9607 "%s: get param port 0x%x param id[0x%x]failed %d\n",
9608 __func__, port_id, param_hdr.param_id, ret);
9609 goto get_params_fail;
9610 }
9611
9612 memcpy(xt_logging, &this_afe.xt_logging_resp.param,
9613 sizeof(this_afe.xt_logging_resp.param));
Aditya Bavanari740b4832018-12-24 18:46:12 +05309614 }
Vangala, Amarnath78732302020-04-09 03:57:14 +05309615 pr_debug("%s: max_excursion %d %d count_exceeded_excursion %d %d"
9616 " max_temperature %d %d count_exceeded_temperature %d %d\n",
Aditya Bavanari740b4832018-12-24 18:46:12 +05309617 __func__, xt_logging->max_excursion[SP_V2_SPKR_1],
9618 xt_logging->max_excursion[SP_V2_SPKR_2],
9619 xt_logging->count_exceeded_excursion[SP_V2_SPKR_1],
9620 xt_logging->count_exceeded_excursion[SP_V2_SPKR_2],
9621 xt_logging->max_temperature[SP_V2_SPKR_1],
9622 xt_logging->max_temperature[SP_V2_SPKR_2],
9623 xt_logging->count_exceeded_temperature[SP_V2_SPKR_1],
9624 xt_logging->count_exceeded_temperature[SP_V2_SPKR_2]);
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009625get_params_fail:
9626 mutex_unlock(&this_afe.afe_cmd_lock);
Aditya Bavanari740b4832018-12-24 18:46:12 +05309627done:
9628 return ret;
9629}
9630EXPORT_SYMBOL(afe_get_sp_rx_tmax_xmax_logging_data);
9631
9632/**
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05309633 * afe_get_av_dev_drift -
9634 * command to retrieve AV drift
9635 *
9636 * @timing_stats: timing stats to be updated with AV drift values
9637 * @port: AFE port ID
9638 *
9639 * Returns 0 on success or error on failure
9640 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309641int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats,
9642 u16 port)
9643{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009644 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309645 int ret = -EINVAL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309646
9647 if (!timing_stats) {
9648 pr_err("%s: Invalid params\n", __func__);
9649 goto exit;
9650 }
9651
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009652 mutex_lock(&this_afe.afe_cmd_lock);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009653 memset(&param_hdr, 0, sizeof(param_hdr));
9654 param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
9655 param_hdr.instance_id = INSTANCE_ID_0;
9656 param_hdr.param_id = AFE_PARAM_ID_DEV_TIMING_STATS;
9657 param_hdr.param_size = sizeof(struct afe_param_id_dev_timing_stats);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309658
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009659 ret = q6afe_get_params(port, NULL, &param_hdr);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309660 if (ret < 0) {
9661 pr_err("%s: get param port 0x%x param id[0x%x] failed %d\n",
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009662 __func__, port, param_hdr.param_id, ret);
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009663 goto get_params_fail;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309664 }
9665
9666 memcpy(timing_stats, &this_afe.av_dev_drift_resp.timing_stats,
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009667 param_hdr.param_size);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309668 ret = 0;
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009669get_params_fail:
9670 mutex_unlock(&this_afe.afe_cmd_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309671exit:
9672 return ret;
9673}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05309674EXPORT_SYMBOL(afe_get_av_dev_drift);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309675
Chaithanya Krishna Bacharaju8c6a1842018-11-16 15:02:39 +05309676/**
9677 * afe_get_doa_tracking_mon -
9678 * command to retrieve doa tracking monitor data
9679 *
9680 * @port: AFE port ID
9681 * @doa_tracking_data: param to be updated with doa tracking data
9682 *
9683 * Returns 0 on success or error on failure
9684 */
9685int afe_get_doa_tracking_mon(u16 port,
9686 struct doa_tracking_mon_param *doa_tracking_data)
9687{
9688 struct param_hdr_v3 param_hdr;
9689 int ret = -EINVAL, i = 0;
9690
9691 if (!doa_tracking_data) {
9692 pr_err("%s: Invalid params\n", __func__);
9693 goto exit;
9694 }
9695
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009696 mutex_lock(&this_afe.afe_cmd_lock);
Chaithanya Krishna Bacharaju8c6a1842018-11-16 15:02:39 +05309697 memset(&param_hdr, 0, sizeof(param_hdr));
9698 param_hdr.module_id = AUDPROC_MODULE_ID_FFNS;
9699 param_hdr.instance_id = INSTANCE_ID_0;
9700 param_hdr.param_id = AUDPROC_PARAM_ID_FFV_DOA_TRACKING_MONITOR;
9701 param_hdr.param_size = sizeof(struct doa_tracking_mon_param);
9702
9703 ret = q6afe_get_params(port, NULL, &param_hdr);
9704 if (ret < 0) {
9705 pr_err("%s: get param port 0x%x param id[0x%x] failed %d\n",
9706 __func__, port, param_hdr.param_id, ret);
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009707 goto get_params_fail;
Chaithanya Krishna Bacharaju8c6a1842018-11-16 15:02:39 +05309708 }
9709
9710 memcpy(doa_tracking_data, &this_afe.doa_tracking_mon_resp.doa,
9711 param_hdr.param_size);
9712 for (i = 0; i < MAX_DOA_TRACKING_ANGLES; i++) {
9713 pr_debug("%s: target angle[%d] = %d\n",
9714 __func__, i, doa_tracking_data->target_angle_L16[i]);
9715 pr_debug("%s: interference angle[%d] = %d\n",
9716 __func__, i, doa_tracking_data->interf_angle_L16[i]);
9717 }
9718
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009719get_params_fail:
9720 mutex_unlock(&this_afe.afe_cmd_lock);
Chaithanya Krishna Bacharaju8c6a1842018-11-16 15:02:39 +05309721exit:
9722 return ret;
9723}
9724EXPORT_SYMBOL(afe_get_doa_tracking_mon);
9725
Vangala, Amarnath78732302020-04-09 03:57:14 +05309726static int afe_spv4_get_calib_data(
9727 struct afe_sp_v4_th_vi_calib_resp *calib_resp)
9728{
9729 struct param_hdr_v3 param_hdr;
9730 int port = SLIMBUS_4_TX;
9731 int ret = -EINVAL;
9732
9733 if (!calib_resp) {
9734 pr_err("%s: Invalid params\n", __func__);
9735 goto fail_cmd;
9736 }
9737 if (this_afe.vi_tx_port != -1)
9738 port = this_afe.vi_tx_port;
9739
9740 mutex_lock(&this_afe.afe_cmd_lock);
9741 memset(&param_hdr, 0, sizeof(param_hdr));
9742 param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI;
9743 param_hdr.instance_id = INSTANCE_ID_0;
9744 param_hdr.param_id = AFE_PARAM_ID_SP_V4_CALIB_RES_CFG;
9745 param_hdr.param_size = sizeof(struct afe_sp_v4_th_vi_calib_resp);
9746
9747 ret = q6afe_get_params(port, NULL, &param_hdr);
9748 if (ret < 0) {
9749 pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n",
9750 __func__, port, param_hdr.param_id, ret);
9751 goto get_params_fail;
9752 }
9753 memcpy(&calib_resp->res_cfg, &this_afe.spv4_calib_data.res_cfg,
9754 sizeof(this_afe.calib_data.res_cfg));
9755 pr_info("%s: state %s resistance %d %d\n", __func__,
9756 fbsp_state[calib_resp->res_cfg.th_vi_ca_state],
9757 calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_1],
9758 calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_2]);
9759 ret = 0;
9760get_params_fail:
9761 mutex_unlock(&this_afe.afe_cmd_lock);
9762fail_cmd:
9763 return ret;
9764}
9765
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309766int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp)
9767{
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009768 struct param_hdr_v3 param_hdr;
9769 int port = SLIMBUS_4_TX;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309770 int ret = -EINVAL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309771
9772 if (!calib_resp) {
9773 pr_err("%s: Invalid params\n", __func__);
9774 goto fail_cmd;
9775 }
9776 if (this_afe.vi_tx_port != -1)
9777 port = this_afe.vi_tx_port;
9778
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009779 mutex_lock(&this_afe.afe_cmd_lock);
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009780 memset(&param_hdr, 0, sizeof(param_hdr));
9781 param_hdr.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2;
9782 param_hdr.instance_id = INSTANCE_ID_0;
9783 param_hdr.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2;
9784 param_hdr.param_size = sizeof(struct afe_spkr_prot_get_vi_calib);
9785
9786 ret = q6afe_get_params(port, NULL, &param_hdr);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309787 if (ret < 0) {
9788 pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n",
Vignesh Kulothungan85073c02018-01-26 10:27:56 -08009789 __func__, port, param_hdr.param_id, ret);
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009790 goto get_params_fail;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309791 }
9792 memcpy(&calib_resp->res_cfg, &this_afe.calib_data.res_cfg,
9793 sizeof(this_afe.calib_data.res_cfg));
9794 pr_info("%s: state %s resistance %d %d\n", __func__,
Laxminath Kasam36384ec2019-02-18 21:57:19 +05309795 fbsp_state[calib_resp->res_cfg.th_vi_ca_state],
9796 calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_1],
9797 calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_2]);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309798 ret = 0;
Karthikeyan Manidaf7d7a2019-09-27 17:51:45 -07009799get_params_fail:
9800 mutex_unlock(&this_afe.afe_cmd_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309801fail_cmd:
9802 return ret;
9803}
9804
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05309805/**
9806 * afe_spk_prot_feed_back_cfg -
9807 * command to setup spk protection feedback config
9808 *
9809 * @src_port: source port id
9810 * @dst_port: destination port id
9811 * @l_ch: left speaker active or not
9812 * @r_ch: right speaker active or not
9813 * @enable: flag to enable or disable
9814 *
9815 * Returns 0 on success or error on failure
9816 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309817int afe_spk_prot_feed_back_cfg(int src_port, int dst_port,
9818 int l_ch, int r_ch, u32 enable)
9819{
9820 int ret = -EINVAL;
9821 union afe_spkr_prot_config prot_config;
9822 int index = 0;
9823
9824 if (!enable) {
9825 pr_debug("%s: Disable Feedback tx path", __func__);
9826 this_afe.vi_tx_port = -1;
9827 this_afe.vi_rx_port = -1;
9828 return 0;
9829 }
9830
9831 if ((q6audio_validate_port(src_port) < 0) ||
9832 (q6audio_validate_port(dst_port) < 0)) {
9833 pr_err("%s: invalid ports src 0x%x dst 0x%x",
9834 __func__, src_port, dst_port);
9835 goto fail_cmd;
9836 }
9837 if (!l_ch && !r_ch) {
9838 pr_err("%s: error ch values zero\n", __func__);
9839 goto fail_cmd;
9840 }
9841 pr_debug("%s: src_port 0x%x dst_port 0x%x l_ch %d r_ch %d\n",
9842 __func__, src_port, dst_port, l_ch, r_ch);
lintaopeie994a2e2021-04-02 14:31:18 +08009843 /*if (q6core_get_avcs_api_version_per_service(
Vangala, Amarnath78732302020-04-09 03:57:14 +05309844 APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) {
9845 if (l_ch) {
9846 this_afe.v4_ch_map_cfg.chan_info[index++] = 1;
9847 this_afe.v4_ch_map_cfg.chan_info[index++] = 2;
9848 }
9849 if (r_ch) {
9850 this_afe.v4_ch_map_cfg.chan_info[index++] = 3;
9851 this_afe.v4_ch_map_cfg.chan_info[index++] = 4;
9852 }
9853 this_afe.v4_ch_map_cfg.num_channels = index;
Vangala, Amarnath3e3537e2020-05-13 23:11:14 +05309854 this_afe.num_spkrs = index / 2;
Vangala, Amarnath78732302020-04-09 03:57:14 +05309855 pr_debug("%s no of channels: %d\n", __func__, index);
9856 this_afe.vi_tx_port = src_port;
9857 this_afe.vi_rx_port = dst_port;
9858 ret = 0;
lintaopeie994a2e2021-04-02 14:31:18 +08009859 } else {*/
Vangala, Amarnath78732302020-04-09 03:57:14 +05309860 memset(&prot_config, 0, sizeof(prot_config));
9861 prot_config.feedback_path_cfg.dst_portid =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309862 q6audio_get_port_id(dst_port);
Vangala, Amarnath78732302020-04-09 03:57:14 +05309863 if (l_ch) {
9864 prot_config.feedback_path_cfg.chan_info[index++] = 1;
9865 prot_config.feedback_path_cfg.chan_info[index++] = 2;
9866 }
9867 if (r_ch) {
9868 prot_config.feedback_path_cfg.chan_info[index++] = 3;
9869 prot_config.feedback_path_cfg.chan_info[index++] = 4;
9870 }
9871 prot_config.feedback_path_cfg.num_channels = index;
9872 pr_debug("%s no of channels: %d\n", __func__, index);
9873 prot_config.feedback_path_cfg.minor_version = 1;
9874 ret = afe_spk_prot_prepare(src_port, dst_port,
9875 AFE_PARAM_ID_FEEDBACK_PATH_CFG, &prot_config,
9876 sizeof(union afe_spkr_prot_config));
lintaopeie994a2e2021-04-02 14:31:18 +08009877// }
Vangala, Amarnath78732302020-04-09 03:57:14 +05309878
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309879fail_cmd:
9880 return ret;
9881}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05309882EXPORT_SYMBOL(afe_spk_prot_feed_back_cfg);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309883
9884static int get_cal_type_index(int32_t cal_type)
9885{
9886 int ret = -EINVAL;
9887
9888 switch (cal_type) {
9889 case AFE_COMMON_RX_CAL_TYPE:
9890 ret = AFE_COMMON_RX_CAL;
9891 break;
9892 case AFE_COMMON_TX_CAL_TYPE:
9893 ret = AFE_COMMON_TX_CAL;
9894 break;
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05309895 case AFE_LSM_TX_CAL_TYPE:
9896 ret = AFE_LSM_TX_CAL;
9897 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309898 case AFE_AANC_CAL_TYPE:
9899 ret = AFE_AANC_CAL;
9900 break;
9901 case AFE_HW_DELAY_CAL_TYPE:
9902 ret = AFE_HW_DELAY_CAL;
9903 break;
9904 case AFE_FB_SPKR_PROT_CAL_TYPE:
9905 ret = AFE_FB_SPKR_PROT_CAL;
9906 break;
9907 case AFE_SIDETONE_CAL_TYPE:
9908 ret = AFE_SIDETONE_CAL;
9909 break;
9910 case AFE_SIDETONE_IIR_CAL_TYPE:
9911 ret = AFE_SIDETONE_IIR_CAL;
9912 break;
9913 case AFE_TOPOLOGY_CAL_TYPE:
9914 ret = AFE_TOPOLOGY_CAL;
9915 break;
Aditya Bavanari3889b4a2017-11-21 19:52:26 +05309916 case AFE_LSM_TOPOLOGY_CAL_TYPE:
9917 ret = AFE_LSM_TOPOLOGY_CAL;
9918 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309919 case AFE_CUST_TOPOLOGY_CAL_TYPE:
9920 ret = AFE_CUST_TOPOLOGY_CAL;
9921 break;
9922 default:
9923 pr_err("%s: invalid cal type %d!\n", __func__, cal_type);
9924 }
9925 return ret;
9926}
9927
9928int afe_alloc_cal(int32_t cal_type, size_t data_size,
9929 void *data)
9930{
9931 int ret = 0;
9932 int cal_index;
9933
9934 cal_index = get_cal_type_index(cal_type);
9935 pr_debug("%s: cal_type = %d cal_index = %d\n",
9936 __func__, cal_type, cal_index);
9937
9938 if (cal_index < 0) {
9939 pr_err("%s: could not get cal index %d!\n",
9940 __func__, cal_index);
9941 ret = -EINVAL;
9942 goto done;
9943 }
9944
Xiaojun Sang41de9e12018-10-16 15:12:47 +08009945 mutex_lock(&this_afe.afe_cmd_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309946 ret = cal_utils_alloc_cal(data_size, data,
9947 this_afe.cal_data[cal_index], 0, NULL);
9948 if (ret < 0) {
9949 pr_err("%s: cal_utils_alloc_block failed, ret = %d, cal type = %d!\n",
9950 __func__, ret, cal_type);
9951 ret = -EINVAL;
Xiaojun Sang41de9e12018-10-16 15:12:47 +08009952 mutex_unlock(&this_afe.afe_cmd_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309953 goto done;
9954 }
Xiaojun Sang41de9e12018-10-16 15:12:47 +08009955 mutex_unlock(&this_afe.afe_cmd_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309956done:
9957 return ret;
9958}
9959
9960static int afe_dealloc_cal(int32_t cal_type, size_t data_size,
9961 void *data)
9962{
9963 int ret = 0;
9964 int cal_index;
9965
9966 pr_debug("%s:\n", __func__);
9967
9968 cal_index = get_cal_type_index(cal_type);
9969 if (cal_index < 0) {
9970 pr_err("%s: could not get cal index %d!\n",
9971 __func__, cal_index);
9972 ret = -EINVAL;
9973 goto done;
9974 }
9975
9976 ret = cal_utils_dealloc_cal(data_size, data,
9977 this_afe.cal_data[cal_index]);
9978 if (ret < 0) {
9979 pr_err("%s: cal_utils_dealloc_block failed, ret = %d, cal type = %d!\n",
9980 __func__, ret, cal_type);
9981 ret = -EINVAL;
9982 goto done;
9983 }
9984done:
9985 return ret;
9986}
9987
9988static int afe_set_cal(int32_t cal_type, size_t data_size,
9989 void *data)
9990{
9991 int ret = 0;
9992 int cal_index;
9993
9994 pr_debug("%s:\n", __func__);
9995
9996 cal_index = get_cal_type_index(cal_type);
9997 if (cal_index < 0) {
9998 pr_err("%s: could not get cal index %d!\n",
9999 __func__, cal_index);
10000 ret = -EINVAL;
10001 goto done;
10002 }
10003
10004 ret = cal_utils_set_cal(data_size, data,
10005 this_afe.cal_data[cal_index], 0, NULL);
10006 if (ret < 0) {
10007 pr_err("%s: cal_utils_set_cal failed, ret = %d, cal type = %d!\n",
10008 __func__, ret, cal_type);
10009 ret = -EINVAL;
10010 goto done;
10011 }
10012
10013 if (cal_index == AFE_CUST_TOPOLOGY_CAL) {
10014 mutex_lock(&this_afe.cal_data[AFE_CUST_TOPOLOGY_CAL]->lock);
10015 this_afe.set_custom_topology = 1;
10016 pr_debug("%s:[AFE_CUSTOM_TOPOLOGY] ret = %d, cal type = %d!\n",
10017 __func__, ret, cal_type);
10018 mutex_unlock(&this_afe.cal_data[AFE_CUST_TOPOLOGY_CAL]->lock);
10019 }
10020
10021done:
10022 return ret;
10023}
10024
10025static struct cal_block_data *afe_find_hw_delay_by_path(
10026 struct cal_type_data *cal_type, int path)
10027{
10028 struct list_head *ptr, *next;
10029 struct cal_block_data *cal_block = NULL;
10030
10031 pr_debug("%s:\n", __func__);
10032
10033 list_for_each_safe(ptr, next,
10034 &cal_type->cal_blocks) {
10035
10036 cal_block = list_entry(ptr,
10037 struct cal_block_data, list);
10038
Vikram Panduranga770b8382017-09-27 12:17:36 -070010039 if (cal_utils_is_cal_stale(cal_block))
10040 continue;
10041
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010042 if (((struct audio_cal_info_hw_delay *)cal_block->cal_info)
10043 ->path == path) {
10044 return cal_block;
10045 }
10046 }
10047 return NULL;
10048}
10049
10050static int afe_get_cal_hw_delay(int32_t path,
10051 struct audio_cal_hw_delay_entry *entry)
10052{
10053 int ret = 0;
10054 int i;
10055 struct cal_block_data *cal_block = NULL;
10056 struct audio_cal_hw_delay_data *hw_delay_info = NULL;
10057
10058 pr_debug("%s:\n", __func__);
10059
10060 if (this_afe.cal_data[AFE_HW_DELAY_CAL] == NULL) {
10061 pr_err("%s: AFE_HW_DELAY_CAL not initialized\n", __func__);
10062 ret = -EINVAL;
10063 goto done;
10064 }
10065 if (entry == NULL) {
10066 pr_err("%s: entry is NULL\n", __func__);
10067 ret = -EINVAL;
10068 goto done;
10069 }
10070 if ((path >= MAX_PATH_TYPE) || (path < 0)) {
10071 pr_err("%s: bad path: %d\n",
10072 __func__, path);
10073 ret = -EINVAL;
10074 goto done;
10075 }
10076
10077 mutex_lock(&this_afe.cal_data[AFE_HW_DELAY_CAL]->lock);
10078 cal_block = afe_find_hw_delay_by_path(
10079 this_afe.cal_data[AFE_HW_DELAY_CAL], path);
10080 if (cal_block == NULL)
10081 goto unlock;
10082
10083 hw_delay_info = &((struct audio_cal_info_hw_delay *)
10084 cal_block->cal_info)->data;
10085 if (hw_delay_info->num_entries > MAX_HW_DELAY_ENTRIES) {
10086 pr_err("%s: invalid num entries: %d\n",
10087 __func__, hw_delay_info->num_entries);
10088 ret = -EINVAL;
10089 goto unlock;
10090 }
10091
10092 for (i = 0; i < hw_delay_info->num_entries; i++) {
10093 if (hw_delay_info->entry[i].sample_rate ==
10094 entry->sample_rate) {
10095 entry->delay_usec = hw_delay_info->entry[i].delay_usec;
10096 break;
10097 }
10098 }
10099 if (i == hw_delay_info->num_entries) {
10100 pr_err("%s: Unable to find delay for sample rate %d\n",
10101 __func__, entry->sample_rate);
10102 ret = -EFAULT;
10103 goto unlock;
10104 }
Vikram Panduranga770b8382017-09-27 12:17:36 -070010105
10106 cal_utils_mark_cal_used(cal_block);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010107 pr_debug("%s: Path = %d samplerate = %u usec = %u status %d\n",
10108 __func__, path, entry->sample_rate, entry->delay_usec, ret);
10109unlock:
10110 mutex_unlock(&this_afe.cal_data[AFE_HW_DELAY_CAL]->lock);
10111done:
10112 return ret;
10113}
10114
Laxminath Kasam2e13d952019-02-20 15:05:39 +053010115static int afe_set_cal_sp_th_vi_v_vali_cfg(int32_t cal_type, size_t data_size,
10116 void *data)
10117{
10118 int ret = 0;
10119 struct audio_cal_type_sp_th_vi_v_vali_cfg *cal_data = data;
10120
10121 if (cal_data == NULL || data_size != sizeof(*cal_data))
10122 goto done;
10123
10124 memcpy(&this_afe.v_vali_cfg, &cal_data->cal_info,
10125 sizeof(this_afe.v_vali_cfg));
10126done:
10127 return ret;
10128}
10129
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010130static int afe_set_cal_sp_th_vi_ftm_cfg(int32_t cal_type, size_t data_size,
10131 void *data)
10132{
10133 int ret = 0;
10134 struct audio_cal_type_sp_th_vi_ftm_cfg *cal_data = data;
10135
Laxminath Kasam2e13d952019-02-20 15:05:39 +053010136 if (cal_data == NULL || data_size != sizeof(*cal_data))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010137 goto done;
10138
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010139 memcpy(&this_afe.th_ftm_cfg, &cal_data->cal_info,
10140 sizeof(this_afe.th_ftm_cfg));
Laxminath Kasam2e13d952019-02-20 15:05:39 +053010141done:
10142 return ret;
10143}
10144
10145static int afe_set_cal_sp_th_vi_cfg(int32_t cal_type, size_t data_size,
10146 void *data)
10147{
10148 int ret = 0;
10149 struct audio_cal_type_sp_th_vi_ftm_cfg *cal_data = data;
10150 uint32_t mode;
10151
10152 if (cal_data == NULL ||
Vatsal Buchaff83a9e2019-09-24 00:33:42 +053010153 data_size > sizeof(*cal_data) ||
Laxminath Kasam2e13d952019-02-20 15:05:39 +053010154 this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL)
10155 goto done;
10156
10157 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
10158 mode = cal_data->cal_info.mode;
10159 pr_debug("%s: cal_type = %d, mode = %d\n", __func__, cal_type, mode);
10160 if (mode == MSM_SPKR_PROT_IN_FTM_MODE) {
10161 ret = afe_set_cal_sp_th_vi_ftm_cfg(cal_type,
10162 data_size, data);
10163 } else if (mode == MSM_SPKR_PROT_IN_V_VALI_MODE) {
10164 ret = afe_set_cal_sp_th_vi_v_vali_cfg(cal_type,
10165 data_size, data);
10166 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010167 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
10168done:
10169 return ret;
10170}
10171
10172static int afe_set_cal_sp_ex_vi_ftm_cfg(int32_t cal_type, size_t data_size,
10173 void *data)
10174{
10175 int ret = 0;
10176 struct audio_cal_type_sp_ex_vi_ftm_cfg *cal_data = data;
10177
10178 if (this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL ||
10179 cal_data == NULL ||
10180 data_size != sizeof(*cal_data))
10181 goto done;
10182
10183 pr_debug("%s: cal_type = %d\n", __func__, cal_type);
10184 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
10185 memcpy(&this_afe.ex_ftm_cfg, &cal_data->cal_info,
10186 sizeof(this_afe.ex_ftm_cfg));
10187 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
10188done:
10189 return ret;
10190}
10191
10192static int afe_set_cal_fb_spkr_prot(int32_t cal_type, size_t data_size,
10193 void *data)
10194{
10195 int ret = 0;
10196 struct audio_cal_type_fb_spk_prot_cfg *cal_data = data;
10197
10198 pr_debug("%s:\n", __func__);
10199
10200 if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL)
10201 goto done;
10202 if (cal_data == NULL)
10203 goto done;
10204 if (data_size != sizeof(*cal_data))
10205 goto done;
10206
10207 if (cal_data->cal_info.mode == MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS)
Meng Wang9524bda2020-03-09 08:37:53 +080010208 __pm_wakeup_event(wl.ws, jiffies_to_msecs(WAKELOCK_TIMEOUT));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010209 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
10210 memcpy(&this_afe.prot_cfg, &cal_data->cal_info,
10211 sizeof(this_afe.prot_cfg));
10212 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
10213done:
10214 return ret;
10215}
10216
Laxminath Kasam2e13d952019-02-20 15:05:39 +053010217static int afe_get_cal_sp_th_vi_v_vali_param(int32_t cal_type, size_t data_size,
10218 void *data)
10219{
10220 int i, ret = 0;
10221 struct audio_cal_type_sp_th_vi_v_vali_param *cal_data = data;
10222 struct afe_sp_th_vi_v_vali_get_param th_vi_v_vali;
Vangala, Amarnath78732302020-04-09 03:57:14 +053010223 uint32_t size;
10224 void *params = NULL;
10225 struct afe_sp_v4_channel_v_vali_params *v_vali_params;
Laxminath Kasam2e13d952019-02-20 15:05:39 +053010226
10227 if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL ||
10228 cal_data == NULL ||
10229 data_size != sizeof(*cal_data))
10230 goto done;
10231
10232 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
10233 cal_data->cal_info.status[i] = -EINVAL;
10234 cal_data->cal_info.vrms_q24[i] = -1;
10235 }
Vangala, Amarnath78732302020-04-09 03:57:14 +053010236 if (q6core_get_avcs_api_version_per_service(
10237 APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) {
10238 size = sizeof(struct afe_sp_v4_param_th_vi_v_vali_params) +
10239 (SP_V2_NUM_MAX_SPKRS *
10240 sizeof(struct afe_sp_v4_channel_v_vali_params));
10241 params = kzalloc(size, GFP_KERNEL);
10242 if (!params)
10243 return -ENOMEM;
10244 v_vali_params =
10245 (struct afe_sp_v4_channel_v_vali_params *)((u8 *)params +
10246 sizeof(struct afe_sp_v4_param_th_vi_v_vali_params));
10247
10248 if (!afe_get_spv4_th_vi_v_vali_data(params, size)) {
10249 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
10250 pr_debug("%s: ftm param status = %d\n",
10251 __func__, v_vali_params[i].status);
10252 if (v_vali_params[i].status ==
10253 V_VALI_IN_PROGRESS) {
10254 cal_data->cal_info.status[i] = -EAGAIN;
10255 } else if (v_vali_params[i].status ==
10256 V_VALI_SUCCESS) {
10257 cal_data->cal_info.status[i] =
10258 V_VALI_SUCCESS;
10259 cal_data->cal_info.vrms_q24[i] =
10260 v_vali_params[i].vrms_q24;
10261 }
10262 }
10263 }
10264 kfree(params);
10265 } else {
10266 if (!afe_get_sp_th_vi_v_vali_data(&th_vi_v_vali)) {
10267 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
10268 pr_debug(
10269 "%s: v-vali param status = %d\n",
10270 __func__, th_vi_v_vali.param.status[i]);
10271 if (th_vi_v_vali.param.status[i] ==
10272 V_VALI_IN_PROGRESS) {
10273 cal_data->cal_info.status[i] = -EAGAIN;
10274 } else if (th_vi_v_vali.param.status[i] ==
10275 V_VALI_SUCCESS) {
10276 cal_data->cal_info.status[i] =
10277 V_VALI_SUCCESS;
10278 cal_data->cal_info.vrms_q24[i] =
10279 th_vi_v_vali.param.vrms_q24[i];
10280 }
Laxminath Kasam2e13d952019-02-20 15:05:39 +053010281 }
10282 }
10283 }
Laxminath Kasam36384ec2019-02-18 21:57:19 +053010284 this_afe.v_vali_flag = 0;
Laxminath Kasam2e13d952019-02-20 15:05:39 +053010285done:
10286 return ret;
10287}
10288
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010289static int afe_get_cal_sp_th_vi_ftm_param(int32_t cal_type, size_t data_size,
10290 void *data)
10291{
10292 int i, ret = 0;
10293 struct audio_cal_type_sp_th_vi_param *cal_data = data;
10294 struct afe_sp_th_vi_get_param th_vi;
Vangala, Amarnath78732302020-04-09 03:57:14 +053010295 uint32_t size;
10296 void *params = NULL;
10297 struct afe_sp_v4_channel_ftm_params *th_vi_ftm_params;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010298
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010299 if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL ||
10300 cal_data == NULL ||
10301 data_size != sizeof(*cal_data))
10302 goto done;
10303
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010304 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
10305 cal_data->cal_info.status[i] = -EINVAL;
10306 cal_data->cal_info.r_dc_q24[i] = -1;
10307 cal_data->cal_info.temp_q22[i] = -1;
10308 }
Vangala, Amarnath78732302020-04-09 03:57:14 +053010309 if (q6core_get_avcs_api_version_per_service(
10310 APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) {
10311 size = sizeof(struct afe_sp_v4_param_th_vi_ftm_params) +
10312 (SP_V2_NUM_MAX_SPKRS *
10313 sizeof(struct afe_sp_v4_channel_ftm_params));
10314 params = kzalloc(size, GFP_KERNEL);
10315 if (!params)
10316 return -ENOMEM;
10317 th_vi_ftm_params = (struct afe_sp_v4_channel_ftm_params *)
10318 ((u8 *)params +
10319 sizeof(struct afe_sp_v4_param_th_vi_ftm_params));
10320
10321 if (!afe_get_spv4_th_vi_ftm_data(params, size)) {
10322 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
10323 pr_debug("%s: SP V4 ftm param status = %d\n",
10324 __func__, th_vi_ftm_params[i].status);
10325 if (th_vi_ftm_params[i].status ==
10326 FBSP_IN_PROGRESS) {
10327 cal_data->cal_info.status[i] = -EAGAIN;
10328 } else if (th_vi_ftm_params[i].status ==
10329 FBSP_SUCCESS) {
10330 cal_data->cal_info.status[i] = 0;
10331 cal_data->cal_info.r_dc_q24[i] =
10332 th_vi_ftm_params[i].dc_res_q24;
10333 cal_data->cal_info.temp_q22[i] =
10334 th_vi_ftm_params[i].temp_q22;
10335 }
10336 }
10337 }
10338 kfree(params);
10339 } else {
10340
10341 if (!afe_get_sp_th_vi_ftm_data(&th_vi)) {
10342 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
10343 pr_debug("%s: ftm param status = %d\n",
10344 __func__, th_vi.param.status[i]);
10345 if (th_vi.param.status[i] == FBSP_IN_PROGRESS) {
10346 cal_data->cal_info.status[i] = -EAGAIN;
10347 } else if (th_vi.param.status[i] ==
10348 FBSP_SUCCESS) {
10349 cal_data->cal_info.status[i] = 0;
10350 cal_data->cal_info.r_dc_q24[i] =
10351 th_vi.param.dc_res_q24[i];
10352 cal_data->cal_info.temp_q22[i] =
10353 th_vi.param.temp_q22[i];
10354 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010355 }
10356 }
10357 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010358done:
10359 return ret;
10360}
10361
Laxminath Kasam2e13d952019-02-20 15:05:39 +053010362static int afe_get_cal_sp_th_vi_param(int32_t cal_type, size_t data_size,
10363 void *data)
10364{
10365 struct audio_cal_type_sp_th_vi_param *cal_data = data;
10366 uint32_t mode;
10367 int ret = 0;
10368
10369 if (cal_data == NULL ||
Vatsal Buchaff83a9e2019-09-24 00:33:42 +053010370 data_size > sizeof(*cal_data) ||
Kunlei Zhang34df55a2021-02-24 11:25:41 +080010371 data_size < sizeof(cal_data->cal_hdr) ||
Laxminath Kasam2e13d952019-02-20 15:05:39 +053010372 this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL)
10373 return 0;
10374
10375 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
10376 mode = cal_data->cal_info.mode;
10377 pr_debug("%s: cal_type = %d,mode = %d\n", __func__, cal_type, mode);
10378 if (mode == MSM_SPKR_PROT_IN_V_VALI_MODE)
10379 ret = afe_get_cal_sp_th_vi_v_vali_param(cal_type,
10380 data_size, data);
10381 else
10382 ret = afe_get_cal_sp_th_vi_ftm_param(cal_type,
10383 data_size, data);
10384 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock);
10385 return ret;
10386}
10387
Vangala, Amarnath78732302020-04-09 03:57:14 +053010388static int afe_get_cal_spv4_ex_vi_ftm_param(int32_t cal_type, size_t data_size,
10389 void *data)
10390{
10391 int i, ret = 0;
10392 struct audio_cal_type_sp_v4_ex_vi_param *cal_data = data;
10393 uint32_t size;
10394 void *params = NULL;
10395 struct afe_sp_v4_channel_ex_vi_ftm_params *ex_vi_ftm_param;
10396
10397 pr_debug("%s: cal_type = %d\n", __func__, cal_type);
10398 if (this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL] == NULL ||
10399 cal_data == NULL ||
Kunlei Zhang34df55a2021-02-24 11:25:41 +080010400 data_size > sizeof(*cal_data) ||
10401 data_size < sizeof(cal_data->cal_hdr))
Vangala, Amarnath78732302020-04-09 03:57:14 +053010402 goto done;
10403
10404 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL]->lock);
10405 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
10406 cal_data->cal_info.status[i] = -EINVAL;
10407 cal_data->cal_info.ftm_re_q24[i] = -1;
10408 cal_data->cal_info.ftm_re_q24[i] = -1;
10409 cal_data->cal_info.ftm_Rms_q24[i] = -1;
10410 cal_data->cal_info.ftm_Kms_q24[i] = -1;
10411 cal_data->cal_info.ftm_freq_q20[i] = -1;
10412 cal_data->cal_info.ftm_Qms_q24[i] = -1;
10413 }
10414
10415 size = sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) +
10416 (SP_V2_NUM_MAX_SPKRS *
10417 sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params));
10418 params = kzalloc(size, GFP_KERNEL);
10419 if (!params) {
10420 mutex_unlock(
10421 &this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL]->lock);
10422 return -ENOMEM;
10423 }
10424 ex_vi_ftm_param = (struct afe_sp_v4_channel_ex_vi_ftm_params *)
10425 ((u8 *)params +
10426 sizeof(struct afe_sp_v4_param_ex_vi_ftm_params));
10427
10428 if (!afe_get_spv4_ex_vi_ftm_data(params, size)) {
10429 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
10430 pr_debug("%s: ftm param status = %d\n",
10431 __func__, ex_vi_ftm_param[i].status);
10432 if (ex_vi_ftm_param[i].status == FBSP_IN_PROGRESS) {
10433 cal_data->cal_info.status[i] = -EAGAIN;
10434 } else if (ex_vi_ftm_param[i].status == FBSP_SUCCESS) {
10435 cal_data->cal_info.status[i] = 0;
10436 cal_data->cal_info.ftm_re_q24[i] =
10437 ex_vi_ftm_param[i].ftm_re_q24;
10438 cal_data->cal_info.ftm_Bl_q24[i] =
10439 ex_vi_ftm_param[i].ftm_Bl_q24;
10440 cal_data->cal_info.ftm_Rms_q24[i] =
10441 ex_vi_ftm_param[i].ftm_Rms_q24;
10442 cal_data->cal_info.ftm_Kms_q24[i] =
10443 ex_vi_ftm_param[i].ftm_Kms_q24;
10444 cal_data->cal_info.ftm_freq_q20[i] =
10445 ex_vi_ftm_param[i].ftm_Fres_q20;
10446 cal_data->cal_info.ftm_Qms_q24[i] =
10447 ex_vi_ftm_param[i].ftm_Qms_q24;
10448 }
10449 }
10450 }
10451 kfree(params);
10452
10453 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL]->lock);
10454done:
10455 return ret;
10456}
10457
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010458static int afe_get_cal_sp_ex_vi_ftm_param(int32_t cal_type, size_t data_size,
10459 void *data)
10460{
10461 int i, ret = 0;
10462 struct audio_cal_type_sp_ex_vi_param *cal_data = data;
10463 struct afe_sp_ex_vi_get_param ex_vi;
10464
10465 pr_debug("%s: cal_type = %d\n", __func__, cal_type);
10466 if (this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL ||
10467 cal_data == NULL ||
Kunlei Zhang34df55a2021-02-24 11:25:41 +080010468 data_size > sizeof(*cal_data) ||
10469 data_size < sizeof(cal_data->cal_hdr))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010470 goto done;
10471
10472 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
10473 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
10474 cal_data->cal_info.status[i] = -EINVAL;
10475 cal_data->cal_info.freq_q20[i] = -1;
10476 cal_data->cal_info.resis_q24[i] = -1;
10477 cal_data->cal_info.qmct_q24[i] = -1;
10478 }
10479 if (!afe_get_sp_ex_vi_ftm_data(&ex_vi)) {
10480 for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) {
10481 pr_debug("%s: ftm param status = %d\n",
10482 __func__, ex_vi.param.status[i]);
10483 if (ex_vi.param.status[i] == FBSP_IN_PROGRESS) {
10484 cal_data->cal_info.status[i] = -EAGAIN;
10485 } else if (ex_vi.param.status[i] == FBSP_SUCCESS) {
10486 cal_data->cal_info.status[i] = 0;
10487 cal_data->cal_info.freq_q20[i] =
10488 ex_vi.param.freq_q20[i];
10489 cal_data->cal_info.resis_q24[i] =
10490 ex_vi.param.resis_q24[i];
10491 cal_data->cal_info.qmct_q24[i] =
10492 ex_vi.param.qmct_q24[i];
10493 }
10494 }
10495 }
10496 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
10497done:
10498 return ret;
10499}
10500
10501static int afe_get_cal_fb_spkr_prot(int32_t cal_type, size_t data_size,
10502 void *data)
10503{
10504 int ret = 0;
10505 struct audio_cal_type_fb_spk_prot_status *cal_data = data;
10506 struct afe_spkr_prot_get_vi_calib calib_resp;
Vangala, Amarnath78732302020-04-09 03:57:14 +053010507 struct afe_sp_v4_th_vi_calib_resp spv4_calib_resp;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010508
10509 pr_debug("%s:\n", __func__);
10510
10511 if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL)
10512 goto done;
10513 if (cal_data == NULL)
10514 goto done;
10515 if (data_size != sizeof(*cal_data))
10516 goto done;
10517
10518 mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
10519 if (this_afe.prot_cfg.mode == MSM_SPKR_PROT_CALIBRATED) {
10520 cal_data->cal_info.r0[SP_V2_SPKR_1] =
10521 this_afe.prot_cfg.r0[SP_V2_SPKR_1];
10522 cal_data->cal_info.r0[SP_V2_SPKR_2] =
10523 this_afe.prot_cfg.r0[SP_V2_SPKR_2];
10524 cal_data->cal_info.status = 0;
10525 } else if (this_afe.prot_cfg.mode ==
10526 MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) {
10527 /*Call AFE to query the status*/
10528 cal_data->cal_info.status = -EINVAL;
10529 cal_data->cal_info.r0[SP_V2_SPKR_1] = -1;
10530 cal_data->cal_info.r0[SP_V2_SPKR_2] = -1;
Vangala, Amarnath78732302020-04-09 03:57:14 +053010531 if (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9) {
10532 if (!(q6core_get_avcs_api_version_per_service(
10533 APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >=
10534 AFE_API_VERSION_V9)) {
10535 pr_debug(
10536 "%s: AFE API version is not supported!\n",
10537 __func__);
10538 goto done;
10539 }
10540 if (!afe_spv4_get_calib_data(&spv4_calib_resp)) {
10541 if (spv4_calib_resp.res_cfg.th_vi_ca_state ==
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010542 FBSP_IN_PROGRESS)
Vangala, Amarnath78732302020-04-09 03:57:14 +053010543 cal_data->cal_info.status = -EAGAIN;
10544 else if (
10545 spv4_calib_resp.res_cfg.th_vi_ca_state ==
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010546 FBSP_SUCCESS) {
Vangala, Amarnath78732302020-04-09 03:57:14 +053010547 cal_data->cal_info.status = 0;
10548 cal_data->cal_info.r0[SP_V2_SPKR_1] =
10549 spv4_calib_resp.res_cfg.r0_cali_q24[
10550 SP_V2_SPKR_1];
10551 cal_data->cal_info.r0[SP_V2_SPKR_2] =
10552 spv4_calib_resp.res_cfg.r0_cali_q24[
10553 SP_V2_SPKR_2];
10554 }
10555 }
10556 } else {
10557
10558 if (!afe_spk_prot_get_calib_data(&calib_resp)) {
10559 if (calib_resp.res_cfg.th_vi_ca_state ==
10560 FBSP_IN_PROGRESS)
10561 cal_data->cal_info.status = -EAGAIN;
10562 else if (calib_resp.res_cfg.th_vi_ca_state ==
10563 FBSP_SUCCESS) {
10564 cal_data->cal_info.status = 0;
10565 cal_data->cal_info.r0[SP_V2_SPKR_1] =
10566 calib_resp.res_cfg.r0_cali_q24[
10567 SP_V2_SPKR_1];
10568 cal_data->cal_info.r0[SP_V2_SPKR_2] =
10569 calib_resp.res_cfg.r0_cali_q24[
10570 SP_V2_SPKR_2];
10571 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010572 }
10573 }
10574 if (!cal_data->cal_info.status) {
10575 this_afe.prot_cfg.mode =
10576 MSM_SPKR_PROT_CALIBRATED;
10577 this_afe.prot_cfg.r0[SP_V2_SPKR_1] =
10578 cal_data->cal_info.r0[SP_V2_SPKR_1];
10579 this_afe.prot_cfg.r0[SP_V2_SPKR_2] =
10580 cal_data->cal_info.r0[SP_V2_SPKR_2];
10581 }
10582 } else {
10583 /*Indicates calibration data is invalid*/
10584 cal_data->cal_info.status = -EINVAL;
10585 cal_data->cal_info.r0[SP_V2_SPKR_1] = -1;
10586 cal_data->cal_info.r0[SP_V2_SPKR_2] = -1;
10587 }
Laxminath Kasam36384ec2019-02-18 21:57:19 +053010588 this_afe.initial_cal = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010589 mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
Meng Wang9524bda2020-03-09 08:37:53 +080010590 __pm_relax(wl.ws);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010591done:
10592 return ret;
10593}
10594
10595static int afe_map_cal_data(int32_t cal_type,
10596 struct cal_block_data *cal_block)
10597{
10598 int ret = 0;
10599 int cal_index;
10600
10601 pr_debug("%s:\n", __func__);
10602
10603 cal_index = get_cal_type_index(cal_type);
10604 if (cal_index < 0) {
10605 pr_err("%s: could not get cal index %d!\n",
10606 __func__, cal_index);
10607 ret = -EINVAL;
10608 goto done;
10609 }
10610
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010611 atomic_set(&this_afe.mem_map_cal_index, cal_index);
10612 ret = afe_cmd_memory_map(cal_block->cal_data.paddr,
10613 cal_block->map_data.map_size);
10614 atomic_set(&this_afe.mem_map_cal_index, -1);
10615 if (ret < 0) {
10616 pr_err("%s: mmap did not work! size = %zd ret %d\n",
10617 __func__,
10618 cal_block->map_data.map_size, ret);
10619 pr_debug("%s: mmap did not work! addr = 0x%pK, size = %zd\n",
10620 __func__,
10621 &cal_block->cal_data.paddr,
10622 cal_block->map_data.map_size);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010623 goto done;
10624 }
10625 cal_block->map_data.q6map_handle = atomic_read(&this_afe.
10626 mem_map_cal_handles[cal_index]);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010627done:
10628 return ret;
10629}
10630
10631static int afe_unmap_cal_data(int32_t cal_type,
10632 struct cal_block_data *cal_block)
10633{
10634 int ret = 0;
10635 int cal_index;
10636
10637 pr_debug("%s:\n", __func__);
10638
10639 cal_index = get_cal_type_index(cal_type);
10640 if (cal_index < 0) {
10641 pr_err("%s: could not get cal index %d!\n",
10642 __func__, cal_index);
10643 ret = -EINVAL;
10644 goto done;
10645 }
10646
10647 if (cal_block == NULL) {
10648 pr_err("%s: Cal block is NULL!\n",
10649 __func__);
10650 goto done;
10651 }
10652
10653 if (cal_block->map_data.q6map_handle == 0) {
10654 pr_err("%s: Map handle is NULL, nothing to unmap\n",
10655 __func__);
10656 goto done;
10657 }
10658
10659 atomic_set(&this_afe.mem_map_cal_handles[cal_index],
10660 cal_block->map_data.q6map_handle);
10661 atomic_set(&this_afe.mem_map_cal_index, cal_index);
10662 ret = afe_cmd_memory_unmap_nowait(
10663 cal_block->map_data.q6map_handle);
10664 atomic_set(&this_afe.mem_map_cal_index, -1);
10665 if (ret < 0) {
10666 pr_err("%s: unmap did not work! cal_type %i ret %d\n",
10667 __func__, cal_index, ret);
10668 }
10669 cal_block->map_data.q6map_handle = 0;
10670done:
10671 return ret;
10672}
10673
10674static void afe_delete_cal_data(void)
10675{
10676 pr_debug("%s:\n", __func__);
10677
10678 cal_utils_destroy_cal_types(MAX_AFE_CAL_TYPES, this_afe.cal_data);
10679}
10680
10681static int afe_init_cal_data(void)
10682{
10683 int ret = 0;
10684 struct cal_type_info cal_type_info[] = {
10685 {{AFE_COMMON_RX_CAL_TYPE,
10686 {afe_alloc_cal, afe_dealloc_cal, NULL,
10687 afe_set_cal, NULL, NULL} },
10688 {afe_map_cal_data, afe_unmap_cal_data,
10689 cal_utils_match_buf_num} },
10690
10691 {{AFE_COMMON_TX_CAL_TYPE,
10692 {afe_alloc_cal, afe_dealloc_cal, NULL,
10693 afe_set_cal, NULL, NULL} },
10694 {afe_map_cal_data, afe_unmap_cal_data,
10695 cal_utils_match_buf_num} },
10696
Aditya Bavanari3889b4a2017-11-21 19:52:26 +053010697 {{AFE_LSM_TX_CAL_TYPE,
10698 {afe_alloc_cal, afe_dealloc_cal, NULL,
10699 afe_set_cal, NULL, NULL} },
10700 {afe_map_cal_data, afe_unmap_cal_data,
10701 cal_utils_match_buf_num} },
10702
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010703 {{AFE_AANC_CAL_TYPE,
10704 {afe_alloc_cal, afe_dealloc_cal, NULL,
10705 afe_set_cal, NULL, NULL} },
10706 {afe_map_cal_data, afe_unmap_cal_data,
10707 cal_utils_match_buf_num} },
10708
10709 {{AFE_FB_SPKR_PROT_CAL_TYPE,
10710 {NULL, NULL, NULL, afe_set_cal_fb_spkr_prot,
10711 afe_get_cal_fb_spkr_prot, NULL} },
10712 {NULL, NULL, cal_utils_match_buf_num} },
10713
10714 {{AFE_HW_DELAY_CAL_TYPE,
10715 {NULL, NULL, NULL,
10716 afe_set_cal, NULL, NULL} },
10717 {NULL, NULL, cal_utils_match_buf_num} },
10718
10719 {{AFE_SIDETONE_CAL_TYPE,
10720 {NULL, NULL, NULL,
10721 afe_set_cal, NULL, NULL} },
10722 {NULL, NULL, cal_utils_match_buf_num} },
10723
10724 {{AFE_SIDETONE_IIR_CAL_TYPE,
10725 {NULL, NULL, NULL,
10726 afe_set_cal, NULL, NULL} },
10727 {NULL, NULL, cal_utils_match_buf_num} },
10728
10729 {{AFE_TOPOLOGY_CAL_TYPE,
10730 {NULL, NULL, NULL,
10731 afe_set_cal, NULL, NULL} },
10732 {NULL, NULL,
10733 cal_utils_match_buf_num} },
10734
Aditya Bavanari3889b4a2017-11-21 19:52:26 +053010735 {{AFE_LSM_TOPOLOGY_CAL_TYPE,
10736 {NULL, NULL, NULL,
10737 afe_set_cal, NULL, NULL} },
10738 {NULL, NULL,
10739 cal_utils_match_buf_num} },
10740
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010741 {{AFE_CUST_TOPOLOGY_CAL_TYPE,
10742 {afe_alloc_cal, afe_dealloc_cal, NULL,
10743 afe_set_cal, NULL, NULL} },
10744 {afe_map_cal_data, afe_unmap_cal_data,
10745 cal_utils_match_buf_num} },
10746
10747 {{AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE,
Laxminath Kasam2e13d952019-02-20 15:05:39 +053010748 {NULL, NULL, NULL, afe_set_cal_sp_th_vi_cfg,
10749 afe_get_cal_sp_th_vi_param, NULL} },
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010750 {NULL, NULL, cal_utils_match_buf_num} },
10751
10752 {{AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE,
10753 {NULL, NULL, NULL, afe_set_cal_sp_ex_vi_ftm_cfg,
10754 afe_get_cal_sp_ex_vi_ftm_param, NULL} },
10755 {NULL, NULL, cal_utils_match_buf_num} },
Vangala, Amarnath78732302020-04-09 03:57:14 +053010756
10757 {{AFE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE,
10758 {NULL, NULL, NULL, NULL,
10759 afe_get_cal_spv4_ex_vi_ftm_param, NULL} },
10760 {NULL, NULL, cal_utils_match_buf_num} },
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010761 };
10762 pr_debug("%s:\n", __func__);
10763
10764 ret = cal_utils_create_cal_types(MAX_AFE_CAL_TYPES, this_afe.cal_data,
10765 cal_type_info);
10766 if (ret < 0) {
10767 pr_err("%s: could not create cal type! %d\n",
10768 __func__, ret);
10769 ret = -EINVAL;
10770 goto err;
10771 }
10772
10773 return ret;
10774err:
10775 afe_delete_cal_data();
10776 return ret;
10777}
10778
10779int afe_map_rtac_block(struct rtac_cal_block_data *cal_block)
10780{
10781 int result = 0;
10782
10783 pr_debug("%s:\n", __func__);
10784
10785 if (cal_block == NULL) {
10786 pr_err("%s: cal_block is NULL!\n",
10787 __func__);
10788 result = -EINVAL;
10789 goto done;
10790 }
10791
10792 if (cal_block->cal_data.paddr == 0) {
10793 pr_debug("%s: No address to map!\n",
10794 __func__);
10795 result = -EINVAL;
10796 goto done;
10797 }
10798
10799 if (cal_block->map_data.map_size == 0) {
10800 pr_debug("%s: map size is 0!\n",
10801 __func__);
10802 result = -EINVAL;
10803 goto done;
10804 }
10805
10806 result = afe_cmd_memory_map(cal_block->cal_data.paddr,
10807 cal_block->map_data.map_size);
10808 if (result < 0) {
10809 pr_err("%s: afe_cmd_memory_map failed for addr = 0x%pK, size = %d, err %d\n",
10810 __func__, &cal_block->cal_data.paddr,
10811 cal_block->map_data.map_size, result);
10812 return result;
10813 }
10814 cal_block->map_data.map_handle = this_afe.mmap_handle;
10815
10816done:
10817 return result;
10818}
10819
10820int afe_unmap_rtac_block(uint32_t *mem_map_handle)
10821{
10822 int result = 0;
10823
10824 pr_debug("%s:\n", __func__);
10825
10826 if (mem_map_handle == NULL) {
10827 pr_err("%s: Map handle is NULL, nothing to unmap\n",
10828 __func__);
10829 goto done;
10830 }
10831
10832 if (*mem_map_handle == 0) {
10833 pr_debug("%s: Map handle is 0, nothing to unmap\n",
10834 __func__);
10835 goto done;
10836 }
10837
10838 result = afe_cmd_memory_unmap(*mem_map_handle);
10839 if (result) {
10840 pr_err("%s: AFE memory unmap failed %d, handle 0x%x\n",
10841 __func__, result, *mem_map_handle);
10842 goto done;
10843 } else {
10844 *mem_map_handle = 0;
10845 }
10846
10847done:
10848 return result;
10849}
10850
Vignesh Kulothunganc3f38982018-05-22 18:08:20 -070010851static void afe_release_uevent_data(struct kobject *kobj)
10852{
10853 struct audio_uevent_data *data = container_of(kobj,
10854 struct audio_uevent_data, kobj);
10855
10856 kfree(data);
10857}
lintaopei746b0122021-03-16 19:35:42 +080010858#ifdef CONFIG_SND_SMARTPA_AW882XX
10859struct aw_afe_func aw_func= {
10860 .afe_get_topology = afe_get_topology,
10861 .aw_send_afe_cal_apr = aw_send_afe_cal_apr,
10862 .aw_send_afe_rx_module_enable = aw_send_afe_rx_module_enable,
10863 .aw_send_afe_tx_module_enable = aw_send_afe_tx_module_enable,
10864// .aw_adm_param_enable = aw_adm_param_enable;
10865};
10866#endif
Laxminath Kasam8b1366a2017-10-05 01:44:16 +053010867int __init afe_init(void)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010868{
10869 int i = 0, ret;
10870
10871 atomic_set(&this_afe.state, 0);
10872 atomic_set(&this_afe.status, 0);
Meng Wang9eacb962019-11-19 09:16:55 +080010873 atomic_set(&this_afe.clk_state, 0);
10874 atomic_set(&this_afe.clk_status, 0);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010875 atomic_set(&this_afe.mem_map_cal_index, -1);
10876 this_afe.apr = NULL;
10877 this_afe.dtmf_gen_rx_portid = -1;
10878 this_afe.mmap_handle = 0;
10879 this_afe.vi_tx_port = -1;
10880 this_afe.vi_rx_port = -1;
Laxminath Kasam688db8a2019-11-05 13:11:30 +053010881 for (i = 0; i < AFE_LPASS_CORE_HW_VOTE_MAX; i++)
10882 this_afe.lpass_hw_core_client_hdl[i] = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010883 this_afe.prot_cfg.mode = MSM_SPKR_PROT_DISABLED;
10884 this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED;
10885 this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED;
10886 mutex_init(&this_afe.afe_cmd_lock);
Aditya Bavanarid6546e32019-10-29 17:24:59 +053010887 mutex_init(&this_afe.afe_apr_lock);
Meng Wang9eacb962019-11-19 09:16:55 +080010888 mutex_init(&this_afe.afe_clk_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010889 for (i = 0; i < AFE_MAX_PORTS; i++) {
10890 this_afe.afe_cal_mode[i] = AFE_CAL_MODE_DEFAULT;
10891 this_afe.afe_sample_rates[i] = 0;
10892 this_afe.dev_acdb_id[i] = 0;
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +053010893 this_afe.island_mode[i] = 0;
10894 this_afe.vad_cfg[i].is_enable = 0;
10895 this_afe.vad_cfg[i].pre_roll = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010896 init_waitqueue_head(&this_afe.wait[i]);
10897 }
Ramprasad Katkam250075f2018-08-31 03:31:54 +053010898 init_waitqueue_head(&this_afe.wait_wakeup);
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +053010899 init_waitqueue_head(&this_afe.lpass_core_hw_wait);
Meng Wang9eacb962019-11-19 09:16:55 +080010900 init_waitqueue_head(&this_afe.clk_wait);
Soumya Managoliadeb3312020-11-27 15:43:55 +053010901 for (i = 0; i < MAX_LSM_SESSIONS; i++)
10902 this_afe.lsm_afe_ports[i] = 0xffff;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010903 ret = afe_init_cal_data();
10904 if (ret)
10905 pr_err("%s: could not init cal data! %d\n", __func__, ret);
10906
10907 config_debug_fs_init();
lintaopei746b0122021-03-16 19:35:42 +080010908#ifdef CONFIG_SND_SMARTPA_AW882XX
10909 aw_reg_fae_func(&aw_func);
10910#endif
Vignesh Kulothunganc3f38982018-05-22 18:08:20 -070010911 this_afe.uevent_data = kzalloc(sizeof(*(this_afe.uevent_data)), GFP_KERNEL);
10912 if (!this_afe.uevent_data)
10913 return -ENOMEM;
Meng Wang9524bda2020-03-09 08:37:53 +080010914#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 110))
10915 wl.ws = wakeup_source_register(NULL, "spkr-prot");
10916#else
10917 wl.ws = wakeup_source_register("spkr-prot");
10918#endif
Vangala, Amarnath78732302020-04-09 03:57:14 +053010919 /*
Vignesh Kulothunganc3f38982018-05-22 18:08:20 -070010920 * Set release function to cleanup memory related to kobject
10921 * before initializing the kobject.
10922 */
10923 this_afe.uevent_data->ktype.release = afe_release_uevent_data;
10924 q6core_init_uevent_data(this_afe.uevent_data, "q6afe_uevent");
10925
Xiaoyu Yebaf28392018-06-22 15:22:27 -070010926 INIT_WORK(&this_afe.afe_dc_work, afe_notify_dc_presence_work_fn);
Ralf Herz044e4762018-09-10 11:04:16 +020010927 INIT_WORK(&this_afe.afe_spdif_work,
10928 afe_notify_spdif_fmt_update_work_fn);
Xiaoyu Yebaf28392018-06-22 15:22:27 -070010929
Ramprasad Katkam250075f2018-08-31 03:31:54 +053010930 this_afe.event_notifier.notifier_call = afe_aud_event_notify;
10931 msm_aud_evt_blocking_register_client(&this_afe.event_notifier);
10932
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010933 return 0;
10934}
10935
Asish Bhattacharya5faacb32017-12-04 17:23:15 +053010936void afe_exit(void)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010937{
Laxminath Kasam30ad7512017-11-28 12:40:22 +053010938 if (this_afe.apr) {
10939 apr_reset(this_afe.apr);
10940 atomic_set(&this_afe.state, 0);
10941 this_afe.apr = NULL;
10942 rtac_set_afe_handle(this_afe.apr);
10943 }
Vignesh Kulothunganc3f38982018-05-22 18:08:20 -070010944
10945 q6core_destroy_uevent_data(this_afe.uevent_data);
10946
lintaopei746b0122021-03-16 19:35:42 +080010947#ifdef CONFIG_SND_SMARTPA_AW882XX
10948 aw_cal_unmap_memory();
10949#endif
10950
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010951 afe_delete_cal_data();
10952
10953 config_debug_fs_exit();
10954 mutex_destroy(&this_afe.afe_cmd_lock);
Aditya Bavanarid6546e32019-10-29 17:24:59 +053010955 mutex_destroy(&this_afe.afe_apr_lock);
Meng Wang9eacb962019-11-19 09:16:55 +080010956 mutex_destroy(&this_afe.afe_clk_lock);
Meng Wang9524bda2020-03-09 08:37:53 +080010957 wakeup_source_unregister(wl.ws);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010958}
Mangesh Kunchamwar4e1e7182018-04-26 17:58:58 +053010959
10960/*
10961 * afe_cal_init_hwdep -
10962 * Initiliaze AFE HW dependent Node
10963 *
10964 * @card: pointer to sound card
10965 *
10966 */
10967int afe_cal_init_hwdep(void *card)
10968{
10969 int ret = 0;
10970
10971 this_afe.fw_data = kzalloc(sizeof(*(this_afe.fw_data)),
10972 GFP_KERNEL);
10973 if (!this_afe.fw_data)
10974 return -ENOMEM;
10975
10976 set_bit(Q6AFE_VAD_CORE_CAL, this_afe.fw_data->cal_bit);
10977 ret = q6afe_cal_create_hwdep(this_afe.fw_data, Q6AFE_HWDEP_NODE, card);
10978 if (ret < 0) {
10979 pr_err("%s: couldn't create hwdep for AFE %d\n", __func__, ret);
10980 return ret;
10981 }
10982 return ret;
10983}
10984EXPORT_SYMBOL(afe_cal_init_hwdep);
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +053010985
10986/*
10987 * afe_vote_lpass_core_hw -
10988 * Voting for lpass core hardware
10989 *
10990 * @hw_block_id: id of the hardware block
10991 * @client_name: client name
10992 * @client_handle: client handle
10993 *
10994 */
10995int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name,
10996 uint32_t *client_handle)
10997{
10998 struct afe_cmd_remote_lpass_core_hw_vote_request hw_vote_cfg;
10999 struct afe_cmd_remote_lpass_core_hw_vote_request *cmd_ptr =
11000 &hw_vote_cfg;
11001 int ret = 0;
11002
11003 if (!client_handle) {
11004 pr_err("%s: Invalid client_handle\n", __func__);
11005 return -EINVAL;
11006 }
11007
11008 if (!client_name) {
11009 pr_err("%s: Invalid client_name\n", __func__);
11010 *client_handle = 0;
11011 return -EINVAL;
11012 }
11013
Karthikeyan Mani5670cbd2019-03-21 18:00:51 -070011014 ret = afe_q6_interface_prepare();
11015 if(ret) {
11016 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
11017 return ret;
11018 }
11019
Meng Wang9eacb962019-11-19 09:16:55 +080011020 mutex_lock(&this_afe.afe_clk_lock);
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +053011021
11022 memset(cmd_ptr, 0, sizeof(hw_vote_cfg));
11023
11024 cmd_ptr->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
11025 APR_HDR_LEN(APR_HDR_SIZE),
11026 APR_PKT_VER);
11027 cmd_ptr->hdr.pkt_size = sizeof(hw_vote_cfg);
11028 cmd_ptr->hdr.src_port = 0;
11029 cmd_ptr->hdr.dest_port = 0;
Laxminath Kasam688db8a2019-11-05 13:11:30 +053011030 cmd_ptr->hdr.token = hw_block_id;
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +053011031 cmd_ptr->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST;
11032 cmd_ptr->hw_block_id = hw_block_id;
11033 strlcpy(cmd_ptr->client_name, client_name,
11034 sizeof(cmd_ptr->client_name));
11035
11036 pr_debug("%s: lpass core hw vote opcode[0x%x] hw id[0x%x]\n",
11037 __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id);
11038
Aditya Bavanarif500a1d2019-09-16 18:27:51 -070011039 trace_printk("%s: lpass core hw vote opcode[0x%x] hw id[0x%x]\n",
11040 __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id);
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +053011041 *client_handle = 0;
Meng Wang9eacb962019-11-19 09:16:55 +080011042
11043 ret = afe_apr_send_clk_pkt((uint32_t *)cmd_ptr,
11044 &this_afe.lpass_core_hw_wait);
Aditya Bavanarid6546e32019-10-29 17:24:59 +053011045 if (ret == 0) {
11046 *client_handle = this_afe.lpass_hw_core_client_hdl[hw_block_id];
11047 pr_debug("%s: lpass_hw_core_client_hdl %d\n", __func__,
11048 this_afe.lpass_hw_core_client_hdl[hw_block_id]);
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +053011049 }
Meng Wang9eacb962019-11-19 09:16:55 +080011050 mutex_unlock(&this_afe.afe_clk_lock);
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +053011051 return ret;
11052}
11053EXPORT_SYMBOL(afe_vote_lpass_core_hw);
11054
11055/*
11056 * afe_unvote_lpass_core_hw -
11057 * unvoting for lpass core hardware
11058 *
11059 * @hw_block_id: id of the hardware block
11060 * @client_handle: client handle
11061 *
11062 */
11063int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle)
11064{
11065 struct afe_cmd_remote_lpass_core_hw_devote_request hw_vote_cfg;
11066 struct afe_cmd_remote_lpass_core_hw_devote_request *cmd_ptr =
11067 &hw_vote_cfg;
11068 int ret = 0;
11069
Karthikeyan Mani5670cbd2019-03-21 18:00:51 -070011070 ret = afe_q6_interface_prepare();
11071 if(ret) {
11072 pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
11073 return ret;
11074 }
11075
Meng Wang9eacb962019-11-19 09:16:55 +080011076 mutex_lock(&this_afe.afe_clk_lock);
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +053011077
Laxminath Kasam688db8a2019-11-05 13:11:30 +053011078 if (!this_afe.lpass_hw_core_client_hdl[hw_block_id]) {
Aditya Bavanari81a54a22019-09-20 00:23:59 +053011079 pr_debug("%s: SSR in progress, return\n", __func__);
Aditya Bavanarif500a1d2019-09-16 18:27:51 -070011080 trace_printk("%s: SSR in progress, return\n", __func__);
Aditya Bavanari81a54a22019-09-20 00:23:59 +053011081 goto done;
11082 }
11083
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +053011084 memset(cmd_ptr, 0, sizeof(hw_vote_cfg));
11085
11086 cmd_ptr->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
11087 APR_HDR_LEN(APR_HDR_SIZE),
11088 APR_PKT_VER);
11089 cmd_ptr->hdr.pkt_size = sizeof(hw_vote_cfg);
11090 cmd_ptr->hdr.src_port = 0;
11091 cmd_ptr->hdr.dest_port = 0;
11092 cmd_ptr->hdr.token = 0;
11093 cmd_ptr->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST;
11094 cmd_ptr->hw_block_id = hw_block_id;
11095 cmd_ptr->client_handle = client_handle;
11096
11097 pr_debug("%s: lpass core hw unvote opcode[0x%x] hw id[0x%x]\n",
11098 __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id);
11099
Aditya Bavanarif500a1d2019-09-16 18:27:51 -070011100 trace_printk("%s: lpass core hw unvote opcode[0x%x] hw id[0x%x]\n",
11101 __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id);
11102
Aditya Bavanari81a54a22019-09-20 00:23:59 +053011103 if (cmd_ptr->client_handle <= 0) {
11104 pr_err("%s: invalid client handle\n", __func__);
11105 ret = -EINVAL;
11106 goto done;
11107 }
11108
Meng Wang9eacb962019-11-19 09:16:55 +080011109 ret = afe_apr_send_clk_pkt((uint32_t *)cmd_ptr,
11110 &this_afe.lpass_core_hw_wait);
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +053011111done:
Meng Wang9eacb962019-11-19 09:16:55 +080011112 mutex_unlock(&this_afe.afe_clk_lock);
Mangesh Kunchamwarcdd68db2019-01-10 16:21:00 +053011113 return ret;
11114}
11115EXPORT_SYMBOL(afe_unvote_lpass_core_hw);
Faiz Nabi Kuchay29093022020-10-08 18:25:49 +053011116
11117/**
11118 * afe_set_cps_config -
11119 * to set cps speaker protection configuration
11120 *
11121 * @src_port: source port to send configuration to
11122 * @cps_config: cps speaker protection v4 configuration
11123 * @ch_mask: channel mask
11124 *
11125 */
11126void afe_set_cps_config(int src_port,
11127 struct afe_cps_hw_intf_cfg *cps_config,
11128 u32 ch_mask)
11129{
11130 this_afe.cps_config = NULL;
11131 this_afe.cps_ch_mask = 0;
11132
11133 if (!cps_config) {
11134 pr_err("%s: cps config is NULL\n", __func__);
11135 return;
11136 }
11137
11138 if (q6audio_validate_port(src_port) < 0) {
11139 pr_err("%s: Invalid src port 0x%x\n", __func__, src_port);
11140 return;
11141 }
11142
11143 this_afe.cps_ch_mask = ch_mask;
11144 this_afe.cps_config = cps_config;
11145}
11146EXPORT_SYMBOL(afe_set_cps_config);
Soumya Managoliadeb3312020-11-27 15:43:55 +053011147
11148static bool q6afe_is_afe_lsm_port(int port_id)
11149{
11150 int i = 0;
11151
11152 for (i = 0; i < MAX_LSM_SESSIONS; i++) {
11153 if (port_id == this_afe.lsm_afe_ports[i])
11154 return true;
11155 }
11156 return false;
11157}
11158
11159/**
11160 * afe_set_lsm_afe_port_id -
11161 * Update LSM AFE port
11162 * idx: LSM port index
11163 * lsm_port: LSM port id
11164*/
11165void afe_set_lsm_afe_port_id(int idx, int lsm_port)
11166{
11167 if (idx < 0 || idx >= MAX_LSM_SESSIONS) {
11168 pr_err("%s: %d Invalid lsm port index\n", __func__, idx);
11169 return;
11170 }
11171 this_afe.lsm_afe_ports[idx] = lsm_port;
11172}
11173EXPORT_SYMBOL(afe_set_lsm_afe_port_id);