xref: /openbmc/linux/sound/soc/qcom/qdsp6/q6afe.c (revision da2ef666)
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
3 // Copyright (c) 2018, Linaro Limited
4 
5 #include <linux/slab.h>
6 #include <linux/kernel.h>
7 #include <linux/uaccess.h>
8 #include <linux/wait.h>
9 #include <linux/jiffies.h>
10 #include <linux/sched.h>
11 #include <linux/module.h>
12 #include <linux/kref.h>
13 #include <linux/of.h>
14 #include <linux/of_platform.h>
15 #include <linux/spinlock.h>
16 #include <linux/delay.h>
17 #include <linux/soc/qcom/apr.h>
18 #include <sound/soc.h>
19 #include <sound/soc-dai.h>
20 #include <sound/pcm.h>
21 #include <sound/pcm_params.h>
22 #include "q6dsp-errno.h"
23 #include "q6core.h"
24 #include "q6afe.h"
25 
26 /* AFE CMDs */
27 #define AFE_PORT_CMD_DEVICE_START	0x000100E5
28 #define AFE_PORT_CMD_DEVICE_STOP	0x000100E6
29 #define AFE_PORT_CMD_SET_PARAM_V2	0x000100EF
30 #define AFE_SVC_CMD_SET_PARAM		0x000100f3
31 #define AFE_PORT_CMDRSP_GET_PARAM_V2	0x00010106
32 #define AFE_PARAM_ID_HDMI_CONFIG	0x00010210
33 #define AFE_MODULE_AUDIO_DEV_INTERFACE	0x0001020C
34 #define AFE_MODULE_TDM			0x0001028A
35 
36 #define AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG 0x00010235
37 
38 #define AFE_PARAM_ID_LPAIF_CLK_CONFIG	0x00010238
39 #define AFE_PARAM_ID_INT_DIGITAL_CDC_CLK_CONFIG	0x00010239
40 
41 #define AFE_PARAM_ID_SLIMBUS_CONFIG    0x00010212
42 #define AFE_PARAM_ID_I2S_CONFIG	0x0001020D
43 #define AFE_PARAM_ID_TDM_CONFIG	0x0001029D
44 #define AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG	0x00010297
45 
46 /* I2S config specific */
47 #define AFE_API_VERSION_I2S_CONFIG	0x1
48 #define AFE_PORT_I2S_SD0		0x1
49 #define AFE_PORT_I2S_SD1		0x2
50 #define AFE_PORT_I2S_SD2		0x3
51 #define AFE_PORT_I2S_SD3		0x4
52 #define AFE_PORT_I2S_SD0_MASK		BIT(0x1)
53 #define AFE_PORT_I2S_SD1_MASK		BIT(0x2)
54 #define AFE_PORT_I2S_SD2_MASK		BIT(0x3)
55 #define AFE_PORT_I2S_SD3_MASK		BIT(0x4)
56 #define AFE_PORT_I2S_SD0_1_MASK		GENMASK(2, 1)
57 #define AFE_PORT_I2S_SD2_3_MASK		GENMASK(4, 3)
58 #define AFE_PORT_I2S_SD0_1_2_MASK	GENMASK(3, 1)
59 #define AFE_PORT_I2S_SD0_1_2_3_MASK	GENMASK(4, 1)
60 #define AFE_PORT_I2S_QUAD01		0x5
61 #define AFE_PORT_I2S_QUAD23		0x6
62 #define AFE_PORT_I2S_6CHS		0x7
63 #define AFE_PORT_I2S_8CHS		0x8
64 #define AFE_PORT_I2S_MONO		0x0
65 #define AFE_PORT_I2S_STEREO		0x1
66 #define AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL	0x0
67 #define AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL	0x1
68 #define AFE_LINEAR_PCM_DATA				0x0
69 
70 
71 /* Port IDs */
72 #define AFE_API_VERSION_HDMI_CONFIG	0x1
73 #define AFE_PORT_ID_MULTICHAN_HDMI_RX	0x100E
74 
75 #define AFE_API_VERSION_SLIMBUS_CONFIG 0x1
76 /* Clock set API version */
77 #define AFE_API_VERSION_CLOCK_SET 1
78 #define Q6AFE_LPASS_CLK_CONFIG_API_VERSION	0x1
79 #define AFE_MODULE_CLOCK_SET		0x0001028F
80 #define AFE_PARAM_ID_CLOCK_SET		0x00010290
81 
82 /* SLIMbus Rx port on channel 0. */
83 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX      0x4000
84 /* SLIMbus Tx port on channel 0. */
85 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX      0x4001
86 /* SLIMbus Rx port on channel 1. */
87 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX      0x4002
88 /* SLIMbus Tx port on channel 1. */
89 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX      0x4003
90 /* SLIMbus Rx port on channel 2. */
91 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX      0x4004
92 /* SLIMbus Tx port on channel 2. */
93 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX      0x4005
94 /* SLIMbus Rx port on channel 3. */
95 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX      0x4006
96 /* SLIMbus Tx port on channel 3. */
97 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX      0x4007
98 /* SLIMbus Rx port on channel 4. */
99 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX      0x4008
100 /* SLIMbus Tx port on channel 4. */
101 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX      0x4009
102 /* SLIMbus Rx port on channel 5. */
103 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX      0x400a
104 /* SLIMbus Tx port on channel 5. */
105 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX      0x400b
106 /* SLIMbus Rx port on channel 6. */
107 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX      0x400c
108 /* SLIMbus Tx port on channel 6. */
109 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX      0x400d
110 #define AFE_PORT_ID_PRIMARY_MI2S_RX         0x1000
111 #define AFE_PORT_ID_PRIMARY_MI2S_TX         0x1001
112 #define AFE_PORT_ID_SECONDARY_MI2S_RX       0x1002
113 #define AFE_PORT_ID_SECONDARY_MI2S_TX       0x1003
114 #define AFE_PORT_ID_TERTIARY_MI2S_RX        0x1004
115 #define AFE_PORT_ID_TERTIARY_MI2S_TX        0x1005
116 #define AFE_PORT_ID_QUATERNARY_MI2S_RX      0x1006
117 #define AFE_PORT_ID_QUATERNARY_MI2S_TX      0x1007
118 
119 /* Start of the range of port IDs for TDM devices. */
120 #define AFE_PORT_ID_TDM_PORT_RANGE_START	0x9000
121 
122 /* End of the range of port IDs for TDM devices. */
123 #define AFE_PORT_ID_TDM_PORT_RANGE_END \
124 	(AFE_PORT_ID_TDM_PORT_RANGE_START+0x50-1)
125 
126 /* Size of the range of port IDs for TDM ports. */
127 #define AFE_PORT_ID_TDM_PORT_RANGE_SIZE \
128 	(AFE_PORT_ID_TDM_PORT_RANGE_END - \
129 	AFE_PORT_ID_TDM_PORT_RANGE_START+1)
130 
131 #define AFE_PORT_ID_PRIMARY_TDM_RX \
132 	(AFE_PORT_ID_TDM_PORT_RANGE_START + 0x00)
133 #define AFE_PORT_ID_PRIMARY_TDM_RX_1 \
134 	(AFE_PORT_ID_PRIMARY_TDM_RX + 0x02)
135 #define AFE_PORT_ID_PRIMARY_TDM_RX_2 \
136 	(AFE_PORT_ID_PRIMARY_TDM_RX + 0x04)
137 #define AFE_PORT_ID_PRIMARY_TDM_RX_3 \
138 	(AFE_PORT_ID_PRIMARY_TDM_RX + 0x06)
139 #define AFE_PORT_ID_PRIMARY_TDM_RX_4 \
140 	(AFE_PORT_ID_PRIMARY_TDM_RX + 0x08)
141 #define AFE_PORT_ID_PRIMARY_TDM_RX_5 \
142 	(AFE_PORT_ID_PRIMARY_TDM_RX + 0x0A)
143 #define AFE_PORT_ID_PRIMARY_TDM_RX_6 \
144 	(AFE_PORT_ID_PRIMARY_TDM_RX + 0x0C)
145 #define AFE_PORT_ID_PRIMARY_TDM_RX_7 \
146 	(AFE_PORT_ID_PRIMARY_TDM_RX + 0x0E)
147 
148 #define AFE_PORT_ID_PRIMARY_TDM_TX \
149 	(AFE_PORT_ID_TDM_PORT_RANGE_START + 0x01)
150 #define AFE_PORT_ID_PRIMARY_TDM_TX_1 \
151 	(AFE_PORT_ID_PRIMARY_TDM_TX + 0x02)
152 #define AFE_PORT_ID_PRIMARY_TDM_TX_2 \
153 	(AFE_PORT_ID_PRIMARY_TDM_TX + 0x04)
154 #define AFE_PORT_ID_PRIMARY_TDM_TX_3 \
155 	(AFE_PORT_ID_PRIMARY_TDM_TX + 0x06)
156 #define AFE_PORT_ID_PRIMARY_TDM_TX_4 \
157 	(AFE_PORT_ID_PRIMARY_TDM_TX + 0x08)
158 #define AFE_PORT_ID_PRIMARY_TDM_TX_5 \
159 	(AFE_PORT_ID_PRIMARY_TDM_TX + 0x0A)
160 #define AFE_PORT_ID_PRIMARY_TDM_TX_6 \
161 	(AFE_PORT_ID_PRIMARY_TDM_TX + 0x0C)
162 #define AFE_PORT_ID_PRIMARY_TDM_TX_7 \
163 	(AFE_PORT_ID_PRIMARY_TDM_TX + 0x0E)
164 
165 #define AFE_PORT_ID_SECONDARY_TDM_RX \
166 	(AFE_PORT_ID_TDM_PORT_RANGE_START + 0x10)
167 #define AFE_PORT_ID_SECONDARY_TDM_RX_1 \
168 	(AFE_PORT_ID_SECONDARY_TDM_RX + 0x02)
169 #define AFE_PORT_ID_SECONDARY_TDM_RX_2 \
170 	(AFE_PORT_ID_SECONDARY_TDM_RX + 0x04)
171 #define AFE_PORT_ID_SECONDARY_TDM_RX_3 \
172 	(AFE_PORT_ID_SECONDARY_TDM_RX + 0x06)
173 #define AFE_PORT_ID_SECONDARY_TDM_RX_4 \
174 	(AFE_PORT_ID_SECONDARY_TDM_RX + 0x08)
175 #define AFE_PORT_ID_SECONDARY_TDM_RX_5 \
176 	(AFE_PORT_ID_SECONDARY_TDM_RX + 0x0A)
177 #define AFE_PORT_ID_SECONDARY_TDM_RX_6 \
178 	(AFE_PORT_ID_SECONDARY_TDM_RX + 0x0C)
179 #define AFE_PORT_ID_SECONDARY_TDM_RX_7 \
180 	(AFE_PORT_ID_SECONDARY_TDM_RX + 0x0E)
181 
182 #define AFE_PORT_ID_SECONDARY_TDM_TX \
183 	(AFE_PORT_ID_TDM_PORT_RANGE_START + 0x11)
184 #define AFE_PORT_ID_SECONDARY_TDM_TX_1 \
185 	(AFE_PORT_ID_SECONDARY_TDM_TX + 0x02)
186 #define AFE_PORT_ID_SECONDARY_TDM_TX_2 \
187 	(AFE_PORT_ID_SECONDARY_TDM_TX + 0x04)
188 #define AFE_PORT_ID_SECONDARY_TDM_TX_3 \
189 	(AFE_PORT_ID_SECONDARY_TDM_TX + 0x06)
190 #define AFE_PORT_ID_SECONDARY_TDM_TX_4 \
191 	(AFE_PORT_ID_SECONDARY_TDM_TX + 0x08)
192 #define AFE_PORT_ID_SECONDARY_TDM_TX_5 \
193 	(AFE_PORT_ID_SECONDARY_TDM_TX + 0x0A)
194 #define AFE_PORT_ID_SECONDARY_TDM_TX_6 \
195 	(AFE_PORT_ID_SECONDARY_TDM_TX + 0x0C)
196 #define AFE_PORT_ID_SECONDARY_TDM_TX_7 \
197 	(AFE_PORT_ID_SECONDARY_TDM_TX + 0x0E)
198 
199 #define AFE_PORT_ID_TERTIARY_TDM_RX \
200 	(AFE_PORT_ID_TDM_PORT_RANGE_START + 0x20)
201 #define AFE_PORT_ID_TERTIARY_TDM_RX_1 \
202 	(AFE_PORT_ID_TERTIARY_TDM_RX + 0x02)
203 #define AFE_PORT_ID_TERTIARY_TDM_RX_2 \
204 	(AFE_PORT_ID_TERTIARY_TDM_RX + 0x04)
205 #define AFE_PORT_ID_TERTIARY_TDM_RX_3 \
206 	(AFE_PORT_ID_TERTIARY_TDM_RX + 0x06)
207 #define AFE_PORT_ID_TERTIARY_TDM_RX_4 \
208 	(AFE_PORT_ID_TERTIARY_TDM_RX + 0x08)
209 #define AFE_PORT_ID_TERTIARY_TDM_RX_5 \
210 	(AFE_PORT_ID_TERTIARY_TDM_RX + 0x0A)
211 #define AFE_PORT_ID_TERTIARY_TDM_RX_6 \
212 	(AFE_PORT_ID_TERTIARY_TDM_RX + 0x0C)
213 #define AFE_PORT_ID_TERTIARY_TDM_RX_7 \
214 	(AFE_PORT_ID_TERTIARY_TDM_RX + 0x0E)
215 
216 #define AFE_PORT_ID_TERTIARY_TDM_TX \
217 	(AFE_PORT_ID_TDM_PORT_RANGE_START + 0x21)
218 #define AFE_PORT_ID_TERTIARY_TDM_TX_1 \
219 	(AFE_PORT_ID_TERTIARY_TDM_TX + 0x02)
220 #define AFE_PORT_ID_TERTIARY_TDM_TX_2 \
221 	(AFE_PORT_ID_TERTIARY_TDM_TX + 0x04)
222 #define AFE_PORT_ID_TERTIARY_TDM_TX_3 \
223 	(AFE_PORT_ID_TERTIARY_TDM_TX + 0x06)
224 #define AFE_PORT_ID_TERTIARY_TDM_TX_4 \
225 	(AFE_PORT_ID_TERTIARY_TDM_TX + 0x08)
226 #define AFE_PORT_ID_TERTIARY_TDM_TX_5 \
227 	(AFE_PORT_ID_TERTIARY_TDM_TX + 0x0A)
228 #define AFE_PORT_ID_TERTIARY_TDM_TX_6 \
229 	(AFE_PORT_ID_TERTIARY_TDM_TX + 0x0C)
230 #define AFE_PORT_ID_TERTIARY_TDM_TX_7 \
231 	(AFE_PORT_ID_TERTIARY_TDM_TX + 0x0E)
232 
233 #define AFE_PORT_ID_QUATERNARY_TDM_RX \
234 	(AFE_PORT_ID_TDM_PORT_RANGE_START + 0x30)
235 #define AFE_PORT_ID_QUATERNARY_TDM_RX_1 \
236 	(AFE_PORT_ID_QUATERNARY_TDM_RX + 0x02)
237 #define AFE_PORT_ID_QUATERNARY_TDM_RX_2 \
238 	(AFE_PORT_ID_QUATERNARY_TDM_RX + 0x04)
239 #define AFE_PORT_ID_QUATERNARY_TDM_RX_3 \
240 	(AFE_PORT_ID_QUATERNARY_TDM_RX + 0x06)
241 #define AFE_PORT_ID_QUATERNARY_TDM_RX_4 \
242 	(AFE_PORT_ID_QUATERNARY_TDM_RX + 0x08)
243 #define AFE_PORT_ID_QUATERNARY_TDM_RX_5 \
244 	(AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0A)
245 #define AFE_PORT_ID_QUATERNARY_TDM_RX_6 \
246 	(AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0C)
247 #define AFE_PORT_ID_QUATERNARY_TDM_RX_7 \
248 	(AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0E)
249 
250 #define AFE_PORT_ID_QUATERNARY_TDM_TX \
251 	(AFE_PORT_ID_TDM_PORT_RANGE_START + 0x31)
252 #define AFE_PORT_ID_QUATERNARY_TDM_TX_1 \
253 	(AFE_PORT_ID_QUATERNARY_TDM_TX + 0x02)
254 #define AFE_PORT_ID_QUATERNARY_TDM_TX_2 \
255 	(AFE_PORT_ID_QUATERNARY_TDM_TX + 0x04)
256 #define AFE_PORT_ID_QUATERNARY_TDM_TX_3 \
257 	(AFE_PORT_ID_QUATERNARY_TDM_TX + 0x06)
258 #define AFE_PORT_ID_QUATERNARY_TDM_TX_4 \
259 	(AFE_PORT_ID_QUATERNARY_TDM_TX + 0x08)
260 #define AFE_PORT_ID_QUATERNARY_TDM_TX_5 \
261 	(AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0A)
262 #define AFE_PORT_ID_QUATERNARY_TDM_TX_6 \
263 	(AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0C)
264 #define AFE_PORT_ID_QUATERNARY_TDM_TX_7 \
265 	(AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0E)
266 
267 #define AFE_PORT_ID_QUINARY_TDM_RX \
268 	(AFE_PORT_ID_TDM_PORT_RANGE_START + 0x40)
269 #define AFE_PORT_ID_QUINARY_TDM_RX_1 \
270 	(AFE_PORT_ID_QUINARY_TDM_RX + 0x02)
271 #define AFE_PORT_ID_QUINARY_TDM_RX_2 \
272 	(AFE_PORT_ID_QUINARY_TDM_RX + 0x04)
273 #define AFE_PORT_ID_QUINARY_TDM_RX_3 \
274 	(AFE_PORT_ID_QUINARY_TDM_RX + 0x06)
275 #define AFE_PORT_ID_QUINARY_TDM_RX_4 \
276 	(AFE_PORT_ID_QUINARY_TDM_RX + 0x08)
277 #define AFE_PORT_ID_QUINARY_TDM_RX_5 \
278 	(AFE_PORT_ID_QUINARY_TDM_RX + 0x0A)
279 #define AFE_PORT_ID_QUINARY_TDM_RX_6 \
280 	(AFE_PORT_ID_QUINARY_TDM_RX + 0x0C)
281 #define AFE_PORT_ID_QUINARY_TDM_RX_7 \
282 	(AFE_PORT_ID_QUINARY_TDM_RX + 0x0E)
283 
284 #define AFE_PORT_ID_QUINARY_TDM_TX \
285 	(AFE_PORT_ID_TDM_PORT_RANGE_START + 0x41)
286 #define AFE_PORT_ID_QUINARY_TDM_TX_1 \
287 	(AFE_PORT_ID_QUINARY_TDM_TX + 0x02)
288 #define AFE_PORT_ID_QUINARY_TDM_TX_2 \
289 	(AFE_PORT_ID_QUINARY_TDM_TX + 0x04)
290 #define AFE_PORT_ID_QUINARY_TDM_TX_3 \
291 	(AFE_PORT_ID_QUINARY_TDM_TX + 0x06)
292 #define AFE_PORT_ID_QUINARY_TDM_TX_4 \
293 	(AFE_PORT_ID_QUINARY_TDM_TX + 0x08)
294 #define AFE_PORT_ID_QUINARY_TDM_TX_5 \
295 	(AFE_PORT_ID_QUINARY_TDM_TX + 0x0A)
296 #define AFE_PORT_ID_QUINARY_TDM_TX_6 \
297 	(AFE_PORT_ID_QUINARY_TDM_TX + 0x0C)
298 #define AFE_PORT_ID_QUINARY_TDM_TX_7 \
299 	(AFE_PORT_ID_QUINARY_TDM_TX + 0x0E)
300 
301 #define Q6AFE_LPASS_MODE_CLK1_VALID 1
302 #define Q6AFE_LPASS_MODE_CLK2_VALID 2
303 #define Q6AFE_LPASS_CLK_SRC_INTERNAL 1
304 #define Q6AFE_LPASS_CLK_ROOT_DEFAULT 0
305 #define AFE_API_VERSION_TDM_CONFIG              1
306 #define AFE_API_VERSION_SLOT_MAPPING_CONFIG	1
307 
308 #define TIMEOUT_MS 1000
309 #define AFE_CMD_RESP_AVAIL	0
310 #define AFE_CMD_RESP_NONE	1
311 
312 struct q6afe {
313 	struct apr_device *apr;
314 	struct device *dev;
315 	struct q6core_svc_api_info ainfo;
316 	struct mutex lock;
317 	struct list_head port_list;
318 	spinlock_t port_list_lock;
319 };
320 
321 struct afe_port_cmd_device_start {
322 	u16 port_id;
323 	u16 reserved;
324 } __packed;
325 
326 struct afe_port_cmd_device_stop {
327 	u16 port_id;
328 	u16 reserved;
329 /* Reserved for 32-bit alignment. This field must be set to 0.*/
330 } __packed;
331 
332 struct afe_port_param_data_v2 {
333 	u32 module_id;
334 	u32 param_id;
335 	u16 param_size;
336 	u16 reserved;
337 } __packed;
338 
339 struct afe_svc_cmd_set_param {
340 	uint32_t payload_size;
341 	uint32_t payload_address_lsw;
342 	uint32_t payload_address_msw;
343 	uint32_t mem_map_handle;
344 } __packed;
345 
346 struct afe_port_cmd_set_param_v2 {
347 	u16 port_id;
348 	u16 payload_size;
349 	u32 payload_address_lsw;
350 	u32 payload_address_msw;
351 	u32 mem_map_handle;
352 } __packed;
353 
354 struct afe_param_id_hdmi_multi_chan_audio_cfg {
355 	u32 hdmi_cfg_minor_version;
356 	u16 datatype;
357 	u16 channel_allocation;
358 	u32 sample_rate;
359 	u16 bit_width;
360 	u16 reserved;
361 } __packed;
362 
363 struct afe_param_id_slimbus_cfg {
364 	u32                  sb_cfg_minor_version;
365 /* Minor version used for tracking the version of the SLIMBUS
366  * configuration interface.
367  * Supported values: #AFE_API_VERSION_SLIMBUS_CONFIG
368  */
369 
370 	u16                  slimbus_dev_id;
371 /* SLIMbus hardware device ID, which is required to handle
372  * multiple SLIMbus hardware blocks.
373  * Supported values: - #AFE_SLIMBUS_DEVICE_1 - #AFE_SLIMBUS_DEVICE_2
374  */
375 	u16                  bit_width;
376 /* Bit width of the sample.
377  * Supported values: 16, 24
378  */
379 	u16                  data_format;
380 /* Data format supported by the SLIMbus hardware. The default is
381  * 0 (#AFE_SB_DATA_FORMAT_NOT_INDICATED), which indicates the
382  * hardware does not perform any format conversions before the data
383  * transfer.
384  */
385 	u16                  num_channels;
386 /* Number of channels.
387  * Supported values: 1 to #AFE_PORT_MAX_AUDIO_CHAN_CNT
388  */
389 	u8  shared_ch_mapping[AFE_PORT_MAX_AUDIO_CHAN_CNT];
390 /* Mapping of shared channel IDs (128 to 255) to which the
391  * master port is to be connected.
392  * Shared_channel_mapping[i] represents the shared channel assigned
393  * for audio channel i in multichannel audio data.
394  */
395 	u32              sample_rate;
396 /* Sampling rate of the port.
397  * Supported values:
398  * - #AFE_PORT_SAMPLE_RATE_8K
399  * - #AFE_PORT_SAMPLE_RATE_16K
400  * - #AFE_PORT_SAMPLE_RATE_48K
401  * - #AFE_PORT_SAMPLE_RATE_96K
402  * - #AFE_PORT_SAMPLE_RATE_192K
403  */
404 } __packed;
405 
406 struct afe_clk_cfg {
407 	u32                  i2s_cfg_minor_version;
408 	u32                  clk_val1;
409 	u32                  clk_val2;
410 	u16                  clk_src;
411 	u16                  clk_root;
412 	u16                  clk_set_mode;
413 	u16                  reserved;
414 } __packed;
415 
416 struct afe_digital_clk_cfg {
417 	u32                  i2s_cfg_minor_version;
418 	u32                  clk_val;
419 	u16                  clk_root;
420 	u16                  reserved;
421 } __packed;
422 
423 struct afe_param_id_i2s_cfg {
424 	u32	i2s_cfg_minor_version;
425 	u16	bit_width;
426 	u16	channel_mode;
427 	u16	mono_stereo;
428 	u16	ws_src;
429 	u32	sample_rate;
430 	u16	data_format;
431 	u16	reserved;
432 } __packed;
433 
434 struct afe_param_id_tdm_cfg {
435 	u32	tdm_cfg_minor_version;
436 	u32	num_channels;
437 	u32	sample_rate;
438 	u32	bit_width;
439 	u16	data_format;
440 	u16	sync_mode;
441 	u16	sync_src;
442 	u16	nslots_per_frame;
443 	u16	ctrl_data_out_enable;
444 	u16	ctrl_invert_sync_pulse;
445 	u16	ctrl_sync_data_delay;
446 	u16	slot_width;
447 	u32	slot_mask;
448 } __packed;
449 
450 union afe_port_config {
451 	struct afe_param_id_hdmi_multi_chan_audio_cfg hdmi_multi_ch;
452 	struct afe_param_id_slimbus_cfg           slim_cfg;
453 	struct afe_param_id_i2s_cfg	i2s_cfg;
454 	struct afe_param_id_tdm_cfg	tdm_cfg;
455 } __packed;
456 
457 
458 struct afe_clk_set {
459 	uint32_t clk_set_minor_version;
460 	uint32_t clk_id;
461 	uint32_t clk_freq_in_hz;
462 	uint16_t clk_attri;
463 	uint16_t clk_root;
464 	uint32_t enable;
465 };
466 
467 struct afe_param_id_slot_mapping_cfg {
468 	u32	minor_version;
469 	u16	num_channels;
470 	u16	bitwidth;
471 	u32	data_align_type;
472 	u16	ch_mapping[AFE_PORT_MAX_AUDIO_CHAN_CNT];
473 } __packed;
474 
475 struct q6afe_port {
476 	wait_queue_head_t wait;
477 	union afe_port_config port_cfg;
478 	struct afe_param_id_slot_mapping_cfg *scfg;
479 	struct aprv2_ibasic_rsp_result_t result;
480 	int token;
481 	int id;
482 	int cfg_type;
483 	struct q6afe *afe;
484 	struct kref refcount;
485 	struct list_head node;
486 };
487 
488 struct afe_port_map {
489 	int port_id;
490 	int token;
491 	int is_rx;
492 	int is_dig_pcm;
493 };
494 
495 /*
496  * Mapping between Virtual Port IDs to DSP AFE Port ID
497  * On B Family SoCs DSP Port IDs are consistent across multiple SoCs
498  * on A Family SoCs DSP port IDs are same as virtual Port IDs.
499  */
500 
501 static struct afe_port_map port_maps[AFE_PORT_MAX] = {
502 	[HDMI_RX] = { AFE_PORT_ID_MULTICHAN_HDMI_RX, HDMI_RX, 1, 1},
503 	[SLIMBUS_0_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX,
504 				SLIMBUS_0_RX, 1, 1},
505 	[SLIMBUS_1_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX,
506 				SLIMBUS_1_RX, 1, 1},
507 	[SLIMBUS_2_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX,
508 				SLIMBUS_2_RX, 1, 1},
509 	[SLIMBUS_3_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX,
510 				SLIMBUS_3_RX, 1, 1},
511 	[SLIMBUS_4_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX,
512 				SLIMBUS_4_RX, 1, 1},
513 	[SLIMBUS_5_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX,
514 				SLIMBUS_5_RX, 1, 1},
515 	[SLIMBUS_6_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX,
516 				SLIMBUS_6_RX, 1, 1},
517 	[SLIMBUS_0_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX,
518 				SLIMBUS_0_TX, 0, 1},
519 	[SLIMBUS_1_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX,
520 				SLIMBUS_1_TX, 0, 1},
521 	[SLIMBUS_2_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX,
522 				SLIMBUS_2_TX, 0, 1},
523 	[SLIMBUS_3_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX,
524 				SLIMBUS_3_TX, 0, 1},
525 	[SLIMBUS_4_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX,
526 				SLIMBUS_4_TX, 0, 1},
527 	[SLIMBUS_5_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX,
528 				SLIMBUS_5_TX, 0, 1},
529 	[SLIMBUS_6_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX,
530 				SLIMBUS_6_TX, 0, 1},
531 	[PRIMARY_MI2S_RX] = { AFE_PORT_ID_PRIMARY_MI2S_RX,
532 				PRIMARY_MI2S_RX, 1, 1},
533 	[PRIMARY_MI2S_TX] = { AFE_PORT_ID_PRIMARY_MI2S_TX,
534 				PRIMARY_MI2S_RX, 0, 1},
535 	[SECONDARY_MI2S_RX] = { AFE_PORT_ID_SECONDARY_MI2S_RX,
536 				SECONDARY_MI2S_RX, 1, 1},
537 	[SECONDARY_MI2S_TX] = { AFE_PORT_ID_SECONDARY_MI2S_TX,
538 				SECONDARY_MI2S_TX, 0, 1},
539 	[TERTIARY_MI2S_RX] = { AFE_PORT_ID_TERTIARY_MI2S_RX,
540 				TERTIARY_MI2S_RX, 1, 1},
541 	[TERTIARY_MI2S_TX] = { AFE_PORT_ID_TERTIARY_MI2S_TX,
542 				TERTIARY_MI2S_TX, 0, 1},
543 	[QUATERNARY_MI2S_RX] = { AFE_PORT_ID_QUATERNARY_MI2S_RX,
544 				QUATERNARY_MI2S_RX, 1, 1},
545 	[QUATERNARY_MI2S_TX] = { AFE_PORT_ID_QUATERNARY_MI2S_TX,
546 				QUATERNARY_MI2S_TX, 0, 1},
547 	[PRIMARY_TDM_RX_0] =  { AFE_PORT_ID_PRIMARY_TDM_RX,
548 				PRIMARY_TDM_RX_0, 1, 1},
549 	[PRIMARY_TDM_TX_0] =  { AFE_PORT_ID_PRIMARY_TDM_TX,
550 				PRIMARY_TDM_TX_0, 0, 1},
551 	[PRIMARY_TDM_RX_1] =  { AFE_PORT_ID_PRIMARY_TDM_RX_1,
552 				PRIMARY_TDM_RX_1, 1, 1},
553 	[PRIMARY_TDM_TX_1] =  { AFE_PORT_ID_PRIMARY_TDM_TX_1,
554 				PRIMARY_TDM_TX_1, 0, 1},
555 	[PRIMARY_TDM_RX_2] =  { AFE_PORT_ID_PRIMARY_TDM_RX_2,
556 				PRIMARY_TDM_RX_2, 1, 1},
557 	[PRIMARY_TDM_TX_2] =  { AFE_PORT_ID_PRIMARY_TDM_TX_2,
558 				PRIMARY_TDM_TX_2, 0, 1},
559 	[PRIMARY_TDM_RX_3] =  { AFE_PORT_ID_PRIMARY_TDM_RX_3,
560 				PRIMARY_TDM_RX_3, 1, 1},
561 	[PRIMARY_TDM_TX_3] =  { AFE_PORT_ID_PRIMARY_TDM_TX_3,
562 				PRIMARY_TDM_TX_3, 0, 1},
563 	[PRIMARY_TDM_RX_4] =  { AFE_PORT_ID_PRIMARY_TDM_RX_4,
564 				PRIMARY_TDM_RX_4, 1, 1},
565 	[PRIMARY_TDM_TX_4] =  { AFE_PORT_ID_PRIMARY_TDM_TX_4,
566 				PRIMARY_TDM_TX_4, 0, 1},
567 	[PRIMARY_TDM_RX_5] =  { AFE_PORT_ID_PRIMARY_TDM_RX_5,
568 				PRIMARY_TDM_RX_5, 1, 1},
569 	[PRIMARY_TDM_TX_5] =  { AFE_PORT_ID_PRIMARY_TDM_TX_5,
570 				PRIMARY_TDM_TX_5, 0, 1},
571 	[PRIMARY_TDM_RX_6] =  { AFE_PORT_ID_PRIMARY_TDM_RX_6,
572 				PRIMARY_TDM_RX_6, 1, 1},
573 	[PRIMARY_TDM_TX_6] =  { AFE_PORT_ID_PRIMARY_TDM_TX_6,
574 				PRIMARY_TDM_TX_6, 0, 1},
575 	[PRIMARY_TDM_RX_7] =  { AFE_PORT_ID_PRIMARY_TDM_RX_7,
576 				PRIMARY_TDM_RX_7, 1, 1},
577 	[PRIMARY_TDM_TX_7] =  { AFE_PORT_ID_PRIMARY_TDM_TX_7,
578 				PRIMARY_TDM_TX_7, 0, 1},
579 	[SECONDARY_TDM_RX_0] =  { AFE_PORT_ID_SECONDARY_TDM_RX,
580 				SECONDARY_TDM_RX_0, 1, 1},
581 	[SECONDARY_TDM_TX_0] =  { AFE_PORT_ID_SECONDARY_TDM_TX,
582 				SECONDARY_TDM_TX_0, 0, 1},
583 	[SECONDARY_TDM_RX_1] =  { AFE_PORT_ID_SECONDARY_TDM_RX_1,
584 				SECONDARY_TDM_RX_1, 1, 1},
585 	[SECONDARY_TDM_TX_1] =  { AFE_PORT_ID_SECONDARY_TDM_TX_1,
586 				SECONDARY_TDM_TX_1, 0, 1},
587 	[SECONDARY_TDM_RX_2] =  { AFE_PORT_ID_SECONDARY_TDM_RX_2,
588 				SECONDARY_TDM_RX_2, 1, 1},
589 	[SECONDARY_TDM_TX_2] =  { AFE_PORT_ID_SECONDARY_TDM_TX_2,
590 				SECONDARY_TDM_TX_2, 0, 1},
591 	[SECONDARY_TDM_RX_3] =  { AFE_PORT_ID_SECONDARY_TDM_RX_3,
592 				SECONDARY_TDM_RX_3, 1, 1},
593 	[SECONDARY_TDM_TX_3] =  { AFE_PORT_ID_SECONDARY_TDM_TX_3,
594 				SECONDARY_TDM_TX_3, 0, 1},
595 	[SECONDARY_TDM_RX_4] =  { AFE_PORT_ID_SECONDARY_TDM_RX_4,
596 				SECONDARY_TDM_RX_4, 1, 1},
597 	[SECONDARY_TDM_TX_4] =  { AFE_PORT_ID_SECONDARY_TDM_TX_4,
598 				SECONDARY_TDM_TX_4, 0, 1},
599 	[SECONDARY_TDM_RX_5] =  { AFE_PORT_ID_SECONDARY_TDM_RX_5,
600 				SECONDARY_TDM_RX_5, 1, 1},
601 	[SECONDARY_TDM_TX_5] =  { AFE_PORT_ID_SECONDARY_TDM_TX_5,
602 				SECONDARY_TDM_TX_5, 0, 1},
603 	[SECONDARY_TDM_RX_6] =  { AFE_PORT_ID_SECONDARY_TDM_RX_6,
604 				SECONDARY_TDM_RX_6, 1, 1},
605 	[SECONDARY_TDM_TX_6] =  { AFE_PORT_ID_SECONDARY_TDM_TX_6,
606 				SECONDARY_TDM_TX_6, 0, 1},
607 	[SECONDARY_TDM_RX_7] =  { AFE_PORT_ID_SECONDARY_TDM_RX_7,
608 				SECONDARY_TDM_RX_7, 1, 1},
609 	[SECONDARY_TDM_TX_7] =  { AFE_PORT_ID_SECONDARY_TDM_TX_7,
610 				SECONDARY_TDM_TX_7, 0, 1},
611 	[TERTIARY_TDM_RX_0] =  { AFE_PORT_ID_TERTIARY_TDM_RX,
612 				TERTIARY_TDM_RX_0, 1, 1},
613 	[TERTIARY_TDM_TX_0] =  { AFE_PORT_ID_TERTIARY_TDM_TX,
614 				TERTIARY_TDM_TX_0, 0, 1},
615 	[TERTIARY_TDM_RX_1] =  { AFE_PORT_ID_TERTIARY_TDM_RX_1,
616 				TERTIARY_TDM_RX_1, 1, 1},
617 	[TERTIARY_TDM_TX_1] =  { AFE_PORT_ID_TERTIARY_TDM_TX_1,
618 				TERTIARY_TDM_TX_1, 0, 1},
619 	[TERTIARY_TDM_RX_2] =  { AFE_PORT_ID_TERTIARY_TDM_RX_2,
620 				TERTIARY_TDM_RX_2, 1, 1},
621 	[TERTIARY_TDM_TX_2] =  { AFE_PORT_ID_TERTIARY_TDM_TX_2,
622 				TERTIARY_TDM_TX_2, 0, 1},
623 	[TERTIARY_TDM_RX_3] =  { AFE_PORT_ID_TERTIARY_TDM_RX_3,
624 				TERTIARY_TDM_RX_3, 1, 1},
625 	[TERTIARY_TDM_TX_3] =  { AFE_PORT_ID_TERTIARY_TDM_TX_3,
626 				TERTIARY_TDM_TX_3, 0, 1},
627 	[TERTIARY_TDM_RX_4] =  { AFE_PORT_ID_TERTIARY_TDM_RX_4,
628 				TERTIARY_TDM_RX_4, 1, 1},
629 	[TERTIARY_TDM_TX_4] =  { AFE_PORT_ID_TERTIARY_TDM_TX_4,
630 				TERTIARY_TDM_TX_4, 0, 1},
631 	[TERTIARY_TDM_RX_5] =  { AFE_PORT_ID_TERTIARY_TDM_RX_5,
632 				TERTIARY_TDM_RX_5, 1, 1},
633 	[TERTIARY_TDM_TX_5] =  { AFE_PORT_ID_TERTIARY_TDM_TX_5,
634 				TERTIARY_TDM_TX_5, 0, 1},
635 	[TERTIARY_TDM_RX_6] =  { AFE_PORT_ID_TERTIARY_TDM_RX_6,
636 				TERTIARY_TDM_RX_6, 1, 1},
637 	[TERTIARY_TDM_TX_6] =  { AFE_PORT_ID_TERTIARY_TDM_TX_6,
638 				TERTIARY_TDM_TX_6, 0, 1},
639 	[TERTIARY_TDM_RX_7] =  { AFE_PORT_ID_TERTIARY_TDM_RX_7,
640 				TERTIARY_TDM_RX_7, 1, 1},
641 	[TERTIARY_TDM_TX_7] =  { AFE_PORT_ID_TERTIARY_TDM_TX_7,
642 				TERTIARY_TDM_TX_7, 0, 1},
643 	[QUATERNARY_TDM_RX_0] =  { AFE_PORT_ID_QUATERNARY_TDM_RX,
644 				QUATERNARY_TDM_RX_0, 1, 1},
645 	[QUATERNARY_TDM_TX_0] =  { AFE_PORT_ID_QUATERNARY_TDM_TX,
646 				QUATERNARY_TDM_TX_0, 0, 1},
647 	[QUATERNARY_TDM_RX_1] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_1,
648 				QUATERNARY_TDM_RX_1, 1, 1},
649 	[QUATERNARY_TDM_TX_1] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_1,
650 				QUATERNARY_TDM_TX_1, 0, 1},
651 	[QUATERNARY_TDM_RX_2] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_2,
652 				QUATERNARY_TDM_RX_2, 1, 1},
653 	[QUATERNARY_TDM_TX_2] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_2,
654 				QUATERNARY_TDM_TX_2, 0, 1},
655 	[QUATERNARY_TDM_RX_3] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_3,
656 				QUATERNARY_TDM_RX_3, 1, 1},
657 	[QUATERNARY_TDM_TX_3] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_3,
658 				QUATERNARY_TDM_TX_3, 0, 1},
659 	[QUATERNARY_TDM_RX_4] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_4,
660 				QUATERNARY_TDM_RX_4, 1, 1},
661 	[QUATERNARY_TDM_TX_4] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_4,
662 				QUATERNARY_TDM_TX_4, 0, 1},
663 	[QUATERNARY_TDM_RX_5] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_5,
664 				QUATERNARY_TDM_RX_5, 1, 1},
665 	[QUATERNARY_TDM_TX_5] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_5,
666 				QUATERNARY_TDM_TX_5, 0, 1},
667 	[QUATERNARY_TDM_RX_6] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_6,
668 				QUATERNARY_TDM_RX_6, 1, 1},
669 	[QUATERNARY_TDM_TX_6] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_6,
670 				QUATERNARY_TDM_TX_6, 0, 1},
671 	[QUATERNARY_TDM_RX_7] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_7,
672 				QUATERNARY_TDM_RX_7, 1, 1},
673 	[QUATERNARY_TDM_TX_7] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_7,
674 				QUATERNARY_TDM_TX_7, 0, 1},
675 	[QUINARY_TDM_RX_0] =  { AFE_PORT_ID_QUINARY_TDM_RX,
676 				QUINARY_TDM_RX_0, 1, 1},
677 	[QUINARY_TDM_TX_0] =  { AFE_PORT_ID_QUINARY_TDM_TX,
678 				QUINARY_TDM_TX_0, 0, 1},
679 	[QUINARY_TDM_RX_1] =  { AFE_PORT_ID_QUINARY_TDM_RX_1,
680 				QUINARY_TDM_RX_1, 1, 1},
681 	[QUINARY_TDM_TX_1] =  { AFE_PORT_ID_QUINARY_TDM_TX_1,
682 				QUINARY_TDM_TX_1, 0, 1},
683 	[QUINARY_TDM_RX_2] =  { AFE_PORT_ID_QUINARY_TDM_RX_2,
684 				QUINARY_TDM_RX_2, 1, 1},
685 	[QUINARY_TDM_TX_2] =  { AFE_PORT_ID_QUINARY_TDM_TX_2,
686 				QUINARY_TDM_TX_2, 0, 1},
687 	[QUINARY_TDM_RX_3] =  { AFE_PORT_ID_QUINARY_TDM_RX_3,
688 				QUINARY_TDM_RX_3, 1, 1},
689 	[QUINARY_TDM_TX_3] =  { AFE_PORT_ID_QUINARY_TDM_TX_3,
690 				QUINARY_TDM_TX_3, 0, 1},
691 	[QUINARY_TDM_RX_4] =  { AFE_PORT_ID_QUINARY_TDM_RX_4,
692 				QUINARY_TDM_RX_4, 1, 1},
693 	[QUINARY_TDM_TX_4] =  { AFE_PORT_ID_QUINARY_TDM_TX_4,
694 				QUINARY_TDM_TX_4, 0, 1},
695 	[QUINARY_TDM_RX_5] =  { AFE_PORT_ID_QUINARY_TDM_RX_5,
696 				QUINARY_TDM_RX_5, 1, 1},
697 	[QUINARY_TDM_TX_5] =  { AFE_PORT_ID_QUINARY_TDM_TX_5,
698 				QUINARY_TDM_TX_5, 0, 1},
699 	[QUINARY_TDM_RX_6] =  { AFE_PORT_ID_QUINARY_TDM_RX_6,
700 				QUINARY_TDM_RX_6, 1, 1},
701 	[QUINARY_TDM_TX_6] =  { AFE_PORT_ID_QUINARY_TDM_TX_6,
702 				QUINARY_TDM_TX_6, 0, 1},
703 	[QUINARY_TDM_RX_7] =  { AFE_PORT_ID_QUINARY_TDM_RX_7,
704 				QUINARY_TDM_RX_7, 1, 1},
705 	[QUINARY_TDM_TX_7] =  { AFE_PORT_ID_QUINARY_TDM_TX_7,
706 				QUINARY_TDM_TX_7, 0, 1},
707 };
708 
709 static void q6afe_port_free(struct kref *ref)
710 {
711 	struct q6afe_port *port;
712 	struct q6afe *afe;
713 	unsigned long flags;
714 
715 	port = container_of(ref, struct q6afe_port, refcount);
716 	afe = port->afe;
717 	spin_lock_irqsave(&afe->port_list_lock, flags);
718 	list_del(&port->node);
719 	spin_unlock_irqrestore(&afe->port_list_lock, flags);
720 	kfree(port->scfg);
721 	kfree(port);
722 }
723 
724 static struct q6afe_port *q6afe_find_port(struct q6afe *afe, int token)
725 {
726 	struct q6afe_port *p = NULL;
727 	struct q6afe_port *ret = NULL;
728 	unsigned long flags;
729 
730 	spin_lock_irqsave(&afe->port_list_lock, flags);
731 	list_for_each_entry(p, &afe->port_list, node)
732 		if (p->token == token) {
733 			ret = p;
734 			kref_get(&p->refcount);
735 			break;
736 		}
737 
738 	spin_unlock_irqrestore(&afe->port_list_lock, flags);
739 	return ret;
740 }
741 
742 static int q6afe_callback(struct apr_device *adev, struct apr_resp_pkt *data)
743 {
744 	struct q6afe *afe = dev_get_drvdata(&adev->dev);
745 	struct aprv2_ibasic_rsp_result_t *res;
746 	struct apr_hdr *hdr = &data->hdr;
747 	struct q6afe_port *port;
748 
749 	if (!data->payload_size)
750 		return 0;
751 
752 	res = data->payload;
753 	switch (hdr->opcode) {
754 	case APR_BASIC_RSP_RESULT: {
755 		if (res->status) {
756 			dev_err(afe->dev, "cmd = 0x%x returned error = 0x%x\n",
757 				res->opcode, res->status);
758 		}
759 		switch (res->opcode) {
760 		case AFE_PORT_CMD_SET_PARAM_V2:
761 		case AFE_PORT_CMD_DEVICE_STOP:
762 		case AFE_PORT_CMD_DEVICE_START:
763 		case AFE_SVC_CMD_SET_PARAM:
764 			port = q6afe_find_port(afe, hdr->token);
765 			if (port) {
766 				port->result = *res;
767 				wake_up(&port->wait);
768 				kref_put(&port->refcount, q6afe_port_free);
769 			}
770 			break;
771 		default:
772 			dev_err(afe->dev, "Unknown cmd 0x%x\n",	res->opcode);
773 			break;
774 		}
775 	}
776 		break;
777 	default:
778 		break;
779 	}
780 
781 	return 0;
782 }
783 
784 /**
785  * q6afe_get_port_id() - Get port id from a given port index
786  *
787  * @index: port index
788  *
789  * Return: Will be an negative on error or valid port_id on success
790  */
791 int q6afe_get_port_id(int index)
792 {
793 	if (index < 0 || index >= AFE_PORT_MAX)
794 		return -EINVAL;
795 
796 	return port_maps[index].port_id;
797 }
798 EXPORT_SYMBOL_GPL(q6afe_get_port_id);
799 
800 static int afe_apr_send_pkt(struct q6afe *afe, struct apr_pkt *pkt,
801 			    struct q6afe_port *port)
802 {
803 	wait_queue_head_t *wait = &port->wait;
804 	struct apr_hdr *hdr = &pkt->hdr;
805 	int ret;
806 
807 	mutex_lock(&afe->lock);
808 	port->result.opcode = 0;
809 	port->result.status = 0;
810 
811 	ret = apr_send_pkt(afe->apr, pkt);
812 	if (ret < 0) {
813 		dev_err(afe->dev, "packet not transmitted (%d)\n", ret);
814 		ret = -EINVAL;
815 		goto err;
816 	}
817 
818 	ret = wait_event_timeout(*wait, (port->result.opcode == hdr->opcode),
819 				 msecs_to_jiffies(TIMEOUT_MS));
820 	if (!ret) {
821 		ret = -ETIMEDOUT;
822 	} else if (port->result.status > 0) {
823 		dev_err(afe->dev, "DSP returned error[%x]\n",
824 			port->result.status);
825 		ret = -EINVAL;
826 	} else {
827 		ret = 0;
828 	}
829 
830 err:
831 	mutex_unlock(&afe->lock);
832 
833 	return ret;
834 }
835 
836 static int q6afe_port_set_param(struct q6afe_port *port, void *data,
837 				int param_id, int module_id, int psize)
838 {
839 	struct afe_svc_cmd_set_param *param;
840 	struct afe_port_param_data_v2 *pdata;
841 	struct q6afe *afe = port->afe;
842 	struct apr_pkt *pkt;
843 	u16 port_id = port->id;
844 	int ret, pkt_size;
845 	void *p, *pl;
846 
847 	pkt_size = APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata) + psize;
848 	p = kzalloc(pkt_size, GFP_KERNEL);
849 	if (!p)
850 		return -ENOMEM;
851 
852 	pkt = p;
853 	param = p + APR_HDR_SIZE;
854 	pdata = p + APR_HDR_SIZE + sizeof(*param);
855 	pl = p + APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata);
856 	memcpy(pl, data, psize);
857 
858 	pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
859 					   APR_HDR_LEN(APR_HDR_SIZE),
860 					   APR_PKT_VER);
861 	pkt->hdr.pkt_size = pkt_size;
862 	pkt->hdr.src_port = 0;
863 	pkt->hdr.dest_port = 0;
864 	pkt->hdr.token = port->token;
865 	pkt->hdr.opcode = AFE_SVC_CMD_SET_PARAM;
866 
867 	param->payload_size = sizeof(*pdata) + psize;
868 	param->payload_address_lsw = 0x00;
869 	param->payload_address_msw = 0x00;
870 	param->mem_map_handle = 0x00;
871 	pdata->module_id = module_id;
872 	pdata->param_id = param_id;
873 	pdata->param_size = psize;
874 
875 	ret = afe_apr_send_pkt(afe, pkt, port);
876 	if (ret)
877 		dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
878 		       port_id, ret);
879 
880 	kfree(pkt);
881 	return ret;
882 }
883 
884 static int q6afe_port_set_param_v2(struct q6afe_port *port, void *data,
885 				   int param_id, int module_id, int psize)
886 {
887 	struct afe_port_cmd_set_param_v2 *param;
888 	struct afe_port_param_data_v2 *pdata;
889 	struct q6afe *afe = port->afe;
890 	struct apr_pkt *pkt;
891 	u16 port_id = port->id;
892 	int ret, pkt_size;
893 	void *p, *pl;
894 
895 	pkt_size = APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata) + psize;
896 	p = kzalloc(pkt_size, GFP_KERNEL);
897 	if (!p)
898 		return -ENOMEM;
899 
900 	pkt = p;
901 	param = p + APR_HDR_SIZE;
902 	pdata = p + APR_HDR_SIZE + sizeof(*param);
903 	pl = p + APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata);
904 	memcpy(pl, data, psize);
905 
906 	pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
907 					   APR_HDR_LEN(APR_HDR_SIZE),
908 					   APR_PKT_VER);
909 	pkt->hdr.pkt_size = pkt_size;
910 	pkt->hdr.src_port = 0;
911 	pkt->hdr.dest_port = 0;
912 	pkt->hdr.token = port->token;
913 	pkt->hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
914 
915 	param->port_id = port_id;
916 	param->payload_size = sizeof(*pdata) + psize;
917 	param->payload_address_lsw = 0x00;
918 	param->payload_address_msw = 0x00;
919 	param->mem_map_handle = 0x00;
920 	pdata->module_id = module_id;
921 	pdata->param_id = param_id;
922 	pdata->param_size = psize;
923 
924 	ret = afe_apr_send_pkt(afe, pkt, port);
925 	if (ret)
926 		dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
927 		       port_id, ret);
928 
929 	kfree(pkt);
930 	return ret;
931 }
932 
933 static int q6afe_set_lpass_clock(struct q6afe_port *port,
934 				 struct afe_clk_cfg *cfg)
935 {
936 	return q6afe_port_set_param_v2(port, cfg,
937 				       AFE_PARAM_ID_LPAIF_CLK_CONFIG,
938 				       AFE_MODULE_AUDIO_DEV_INTERFACE,
939 				       sizeof(*cfg));
940 }
941 
942 static int q6afe_set_lpass_clock_v2(struct q6afe_port *port,
943 				 struct afe_clk_set *cfg)
944 {
945 	return q6afe_port_set_param(port, cfg, AFE_PARAM_ID_CLOCK_SET,
946 				    AFE_MODULE_CLOCK_SET, sizeof(*cfg));
947 }
948 
949 static int q6afe_set_digital_codec_core_clock(struct q6afe_port *port,
950 					      struct afe_digital_clk_cfg *cfg)
951 {
952 	return q6afe_port_set_param_v2(port, cfg,
953 				       AFE_PARAM_ID_INT_DIGITAL_CDC_CLK_CONFIG,
954 				       AFE_MODULE_AUDIO_DEV_INTERFACE,
955 				       sizeof(*cfg));
956 }
957 
958 int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id,
959 			  int clk_src, int clk_root,
960 			  unsigned int freq, int dir)
961 {
962 	struct afe_clk_cfg ccfg = {0,};
963 	struct afe_clk_set cset = {0,};
964 	struct afe_digital_clk_cfg dcfg = {0,};
965 	int ret;
966 
967 	switch (clk_id) {
968 	case LPAIF_DIG_CLK:
969 		dcfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
970 		dcfg.clk_val = freq;
971 		dcfg.clk_root = clk_root;
972 		ret = q6afe_set_digital_codec_core_clock(port, &dcfg);
973 		break;
974 	case LPAIF_BIT_CLK:
975 		ccfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
976 		ccfg.clk_val1 = freq;
977 		ccfg.clk_src = clk_src;
978 		ccfg.clk_root = clk_root;
979 		ccfg.clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID;
980 		ret = q6afe_set_lpass_clock(port, &ccfg);
981 		break;
982 
983 	case LPAIF_OSR_CLK:
984 		ccfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
985 		ccfg.clk_val2 = freq;
986 		ccfg.clk_src = clk_src;
987 		ccfg.clk_root = clk_root;
988 		ccfg.clk_set_mode = Q6AFE_LPASS_MODE_CLK2_VALID;
989 		ret = q6afe_set_lpass_clock(port, &ccfg);
990 		break;
991 	case Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT ... Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR:
992 	case Q6AFE_LPASS_CLK_ID_MCLK_1 ... Q6AFE_LPASS_CLK_ID_INT_MCLK_1:
993 	case Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT ... Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT:
994 		cset.clk_set_minor_version = AFE_API_VERSION_CLOCK_SET;
995 		cset.clk_id = clk_id;
996 		cset.clk_freq_in_hz = freq;
997 		cset.clk_attri = clk_src;
998 		cset.clk_root = clk_root;
999 		cset.enable = !!freq;
1000 		ret = q6afe_set_lpass_clock_v2(port, &cset);
1001 		break;
1002 	default:
1003 		ret = -EINVAL;
1004 		break;
1005 	}
1006 
1007 	return ret;
1008 }
1009 EXPORT_SYMBOL_GPL(q6afe_port_set_sysclk);
1010 
1011 /**
1012  * q6afe_port_stop() - Stop a afe port
1013  *
1014  * @port: Instance of port to stop
1015  *
1016  * Return: Will be an negative on packet size on success.
1017  */
1018 int q6afe_port_stop(struct q6afe_port *port)
1019 {
1020 	struct afe_port_cmd_device_stop *stop;
1021 	struct q6afe *afe = port->afe;
1022 	struct apr_pkt *pkt;
1023 	int port_id = port->id;
1024 	int ret = 0;
1025 	int index, pkt_size;
1026 	void *p;
1027 
1028 	port_id = port->id;
1029 	index = port->token;
1030 	if (index < 0 || index >= AFE_PORT_MAX) {
1031 		dev_err(afe->dev, "AFE port index[%d] invalid!\n", index);
1032 		return -EINVAL;
1033 	}
1034 
1035 	pkt_size = APR_HDR_SIZE + sizeof(*stop);
1036 	p = kzalloc(pkt_size, GFP_KERNEL);
1037 	if (!p)
1038 		return -ENOMEM;
1039 
1040 	pkt = p;
1041 	stop = p + APR_HDR_SIZE;
1042 
1043 	pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1044 					   APR_HDR_LEN(APR_HDR_SIZE),
1045 					   APR_PKT_VER);
1046 	pkt->hdr.pkt_size = pkt_size;
1047 	pkt->hdr.src_port = 0;
1048 	pkt->hdr.dest_port = 0;
1049 	pkt->hdr.token = index;
1050 	pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_STOP;
1051 	stop->port_id = port_id;
1052 	stop->reserved = 0;
1053 
1054 	ret = afe_apr_send_pkt(afe, pkt, port);
1055 	if (ret)
1056 		dev_err(afe->dev, "AFE close failed %d\n", ret);
1057 
1058 	kfree(pkt);
1059 	return ret;
1060 }
1061 EXPORT_SYMBOL_GPL(q6afe_port_stop);
1062 
1063 /**
1064  * q6afe_slim_port_prepare() - Prepare slim afe port.
1065  *
1066  * @port: Instance of afe port
1067  * @cfg: SLIM configuration for the afe port
1068  *
1069  */
1070 void q6afe_slim_port_prepare(struct q6afe_port *port,
1071 			     struct q6afe_slim_cfg *cfg)
1072 {
1073 	union afe_port_config *pcfg = &port->port_cfg;
1074 
1075 	pcfg->slim_cfg.sb_cfg_minor_version = AFE_API_VERSION_SLIMBUS_CONFIG;
1076 	pcfg->slim_cfg.sample_rate = cfg->sample_rate;
1077 	pcfg->slim_cfg.bit_width = cfg->bit_width;
1078 	pcfg->slim_cfg.num_channels = cfg->num_channels;
1079 	pcfg->slim_cfg.data_format = cfg->data_format;
1080 	pcfg->slim_cfg.shared_ch_mapping[0] = cfg->ch_mapping[0];
1081 	pcfg->slim_cfg.shared_ch_mapping[1] = cfg->ch_mapping[1];
1082 	pcfg->slim_cfg.shared_ch_mapping[2] = cfg->ch_mapping[2];
1083 	pcfg->slim_cfg.shared_ch_mapping[3] = cfg->ch_mapping[3];
1084 
1085 }
1086 EXPORT_SYMBOL_GPL(q6afe_slim_port_prepare);
1087 
1088 /**
1089  * q6afe_tdm_port_prepare() - Prepare tdm afe port.
1090  *
1091  * @port: Instance of afe port
1092  * @cfg: TDM configuration for the afe port
1093  *
1094  */
1095 void q6afe_tdm_port_prepare(struct q6afe_port *port,
1096 			     struct q6afe_tdm_cfg *cfg)
1097 {
1098 	union afe_port_config *pcfg = &port->port_cfg;
1099 
1100 	pcfg->tdm_cfg.tdm_cfg_minor_version = AFE_API_VERSION_TDM_CONFIG;
1101 	pcfg->tdm_cfg.num_channels = cfg->num_channels;
1102 	pcfg->tdm_cfg.sample_rate = cfg->sample_rate;
1103 	pcfg->tdm_cfg.bit_width = cfg->bit_width;
1104 	pcfg->tdm_cfg.data_format = cfg->data_format;
1105 	pcfg->tdm_cfg.sync_mode = cfg->sync_mode;
1106 	pcfg->tdm_cfg.sync_src = cfg->sync_src;
1107 	pcfg->tdm_cfg.nslots_per_frame = cfg->nslots_per_frame;
1108 
1109 	pcfg->tdm_cfg.slot_width = cfg->slot_width;
1110 	pcfg->tdm_cfg.slot_mask = cfg->slot_mask;
1111 	port->scfg = kzalloc(sizeof(*port->scfg), GFP_KERNEL);
1112 	if (!port->scfg)
1113 		return;
1114 
1115 	port->scfg->minor_version = AFE_API_VERSION_SLOT_MAPPING_CONFIG;
1116 	port->scfg->num_channels = cfg->num_channels;
1117 	port->scfg->bitwidth = cfg->bit_width;
1118 	port->scfg->data_align_type = cfg->data_align_type;
1119 	memcpy(port->scfg->ch_mapping, cfg->ch_mapping,
1120 			sizeof(u16) * AFE_PORT_MAX_AUDIO_CHAN_CNT);
1121 }
1122 EXPORT_SYMBOL_GPL(q6afe_tdm_port_prepare);
1123 
1124 /**
1125  * q6afe_hdmi_port_prepare() - Prepare hdmi afe port.
1126  *
1127  * @port: Instance of afe port
1128  * @cfg: HDMI configuration for the afe port
1129  *
1130  */
1131 void q6afe_hdmi_port_prepare(struct q6afe_port *port,
1132 			     struct q6afe_hdmi_cfg *cfg)
1133 {
1134 	union afe_port_config *pcfg = &port->port_cfg;
1135 
1136 	pcfg->hdmi_multi_ch.hdmi_cfg_minor_version =
1137 					AFE_API_VERSION_HDMI_CONFIG;
1138 	pcfg->hdmi_multi_ch.datatype = cfg->datatype;
1139 	pcfg->hdmi_multi_ch.channel_allocation = cfg->channel_allocation;
1140 	pcfg->hdmi_multi_ch.sample_rate = cfg->sample_rate;
1141 	pcfg->hdmi_multi_ch.bit_width = cfg->bit_width;
1142 }
1143 EXPORT_SYMBOL_GPL(q6afe_hdmi_port_prepare);
1144 
1145 /**
1146  * q6afe_i2s_port_prepare() - Prepare i2s afe port.
1147  *
1148  * @port: Instance of afe port
1149  * @cfg: I2S configuration for the afe port
1150  * Return: Will be an negative on error and zero on success.
1151  */
1152 int q6afe_i2s_port_prepare(struct q6afe_port *port, struct q6afe_i2s_cfg *cfg)
1153 {
1154 	union afe_port_config *pcfg = &port->port_cfg;
1155 	struct device *dev = port->afe->dev;
1156 	int num_sd_lines;
1157 
1158 	pcfg->i2s_cfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
1159 	pcfg->i2s_cfg.sample_rate = cfg->sample_rate;
1160 	pcfg->i2s_cfg.bit_width = cfg->bit_width;
1161 	pcfg->i2s_cfg.data_format = AFE_LINEAR_PCM_DATA;
1162 
1163 	switch (cfg->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1164 	case SND_SOC_DAIFMT_CBS_CFS:
1165 		pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL;
1166 		break;
1167 	case SND_SOC_DAIFMT_CBM_CFM:
1168 		/* CPU is slave */
1169 		pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL;
1170 		break;
1171 	default:
1172 		break;
1173 	}
1174 
1175 	num_sd_lines = hweight_long(cfg->sd_line_mask);
1176 
1177 	switch (num_sd_lines) {
1178 	case 0:
1179 		dev_err(dev, "no line is assigned\n");
1180 		return -EINVAL;
1181 	case 1:
1182 		switch (cfg->sd_line_mask) {
1183 		case AFE_PORT_I2S_SD0_MASK:
1184 			pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0;
1185 			break;
1186 		case AFE_PORT_I2S_SD1_MASK:
1187 			pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD1;
1188 			break;
1189 		case AFE_PORT_I2S_SD2_MASK:
1190 			pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2;
1191 			break;
1192 		case AFE_PORT_I2S_SD3_MASK:
1193 			pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD3;
1194 			break;
1195 		default:
1196 			dev_err(dev, "Invalid SD lines\n");
1197 			return -EINVAL;
1198 		}
1199 		break;
1200 	case 2:
1201 		switch (cfg->sd_line_mask) {
1202 		case AFE_PORT_I2S_SD0_1_MASK:
1203 			pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD01;
1204 			break;
1205 		case AFE_PORT_I2S_SD2_3_MASK:
1206 			pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD23;
1207 			break;
1208 		default:
1209 			dev_err(dev, "Invalid SD lines\n");
1210 			return -EINVAL;
1211 		}
1212 		break;
1213 	case 3:
1214 		switch (cfg->sd_line_mask) {
1215 		case AFE_PORT_I2S_SD0_1_2_MASK:
1216 			pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_6CHS;
1217 			break;
1218 		default:
1219 			dev_err(dev, "Invalid SD lines\n");
1220 			return -EINVAL;
1221 		}
1222 		break;
1223 	case 4:
1224 		switch (cfg->sd_line_mask) {
1225 		case AFE_PORT_I2S_SD0_1_2_3_MASK:
1226 			pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_8CHS;
1227 
1228 			break;
1229 		default:
1230 			dev_err(dev, "Invalid SD lines\n");
1231 			return -EINVAL;
1232 		}
1233 		break;
1234 	default:
1235 		dev_err(dev, "Invalid SD lines\n");
1236 		return -EINVAL;
1237 	}
1238 
1239 	switch (cfg->num_channels) {
1240 	case 1:
1241 	case 2:
1242 		switch (pcfg->i2s_cfg.channel_mode) {
1243 		case AFE_PORT_I2S_QUAD01:
1244 		case AFE_PORT_I2S_6CHS:
1245 		case AFE_PORT_I2S_8CHS:
1246 			pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0;
1247 			break;
1248 		case AFE_PORT_I2S_QUAD23:
1249 				pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2;
1250 			break;
1251 		}
1252 
1253 		if (cfg->num_channels == 2)
1254 			pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_STEREO;
1255 		else
1256 			pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_MONO;
1257 
1258 		break;
1259 	case 3:
1260 	case 4:
1261 		if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_QUAD01) {
1262 			dev_err(dev, "Invalid Channel mode\n");
1263 			return -EINVAL;
1264 		}
1265 		break;
1266 	case 5:
1267 	case 6:
1268 		if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_6CHS) {
1269 			dev_err(dev, "Invalid Channel mode\n");
1270 			return -EINVAL;
1271 		}
1272 		break;
1273 	case 7:
1274 	case 8:
1275 		if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_8CHS) {
1276 			dev_err(dev, "Invalid Channel mode\n");
1277 			return -EINVAL;
1278 		}
1279 		break;
1280 	default:
1281 		break;
1282 	}
1283 
1284 	return 0;
1285 }
1286 EXPORT_SYMBOL_GPL(q6afe_i2s_port_prepare);
1287 
1288 /**
1289  * q6afe_port_start() - Start a afe port
1290  *
1291  * @port: Instance of port to start
1292  *
1293  * Return: Will be an negative on packet size on success.
1294  */
1295 int q6afe_port_start(struct q6afe_port *port)
1296 {
1297 	struct afe_port_cmd_device_start *start;
1298 	struct q6afe *afe = port->afe;
1299 	int port_id = port->id;
1300 	int ret, param_id = port->cfg_type;
1301 	struct apr_pkt *pkt;
1302 	int pkt_size;
1303 	void *p;
1304 
1305 	ret  = q6afe_port_set_param_v2(port, &port->port_cfg, param_id,
1306 				       AFE_MODULE_AUDIO_DEV_INTERFACE,
1307 				       sizeof(port->port_cfg));
1308 	if (ret) {
1309 		dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
1310 			port_id, ret);
1311 		return ret;
1312 	}
1313 
1314 	if (port->scfg) {
1315 		ret  = q6afe_port_set_param_v2(port, port->scfg,
1316 					AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG,
1317 					AFE_MODULE_TDM, sizeof(*port->scfg));
1318 		if (ret) {
1319 			dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
1320 			port_id, ret);
1321 			return ret;
1322 		}
1323 	}
1324 
1325 	pkt_size = APR_HDR_SIZE + sizeof(*start);
1326 	p = kzalloc(pkt_size, GFP_KERNEL);
1327 	if (!p)
1328 		return -ENOMEM;
1329 
1330 	pkt = p;
1331 	start = p + APR_HDR_SIZE;
1332 
1333 	pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1334 					    APR_HDR_LEN(APR_HDR_SIZE),
1335 					    APR_PKT_VER);
1336 	pkt->hdr.pkt_size = pkt_size;
1337 	pkt->hdr.src_port = 0;
1338 	pkt->hdr.dest_port = 0;
1339 	pkt->hdr.token = port->token;
1340 	pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_START;
1341 
1342 	start->port_id = port_id;
1343 
1344 	ret = afe_apr_send_pkt(afe, pkt, port);
1345 	if (ret)
1346 		dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
1347 			port_id, ret);
1348 
1349 	kfree(pkt);
1350 	return ret;
1351 }
1352 EXPORT_SYMBOL_GPL(q6afe_port_start);
1353 
1354 /**
1355  * q6afe_port_get_from_id() - Get port instance from a port id
1356  *
1357  * @dev: Pointer to afe child device.
1358  * @id: port id
1359  *
1360  * Return: Will be an error pointer on error or a valid afe port
1361  * on success.
1362  */
1363 struct q6afe_port *q6afe_port_get_from_id(struct device *dev, int id)
1364 {
1365 	int port_id;
1366 	struct q6afe *afe = dev_get_drvdata(dev->parent);
1367 	struct q6afe_port *port;
1368 	unsigned long flags;
1369 	int cfg_type;
1370 
1371 	if (id < 0 || id >= AFE_PORT_MAX) {
1372 		dev_err(dev, "AFE port token[%d] invalid!\n", id);
1373 		return ERR_PTR(-EINVAL);
1374 	}
1375 
1376 	/* if port is multiple times bind/unbind before callback finishes */
1377 	port = q6afe_find_port(afe, id);
1378 	if (port) {
1379 		dev_err(dev, "AFE Port already open\n");
1380 		return port;
1381 	}
1382 
1383 	port_id = port_maps[id].port_id;
1384 
1385 	switch (port_id) {
1386 	case AFE_PORT_ID_MULTICHAN_HDMI_RX:
1387 		cfg_type = AFE_PARAM_ID_HDMI_CONFIG;
1388 		break;
1389 	case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX:
1390 	case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX:
1391 	case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX:
1392 	case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX:
1393 	case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX:
1394 	case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX:
1395 	case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX:
1396 	case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX:
1397 	case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX:
1398 	case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX:
1399 	case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX:
1400 	case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX:
1401 	case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX:
1402 	case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX:
1403 		cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG;
1404 		break;
1405 
1406 	case AFE_PORT_ID_PRIMARY_MI2S_RX:
1407 	case AFE_PORT_ID_PRIMARY_MI2S_TX:
1408 	case AFE_PORT_ID_SECONDARY_MI2S_RX:
1409 	case AFE_PORT_ID_SECONDARY_MI2S_TX:
1410 	case AFE_PORT_ID_TERTIARY_MI2S_RX:
1411 	case AFE_PORT_ID_TERTIARY_MI2S_TX:
1412 	case AFE_PORT_ID_QUATERNARY_MI2S_RX:
1413 	case AFE_PORT_ID_QUATERNARY_MI2S_TX:
1414 		cfg_type = AFE_PARAM_ID_I2S_CONFIG;
1415 		break;
1416 	case AFE_PORT_ID_PRIMARY_TDM_RX ... AFE_PORT_ID_QUINARY_TDM_TX_7:
1417 		cfg_type = AFE_PARAM_ID_TDM_CONFIG;
1418 		break;
1419 
1420 	default:
1421 		dev_err(dev, "Invalid port id 0x%x\n", port_id);
1422 		return ERR_PTR(-EINVAL);
1423 	}
1424 
1425 	port = kzalloc(sizeof(*port), GFP_KERNEL);
1426 	if (!port)
1427 		return ERR_PTR(-ENOMEM);
1428 
1429 	init_waitqueue_head(&port->wait);
1430 
1431 	port->token = id;
1432 	port->id = port_id;
1433 	port->afe = afe;
1434 	port->cfg_type = cfg_type;
1435 	kref_init(&port->refcount);
1436 
1437 	spin_lock_irqsave(&afe->port_list_lock, flags);
1438 	list_add_tail(&port->node, &afe->port_list);
1439 	spin_unlock_irqrestore(&afe->port_list_lock, flags);
1440 
1441 	return port;
1442 
1443 }
1444 EXPORT_SYMBOL_GPL(q6afe_port_get_from_id);
1445 
1446 /**
1447  * q6afe_port_put() - Release port reference
1448  *
1449  * @port: Instance of port to put
1450  */
1451 void q6afe_port_put(struct q6afe_port *port)
1452 {
1453 	kref_put(&port->refcount, q6afe_port_free);
1454 }
1455 EXPORT_SYMBOL_GPL(q6afe_port_put);
1456 
1457 static int q6afe_probe(struct apr_device *adev)
1458 {
1459 	struct q6afe *afe;
1460 	struct device *dev = &adev->dev;
1461 
1462 	afe = devm_kzalloc(dev, sizeof(*afe), GFP_KERNEL);
1463 	if (!afe)
1464 		return -ENOMEM;
1465 
1466 	q6core_get_svc_api_info(adev->svc_id, &afe->ainfo);
1467 	afe->apr = adev;
1468 	mutex_init(&afe->lock);
1469 	afe->dev = dev;
1470 	INIT_LIST_HEAD(&afe->port_list);
1471 	spin_lock_init(&afe->port_list_lock);
1472 
1473 	dev_set_drvdata(dev, afe);
1474 
1475 	return of_platform_populate(dev->of_node, NULL, NULL, dev);
1476 }
1477 
1478 static int q6afe_remove(struct apr_device *adev)
1479 {
1480 	of_platform_depopulate(&adev->dev);
1481 
1482 	return 0;
1483 }
1484 
1485 static const struct of_device_id q6afe_device_id[]  = {
1486 	{ .compatible = "qcom,q6afe" },
1487 	{},
1488 };
1489 MODULE_DEVICE_TABLE(of, q6afe_device_id);
1490 
1491 static struct apr_driver qcom_q6afe_driver = {
1492 	.probe = q6afe_probe,
1493 	.remove = q6afe_remove,
1494 	.callback = q6afe_callback,
1495 	.driver = {
1496 		.name = "qcom-q6afe",
1497 		.of_match_table = of_match_ptr(q6afe_device_id),
1498 
1499 	},
1500 };
1501 
1502 module_apr_driver(qcom_q6afe_driver);
1503 MODULE_DESCRIPTION("Q6 Audio Front End");
1504 MODULE_LICENSE("GPL v2");
1505