1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
3 // Copyright (c) 2018, Linaro Limited
5 #include <dt-bindings/sound/qcom,q6afe.h>
6 #include <linux/slab.h>
7 #include <linux/kernel.h>
8 #include <linux/uaccess.h>
9 #include <linux/wait.h>
10 #include <linux/jiffies.h>
11 #include <linux/sched.h>
12 #include <linux/module.h>
13 #include <linux/kref.h>
15 #include <linux/of_platform.h>
16 #include <linux/spinlock.h>
17 #include <linux/delay.h>
18 #include <linux/soc/qcom/apr.h>
19 #include <sound/soc.h>
20 #include <sound/soc-dai.h>
21 #include <sound/pcm.h>
22 #include <sound/pcm_params.h>
23 #include "q6dsp-errno.h"
28 #define AFE_PORT_CMD_DEVICE_START 0x000100E5
29 #define AFE_PORT_CMD_DEVICE_STOP 0x000100E6
30 #define AFE_PORT_CMD_SET_PARAM_V2 0x000100EF
31 #define AFE_SVC_CMD_SET_PARAM 0x000100f3
32 #define AFE_PORT_CMDRSP_GET_PARAM_V2 0x00010106
33 #define AFE_PARAM_ID_HDMI_CONFIG 0x00010210
34 #define AFE_MODULE_AUDIO_DEV_INTERFACE 0x0001020C
35 #define AFE_MODULE_TDM 0x0001028A
37 #define AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG 0x00010235
39 #define AFE_PARAM_ID_LPAIF_CLK_CONFIG 0x00010238
40 #define AFE_PARAM_ID_INT_DIGITAL_CDC_CLK_CONFIG 0x00010239
42 #define AFE_PARAM_ID_SLIMBUS_CONFIG 0x00010212
43 #define AFE_PARAM_ID_I2S_CONFIG 0x0001020D
44 #define AFE_PARAM_ID_TDM_CONFIG 0x0001029D
45 #define AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG 0x00010297
46 #define AFE_PARAM_ID_CODEC_DMA_CONFIG 0x000102B8
47 #define AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST 0x000100f4
48 #define AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST 0x000100f5
49 #define AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST 0x000100f6
51 /* I2S config specific */
52 #define AFE_API_VERSION_I2S_CONFIG 0x1
53 #define AFE_PORT_I2S_SD0 0x1
54 #define AFE_PORT_I2S_SD1 0x2
55 #define AFE_PORT_I2S_SD2 0x3
56 #define AFE_PORT_I2S_SD3 0x4
57 #define AFE_PORT_I2S_SD0_MASK BIT(0x0)
58 #define AFE_PORT_I2S_SD1_MASK BIT(0x1)
59 #define AFE_PORT_I2S_SD2_MASK BIT(0x2)
60 #define AFE_PORT_I2S_SD3_MASK BIT(0x3)
61 #define AFE_PORT_I2S_SD0_1_MASK GENMASK(1, 0)
62 #define AFE_PORT_I2S_SD2_3_MASK GENMASK(3, 2)
63 #define AFE_PORT_I2S_SD0_1_2_MASK GENMASK(2, 0)
64 #define AFE_PORT_I2S_SD0_1_2_3_MASK GENMASK(3, 0)
65 #define AFE_PORT_I2S_QUAD01 0x5
66 #define AFE_PORT_I2S_QUAD23 0x6
67 #define AFE_PORT_I2S_6CHS 0x7
68 #define AFE_PORT_I2S_8CHS 0x8
69 #define AFE_PORT_I2S_MONO 0x0
70 #define AFE_PORT_I2S_STEREO 0x1
71 #define AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL 0x0
72 #define AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL 0x1
73 #define AFE_LINEAR_PCM_DATA 0x0
77 #define AFE_API_VERSION_HDMI_CONFIG 0x1
78 #define AFE_PORT_ID_MULTICHAN_HDMI_RX 0x100E
79 #define AFE_PORT_ID_HDMI_OVER_DP_RX 0x6020
81 #define AFE_API_VERSION_SLIMBUS_CONFIG 0x1
82 /* Clock set API version */
83 #define AFE_API_VERSION_CLOCK_SET 1
84 #define Q6AFE_LPASS_CLK_CONFIG_API_VERSION 0x1
85 #define AFE_MODULE_CLOCK_SET 0x0001028F
86 #define AFE_PARAM_ID_CLOCK_SET 0x00010290
88 /* SLIMbus Rx port on channel 0. */
89 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX 0x4000
90 /* SLIMbus Tx port on channel 0. */
91 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX 0x4001
92 /* SLIMbus Rx port on channel 1. */
93 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX 0x4002
94 /* SLIMbus Tx port on channel 1. */
95 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX 0x4003
96 /* SLIMbus Rx port on channel 2. */
97 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX 0x4004
98 /* SLIMbus Tx port on channel 2. */
99 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX 0x4005
100 /* SLIMbus Rx port on channel 3. */
101 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX 0x4006
102 /* SLIMbus Tx port on channel 3. */
103 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX 0x4007
104 /* SLIMbus Rx port on channel 4. */
105 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX 0x4008
106 /* SLIMbus Tx port on channel 4. */
107 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX 0x4009
108 /* SLIMbus Rx port on channel 5. */
109 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX 0x400a
110 /* SLIMbus Tx port on channel 5. */
111 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX 0x400b
112 /* SLIMbus Rx port on channel 6. */
113 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX 0x400c
114 /* SLIMbus Tx port on channel 6. */
115 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX 0x400d
116 #define AFE_PORT_ID_PRIMARY_MI2S_RX 0x1000
117 #define AFE_PORT_ID_PRIMARY_MI2S_TX 0x1001
118 #define AFE_PORT_ID_SECONDARY_MI2S_RX 0x1002
119 #define AFE_PORT_ID_SECONDARY_MI2S_TX 0x1003
120 #define AFE_PORT_ID_TERTIARY_MI2S_RX 0x1004
121 #define AFE_PORT_ID_TERTIARY_MI2S_TX 0x1005
122 #define AFE_PORT_ID_QUATERNARY_MI2S_RX 0x1006
123 #define AFE_PORT_ID_QUATERNARY_MI2S_TX 0x1007
124 #define AFE_PORT_ID_QUINARY_MI2S_RX 0x1016
125 #define AFE_PORT_ID_QUINARY_MI2S_TX 0x1017
127 /* Start of the range of port IDs for TDM devices. */
128 #define AFE_PORT_ID_TDM_PORT_RANGE_START 0x9000
130 /* End of the range of port IDs for TDM devices. */
131 #define AFE_PORT_ID_TDM_PORT_RANGE_END \
132 (AFE_PORT_ID_TDM_PORT_RANGE_START+0x50-1)
134 /* Size of the range of port IDs for TDM ports. */
135 #define AFE_PORT_ID_TDM_PORT_RANGE_SIZE \
136 (AFE_PORT_ID_TDM_PORT_RANGE_END - \
137 AFE_PORT_ID_TDM_PORT_RANGE_START+1)
139 #define AFE_PORT_ID_PRIMARY_TDM_RX \
140 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x00)
141 #define AFE_PORT_ID_PRIMARY_TDM_RX_1 \
142 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x02)
143 #define AFE_PORT_ID_PRIMARY_TDM_RX_2 \
144 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x04)
145 #define AFE_PORT_ID_PRIMARY_TDM_RX_3 \
146 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x06)
147 #define AFE_PORT_ID_PRIMARY_TDM_RX_4 \
148 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x08)
149 #define AFE_PORT_ID_PRIMARY_TDM_RX_5 \
150 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0A)
151 #define AFE_PORT_ID_PRIMARY_TDM_RX_6 \
152 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0C)
153 #define AFE_PORT_ID_PRIMARY_TDM_RX_7 \
154 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0E)
156 #define AFE_PORT_ID_PRIMARY_TDM_TX \
157 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x01)
158 #define AFE_PORT_ID_PRIMARY_TDM_TX_1 \
159 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x02)
160 #define AFE_PORT_ID_PRIMARY_TDM_TX_2 \
161 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x04)
162 #define AFE_PORT_ID_PRIMARY_TDM_TX_3 \
163 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x06)
164 #define AFE_PORT_ID_PRIMARY_TDM_TX_4 \
165 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x08)
166 #define AFE_PORT_ID_PRIMARY_TDM_TX_5 \
167 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0A)
168 #define AFE_PORT_ID_PRIMARY_TDM_TX_6 \
169 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0C)
170 #define AFE_PORT_ID_PRIMARY_TDM_TX_7 \
171 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0E)
173 #define AFE_PORT_ID_SECONDARY_TDM_RX \
174 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x10)
175 #define AFE_PORT_ID_SECONDARY_TDM_RX_1 \
176 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x02)
177 #define AFE_PORT_ID_SECONDARY_TDM_RX_2 \
178 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x04)
179 #define AFE_PORT_ID_SECONDARY_TDM_RX_3 \
180 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x06)
181 #define AFE_PORT_ID_SECONDARY_TDM_RX_4 \
182 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x08)
183 #define AFE_PORT_ID_SECONDARY_TDM_RX_5 \
184 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0A)
185 #define AFE_PORT_ID_SECONDARY_TDM_RX_6 \
186 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0C)
187 #define AFE_PORT_ID_SECONDARY_TDM_RX_7 \
188 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0E)
190 #define AFE_PORT_ID_SECONDARY_TDM_TX \
191 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x11)
192 #define AFE_PORT_ID_SECONDARY_TDM_TX_1 \
193 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x02)
194 #define AFE_PORT_ID_SECONDARY_TDM_TX_2 \
195 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x04)
196 #define AFE_PORT_ID_SECONDARY_TDM_TX_3 \
197 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x06)
198 #define AFE_PORT_ID_SECONDARY_TDM_TX_4 \
199 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x08)
200 #define AFE_PORT_ID_SECONDARY_TDM_TX_5 \
201 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0A)
202 #define AFE_PORT_ID_SECONDARY_TDM_TX_6 \
203 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0C)
204 #define AFE_PORT_ID_SECONDARY_TDM_TX_7 \
205 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0E)
207 #define AFE_PORT_ID_TERTIARY_TDM_RX \
208 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x20)
209 #define AFE_PORT_ID_TERTIARY_TDM_RX_1 \
210 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x02)
211 #define AFE_PORT_ID_TERTIARY_TDM_RX_2 \
212 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x04)
213 #define AFE_PORT_ID_TERTIARY_TDM_RX_3 \
214 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x06)
215 #define AFE_PORT_ID_TERTIARY_TDM_RX_4 \
216 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x08)
217 #define AFE_PORT_ID_TERTIARY_TDM_RX_5 \
218 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0A)
219 #define AFE_PORT_ID_TERTIARY_TDM_RX_6 \
220 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0C)
221 #define AFE_PORT_ID_TERTIARY_TDM_RX_7 \
222 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0E)
224 #define AFE_PORT_ID_TERTIARY_TDM_TX \
225 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x21)
226 #define AFE_PORT_ID_TERTIARY_TDM_TX_1 \
227 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x02)
228 #define AFE_PORT_ID_TERTIARY_TDM_TX_2 \
229 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x04)
230 #define AFE_PORT_ID_TERTIARY_TDM_TX_3 \
231 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x06)
232 #define AFE_PORT_ID_TERTIARY_TDM_TX_4 \
233 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x08)
234 #define AFE_PORT_ID_TERTIARY_TDM_TX_5 \
235 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0A)
236 #define AFE_PORT_ID_TERTIARY_TDM_TX_6 \
237 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0C)
238 #define AFE_PORT_ID_TERTIARY_TDM_TX_7 \
239 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0E)
241 #define AFE_PORT_ID_QUATERNARY_TDM_RX \
242 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x30)
243 #define AFE_PORT_ID_QUATERNARY_TDM_RX_1 \
244 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x02)
245 #define AFE_PORT_ID_QUATERNARY_TDM_RX_2 \
246 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x04)
247 #define AFE_PORT_ID_QUATERNARY_TDM_RX_3 \
248 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x06)
249 #define AFE_PORT_ID_QUATERNARY_TDM_RX_4 \
250 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x08)
251 #define AFE_PORT_ID_QUATERNARY_TDM_RX_5 \
252 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0A)
253 #define AFE_PORT_ID_QUATERNARY_TDM_RX_6 \
254 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0C)
255 #define AFE_PORT_ID_QUATERNARY_TDM_RX_7 \
256 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0E)
258 #define AFE_PORT_ID_QUATERNARY_TDM_TX \
259 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x31)
260 #define AFE_PORT_ID_QUATERNARY_TDM_TX_1 \
261 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x02)
262 #define AFE_PORT_ID_QUATERNARY_TDM_TX_2 \
263 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x04)
264 #define AFE_PORT_ID_QUATERNARY_TDM_TX_3 \
265 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x06)
266 #define AFE_PORT_ID_QUATERNARY_TDM_TX_4 \
267 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x08)
268 #define AFE_PORT_ID_QUATERNARY_TDM_TX_5 \
269 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0A)
270 #define AFE_PORT_ID_QUATERNARY_TDM_TX_6 \
271 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0C)
272 #define AFE_PORT_ID_QUATERNARY_TDM_TX_7 \
273 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0E)
275 #define AFE_PORT_ID_QUINARY_TDM_RX \
276 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x40)
277 #define AFE_PORT_ID_QUINARY_TDM_RX_1 \
278 (AFE_PORT_ID_QUINARY_TDM_RX + 0x02)
279 #define AFE_PORT_ID_QUINARY_TDM_RX_2 \
280 (AFE_PORT_ID_QUINARY_TDM_RX + 0x04)
281 #define AFE_PORT_ID_QUINARY_TDM_RX_3 \
282 (AFE_PORT_ID_QUINARY_TDM_RX + 0x06)
283 #define AFE_PORT_ID_QUINARY_TDM_RX_4 \
284 (AFE_PORT_ID_QUINARY_TDM_RX + 0x08)
285 #define AFE_PORT_ID_QUINARY_TDM_RX_5 \
286 (AFE_PORT_ID_QUINARY_TDM_RX + 0x0A)
287 #define AFE_PORT_ID_QUINARY_TDM_RX_6 \
288 (AFE_PORT_ID_QUINARY_TDM_RX + 0x0C)
289 #define AFE_PORT_ID_QUINARY_TDM_RX_7 \
290 (AFE_PORT_ID_QUINARY_TDM_RX + 0x0E)
292 #define AFE_PORT_ID_QUINARY_TDM_TX \
293 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x41)
294 #define AFE_PORT_ID_QUINARY_TDM_TX_1 \
295 (AFE_PORT_ID_QUINARY_TDM_TX + 0x02)
296 #define AFE_PORT_ID_QUINARY_TDM_TX_2 \
297 (AFE_PORT_ID_QUINARY_TDM_TX + 0x04)
298 #define AFE_PORT_ID_QUINARY_TDM_TX_3 \
299 (AFE_PORT_ID_QUINARY_TDM_TX + 0x06)
300 #define AFE_PORT_ID_QUINARY_TDM_TX_4 \
301 (AFE_PORT_ID_QUINARY_TDM_TX + 0x08)
302 #define AFE_PORT_ID_QUINARY_TDM_TX_5 \
303 (AFE_PORT_ID_QUINARY_TDM_TX + 0x0A)
304 #define AFE_PORT_ID_QUINARY_TDM_TX_6 \
305 (AFE_PORT_ID_QUINARY_TDM_TX + 0x0C)
306 #define AFE_PORT_ID_QUINARY_TDM_TX_7 \
307 (AFE_PORT_ID_QUINARY_TDM_TX + 0x0E)
309 /* AFE WSA Codec DMA Rx port 0 */
310 #define AFE_PORT_ID_WSA_CODEC_DMA_RX_0 0xB000
311 /* AFE WSA Codec DMA Tx port 0 */
312 #define AFE_PORT_ID_WSA_CODEC_DMA_TX_0 0xB001
313 /* AFE WSA Codec DMA Rx port 1 */
314 #define AFE_PORT_ID_WSA_CODEC_DMA_RX_1 0xB002
315 /* AFE WSA Codec DMA Tx port 1 */
316 #define AFE_PORT_ID_WSA_CODEC_DMA_TX_1 0xB003
317 /* AFE WSA Codec DMA Tx port 2 */
318 #define AFE_PORT_ID_WSA_CODEC_DMA_TX_2 0xB005
319 /* AFE VA Codec DMA Tx port 0 */
320 #define AFE_PORT_ID_VA_CODEC_DMA_TX_0 0xB021
321 /* AFE VA Codec DMA Tx port 1 */
322 #define AFE_PORT_ID_VA_CODEC_DMA_TX_1 0xB023
323 /* AFE VA Codec DMA Tx port 2 */
324 #define AFE_PORT_ID_VA_CODEC_DMA_TX_2 0xB025
325 /* AFE Rx Codec DMA Rx port 0 */
326 #define AFE_PORT_ID_RX_CODEC_DMA_RX_0 0xB030
327 /* AFE Tx Codec DMA Tx port 0 */
328 #define AFE_PORT_ID_TX_CODEC_DMA_TX_0 0xB031
329 /* AFE Rx Codec DMA Rx port 1 */
330 #define AFE_PORT_ID_RX_CODEC_DMA_RX_1 0xB032
331 /* AFE Tx Codec DMA Tx port 1 */
332 #define AFE_PORT_ID_TX_CODEC_DMA_TX_1 0xB033
333 /* AFE Rx Codec DMA Rx port 2 */
334 #define AFE_PORT_ID_RX_CODEC_DMA_RX_2 0xB034
335 /* AFE Tx Codec DMA Tx port 2 */
336 #define AFE_PORT_ID_TX_CODEC_DMA_TX_2 0xB035
337 /* AFE Rx Codec DMA Rx port 3 */
338 #define AFE_PORT_ID_RX_CODEC_DMA_RX_3 0xB036
339 /* AFE Tx Codec DMA Tx port 3 */
340 #define AFE_PORT_ID_TX_CODEC_DMA_TX_3 0xB037
341 /* AFE Rx Codec DMA Rx port 4 */
342 #define AFE_PORT_ID_RX_CODEC_DMA_RX_4 0xB038
343 /* AFE Tx Codec DMA Tx port 4 */
344 #define AFE_PORT_ID_TX_CODEC_DMA_TX_4 0xB039
345 /* AFE Rx Codec DMA Rx port 5 */
346 #define AFE_PORT_ID_RX_CODEC_DMA_RX_5 0xB03A
347 /* AFE Tx Codec DMA Tx port 5 */
348 #define AFE_PORT_ID_TX_CODEC_DMA_TX_5 0xB03B
349 /* AFE Rx Codec DMA Rx port 6 */
350 #define AFE_PORT_ID_RX_CODEC_DMA_RX_6 0xB03C
351 /* AFE Rx Codec DMA Rx port 7 */
352 #define AFE_PORT_ID_RX_CODEC_DMA_RX_7 0xB03E
354 #define Q6AFE_LPASS_MODE_CLK1_VALID 1
355 #define Q6AFE_LPASS_MODE_CLK2_VALID 2
356 #define Q6AFE_LPASS_CLK_SRC_INTERNAL 1
357 #define Q6AFE_LPASS_CLK_ROOT_DEFAULT 0
358 #define AFE_API_VERSION_TDM_CONFIG 1
359 #define AFE_API_VERSION_SLOT_MAPPING_CONFIG 1
360 #define AFE_API_VERSION_CODEC_DMA_CONFIG 1
362 #define TIMEOUT_MS 1000
363 #define AFE_CMD_RESP_AVAIL 0
364 #define AFE_CMD_RESP_NONE 1
365 #define AFE_CLK_TOKEN 1024
368 struct apr_device
*apr
;
370 struct q6core_svc_api_info ainfo
;
372 struct aprv2_ibasic_rsp_result_t result
;
373 wait_queue_head_t wait
;
374 struct list_head port_list
;
375 spinlock_t port_list_lock
;
378 struct afe_port_cmd_device_start
{
383 struct afe_port_cmd_device_stop
{
386 /* Reserved for 32-bit alignment. This field must be set to 0.*/
389 struct afe_port_param_data_v2
{
396 struct afe_svc_cmd_set_param
{
397 uint32_t payload_size
;
398 uint32_t payload_address_lsw
;
399 uint32_t payload_address_msw
;
400 uint32_t mem_map_handle
;
403 struct afe_port_cmd_set_param_v2
{
406 u32 payload_address_lsw
;
407 u32 payload_address_msw
;
411 struct afe_param_id_hdmi_multi_chan_audio_cfg
{
412 u32 hdmi_cfg_minor_version
;
414 u16 channel_allocation
;
420 struct afe_param_id_slimbus_cfg
{
421 u32 sb_cfg_minor_version
;
422 /* Minor version used for tracking the version of the SLIMBUS
423 * configuration interface.
424 * Supported values: #AFE_API_VERSION_SLIMBUS_CONFIG
428 /* SLIMbus hardware device ID, which is required to handle
429 * multiple SLIMbus hardware blocks.
430 * Supported values: - #AFE_SLIMBUS_DEVICE_1 - #AFE_SLIMBUS_DEVICE_2
433 /* Bit width of the sample.
434 * Supported values: 16, 24
437 /* Data format supported by the SLIMbus hardware. The default is
438 * 0 (#AFE_SB_DATA_FORMAT_NOT_INDICATED), which indicates the
439 * hardware does not perform any format conversions before the data
443 /* Number of channels.
444 * Supported values: 1 to #AFE_PORT_MAX_AUDIO_CHAN_CNT
446 u8 shared_ch_mapping
[AFE_PORT_MAX_AUDIO_CHAN_CNT
];
447 /* Mapping of shared channel IDs (128 to 255) to which the
448 * master port is to be connected.
449 * Shared_channel_mapping[i] represents the shared channel assigned
450 * for audio channel i in multichannel audio data.
453 /* Sampling rate of the port.
455 * - #AFE_PORT_SAMPLE_RATE_8K
456 * - #AFE_PORT_SAMPLE_RATE_16K
457 * - #AFE_PORT_SAMPLE_RATE_48K
458 * - #AFE_PORT_SAMPLE_RATE_96K
459 * - #AFE_PORT_SAMPLE_RATE_192K
464 u32 i2s_cfg_minor_version
;
473 struct afe_digital_clk_cfg
{
474 u32 i2s_cfg_minor_version
;
480 struct afe_param_id_i2s_cfg
{
481 u32 i2s_cfg_minor_version
;
491 struct afe_param_id_tdm_cfg
{
492 u32 tdm_cfg_minor_version
;
499 u16 nslots_per_frame
;
500 u16 ctrl_data_out_enable
;
501 u16 ctrl_invert_sync_pulse
;
502 u16 ctrl_sync_data_delay
;
507 struct afe_param_id_cdc_dma_cfg
{
508 u32 cdc_dma_cfg_minor_version
;
513 u16 active_channels_mask
;
516 union afe_port_config
{
517 struct afe_param_id_hdmi_multi_chan_audio_cfg hdmi_multi_ch
;
518 struct afe_param_id_slimbus_cfg slim_cfg
;
519 struct afe_param_id_i2s_cfg i2s_cfg
;
520 struct afe_param_id_tdm_cfg tdm_cfg
;
521 struct afe_param_id_cdc_dma_cfg dma_cfg
;
526 uint32_t clk_set_minor_version
;
528 uint32_t clk_freq_in_hz
;
534 struct afe_param_id_slot_mapping_cfg
{
539 u16 ch_mapping
[AFE_PORT_MAX_AUDIO_CHAN_CNT
];
543 wait_queue_head_t wait
;
544 union afe_port_config port_cfg
;
545 struct afe_param_id_slot_mapping_cfg
*scfg
;
546 struct aprv2_ibasic_rsp_result_t result
;
551 struct kref refcount
;
552 struct list_head node
;
555 struct afe_cmd_remote_lpass_core_hw_vote_request
{
556 uint32_t hw_block_id
;
560 struct afe_cmd_remote_lpass_core_hw_devote_request
{
561 uint32_t hw_block_id
;
562 uint32_t client_handle
;
567 struct afe_port_map
{
575 * Mapping between Virtual Port IDs to DSP AFE Port ID
576 * On B Family SoCs DSP Port IDs are consistent across multiple SoCs
577 * on A Family SoCs DSP port IDs are same as virtual Port IDs.
580 static struct afe_port_map port_maps
[AFE_PORT_MAX
] = {
581 [HDMI_RX
] = { AFE_PORT_ID_MULTICHAN_HDMI_RX
, HDMI_RX
, 1, 1},
582 [SLIMBUS_0_RX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX
,
584 [SLIMBUS_1_RX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX
,
586 [SLIMBUS_2_RX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX
,
588 [SLIMBUS_3_RX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX
,
590 [SLIMBUS_4_RX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX
,
592 [SLIMBUS_5_RX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX
,
594 [SLIMBUS_6_RX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX
,
596 [SLIMBUS_0_TX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX
,
598 [SLIMBUS_1_TX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX
,
600 [SLIMBUS_2_TX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX
,
602 [SLIMBUS_3_TX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX
,
604 [SLIMBUS_4_TX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX
,
606 [SLIMBUS_5_TX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX
,
608 [SLIMBUS_6_TX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX
,
610 [PRIMARY_MI2S_RX
] = { AFE_PORT_ID_PRIMARY_MI2S_RX
,
611 PRIMARY_MI2S_RX
, 1, 1},
612 [PRIMARY_MI2S_TX
] = { AFE_PORT_ID_PRIMARY_MI2S_TX
,
613 PRIMARY_MI2S_RX
, 0, 1},
614 [SECONDARY_MI2S_RX
] = { AFE_PORT_ID_SECONDARY_MI2S_RX
,
615 SECONDARY_MI2S_RX
, 1, 1},
616 [SECONDARY_MI2S_TX
] = { AFE_PORT_ID_SECONDARY_MI2S_TX
,
617 SECONDARY_MI2S_TX
, 0, 1},
618 [TERTIARY_MI2S_RX
] = { AFE_PORT_ID_TERTIARY_MI2S_RX
,
619 TERTIARY_MI2S_RX
, 1, 1},
620 [TERTIARY_MI2S_TX
] = { AFE_PORT_ID_TERTIARY_MI2S_TX
,
621 TERTIARY_MI2S_TX
, 0, 1},
622 [QUATERNARY_MI2S_RX
] = { AFE_PORT_ID_QUATERNARY_MI2S_RX
,
623 QUATERNARY_MI2S_RX
, 1, 1},
624 [QUATERNARY_MI2S_TX
] = { AFE_PORT_ID_QUATERNARY_MI2S_TX
,
625 QUATERNARY_MI2S_TX
, 0, 1},
626 [QUINARY_MI2S_RX
] = { AFE_PORT_ID_QUINARY_MI2S_RX
,
627 QUINARY_MI2S_RX
, 1, 1},
628 [QUINARY_MI2S_TX
] = { AFE_PORT_ID_QUINARY_MI2S_TX
,
629 QUINARY_MI2S_TX
, 0, 1},
630 [PRIMARY_TDM_RX_0
] = { AFE_PORT_ID_PRIMARY_TDM_RX
,
631 PRIMARY_TDM_RX_0
, 1, 1},
632 [PRIMARY_TDM_TX_0
] = { AFE_PORT_ID_PRIMARY_TDM_TX
,
633 PRIMARY_TDM_TX_0
, 0, 1},
634 [PRIMARY_TDM_RX_1
] = { AFE_PORT_ID_PRIMARY_TDM_RX_1
,
635 PRIMARY_TDM_RX_1
, 1, 1},
636 [PRIMARY_TDM_TX_1
] = { AFE_PORT_ID_PRIMARY_TDM_TX_1
,
637 PRIMARY_TDM_TX_1
, 0, 1},
638 [PRIMARY_TDM_RX_2
] = { AFE_PORT_ID_PRIMARY_TDM_RX_2
,
639 PRIMARY_TDM_RX_2
, 1, 1},
640 [PRIMARY_TDM_TX_2
] = { AFE_PORT_ID_PRIMARY_TDM_TX_2
,
641 PRIMARY_TDM_TX_2
, 0, 1},
642 [PRIMARY_TDM_RX_3
] = { AFE_PORT_ID_PRIMARY_TDM_RX_3
,
643 PRIMARY_TDM_RX_3
, 1, 1},
644 [PRIMARY_TDM_TX_3
] = { AFE_PORT_ID_PRIMARY_TDM_TX_3
,
645 PRIMARY_TDM_TX_3
, 0, 1},
646 [PRIMARY_TDM_RX_4
] = { AFE_PORT_ID_PRIMARY_TDM_RX_4
,
647 PRIMARY_TDM_RX_4
, 1, 1},
648 [PRIMARY_TDM_TX_4
] = { AFE_PORT_ID_PRIMARY_TDM_TX_4
,
649 PRIMARY_TDM_TX_4
, 0, 1},
650 [PRIMARY_TDM_RX_5
] = { AFE_PORT_ID_PRIMARY_TDM_RX_5
,
651 PRIMARY_TDM_RX_5
, 1, 1},
652 [PRIMARY_TDM_TX_5
] = { AFE_PORT_ID_PRIMARY_TDM_TX_5
,
653 PRIMARY_TDM_TX_5
, 0, 1},
654 [PRIMARY_TDM_RX_6
] = { AFE_PORT_ID_PRIMARY_TDM_RX_6
,
655 PRIMARY_TDM_RX_6
, 1, 1},
656 [PRIMARY_TDM_TX_6
] = { AFE_PORT_ID_PRIMARY_TDM_TX_6
,
657 PRIMARY_TDM_TX_6
, 0, 1},
658 [PRIMARY_TDM_RX_7
] = { AFE_PORT_ID_PRIMARY_TDM_RX_7
,
659 PRIMARY_TDM_RX_7
, 1, 1},
660 [PRIMARY_TDM_TX_7
] = { AFE_PORT_ID_PRIMARY_TDM_TX_7
,
661 PRIMARY_TDM_TX_7
, 0, 1},
662 [SECONDARY_TDM_RX_0
] = { AFE_PORT_ID_SECONDARY_TDM_RX
,
663 SECONDARY_TDM_RX_0
, 1, 1},
664 [SECONDARY_TDM_TX_0
] = { AFE_PORT_ID_SECONDARY_TDM_TX
,
665 SECONDARY_TDM_TX_0
, 0, 1},
666 [SECONDARY_TDM_RX_1
] = { AFE_PORT_ID_SECONDARY_TDM_RX_1
,
667 SECONDARY_TDM_RX_1
, 1, 1},
668 [SECONDARY_TDM_TX_1
] = { AFE_PORT_ID_SECONDARY_TDM_TX_1
,
669 SECONDARY_TDM_TX_1
, 0, 1},
670 [SECONDARY_TDM_RX_2
] = { AFE_PORT_ID_SECONDARY_TDM_RX_2
,
671 SECONDARY_TDM_RX_2
, 1, 1},
672 [SECONDARY_TDM_TX_2
] = { AFE_PORT_ID_SECONDARY_TDM_TX_2
,
673 SECONDARY_TDM_TX_2
, 0, 1},
674 [SECONDARY_TDM_RX_3
] = { AFE_PORT_ID_SECONDARY_TDM_RX_3
,
675 SECONDARY_TDM_RX_3
, 1, 1},
676 [SECONDARY_TDM_TX_3
] = { AFE_PORT_ID_SECONDARY_TDM_TX_3
,
677 SECONDARY_TDM_TX_3
, 0, 1},
678 [SECONDARY_TDM_RX_4
] = { AFE_PORT_ID_SECONDARY_TDM_RX_4
,
679 SECONDARY_TDM_RX_4
, 1, 1},
680 [SECONDARY_TDM_TX_4
] = { AFE_PORT_ID_SECONDARY_TDM_TX_4
,
681 SECONDARY_TDM_TX_4
, 0, 1},
682 [SECONDARY_TDM_RX_5
] = { AFE_PORT_ID_SECONDARY_TDM_RX_5
,
683 SECONDARY_TDM_RX_5
, 1, 1},
684 [SECONDARY_TDM_TX_5
] = { AFE_PORT_ID_SECONDARY_TDM_TX_5
,
685 SECONDARY_TDM_TX_5
, 0, 1},
686 [SECONDARY_TDM_RX_6
] = { AFE_PORT_ID_SECONDARY_TDM_RX_6
,
687 SECONDARY_TDM_RX_6
, 1, 1},
688 [SECONDARY_TDM_TX_6
] = { AFE_PORT_ID_SECONDARY_TDM_TX_6
,
689 SECONDARY_TDM_TX_6
, 0, 1},
690 [SECONDARY_TDM_RX_7
] = { AFE_PORT_ID_SECONDARY_TDM_RX_7
,
691 SECONDARY_TDM_RX_7
, 1, 1},
692 [SECONDARY_TDM_TX_7
] = { AFE_PORT_ID_SECONDARY_TDM_TX_7
,
693 SECONDARY_TDM_TX_7
, 0, 1},
694 [TERTIARY_TDM_RX_0
] = { AFE_PORT_ID_TERTIARY_TDM_RX
,
695 TERTIARY_TDM_RX_0
, 1, 1},
696 [TERTIARY_TDM_TX_0
] = { AFE_PORT_ID_TERTIARY_TDM_TX
,
697 TERTIARY_TDM_TX_0
, 0, 1},
698 [TERTIARY_TDM_RX_1
] = { AFE_PORT_ID_TERTIARY_TDM_RX_1
,
699 TERTIARY_TDM_RX_1
, 1, 1},
700 [TERTIARY_TDM_TX_1
] = { AFE_PORT_ID_TERTIARY_TDM_TX_1
,
701 TERTIARY_TDM_TX_1
, 0, 1},
702 [TERTIARY_TDM_RX_2
] = { AFE_PORT_ID_TERTIARY_TDM_RX_2
,
703 TERTIARY_TDM_RX_2
, 1, 1},
704 [TERTIARY_TDM_TX_2
] = { AFE_PORT_ID_TERTIARY_TDM_TX_2
,
705 TERTIARY_TDM_TX_2
, 0, 1},
706 [TERTIARY_TDM_RX_3
] = { AFE_PORT_ID_TERTIARY_TDM_RX_3
,
707 TERTIARY_TDM_RX_3
, 1, 1},
708 [TERTIARY_TDM_TX_3
] = { AFE_PORT_ID_TERTIARY_TDM_TX_3
,
709 TERTIARY_TDM_TX_3
, 0, 1},
710 [TERTIARY_TDM_RX_4
] = { AFE_PORT_ID_TERTIARY_TDM_RX_4
,
711 TERTIARY_TDM_RX_4
, 1, 1},
712 [TERTIARY_TDM_TX_4
] = { AFE_PORT_ID_TERTIARY_TDM_TX_4
,
713 TERTIARY_TDM_TX_4
, 0, 1},
714 [TERTIARY_TDM_RX_5
] = { AFE_PORT_ID_TERTIARY_TDM_RX_5
,
715 TERTIARY_TDM_RX_5
, 1, 1},
716 [TERTIARY_TDM_TX_5
] = { AFE_PORT_ID_TERTIARY_TDM_TX_5
,
717 TERTIARY_TDM_TX_5
, 0, 1},
718 [TERTIARY_TDM_RX_6
] = { AFE_PORT_ID_TERTIARY_TDM_RX_6
,
719 TERTIARY_TDM_RX_6
, 1, 1},
720 [TERTIARY_TDM_TX_6
] = { AFE_PORT_ID_TERTIARY_TDM_TX_6
,
721 TERTIARY_TDM_TX_6
, 0, 1},
722 [TERTIARY_TDM_RX_7
] = { AFE_PORT_ID_TERTIARY_TDM_RX_7
,
723 TERTIARY_TDM_RX_7
, 1, 1},
724 [TERTIARY_TDM_TX_7
] = { AFE_PORT_ID_TERTIARY_TDM_TX_7
,
725 TERTIARY_TDM_TX_7
, 0, 1},
726 [QUATERNARY_TDM_RX_0
] = { AFE_PORT_ID_QUATERNARY_TDM_RX
,
727 QUATERNARY_TDM_RX_0
, 1, 1},
728 [QUATERNARY_TDM_TX_0
] = { AFE_PORT_ID_QUATERNARY_TDM_TX
,
729 QUATERNARY_TDM_TX_0
, 0, 1},
730 [QUATERNARY_TDM_RX_1
] = { AFE_PORT_ID_QUATERNARY_TDM_RX_1
,
731 QUATERNARY_TDM_RX_1
, 1, 1},
732 [QUATERNARY_TDM_TX_1
] = { AFE_PORT_ID_QUATERNARY_TDM_TX_1
,
733 QUATERNARY_TDM_TX_1
, 0, 1},
734 [QUATERNARY_TDM_RX_2
] = { AFE_PORT_ID_QUATERNARY_TDM_RX_2
,
735 QUATERNARY_TDM_RX_2
, 1, 1},
736 [QUATERNARY_TDM_TX_2
] = { AFE_PORT_ID_QUATERNARY_TDM_TX_2
,
737 QUATERNARY_TDM_TX_2
, 0, 1},
738 [QUATERNARY_TDM_RX_3
] = { AFE_PORT_ID_QUATERNARY_TDM_RX_3
,
739 QUATERNARY_TDM_RX_3
, 1, 1},
740 [QUATERNARY_TDM_TX_3
] = { AFE_PORT_ID_QUATERNARY_TDM_TX_3
,
741 QUATERNARY_TDM_TX_3
, 0, 1},
742 [QUATERNARY_TDM_RX_4
] = { AFE_PORT_ID_QUATERNARY_TDM_RX_4
,
743 QUATERNARY_TDM_RX_4
, 1, 1},
744 [QUATERNARY_TDM_TX_4
] = { AFE_PORT_ID_QUATERNARY_TDM_TX_4
,
745 QUATERNARY_TDM_TX_4
, 0, 1},
746 [QUATERNARY_TDM_RX_5
] = { AFE_PORT_ID_QUATERNARY_TDM_RX_5
,
747 QUATERNARY_TDM_RX_5
, 1, 1},
748 [QUATERNARY_TDM_TX_5
] = { AFE_PORT_ID_QUATERNARY_TDM_TX_5
,
749 QUATERNARY_TDM_TX_5
, 0, 1},
750 [QUATERNARY_TDM_RX_6
] = { AFE_PORT_ID_QUATERNARY_TDM_RX_6
,
751 QUATERNARY_TDM_RX_6
, 1, 1},
752 [QUATERNARY_TDM_TX_6
] = { AFE_PORT_ID_QUATERNARY_TDM_TX_6
,
753 QUATERNARY_TDM_TX_6
, 0, 1},
754 [QUATERNARY_TDM_RX_7
] = { AFE_PORT_ID_QUATERNARY_TDM_RX_7
,
755 QUATERNARY_TDM_RX_7
, 1, 1},
756 [QUATERNARY_TDM_TX_7
] = { AFE_PORT_ID_QUATERNARY_TDM_TX_7
,
757 QUATERNARY_TDM_TX_7
, 0, 1},
758 [QUINARY_TDM_RX_0
] = { AFE_PORT_ID_QUINARY_TDM_RX
,
759 QUINARY_TDM_RX_0
, 1, 1},
760 [QUINARY_TDM_TX_0
] = { AFE_PORT_ID_QUINARY_TDM_TX
,
761 QUINARY_TDM_TX_0
, 0, 1},
762 [QUINARY_TDM_RX_1
] = { AFE_PORT_ID_QUINARY_TDM_RX_1
,
763 QUINARY_TDM_RX_1
, 1, 1},
764 [QUINARY_TDM_TX_1
] = { AFE_PORT_ID_QUINARY_TDM_TX_1
,
765 QUINARY_TDM_TX_1
, 0, 1},
766 [QUINARY_TDM_RX_2
] = { AFE_PORT_ID_QUINARY_TDM_RX_2
,
767 QUINARY_TDM_RX_2
, 1, 1},
768 [QUINARY_TDM_TX_2
] = { AFE_PORT_ID_QUINARY_TDM_TX_2
,
769 QUINARY_TDM_TX_2
, 0, 1},
770 [QUINARY_TDM_RX_3
] = { AFE_PORT_ID_QUINARY_TDM_RX_3
,
771 QUINARY_TDM_RX_3
, 1, 1},
772 [QUINARY_TDM_TX_3
] = { AFE_PORT_ID_QUINARY_TDM_TX_3
,
773 QUINARY_TDM_TX_3
, 0, 1},
774 [QUINARY_TDM_RX_4
] = { AFE_PORT_ID_QUINARY_TDM_RX_4
,
775 QUINARY_TDM_RX_4
, 1, 1},
776 [QUINARY_TDM_TX_4
] = { AFE_PORT_ID_QUINARY_TDM_TX_4
,
777 QUINARY_TDM_TX_4
, 0, 1},
778 [QUINARY_TDM_RX_5
] = { AFE_PORT_ID_QUINARY_TDM_RX_5
,
779 QUINARY_TDM_RX_5
, 1, 1},
780 [QUINARY_TDM_TX_5
] = { AFE_PORT_ID_QUINARY_TDM_TX_5
,
781 QUINARY_TDM_TX_5
, 0, 1},
782 [QUINARY_TDM_RX_6
] = { AFE_PORT_ID_QUINARY_TDM_RX_6
,
783 QUINARY_TDM_RX_6
, 1, 1},
784 [QUINARY_TDM_TX_6
] = { AFE_PORT_ID_QUINARY_TDM_TX_6
,
785 QUINARY_TDM_TX_6
, 0, 1},
786 [QUINARY_TDM_RX_7
] = { AFE_PORT_ID_QUINARY_TDM_RX_7
,
787 QUINARY_TDM_RX_7
, 1, 1},
788 [QUINARY_TDM_TX_7
] = { AFE_PORT_ID_QUINARY_TDM_TX_7
,
789 QUINARY_TDM_TX_7
, 0, 1},
790 [DISPLAY_PORT_RX
] = { AFE_PORT_ID_HDMI_OVER_DP_RX
,
791 DISPLAY_PORT_RX
, 1, 1},
792 [WSA_CODEC_DMA_RX_0
] = { AFE_PORT_ID_WSA_CODEC_DMA_RX_0
,
793 WSA_CODEC_DMA_RX_0
, 1, 1},
794 [WSA_CODEC_DMA_TX_0
] = { AFE_PORT_ID_WSA_CODEC_DMA_TX_0
,
795 WSA_CODEC_DMA_TX_0
, 0, 1},
796 [WSA_CODEC_DMA_RX_1
] = { AFE_PORT_ID_WSA_CODEC_DMA_RX_1
,
797 WSA_CODEC_DMA_RX_1
, 1, 1},
798 [WSA_CODEC_DMA_TX_1
] = { AFE_PORT_ID_WSA_CODEC_DMA_TX_1
,
799 WSA_CODEC_DMA_TX_1
, 0, 1},
800 [WSA_CODEC_DMA_TX_2
] = { AFE_PORT_ID_WSA_CODEC_DMA_TX_2
,
801 WSA_CODEC_DMA_TX_2
, 0, 1},
802 [VA_CODEC_DMA_TX_0
] = { AFE_PORT_ID_VA_CODEC_DMA_TX_0
,
803 VA_CODEC_DMA_TX_0
, 0, 1},
804 [VA_CODEC_DMA_TX_1
] = { AFE_PORT_ID_VA_CODEC_DMA_TX_1
,
805 VA_CODEC_DMA_TX_1
, 0, 1},
806 [VA_CODEC_DMA_TX_2
] = { AFE_PORT_ID_VA_CODEC_DMA_TX_2
,
807 VA_CODEC_DMA_TX_2
, 0, 1},
808 [RX_CODEC_DMA_RX_0
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_0
,
809 RX_CODEC_DMA_RX_0
, 1, 1},
810 [TX_CODEC_DMA_TX_0
] = { AFE_PORT_ID_TX_CODEC_DMA_TX_0
,
811 TX_CODEC_DMA_TX_0
, 0, 1},
812 [RX_CODEC_DMA_RX_1
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_1
,
813 RX_CODEC_DMA_RX_1
, 1, 1},
814 [TX_CODEC_DMA_TX_1
] = { AFE_PORT_ID_TX_CODEC_DMA_TX_1
,
815 TX_CODEC_DMA_TX_1
, 0, 1},
816 [RX_CODEC_DMA_RX_2
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_2
,
817 RX_CODEC_DMA_RX_2
, 1, 1},
818 [TX_CODEC_DMA_TX_2
] = { AFE_PORT_ID_TX_CODEC_DMA_TX_2
,
819 TX_CODEC_DMA_TX_2
, 0, 1},
820 [RX_CODEC_DMA_RX_3
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_3
,
821 RX_CODEC_DMA_RX_3
, 1, 1},
822 [TX_CODEC_DMA_TX_3
] = { AFE_PORT_ID_TX_CODEC_DMA_TX_3
,
823 TX_CODEC_DMA_TX_3
, 0, 1},
824 [RX_CODEC_DMA_RX_4
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_4
,
825 RX_CODEC_DMA_RX_4
, 1, 1},
826 [TX_CODEC_DMA_TX_4
] = { AFE_PORT_ID_TX_CODEC_DMA_TX_4
,
827 TX_CODEC_DMA_TX_4
, 0, 1},
828 [RX_CODEC_DMA_RX_5
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_5
,
829 RX_CODEC_DMA_RX_5
, 1, 1},
830 [TX_CODEC_DMA_TX_5
] = { AFE_PORT_ID_TX_CODEC_DMA_TX_5
,
831 TX_CODEC_DMA_TX_5
, 0, 1},
832 [RX_CODEC_DMA_RX_6
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_6
,
833 RX_CODEC_DMA_RX_6
, 1, 1},
834 [RX_CODEC_DMA_RX_7
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_7
,
835 RX_CODEC_DMA_RX_7
, 1, 1},
838 static void q6afe_port_free(struct kref
*ref
)
840 struct q6afe_port
*port
;
844 port
= container_of(ref
, struct q6afe_port
, refcount
);
846 spin_lock_irqsave(&afe
->port_list_lock
, flags
);
847 list_del(&port
->node
);
848 spin_unlock_irqrestore(&afe
->port_list_lock
, flags
);
853 static struct q6afe_port
*q6afe_find_port(struct q6afe
*afe
, int token
)
855 struct q6afe_port
*p
;
856 struct q6afe_port
*ret
= NULL
;
859 spin_lock_irqsave(&afe
->port_list_lock
, flags
);
860 list_for_each_entry(p
, &afe
->port_list
, node
)
861 if (p
->token
== token
) {
863 kref_get(&p
->refcount
);
867 spin_unlock_irqrestore(&afe
->port_list_lock
, flags
);
871 static int q6afe_callback(struct apr_device
*adev
, struct apr_resp_pkt
*data
)
873 struct q6afe
*afe
= dev_get_drvdata(&adev
->dev
);
874 struct aprv2_ibasic_rsp_result_t
*res
;
875 struct apr_hdr
*hdr
= &data
->hdr
;
876 struct q6afe_port
*port
;
878 if (!data
->payload_size
)
882 switch (hdr
->opcode
) {
883 case APR_BASIC_RSP_RESULT
: {
885 dev_err(afe
->dev
, "cmd = 0x%x returned error = 0x%x\n",
886 res
->opcode
, res
->status
);
888 switch (res
->opcode
) {
889 case AFE_PORT_CMD_SET_PARAM_V2
:
890 case AFE_PORT_CMD_DEVICE_STOP
:
891 case AFE_PORT_CMD_DEVICE_START
:
892 case AFE_SVC_CMD_SET_PARAM
:
893 port
= q6afe_find_port(afe
, hdr
->token
);
896 wake_up(&port
->wait
);
897 kref_put(&port
->refcount
, q6afe_port_free
);
898 } else if (hdr
->token
== AFE_CLK_TOKEN
) {
904 dev_err(afe
->dev
, "Unknown cmd 0x%x\n", res
->opcode
);
909 case AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST
:
910 afe
->result
.opcode
= hdr
->opcode
;
911 afe
->result
.status
= res
->status
;
922 * q6afe_get_port_id() - Get port id from a given port index
926 * Return: Will be an negative on error or valid port_id on success
928 int q6afe_get_port_id(int index
)
930 if (index
< 0 || index
>= AFE_PORT_MAX
)
933 return port_maps
[index
].port_id
;
935 EXPORT_SYMBOL_GPL(q6afe_get_port_id
);
937 static int afe_apr_send_pkt(struct q6afe
*afe
, struct apr_pkt
*pkt
,
938 struct q6afe_port
*port
, uint32_t rsp_opcode
)
940 wait_queue_head_t
*wait
;
941 struct aprv2_ibasic_rsp_result_t
*result
;
944 mutex_lock(&afe
->lock
);
947 result
= &port
->result
;
949 result
= &afe
->result
;
956 ret
= apr_send_pkt(afe
->apr
, pkt
);
958 dev_err(afe
->dev
, "packet not transmitted (%d)\n", ret
);
963 ret
= wait_event_timeout(*wait
, (result
->opcode
== rsp_opcode
),
964 msecs_to_jiffies(TIMEOUT_MS
));
967 } else if (result
->status
> 0) {
968 dev_err(afe
->dev
, "DSP returned error[%x]\n",
976 mutex_unlock(&afe
->lock
);
981 static int q6afe_set_param(struct q6afe
*afe
, struct q6afe_port
*port
,
982 void *data
, int param_id
, int module_id
, int psize
,
985 struct afe_svc_cmd_set_param
*param
;
986 struct afe_port_param_data_v2
*pdata
;
991 pkt_size
= APR_HDR_SIZE
+ sizeof(*param
) + sizeof(*pdata
) + psize
;
992 p
= kzalloc(pkt_size
, GFP_KERNEL
);
997 param
= p
+ APR_HDR_SIZE
;
998 pdata
= p
+ APR_HDR_SIZE
+ sizeof(*param
);
999 pl
= p
+ APR_HDR_SIZE
+ sizeof(*param
) + sizeof(*pdata
);
1000 memcpy(pl
, data
, psize
);
1002 pkt
->hdr
.hdr_field
= APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD
,
1003 APR_HDR_LEN(APR_HDR_SIZE
),
1005 pkt
->hdr
.pkt_size
= pkt_size
;
1006 pkt
->hdr
.src_port
= 0;
1007 pkt
->hdr
.dest_port
= 0;
1008 pkt
->hdr
.token
= token
;
1009 pkt
->hdr
.opcode
= AFE_SVC_CMD_SET_PARAM
;
1011 param
->payload_size
= sizeof(*pdata
) + psize
;
1012 param
->payload_address_lsw
= 0x00;
1013 param
->payload_address_msw
= 0x00;
1014 param
->mem_map_handle
= 0x00;
1015 pdata
->module_id
= module_id
;
1016 pdata
->param_id
= param_id
;
1017 pdata
->param_size
= psize
;
1019 ret
= afe_apr_send_pkt(afe
, pkt
, port
, AFE_SVC_CMD_SET_PARAM
);
1021 dev_err(afe
->dev
, "AFE set params failed %d\n", ret
);
1027 static int q6afe_port_set_param(struct q6afe_port
*port
, void *data
,
1028 int param_id
, int module_id
, int psize
)
1030 return q6afe_set_param(port
->afe
, port
, data
, param_id
, module_id
,
1031 psize
, port
->token
);
1034 static int q6afe_port_set_param_v2(struct q6afe_port
*port
, void *data
,
1035 int param_id
, int module_id
, int psize
)
1037 struct afe_port_cmd_set_param_v2
*param
;
1038 struct afe_port_param_data_v2
*pdata
;
1039 struct q6afe
*afe
= port
->afe
;
1040 struct apr_pkt
*pkt
;
1041 u16 port_id
= port
->id
;
1045 pkt_size
= APR_HDR_SIZE
+ sizeof(*param
) + sizeof(*pdata
) + psize
;
1046 p
= kzalloc(pkt_size
, GFP_KERNEL
);
1051 param
= p
+ APR_HDR_SIZE
;
1052 pdata
= p
+ APR_HDR_SIZE
+ sizeof(*param
);
1053 pl
= p
+ APR_HDR_SIZE
+ sizeof(*param
) + sizeof(*pdata
);
1054 memcpy(pl
, data
, psize
);
1056 pkt
->hdr
.hdr_field
= APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD
,
1057 APR_HDR_LEN(APR_HDR_SIZE
),
1059 pkt
->hdr
.pkt_size
= pkt_size
;
1060 pkt
->hdr
.src_port
= 0;
1061 pkt
->hdr
.dest_port
= 0;
1062 pkt
->hdr
.token
= port
->token
;
1063 pkt
->hdr
.opcode
= AFE_PORT_CMD_SET_PARAM_V2
;
1065 param
->port_id
= port_id
;
1066 param
->payload_size
= sizeof(*pdata
) + psize
;
1067 param
->payload_address_lsw
= 0x00;
1068 param
->payload_address_msw
= 0x00;
1069 param
->mem_map_handle
= 0x00;
1070 pdata
->module_id
= module_id
;
1071 pdata
->param_id
= param_id
;
1072 pdata
->param_size
= psize
;
1074 ret
= afe_apr_send_pkt(afe
, pkt
, port
, AFE_PORT_CMD_SET_PARAM_V2
);
1076 dev_err(afe
->dev
, "AFE enable for port 0x%x failed %d\n",
1083 static int q6afe_port_set_lpass_clock(struct q6afe_port
*port
,
1084 struct afe_clk_cfg
*cfg
)
1086 return q6afe_port_set_param_v2(port
, cfg
,
1087 AFE_PARAM_ID_LPAIF_CLK_CONFIG
,
1088 AFE_MODULE_AUDIO_DEV_INTERFACE
,
1092 static int q6afe_set_lpass_clock_v2(struct q6afe_port
*port
,
1093 struct afe_clk_set
*cfg
)
1095 return q6afe_port_set_param(port
, cfg
, AFE_PARAM_ID_CLOCK_SET
,
1096 AFE_MODULE_CLOCK_SET
, sizeof(*cfg
));
1099 static int q6afe_set_digital_codec_core_clock(struct q6afe_port
*port
,
1100 struct afe_digital_clk_cfg
*cfg
)
1102 return q6afe_port_set_param_v2(port
, cfg
,
1103 AFE_PARAM_ID_INT_DIGITAL_CDC_CLK_CONFIG
,
1104 AFE_MODULE_AUDIO_DEV_INTERFACE
,
1108 int q6afe_set_lpass_clock(struct device
*dev
, int clk_id
, int attri
,
1109 int clk_root
, unsigned int freq
)
1111 struct q6afe
*afe
= dev_get_drvdata(dev
->parent
);
1112 struct afe_clk_set cset
= {0,};
1114 cset
.clk_set_minor_version
= AFE_API_VERSION_CLOCK_SET
;
1115 cset
.clk_id
= clk_id
;
1116 cset
.clk_freq_in_hz
= freq
;
1117 cset
.clk_attri
= attri
;
1118 cset
.clk_root
= clk_root
;
1119 cset
.enable
= !!freq
;
1121 return q6afe_set_param(afe
, NULL
, &cset
, AFE_PARAM_ID_CLOCK_SET
,
1122 AFE_MODULE_CLOCK_SET
, sizeof(cset
),
1125 EXPORT_SYMBOL_GPL(q6afe_set_lpass_clock
);
1127 int q6afe_port_set_sysclk(struct q6afe_port
*port
, int clk_id
,
1128 int clk_src
, int clk_root
,
1129 unsigned int freq
, int dir
)
1131 struct afe_clk_cfg ccfg
= {0,};
1132 struct afe_clk_set cset
= {0,};
1133 struct afe_digital_clk_cfg dcfg
= {0,};
1138 dcfg
.i2s_cfg_minor_version
= AFE_API_VERSION_I2S_CONFIG
;
1139 dcfg
.clk_val
= freq
;
1140 dcfg
.clk_root
= clk_root
;
1141 ret
= q6afe_set_digital_codec_core_clock(port
, &dcfg
);
1144 ccfg
.i2s_cfg_minor_version
= AFE_API_VERSION_I2S_CONFIG
;
1145 ccfg
.clk_val1
= freq
;
1146 ccfg
.clk_src
= clk_src
;
1147 ccfg
.clk_root
= clk_root
;
1148 ccfg
.clk_set_mode
= Q6AFE_LPASS_MODE_CLK1_VALID
;
1149 ret
= q6afe_port_set_lpass_clock(port
, &ccfg
);
1153 ccfg
.i2s_cfg_minor_version
= AFE_API_VERSION_I2S_CONFIG
;
1154 ccfg
.clk_val2
= freq
;
1155 ccfg
.clk_src
= clk_src
;
1156 ccfg
.clk_root
= clk_root
;
1157 ccfg
.clk_set_mode
= Q6AFE_LPASS_MODE_CLK2_VALID
;
1158 ret
= q6afe_port_set_lpass_clock(port
, &ccfg
);
1160 case Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT
... Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR
:
1161 case Q6AFE_LPASS_CLK_ID_MCLK_1
... Q6AFE_LPASS_CLK_ID_INT_MCLK_1
:
1162 case Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT
... Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT
:
1163 case Q6AFE_LPASS_CLK_ID_WSA_CORE_MCLK
... Q6AFE_LPASS_CLK_ID_VA_CORE_2X_MCLK
:
1164 cset
.clk_set_minor_version
= AFE_API_VERSION_CLOCK_SET
;
1165 cset
.clk_id
= clk_id
;
1166 cset
.clk_freq_in_hz
= freq
;
1167 cset
.clk_attri
= clk_src
;
1168 cset
.clk_root
= clk_root
;
1169 cset
.enable
= !!freq
;
1170 ret
= q6afe_set_lpass_clock_v2(port
, &cset
);
1179 EXPORT_SYMBOL_GPL(q6afe_port_set_sysclk
);
1182 * q6afe_port_stop() - Stop a afe port
1184 * @port: Instance of port to stop
1186 * Return: Will be an negative on packet size on success.
1188 int q6afe_port_stop(struct q6afe_port
*port
)
1190 struct afe_port_cmd_device_stop
*stop
;
1191 struct q6afe
*afe
= port
->afe
;
1192 struct apr_pkt
*pkt
;
1193 int port_id
= port
->id
;
1195 int index
, pkt_size
;
1198 index
= port
->token
;
1199 if (index
< 0 || index
>= AFE_PORT_MAX
) {
1200 dev_err(afe
->dev
, "AFE port index[%d] invalid!\n", index
);
1204 pkt_size
= APR_HDR_SIZE
+ sizeof(*stop
);
1205 p
= kzalloc(pkt_size
, GFP_KERNEL
);
1210 stop
= p
+ APR_HDR_SIZE
;
1212 pkt
->hdr
.hdr_field
= APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD
,
1213 APR_HDR_LEN(APR_HDR_SIZE
),
1215 pkt
->hdr
.pkt_size
= pkt_size
;
1216 pkt
->hdr
.src_port
= 0;
1217 pkt
->hdr
.dest_port
= 0;
1218 pkt
->hdr
.token
= index
;
1219 pkt
->hdr
.opcode
= AFE_PORT_CMD_DEVICE_STOP
;
1220 stop
->port_id
= port_id
;
1223 ret
= afe_apr_send_pkt(afe
, pkt
, port
, AFE_PORT_CMD_DEVICE_STOP
);
1225 dev_err(afe
->dev
, "AFE close failed %d\n", ret
);
1230 EXPORT_SYMBOL_GPL(q6afe_port_stop
);
1233 * q6afe_slim_port_prepare() - Prepare slim afe port.
1235 * @port: Instance of afe port
1236 * @cfg: SLIM configuration for the afe port
1239 void q6afe_slim_port_prepare(struct q6afe_port
*port
,
1240 struct q6afe_slim_cfg
*cfg
)
1242 union afe_port_config
*pcfg
= &port
->port_cfg
;
1244 pcfg
->slim_cfg
.sb_cfg_minor_version
= AFE_API_VERSION_SLIMBUS_CONFIG
;
1245 pcfg
->slim_cfg
.sample_rate
= cfg
->sample_rate
;
1246 pcfg
->slim_cfg
.bit_width
= cfg
->bit_width
;
1247 pcfg
->slim_cfg
.num_channels
= cfg
->num_channels
;
1248 pcfg
->slim_cfg
.data_format
= cfg
->data_format
;
1249 pcfg
->slim_cfg
.shared_ch_mapping
[0] = cfg
->ch_mapping
[0];
1250 pcfg
->slim_cfg
.shared_ch_mapping
[1] = cfg
->ch_mapping
[1];
1251 pcfg
->slim_cfg
.shared_ch_mapping
[2] = cfg
->ch_mapping
[2];
1252 pcfg
->slim_cfg
.shared_ch_mapping
[3] = cfg
->ch_mapping
[3];
1255 EXPORT_SYMBOL_GPL(q6afe_slim_port_prepare
);
1258 * q6afe_tdm_port_prepare() - Prepare tdm afe port.
1260 * @port: Instance of afe port
1261 * @cfg: TDM configuration for the afe port
1264 void q6afe_tdm_port_prepare(struct q6afe_port
*port
,
1265 struct q6afe_tdm_cfg
*cfg
)
1267 union afe_port_config
*pcfg
= &port
->port_cfg
;
1269 pcfg
->tdm_cfg
.tdm_cfg_minor_version
= AFE_API_VERSION_TDM_CONFIG
;
1270 pcfg
->tdm_cfg
.num_channels
= cfg
->num_channels
;
1271 pcfg
->tdm_cfg
.sample_rate
= cfg
->sample_rate
;
1272 pcfg
->tdm_cfg
.bit_width
= cfg
->bit_width
;
1273 pcfg
->tdm_cfg
.data_format
= cfg
->data_format
;
1274 pcfg
->tdm_cfg
.sync_mode
= cfg
->sync_mode
;
1275 pcfg
->tdm_cfg
.sync_src
= cfg
->sync_src
;
1276 pcfg
->tdm_cfg
.nslots_per_frame
= cfg
->nslots_per_frame
;
1278 pcfg
->tdm_cfg
.slot_width
= cfg
->slot_width
;
1279 pcfg
->tdm_cfg
.slot_mask
= cfg
->slot_mask
;
1280 port
->scfg
= kzalloc(sizeof(*port
->scfg
), GFP_KERNEL
);
1284 port
->scfg
->minor_version
= AFE_API_VERSION_SLOT_MAPPING_CONFIG
;
1285 port
->scfg
->num_channels
= cfg
->num_channels
;
1286 port
->scfg
->bitwidth
= cfg
->bit_width
;
1287 port
->scfg
->data_align_type
= cfg
->data_align_type
;
1288 memcpy(port
->scfg
->ch_mapping
, cfg
->ch_mapping
,
1289 sizeof(u16
) * AFE_PORT_MAX_AUDIO_CHAN_CNT
);
1291 EXPORT_SYMBOL_GPL(q6afe_tdm_port_prepare
);
1294 * q6afe_hdmi_port_prepare() - Prepare hdmi afe port.
1296 * @port: Instance of afe port
1297 * @cfg: HDMI configuration for the afe port
1300 void q6afe_hdmi_port_prepare(struct q6afe_port
*port
,
1301 struct q6afe_hdmi_cfg
*cfg
)
1303 union afe_port_config
*pcfg
= &port
->port_cfg
;
1305 pcfg
->hdmi_multi_ch
.hdmi_cfg_minor_version
=
1306 AFE_API_VERSION_HDMI_CONFIG
;
1307 pcfg
->hdmi_multi_ch
.datatype
= cfg
->datatype
;
1308 pcfg
->hdmi_multi_ch
.channel_allocation
= cfg
->channel_allocation
;
1309 pcfg
->hdmi_multi_ch
.sample_rate
= cfg
->sample_rate
;
1310 pcfg
->hdmi_multi_ch
.bit_width
= cfg
->bit_width
;
1312 EXPORT_SYMBOL_GPL(q6afe_hdmi_port_prepare
);
1315 * q6afe_i2s_port_prepare() - Prepare i2s afe port.
1317 * @port: Instance of afe port
1318 * @cfg: I2S configuration for the afe port
1319 * Return: Will be an negative on error and zero on success.
1321 int q6afe_i2s_port_prepare(struct q6afe_port
*port
, struct q6afe_i2s_cfg
*cfg
)
1323 union afe_port_config
*pcfg
= &port
->port_cfg
;
1324 struct device
*dev
= port
->afe
->dev
;
1327 pcfg
->i2s_cfg
.i2s_cfg_minor_version
= AFE_API_VERSION_I2S_CONFIG
;
1328 pcfg
->i2s_cfg
.sample_rate
= cfg
->sample_rate
;
1329 pcfg
->i2s_cfg
.bit_width
= cfg
->bit_width
;
1330 pcfg
->i2s_cfg
.data_format
= AFE_LINEAR_PCM_DATA
;
1332 switch (cfg
->fmt
& SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK
) {
1333 case SND_SOC_DAIFMT_BP_FP
:
1334 pcfg
->i2s_cfg
.ws_src
= AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL
;
1336 case SND_SOC_DAIFMT_BC_FC
:
1338 pcfg
->i2s_cfg
.ws_src
= AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL
;
1344 num_sd_lines
= hweight_long(cfg
->sd_line_mask
);
1346 switch (num_sd_lines
) {
1348 dev_err(dev
, "no line is assigned\n");
1351 switch (cfg
->sd_line_mask
) {
1352 case AFE_PORT_I2S_SD0_MASK
:
1353 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_SD0
;
1355 case AFE_PORT_I2S_SD1_MASK
:
1356 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_SD1
;
1358 case AFE_PORT_I2S_SD2_MASK
:
1359 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_SD2
;
1361 case AFE_PORT_I2S_SD3_MASK
:
1362 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_SD3
;
1365 dev_err(dev
, "Invalid SD lines\n");
1370 switch (cfg
->sd_line_mask
) {
1371 case AFE_PORT_I2S_SD0_1_MASK
:
1372 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_QUAD01
;
1374 case AFE_PORT_I2S_SD2_3_MASK
:
1375 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_QUAD23
;
1378 dev_err(dev
, "Invalid SD lines\n");
1383 switch (cfg
->sd_line_mask
) {
1384 case AFE_PORT_I2S_SD0_1_2_MASK
:
1385 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_6CHS
;
1388 dev_err(dev
, "Invalid SD lines\n");
1393 switch (cfg
->sd_line_mask
) {
1394 case AFE_PORT_I2S_SD0_1_2_3_MASK
:
1395 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_8CHS
;
1399 dev_err(dev
, "Invalid SD lines\n");
1404 dev_err(dev
, "Invalid SD lines\n");
1408 switch (cfg
->num_channels
) {
1411 switch (pcfg
->i2s_cfg
.channel_mode
) {
1412 case AFE_PORT_I2S_QUAD01
:
1413 case AFE_PORT_I2S_6CHS
:
1414 case AFE_PORT_I2S_8CHS
:
1415 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_SD0
;
1417 case AFE_PORT_I2S_QUAD23
:
1418 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_SD2
;
1422 if (cfg
->num_channels
== 2)
1423 pcfg
->i2s_cfg
.mono_stereo
= AFE_PORT_I2S_STEREO
;
1425 pcfg
->i2s_cfg
.mono_stereo
= AFE_PORT_I2S_MONO
;
1430 if (pcfg
->i2s_cfg
.channel_mode
< AFE_PORT_I2S_QUAD01
) {
1431 dev_err(dev
, "Invalid Channel mode\n");
1437 if (pcfg
->i2s_cfg
.channel_mode
< AFE_PORT_I2S_6CHS
) {
1438 dev_err(dev
, "Invalid Channel mode\n");
1444 if (pcfg
->i2s_cfg
.channel_mode
< AFE_PORT_I2S_8CHS
) {
1445 dev_err(dev
, "Invalid Channel mode\n");
1455 EXPORT_SYMBOL_GPL(q6afe_i2s_port_prepare
);
1458 * q6afe_cdc_dma_port_prepare() - Prepare dma afe port.
1460 * @port: Instance of afe port
1461 * @cfg: DMA configuration for the afe port
1464 void q6afe_cdc_dma_port_prepare(struct q6afe_port
*port
,
1465 struct q6afe_cdc_dma_cfg
*cfg
)
1467 union afe_port_config
*pcfg
= &port
->port_cfg
;
1468 struct afe_param_id_cdc_dma_cfg
*dma_cfg
= &pcfg
->dma_cfg
;
1470 dma_cfg
->cdc_dma_cfg_minor_version
= AFE_API_VERSION_CODEC_DMA_CONFIG
;
1471 dma_cfg
->sample_rate
= cfg
->sample_rate
;
1472 dma_cfg
->bit_width
= cfg
->bit_width
;
1473 dma_cfg
->data_format
= cfg
->data_format
;
1474 dma_cfg
->num_channels
= cfg
->num_channels
;
1475 if (!cfg
->active_channels_mask
)
1476 dma_cfg
->active_channels_mask
= (1 << cfg
->num_channels
) - 1;
1478 EXPORT_SYMBOL_GPL(q6afe_cdc_dma_port_prepare
);
1480 * q6afe_port_start() - Start a afe port
1482 * @port: Instance of port to start
1484 * Return: Will be an negative on packet size on success.
1486 int q6afe_port_start(struct q6afe_port
*port
)
1488 struct afe_port_cmd_device_start
*start
;
1489 struct q6afe
*afe
= port
->afe
;
1490 int port_id
= port
->id
;
1491 int ret
, param_id
= port
->cfg_type
;
1492 struct apr_pkt
*pkt
;
1496 ret
= q6afe_port_set_param_v2(port
, &port
->port_cfg
, param_id
,
1497 AFE_MODULE_AUDIO_DEV_INTERFACE
,
1498 sizeof(port
->port_cfg
));
1500 dev_err(afe
->dev
, "AFE enable for port 0x%x failed %d\n",
1506 ret
= q6afe_port_set_param_v2(port
, port
->scfg
,
1507 AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG
,
1508 AFE_MODULE_TDM
, sizeof(*port
->scfg
));
1510 dev_err(afe
->dev
, "AFE enable for port 0x%x failed %d\n",
1516 pkt_size
= APR_HDR_SIZE
+ sizeof(*start
);
1517 p
= kzalloc(pkt_size
, GFP_KERNEL
);
1522 start
= p
+ APR_HDR_SIZE
;
1524 pkt
->hdr
.hdr_field
= APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD
,
1525 APR_HDR_LEN(APR_HDR_SIZE
),
1527 pkt
->hdr
.pkt_size
= pkt_size
;
1528 pkt
->hdr
.src_port
= 0;
1529 pkt
->hdr
.dest_port
= 0;
1530 pkt
->hdr
.token
= port
->token
;
1531 pkt
->hdr
.opcode
= AFE_PORT_CMD_DEVICE_START
;
1533 start
->port_id
= port_id
;
1535 ret
= afe_apr_send_pkt(afe
, pkt
, port
, AFE_PORT_CMD_DEVICE_START
);
1537 dev_err(afe
->dev
, "AFE enable for port 0x%x failed %d\n",
1543 EXPORT_SYMBOL_GPL(q6afe_port_start
);
1546 * q6afe_port_get_from_id() - Get port instance from a port id
1548 * @dev: Pointer to afe child device.
1551 * Return: Will be an error pointer on error or a valid afe port
1554 struct q6afe_port
*q6afe_port_get_from_id(struct device
*dev
, int id
)
1557 struct q6afe
*afe
= dev_get_drvdata(dev
->parent
);
1558 struct q6afe_port
*port
;
1559 unsigned long flags
;
1562 if (id
< 0 || id
>= AFE_PORT_MAX
) {
1563 dev_err(dev
, "AFE port token[%d] invalid!\n", id
);
1564 return ERR_PTR(-EINVAL
);
1567 /* if port is multiple times bind/unbind before callback finishes */
1568 port
= q6afe_find_port(afe
, id
);
1570 dev_err(dev
, "AFE Port already open\n");
1574 port_id
= port_maps
[id
].port_id
;
1577 case AFE_PORT_ID_MULTICHAN_HDMI_RX
:
1578 case AFE_PORT_ID_HDMI_OVER_DP_RX
:
1579 cfg_type
= AFE_PARAM_ID_HDMI_CONFIG
;
1581 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX
:
1582 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX
:
1583 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX
:
1584 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX
:
1585 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX
:
1586 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX
:
1587 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX
:
1588 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX
:
1589 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX
:
1590 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX
:
1591 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX
:
1592 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX
:
1593 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX
:
1594 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX
:
1595 cfg_type
= AFE_PARAM_ID_SLIMBUS_CONFIG
;
1598 case AFE_PORT_ID_PRIMARY_MI2S_RX
:
1599 case AFE_PORT_ID_PRIMARY_MI2S_TX
:
1600 case AFE_PORT_ID_SECONDARY_MI2S_RX
:
1601 case AFE_PORT_ID_SECONDARY_MI2S_TX
:
1602 case AFE_PORT_ID_TERTIARY_MI2S_RX
:
1603 case AFE_PORT_ID_TERTIARY_MI2S_TX
:
1604 case AFE_PORT_ID_QUATERNARY_MI2S_RX
:
1605 case AFE_PORT_ID_QUATERNARY_MI2S_TX
:
1606 case AFE_PORT_ID_QUINARY_MI2S_RX
:
1607 case AFE_PORT_ID_QUINARY_MI2S_TX
:
1608 cfg_type
= AFE_PARAM_ID_I2S_CONFIG
;
1610 case AFE_PORT_ID_PRIMARY_TDM_RX
... AFE_PORT_ID_QUINARY_TDM_TX_7
:
1611 cfg_type
= AFE_PARAM_ID_TDM_CONFIG
;
1613 case AFE_PORT_ID_WSA_CODEC_DMA_RX_0
... AFE_PORT_ID_RX_CODEC_DMA_RX_7
:
1614 cfg_type
= AFE_PARAM_ID_CODEC_DMA_CONFIG
;
1617 dev_err(dev
, "Invalid port id 0x%x\n", port_id
);
1618 return ERR_PTR(-EINVAL
);
1621 port
= kzalloc(sizeof(*port
), GFP_KERNEL
);
1623 return ERR_PTR(-ENOMEM
);
1625 init_waitqueue_head(&port
->wait
);
1630 port
->cfg_type
= cfg_type
;
1631 kref_init(&port
->refcount
);
1633 spin_lock_irqsave(&afe
->port_list_lock
, flags
);
1634 list_add_tail(&port
->node
, &afe
->port_list
);
1635 spin_unlock_irqrestore(&afe
->port_list_lock
, flags
);
1640 EXPORT_SYMBOL_GPL(q6afe_port_get_from_id
);
1643 * q6afe_port_put() - Release port reference
1645 * @port: Instance of port to put
1647 void q6afe_port_put(struct q6afe_port
*port
)
1649 kref_put(&port
->refcount
, q6afe_port_free
);
1651 EXPORT_SYMBOL_GPL(q6afe_port_put
);
1653 int q6afe_unvote_lpass_core_hw(struct device
*dev
, uint32_t hw_block_id
,
1654 uint32_t client_handle
)
1656 struct q6afe
*afe
= dev_get_drvdata(dev
->parent
);
1657 struct afe_cmd_remote_lpass_core_hw_devote_request
*vote_cfg
;
1658 struct apr_pkt
*pkt
;
1663 pkt_size
= APR_HDR_SIZE
+ sizeof(*vote_cfg
);
1664 p
= kzalloc(pkt_size
, GFP_KERNEL
);
1669 vote_cfg
= p
+ APR_HDR_SIZE
;
1671 pkt
->hdr
.hdr_field
= APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD
,
1672 APR_HDR_LEN(APR_HDR_SIZE
),
1674 pkt
->hdr
.pkt_size
= pkt_size
;
1675 pkt
->hdr
.src_port
= 0;
1676 pkt
->hdr
.dest_port
= 0;
1677 pkt
->hdr
.token
= hw_block_id
;
1678 pkt
->hdr
.opcode
= AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST
;
1679 vote_cfg
->hw_block_id
= hw_block_id
;
1680 vote_cfg
->client_handle
= client_handle
;
1682 ret
= apr_send_pkt(afe
->apr
, pkt
);
1684 dev_err(afe
->dev
, "AFE failed to unvote (%d)\n", hw_block_id
);
1689 EXPORT_SYMBOL(q6afe_unvote_lpass_core_hw
);
1691 int q6afe_vote_lpass_core_hw(struct device
*dev
, uint32_t hw_block_id
,
1692 const char *client_name
, uint32_t *client_handle
)
1694 struct q6afe
*afe
= dev_get_drvdata(dev
->parent
);
1695 struct afe_cmd_remote_lpass_core_hw_vote_request
*vote_cfg
;
1696 struct apr_pkt
*pkt
;
1701 pkt_size
= APR_HDR_SIZE
+ sizeof(*vote_cfg
);
1702 p
= kzalloc(pkt_size
, GFP_KERNEL
);
1707 vote_cfg
= p
+ APR_HDR_SIZE
;
1709 pkt
->hdr
.hdr_field
= APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD
,
1710 APR_HDR_LEN(APR_HDR_SIZE
),
1712 pkt
->hdr
.pkt_size
= pkt_size
;
1713 pkt
->hdr
.src_port
= 0;
1714 pkt
->hdr
.dest_port
= 0;
1715 pkt
->hdr
.token
= hw_block_id
;
1716 pkt
->hdr
.opcode
= AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST
;
1717 vote_cfg
->hw_block_id
= hw_block_id
;
1718 strscpy(vote_cfg
->client_name
, client_name
,
1719 sizeof(vote_cfg
->client_name
));
1721 ret
= afe_apr_send_pkt(afe
, pkt
, NULL
,
1722 AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST
);
1724 dev_err(afe
->dev
, "AFE failed to vote (%d)\n", hw_block_id
);
1730 EXPORT_SYMBOL(q6afe_vote_lpass_core_hw
);
1732 static int q6afe_probe(struct apr_device
*adev
)
1735 struct device
*dev
= &adev
->dev
;
1737 afe
= devm_kzalloc(dev
, sizeof(*afe
), GFP_KERNEL
);
1741 q6core_get_svc_api_info(adev
->svc_id
, &afe
->ainfo
);
1743 mutex_init(&afe
->lock
);
1744 init_waitqueue_head(&afe
->wait
);
1746 INIT_LIST_HEAD(&afe
->port_list
);
1747 spin_lock_init(&afe
->port_list_lock
);
1749 dev_set_drvdata(dev
, afe
);
1751 return devm_of_platform_populate(dev
);
1755 static const struct of_device_id q6afe_device_id
[] = {
1756 { .compatible
= "qcom,q6afe" },
1759 MODULE_DEVICE_TABLE(of
, q6afe_device_id
);
1762 static struct apr_driver qcom_q6afe_driver
= {
1763 .probe
= q6afe_probe
,
1764 .callback
= q6afe_callback
,
1766 .name
= "qcom-q6afe",
1767 .of_match_table
= of_match_ptr(q6afe_device_id
),
1772 module_apr_driver(qcom_q6afe_driver
);
1773 MODULE_DESCRIPTION("Q6 Audio Front End");
1774 MODULE_LICENSE("GPL v2");