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 <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>
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"
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
36 #define AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG 0x00010235
38 #define AFE_PARAM_ID_LPAIF_CLK_CONFIG 0x00010238
39 #define AFE_PARAM_ID_INT_DIGITAL_CDC_CLK_CONFIG 0x00010239
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 #define AFE_PARAM_ID_CODEC_DMA_CONFIG 0x000102B8
46 #define AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST 0x000100f4
47 #define AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST 0x000100f5
48 #define AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST 0x000100f6
50 /* I2S config specific */
51 #define AFE_API_VERSION_I2S_CONFIG 0x1
52 #define AFE_PORT_I2S_SD0 0x1
53 #define AFE_PORT_I2S_SD1 0x2
54 #define AFE_PORT_I2S_SD2 0x3
55 #define AFE_PORT_I2S_SD3 0x4
56 #define AFE_PORT_I2S_SD0_MASK BIT(0x0)
57 #define AFE_PORT_I2S_SD1_MASK BIT(0x1)
58 #define AFE_PORT_I2S_SD2_MASK BIT(0x2)
59 #define AFE_PORT_I2S_SD3_MASK BIT(0x3)
60 #define AFE_PORT_I2S_SD0_1_MASK GENMASK(1, 0)
61 #define AFE_PORT_I2S_SD2_3_MASK GENMASK(3, 2)
62 #define AFE_PORT_I2S_SD0_1_2_MASK GENMASK(2, 0)
63 #define AFE_PORT_I2S_SD0_1_2_3_MASK GENMASK(3, 0)
64 #define AFE_PORT_I2S_QUAD01 0x5
65 #define AFE_PORT_I2S_QUAD23 0x6
66 #define AFE_PORT_I2S_6CHS 0x7
67 #define AFE_PORT_I2S_8CHS 0x8
68 #define AFE_PORT_I2S_MONO 0x0
69 #define AFE_PORT_I2S_STEREO 0x1
70 #define AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL 0x0
71 #define AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL 0x1
72 #define AFE_LINEAR_PCM_DATA 0x0
76 #define AFE_API_VERSION_HDMI_CONFIG 0x1
77 #define AFE_PORT_ID_MULTICHAN_HDMI_RX 0x100E
78 #define AFE_PORT_ID_HDMI_OVER_DP_RX 0x6020
80 #define AFE_API_VERSION_SLIMBUS_CONFIG 0x1
81 /* Clock set API version */
82 #define AFE_API_VERSION_CLOCK_SET 1
83 #define Q6AFE_LPASS_CLK_CONFIG_API_VERSION 0x1
84 #define AFE_MODULE_CLOCK_SET 0x0001028F
85 #define AFE_PARAM_ID_CLOCK_SET 0x00010290
87 /* SLIMbus Rx port on channel 0. */
88 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX 0x4000
89 /* SLIMbus Tx port on channel 0. */
90 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX 0x4001
91 /* SLIMbus Rx port on channel 1. */
92 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX 0x4002
93 /* SLIMbus Tx port on channel 1. */
94 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX 0x4003
95 /* SLIMbus Rx port on channel 2. */
96 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX 0x4004
97 /* SLIMbus Tx port on channel 2. */
98 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX 0x4005
99 /* SLIMbus Rx port on channel 3. */
100 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX 0x4006
101 /* SLIMbus Tx port on channel 3. */
102 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX 0x4007
103 /* SLIMbus Rx port on channel 4. */
104 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX 0x4008
105 /* SLIMbus Tx port on channel 4. */
106 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX 0x4009
107 /* SLIMbus Rx port on channel 5. */
108 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX 0x400a
109 /* SLIMbus Tx port on channel 5. */
110 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX 0x400b
111 /* SLIMbus Rx port on channel 6. */
112 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX 0x400c
113 /* SLIMbus Tx port on channel 6. */
114 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX 0x400d
115 #define AFE_PORT_ID_PRIMARY_MI2S_RX 0x1000
116 #define AFE_PORT_ID_PRIMARY_MI2S_TX 0x1001
117 #define AFE_PORT_ID_SECONDARY_MI2S_RX 0x1002
118 #define AFE_PORT_ID_SECONDARY_MI2S_TX 0x1003
119 #define AFE_PORT_ID_TERTIARY_MI2S_RX 0x1004
120 #define AFE_PORT_ID_TERTIARY_MI2S_TX 0x1005
121 #define AFE_PORT_ID_QUATERNARY_MI2S_RX 0x1006
122 #define AFE_PORT_ID_QUATERNARY_MI2S_TX 0x1007
124 /* Start of the range of port IDs for TDM devices. */
125 #define AFE_PORT_ID_TDM_PORT_RANGE_START 0x9000
127 /* End of the range of port IDs for TDM devices. */
128 #define AFE_PORT_ID_TDM_PORT_RANGE_END \
129 (AFE_PORT_ID_TDM_PORT_RANGE_START+0x50-1)
131 /* Size of the range of port IDs for TDM ports. */
132 #define AFE_PORT_ID_TDM_PORT_RANGE_SIZE \
133 (AFE_PORT_ID_TDM_PORT_RANGE_END - \
134 AFE_PORT_ID_TDM_PORT_RANGE_START+1)
136 #define AFE_PORT_ID_PRIMARY_TDM_RX \
137 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x00)
138 #define AFE_PORT_ID_PRIMARY_TDM_RX_1 \
139 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x02)
140 #define AFE_PORT_ID_PRIMARY_TDM_RX_2 \
141 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x04)
142 #define AFE_PORT_ID_PRIMARY_TDM_RX_3 \
143 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x06)
144 #define AFE_PORT_ID_PRIMARY_TDM_RX_4 \
145 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x08)
146 #define AFE_PORT_ID_PRIMARY_TDM_RX_5 \
147 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0A)
148 #define AFE_PORT_ID_PRIMARY_TDM_RX_6 \
149 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0C)
150 #define AFE_PORT_ID_PRIMARY_TDM_RX_7 \
151 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0E)
153 #define AFE_PORT_ID_PRIMARY_TDM_TX \
154 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x01)
155 #define AFE_PORT_ID_PRIMARY_TDM_TX_1 \
156 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x02)
157 #define AFE_PORT_ID_PRIMARY_TDM_TX_2 \
158 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x04)
159 #define AFE_PORT_ID_PRIMARY_TDM_TX_3 \
160 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x06)
161 #define AFE_PORT_ID_PRIMARY_TDM_TX_4 \
162 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x08)
163 #define AFE_PORT_ID_PRIMARY_TDM_TX_5 \
164 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0A)
165 #define AFE_PORT_ID_PRIMARY_TDM_TX_6 \
166 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0C)
167 #define AFE_PORT_ID_PRIMARY_TDM_TX_7 \
168 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0E)
170 #define AFE_PORT_ID_SECONDARY_TDM_RX \
171 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x10)
172 #define AFE_PORT_ID_SECONDARY_TDM_RX_1 \
173 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x02)
174 #define AFE_PORT_ID_SECONDARY_TDM_RX_2 \
175 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x04)
176 #define AFE_PORT_ID_SECONDARY_TDM_RX_3 \
177 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x06)
178 #define AFE_PORT_ID_SECONDARY_TDM_RX_4 \
179 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x08)
180 #define AFE_PORT_ID_SECONDARY_TDM_RX_5 \
181 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0A)
182 #define AFE_PORT_ID_SECONDARY_TDM_RX_6 \
183 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0C)
184 #define AFE_PORT_ID_SECONDARY_TDM_RX_7 \
185 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0E)
187 #define AFE_PORT_ID_SECONDARY_TDM_TX \
188 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x11)
189 #define AFE_PORT_ID_SECONDARY_TDM_TX_1 \
190 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x02)
191 #define AFE_PORT_ID_SECONDARY_TDM_TX_2 \
192 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x04)
193 #define AFE_PORT_ID_SECONDARY_TDM_TX_3 \
194 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x06)
195 #define AFE_PORT_ID_SECONDARY_TDM_TX_4 \
196 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x08)
197 #define AFE_PORT_ID_SECONDARY_TDM_TX_5 \
198 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0A)
199 #define AFE_PORT_ID_SECONDARY_TDM_TX_6 \
200 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0C)
201 #define AFE_PORT_ID_SECONDARY_TDM_TX_7 \
202 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0E)
204 #define AFE_PORT_ID_TERTIARY_TDM_RX \
205 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x20)
206 #define AFE_PORT_ID_TERTIARY_TDM_RX_1 \
207 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x02)
208 #define AFE_PORT_ID_TERTIARY_TDM_RX_2 \
209 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x04)
210 #define AFE_PORT_ID_TERTIARY_TDM_RX_3 \
211 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x06)
212 #define AFE_PORT_ID_TERTIARY_TDM_RX_4 \
213 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x08)
214 #define AFE_PORT_ID_TERTIARY_TDM_RX_5 \
215 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0A)
216 #define AFE_PORT_ID_TERTIARY_TDM_RX_6 \
217 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0C)
218 #define AFE_PORT_ID_TERTIARY_TDM_RX_7 \
219 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0E)
221 #define AFE_PORT_ID_TERTIARY_TDM_TX \
222 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x21)
223 #define AFE_PORT_ID_TERTIARY_TDM_TX_1 \
224 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x02)
225 #define AFE_PORT_ID_TERTIARY_TDM_TX_2 \
226 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x04)
227 #define AFE_PORT_ID_TERTIARY_TDM_TX_3 \
228 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x06)
229 #define AFE_PORT_ID_TERTIARY_TDM_TX_4 \
230 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x08)
231 #define AFE_PORT_ID_TERTIARY_TDM_TX_5 \
232 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0A)
233 #define AFE_PORT_ID_TERTIARY_TDM_TX_6 \
234 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0C)
235 #define AFE_PORT_ID_TERTIARY_TDM_TX_7 \
236 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0E)
238 #define AFE_PORT_ID_QUATERNARY_TDM_RX \
239 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x30)
240 #define AFE_PORT_ID_QUATERNARY_TDM_RX_1 \
241 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x02)
242 #define AFE_PORT_ID_QUATERNARY_TDM_RX_2 \
243 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x04)
244 #define AFE_PORT_ID_QUATERNARY_TDM_RX_3 \
245 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x06)
246 #define AFE_PORT_ID_QUATERNARY_TDM_RX_4 \
247 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x08)
248 #define AFE_PORT_ID_QUATERNARY_TDM_RX_5 \
249 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0A)
250 #define AFE_PORT_ID_QUATERNARY_TDM_RX_6 \
251 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0C)
252 #define AFE_PORT_ID_QUATERNARY_TDM_RX_7 \
253 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0E)
255 #define AFE_PORT_ID_QUATERNARY_TDM_TX \
256 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x31)
257 #define AFE_PORT_ID_QUATERNARY_TDM_TX_1 \
258 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x02)
259 #define AFE_PORT_ID_QUATERNARY_TDM_TX_2 \
260 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x04)
261 #define AFE_PORT_ID_QUATERNARY_TDM_TX_3 \
262 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x06)
263 #define AFE_PORT_ID_QUATERNARY_TDM_TX_4 \
264 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x08)
265 #define AFE_PORT_ID_QUATERNARY_TDM_TX_5 \
266 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0A)
267 #define AFE_PORT_ID_QUATERNARY_TDM_TX_6 \
268 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0C)
269 #define AFE_PORT_ID_QUATERNARY_TDM_TX_7 \
270 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0E)
272 #define AFE_PORT_ID_QUINARY_TDM_RX \
273 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x40)
274 #define AFE_PORT_ID_QUINARY_TDM_RX_1 \
275 (AFE_PORT_ID_QUINARY_TDM_RX + 0x02)
276 #define AFE_PORT_ID_QUINARY_TDM_RX_2 \
277 (AFE_PORT_ID_QUINARY_TDM_RX + 0x04)
278 #define AFE_PORT_ID_QUINARY_TDM_RX_3 \
279 (AFE_PORT_ID_QUINARY_TDM_RX + 0x06)
280 #define AFE_PORT_ID_QUINARY_TDM_RX_4 \
281 (AFE_PORT_ID_QUINARY_TDM_RX + 0x08)
282 #define AFE_PORT_ID_QUINARY_TDM_RX_5 \
283 (AFE_PORT_ID_QUINARY_TDM_RX + 0x0A)
284 #define AFE_PORT_ID_QUINARY_TDM_RX_6 \
285 (AFE_PORT_ID_QUINARY_TDM_RX + 0x0C)
286 #define AFE_PORT_ID_QUINARY_TDM_RX_7 \
287 (AFE_PORT_ID_QUINARY_TDM_RX + 0x0E)
289 #define AFE_PORT_ID_QUINARY_TDM_TX \
290 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x41)
291 #define AFE_PORT_ID_QUINARY_TDM_TX_1 \
292 (AFE_PORT_ID_QUINARY_TDM_TX + 0x02)
293 #define AFE_PORT_ID_QUINARY_TDM_TX_2 \
294 (AFE_PORT_ID_QUINARY_TDM_TX + 0x04)
295 #define AFE_PORT_ID_QUINARY_TDM_TX_3 \
296 (AFE_PORT_ID_QUINARY_TDM_TX + 0x06)
297 #define AFE_PORT_ID_QUINARY_TDM_TX_4 \
298 (AFE_PORT_ID_QUINARY_TDM_TX + 0x08)
299 #define AFE_PORT_ID_QUINARY_TDM_TX_5 \
300 (AFE_PORT_ID_QUINARY_TDM_TX + 0x0A)
301 #define AFE_PORT_ID_QUINARY_TDM_TX_6 \
302 (AFE_PORT_ID_QUINARY_TDM_TX + 0x0C)
303 #define AFE_PORT_ID_QUINARY_TDM_TX_7 \
304 (AFE_PORT_ID_QUINARY_TDM_TX + 0x0E)
306 /* AFE WSA Codec DMA Rx port 0 */
307 #define AFE_PORT_ID_WSA_CODEC_DMA_RX_0 0xB000
308 /* AFE WSA Codec DMA Tx port 0 */
309 #define AFE_PORT_ID_WSA_CODEC_DMA_TX_0 0xB001
310 /* AFE WSA Codec DMA Rx port 1 */
311 #define AFE_PORT_ID_WSA_CODEC_DMA_RX_1 0xB002
312 /* AFE WSA Codec DMA Tx port 1 */
313 #define AFE_PORT_ID_WSA_CODEC_DMA_TX_1 0xB003
314 /* AFE WSA Codec DMA Tx port 2 */
315 #define AFE_PORT_ID_WSA_CODEC_DMA_TX_2 0xB005
316 /* AFE VA Codec DMA Tx port 0 */
317 #define AFE_PORT_ID_VA_CODEC_DMA_TX_0 0xB021
318 /* AFE VA Codec DMA Tx port 1 */
319 #define AFE_PORT_ID_VA_CODEC_DMA_TX_1 0xB023
320 /* AFE VA Codec DMA Tx port 2 */
321 #define AFE_PORT_ID_VA_CODEC_DMA_TX_2 0xB025
322 /* AFE Rx Codec DMA Rx port 0 */
323 #define AFE_PORT_ID_RX_CODEC_DMA_RX_0 0xB030
324 /* AFE Tx Codec DMA Tx port 0 */
325 #define AFE_PORT_ID_TX_CODEC_DMA_TX_0 0xB031
326 /* AFE Rx Codec DMA Rx port 1 */
327 #define AFE_PORT_ID_RX_CODEC_DMA_RX_1 0xB032
328 /* AFE Tx Codec DMA Tx port 1 */
329 #define AFE_PORT_ID_TX_CODEC_DMA_TX_1 0xB033
330 /* AFE Rx Codec DMA Rx port 2 */
331 #define AFE_PORT_ID_RX_CODEC_DMA_RX_2 0xB034
332 /* AFE Tx Codec DMA Tx port 2 */
333 #define AFE_PORT_ID_TX_CODEC_DMA_TX_2 0xB035
334 /* AFE Rx Codec DMA Rx port 3 */
335 #define AFE_PORT_ID_RX_CODEC_DMA_RX_3 0xB036
336 /* AFE Tx Codec DMA Tx port 3 */
337 #define AFE_PORT_ID_TX_CODEC_DMA_TX_3 0xB037
338 /* AFE Rx Codec DMA Rx port 4 */
339 #define AFE_PORT_ID_RX_CODEC_DMA_RX_4 0xB038
340 /* AFE Tx Codec DMA Tx port 4 */
341 #define AFE_PORT_ID_TX_CODEC_DMA_TX_4 0xB039
342 /* AFE Rx Codec DMA Rx port 5 */
343 #define AFE_PORT_ID_RX_CODEC_DMA_RX_5 0xB03A
344 /* AFE Tx Codec DMA Tx port 5 */
345 #define AFE_PORT_ID_TX_CODEC_DMA_TX_5 0xB03B
346 /* AFE Rx Codec DMA Rx port 6 */
347 #define AFE_PORT_ID_RX_CODEC_DMA_RX_6 0xB03C
348 /* AFE Rx Codec DMA Rx port 7 */
349 #define AFE_PORT_ID_RX_CODEC_DMA_RX_7 0xB03E
351 #define Q6AFE_LPASS_MODE_CLK1_VALID 1
352 #define Q6AFE_LPASS_MODE_CLK2_VALID 2
353 #define Q6AFE_LPASS_CLK_SRC_INTERNAL 1
354 #define Q6AFE_LPASS_CLK_ROOT_DEFAULT 0
355 #define AFE_API_VERSION_TDM_CONFIG 1
356 #define AFE_API_VERSION_SLOT_MAPPING_CONFIG 1
357 #define AFE_API_VERSION_CODEC_DMA_CONFIG 1
359 #define TIMEOUT_MS 1000
360 #define AFE_CMD_RESP_AVAIL 0
361 #define AFE_CMD_RESP_NONE 1
362 #define AFE_CLK_TOKEN 1024
365 struct apr_device
*apr
;
367 struct q6core_svc_api_info ainfo
;
369 struct aprv2_ibasic_rsp_result_t result
;
370 wait_queue_head_t wait
;
371 struct list_head port_list
;
372 spinlock_t port_list_lock
;
375 struct afe_port_cmd_device_start
{
380 struct afe_port_cmd_device_stop
{
383 /* Reserved for 32-bit alignment. This field must be set to 0.*/
386 struct afe_port_param_data_v2
{
393 struct afe_svc_cmd_set_param
{
394 uint32_t payload_size
;
395 uint32_t payload_address_lsw
;
396 uint32_t payload_address_msw
;
397 uint32_t mem_map_handle
;
400 struct afe_port_cmd_set_param_v2
{
403 u32 payload_address_lsw
;
404 u32 payload_address_msw
;
408 struct afe_param_id_hdmi_multi_chan_audio_cfg
{
409 u32 hdmi_cfg_minor_version
;
411 u16 channel_allocation
;
417 struct afe_param_id_slimbus_cfg
{
418 u32 sb_cfg_minor_version
;
419 /* Minor version used for tracking the version of the SLIMBUS
420 * configuration interface.
421 * Supported values: #AFE_API_VERSION_SLIMBUS_CONFIG
425 /* SLIMbus hardware device ID, which is required to handle
426 * multiple SLIMbus hardware blocks.
427 * Supported values: - #AFE_SLIMBUS_DEVICE_1 - #AFE_SLIMBUS_DEVICE_2
430 /* Bit width of the sample.
431 * Supported values: 16, 24
434 /* Data format supported by the SLIMbus hardware. The default is
435 * 0 (#AFE_SB_DATA_FORMAT_NOT_INDICATED), which indicates the
436 * hardware does not perform any format conversions before the data
440 /* Number of channels.
441 * Supported values: 1 to #AFE_PORT_MAX_AUDIO_CHAN_CNT
443 u8 shared_ch_mapping
[AFE_PORT_MAX_AUDIO_CHAN_CNT
];
444 /* Mapping of shared channel IDs (128 to 255) to which the
445 * master port is to be connected.
446 * Shared_channel_mapping[i] represents the shared channel assigned
447 * for audio channel i in multichannel audio data.
450 /* Sampling rate of the port.
452 * - #AFE_PORT_SAMPLE_RATE_8K
453 * - #AFE_PORT_SAMPLE_RATE_16K
454 * - #AFE_PORT_SAMPLE_RATE_48K
455 * - #AFE_PORT_SAMPLE_RATE_96K
456 * - #AFE_PORT_SAMPLE_RATE_192K
461 u32 i2s_cfg_minor_version
;
470 struct afe_digital_clk_cfg
{
471 u32 i2s_cfg_minor_version
;
477 struct afe_param_id_i2s_cfg
{
478 u32 i2s_cfg_minor_version
;
488 struct afe_param_id_tdm_cfg
{
489 u32 tdm_cfg_minor_version
;
496 u16 nslots_per_frame
;
497 u16 ctrl_data_out_enable
;
498 u16 ctrl_invert_sync_pulse
;
499 u16 ctrl_sync_data_delay
;
504 struct afe_param_id_cdc_dma_cfg
{
505 u32 cdc_dma_cfg_minor_version
;
510 u16 active_channels_mask
;
513 union afe_port_config
{
514 struct afe_param_id_hdmi_multi_chan_audio_cfg hdmi_multi_ch
;
515 struct afe_param_id_slimbus_cfg slim_cfg
;
516 struct afe_param_id_i2s_cfg i2s_cfg
;
517 struct afe_param_id_tdm_cfg tdm_cfg
;
518 struct afe_param_id_cdc_dma_cfg dma_cfg
;
523 uint32_t clk_set_minor_version
;
525 uint32_t clk_freq_in_hz
;
531 struct afe_param_id_slot_mapping_cfg
{
536 u16 ch_mapping
[AFE_PORT_MAX_AUDIO_CHAN_CNT
];
540 wait_queue_head_t wait
;
541 union afe_port_config port_cfg
;
542 struct afe_param_id_slot_mapping_cfg
*scfg
;
543 struct aprv2_ibasic_rsp_result_t result
;
548 struct kref refcount
;
549 struct list_head node
;
552 struct afe_cmd_remote_lpass_core_hw_vote_request
{
553 uint32_t hw_block_id
;
557 struct afe_cmd_remote_lpass_core_hw_devote_request
{
558 uint32_t hw_block_id
;
559 uint32_t client_handle
;
564 struct afe_port_map
{
572 * Mapping between Virtual Port IDs to DSP AFE Port ID
573 * On B Family SoCs DSP Port IDs are consistent across multiple SoCs
574 * on A Family SoCs DSP port IDs are same as virtual Port IDs.
577 static struct afe_port_map port_maps
[AFE_PORT_MAX
] = {
578 [HDMI_RX
] = { AFE_PORT_ID_MULTICHAN_HDMI_RX
, HDMI_RX
, 1, 1},
579 [SLIMBUS_0_RX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX
,
581 [SLIMBUS_1_RX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX
,
583 [SLIMBUS_2_RX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX
,
585 [SLIMBUS_3_RX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX
,
587 [SLIMBUS_4_RX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX
,
589 [SLIMBUS_5_RX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX
,
591 [SLIMBUS_6_RX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX
,
593 [SLIMBUS_0_TX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX
,
595 [SLIMBUS_1_TX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX
,
597 [SLIMBUS_2_TX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX
,
599 [SLIMBUS_3_TX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX
,
601 [SLIMBUS_4_TX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX
,
603 [SLIMBUS_5_TX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX
,
605 [SLIMBUS_6_TX
] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX
,
607 [PRIMARY_MI2S_RX
] = { AFE_PORT_ID_PRIMARY_MI2S_RX
,
608 PRIMARY_MI2S_RX
, 1, 1},
609 [PRIMARY_MI2S_TX
] = { AFE_PORT_ID_PRIMARY_MI2S_TX
,
610 PRIMARY_MI2S_RX
, 0, 1},
611 [SECONDARY_MI2S_RX
] = { AFE_PORT_ID_SECONDARY_MI2S_RX
,
612 SECONDARY_MI2S_RX
, 1, 1},
613 [SECONDARY_MI2S_TX
] = { AFE_PORT_ID_SECONDARY_MI2S_TX
,
614 SECONDARY_MI2S_TX
, 0, 1},
615 [TERTIARY_MI2S_RX
] = { AFE_PORT_ID_TERTIARY_MI2S_RX
,
616 TERTIARY_MI2S_RX
, 1, 1},
617 [TERTIARY_MI2S_TX
] = { AFE_PORT_ID_TERTIARY_MI2S_TX
,
618 TERTIARY_MI2S_TX
, 0, 1},
619 [QUATERNARY_MI2S_RX
] = { AFE_PORT_ID_QUATERNARY_MI2S_RX
,
620 QUATERNARY_MI2S_RX
, 1, 1},
621 [QUATERNARY_MI2S_TX
] = { AFE_PORT_ID_QUATERNARY_MI2S_TX
,
622 QUATERNARY_MI2S_TX
, 0, 1},
623 [PRIMARY_TDM_RX_0
] = { AFE_PORT_ID_PRIMARY_TDM_RX
,
624 PRIMARY_TDM_RX_0
, 1, 1},
625 [PRIMARY_TDM_TX_0
] = { AFE_PORT_ID_PRIMARY_TDM_TX
,
626 PRIMARY_TDM_TX_0
, 0, 1},
627 [PRIMARY_TDM_RX_1
] = { AFE_PORT_ID_PRIMARY_TDM_RX_1
,
628 PRIMARY_TDM_RX_1
, 1, 1},
629 [PRIMARY_TDM_TX_1
] = { AFE_PORT_ID_PRIMARY_TDM_TX_1
,
630 PRIMARY_TDM_TX_1
, 0, 1},
631 [PRIMARY_TDM_RX_2
] = { AFE_PORT_ID_PRIMARY_TDM_RX_2
,
632 PRIMARY_TDM_RX_2
, 1, 1},
633 [PRIMARY_TDM_TX_2
] = { AFE_PORT_ID_PRIMARY_TDM_TX_2
,
634 PRIMARY_TDM_TX_2
, 0, 1},
635 [PRIMARY_TDM_RX_3
] = { AFE_PORT_ID_PRIMARY_TDM_RX_3
,
636 PRIMARY_TDM_RX_3
, 1, 1},
637 [PRIMARY_TDM_TX_3
] = { AFE_PORT_ID_PRIMARY_TDM_TX_3
,
638 PRIMARY_TDM_TX_3
, 0, 1},
639 [PRIMARY_TDM_RX_4
] = { AFE_PORT_ID_PRIMARY_TDM_RX_4
,
640 PRIMARY_TDM_RX_4
, 1, 1},
641 [PRIMARY_TDM_TX_4
] = { AFE_PORT_ID_PRIMARY_TDM_TX_4
,
642 PRIMARY_TDM_TX_4
, 0, 1},
643 [PRIMARY_TDM_RX_5
] = { AFE_PORT_ID_PRIMARY_TDM_RX_5
,
644 PRIMARY_TDM_RX_5
, 1, 1},
645 [PRIMARY_TDM_TX_5
] = { AFE_PORT_ID_PRIMARY_TDM_TX_5
,
646 PRIMARY_TDM_TX_5
, 0, 1},
647 [PRIMARY_TDM_RX_6
] = { AFE_PORT_ID_PRIMARY_TDM_RX_6
,
648 PRIMARY_TDM_RX_6
, 1, 1},
649 [PRIMARY_TDM_TX_6
] = { AFE_PORT_ID_PRIMARY_TDM_TX_6
,
650 PRIMARY_TDM_TX_6
, 0, 1},
651 [PRIMARY_TDM_RX_7
] = { AFE_PORT_ID_PRIMARY_TDM_RX_7
,
652 PRIMARY_TDM_RX_7
, 1, 1},
653 [PRIMARY_TDM_TX_7
] = { AFE_PORT_ID_PRIMARY_TDM_TX_7
,
654 PRIMARY_TDM_TX_7
, 0, 1},
655 [SECONDARY_TDM_RX_0
] = { AFE_PORT_ID_SECONDARY_TDM_RX
,
656 SECONDARY_TDM_RX_0
, 1, 1},
657 [SECONDARY_TDM_TX_0
] = { AFE_PORT_ID_SECONDARY_TDM_TX
,
658 SECONDARY_TDM_TX_0
, 0, 1},
659 [SECONDARY_TDM_RX_1
] = { AFE_PORT_ID_SECONDARY_TDM_RX_1
,
660 SECONDARY_TDM_RX_1
, 1, 1},
661 [SECONDARY_TDM_TX_1
] = { AFE_PORT_ID_SECONDARY_TDM_TX_1
,
662 SECONDARY_TDM_TX_1
, 0, 1},
663 [SECONDARY_TDM_RX_2
] = { AFE_PORT_ID_SECONDARY_TDM_RX_2
,
664 SECONDARY_TDM_RX_2
, 1, 1},
665 [SECONDARY_TDM_TX_2
] = { AFE_PORT_ID_SECONDARY_TDM_TX_2
,
666 SECONDARY_TDM_TX_2
, 0, 1},
667 [SECONDARY_TDM_RX_3
] = { AFE_PORT_ID_SECONDARY_TDM_RX_3
,
668 SECONDARY_TDM_RX_3
, 1, 1},
669 [SECONDARY_TDM_TX_3
] = { AFE_PORT_ID_SECONDARY_TDM_TX_3
,
670 SECONDARY_TDM_TX_3
, 0, 1},
671 [SECONDARY_TDM_RX_4
] = { AFE_PORT_ID_SECONDARY_TDM_RX_4
,
672 SECONDARY_TDM_RX_4
, 1, 1},
673 [SECONDARY_TDM_TX_4
] = { AFE_PORT_ID_SECONDARY_TDM_TX_4
,
674 SECONDARY_TDM_TX_4
, 0, 1},
675 [SECONDARY_TDM_RX_5
] = { AFE_PORT_ID_SECONDARY_TDM_RX_5
,
676 SECONDARY_TDM_RX_5
, 1, 1},
677 [SECONDARY_TDM_TX_5
] = { AFE_PORT_ID_SECONDARY_TDM_TX_5
,
678 SECONDARY_TDM_TX_5
, 0, 1},
679 [SECONDARY_TDM_RX_6
] = { AFE_PORT_ID_SECONDARY_TDM_RX_6
,
680 SECONDARY_TDM_RX_6
, 1, 1},
681 [SECONDARY_TDM_TX_6
] = { AFE_PORT_ID_SECONDARY_TDM_TX_6
,
682 SECONDARY_TDM_TX_6
, 0, 1},
683 [SECONDARY_TDM_RX_7
] = { AFE_PORT_ID_SECONDARY_TDM_RX_7
,
684 SECONDARY_TDM_RX_7
, 1, 1},
685 [SECONDARY_TDM_TX_7
] = { AFE_PORT_ID_SECONDARY_TDM_TX_7
,
686 SECONDARY_TDM_TX_7
, 0, 1},
687 [TERTIARY_TDM_RX_0
] = { AFE_PORT_ID_TERTIARY_TDM_RX
,
688 TERTIARY_TDM_RX_0
, 1, 1},
689 [TERTIARY_TDM_TX_0
] = { AFE_PORT_ID_TERTIARY_TDM_TX
,
690 TERTIARY_TDM_TX_0
, 0, 1},
691 [TERTIARY_TDM_RX_1
] = { AFE_PORT_ID_TERTIARY_TDM_RX_1
,
692 TERTIARY_TDM_RX_1
, 1, 1},
693 [TERTIARY_TDM_TX_1
] = { AFE_PORT_ID_TERTIARY_TDM_TX_1
,
694 TERTIARY_TDM_TX_1
, 0, 1},
695 [TERTIARY_TDM_RX_2
] = { AFE_PORT_ID_TERTIARY_TDM_RX_2
,
696 TERTIARY_TDM_RX_2
, 1, 1},
697 [TERTIARY_TDM_TX_2
] = { AFE_PORT_ID_TERTIARY_TDM_TX_2
,
698 TERTIARY_TDM_TX_2
, 0, 1},
699 [TERTIARY_TDM_RX_3
] = { AFE_PORT_ID_TERTIARY_TDM_RX_3
,
700 TERTIARY_TDM_RX_3
, 1, 1},
701 [TERTIARY_TDM_TX_3
] = { AFE_PORT_ID_TERTIARY_TDM_TX_3
,
702 TERTIARY_TDM_TX_3
, 0, 1},
703 [TERTIARY_TDM_RX_4
] = { AFE_PORT_ID_TERTIARY_TDM_RX_4
,
704 TERTIARY_TDM_RX_4
, 1, 1},
705 [TERTIARY_TDM_TX_4
] = { AFE_PORT_ID_TERTIARY_TDM_TX_4
,
706 TERTIARY_TDM_TX_4
, 0, 1},
707 [TERTIARY_TDM_RX_5
] = { AFE_PORT_ID_TERTIARY_TDM_RX_5
,
708 TERTIARY_TDM_RX_5
, 1, 1},
709 [TERTIARY_TDM_TX_5
] = { AFE_PORT_ID_TERTIARY_TDM_TX_5
,
710 TERTIARY_TDM_TX_5
, 0, 1},
711 [TERTIARY_TDM_RX_6
] = { AFE_PORT_ID_TERTIARY_TDM_RX_6
,
712 TERTIARY_TDM_RX_6
, 1, 1},
713 [TERTIARY_TDM_TX_6
] = { AFE_PORT_ID_TERTIARY_TDM_TX_6
,
714 TERTIARY_TDM_TX_6
, 0, 1},
715 [TERTIARY_TDM_RX_7
] = { AFE_PORT_ID_TERTIARY_TDM_RX_7
,
716 TERTIARY_TDM_RX_7
, 1, 1},
717 [TERTIARY_TDM_TX_7
] = { AFE_PORT_ID_TERTIARY_TDM_TX_7
,
718 TERTIARY_TDM_TX_7
, 0, 1},
719 [QUATERNARY_TDM_RX_0
] = { AFE_PORT_ID_QUATERNARY_TDM_RX
,
720 QUATERNARY_TDM_RX_0
, 1, 1},
721 [QUATERNARY_TDM_TX_0
] = { AFE_PORT_ID_QUATERNARY_TDM_TX
,
722 QUATERNARY_TDM_TX_0
, 0, 1},
723 [QUATERNARY_TDM_RX_1
] = { AFE_PORT_ID_QUATERNARY_TDM_RX_1
,
724 QUATERNARY_TDM_RX_1
, 1, 1},
725 [QUATERNARY_TDM_TX_1
] = { AFE_PORT_ID_QUATERNARY_TDM_TX_1
,
726 QUATERNARY_TDM_TX_1
, 0, 1},
727 [QUATERNARY_TDM_RX_2
] = { AFE_PORT_ID_QUATERNARY_TDM_RX_2
,
728 QUATERNARY_TDM_RX_2
, 1, 1},
729 [QUATERNARY_TDM_TX_2
] = { AFE_PORT_ID_QUATERNARY_TDM_TX_2
,
730 QUATERNARY_TDM_TX_2
, 0, 1},
731 [QUATERNARY_TDM_RX_3
] = { AFE_PORT_ID_QUATERNARY_TDM_RX_3
,
732 QUATERNARY_TDM_RX_3
, 1, 1},
733 [QUATERNARY_TDM_TX_3
] = { AFE_PORT_ID_QUATERNARY_TDM_TX_3
,
734 QUATERNARY_TDM_TX_3
, 0, 1},
735 [QUATERNARY_TDM_RX_4
] = { AFE_PORT_ID_QUATERNARY_TDM_RX_4
,
736 QUATERNARY_TDM_RX_4
, 1, 1},
737 [QUATERNARY_TDM_TX_4
] = { AFE_PORT_ID_QUATERNARY_TDM_TX_4
,
738 QUATERNARY_TDM_TX_4
, 0, 1},
739 [QUATERNARY_TDM_RX_5
] = { AFE_PORT_ID_QUATERNARY_TDM_RX_5
,
740 QUATERNARY_TDM_RX_5
, 1, 1},
741 [QUATERNARY_TDM_TX_5
] = { AFE_PORT_ID_QUATERNARY_TDM_TX_5
,
742 QUATERNARY_TDM_TX_5
, 0, 1},
743 [QUATERNARY_TDM_RX_6
] = { AFE_PORT_ID_QUATERNARY_TDM_RX_6
,
744 QUATERNARY_TDM_RX_6
, 1, 1},
745 [QUATERNARY_TDM_TX_6
] = { AFE_PORT_ID_QUATERNARY_TDM_TX_6
,
746 QUATERNARY_TDM_TX_6
, 0, 1},
747 [QUATERNARY_TDM_RX_7
] = { AFE_PORT_ID_QUATERNARY_TDM_RX_7
,
748 QUATERNARY_TDM_RX_7
, 1, 1},
749 [QUATERNARY_TDM_TX_7
] = { AFE_PORT_ID_QUATERNARY_TDM_TX_7
,
750 QUATERNARY_TDM_TX_7
, 0, 1},
751 [QUINARY_TDM_RX_0
] = { AFE_PORT_ID_QUINARY_TDM_RX
,
752 QUINARY_TDM_RX_0
, 1, 1},
753 [QUINARY_TDM_TX_0
] = { AFE_PORT_ID_QUINARY_TDM_TX
,
754 QUINARY_TDM_TX_0
, 0, 1},
755 [QUINARY_TDM_RX_1
] = { AFE_PORT_ID_QUINARY_TDM_RX_1
,
756 QUINARY_TDM_RX_1
, 1, 1},
757 [QUINARY_TDM_TX_1
] = { AFE_PORT_ID_QUINARY_TDM_TX_1
,
758 QUINARY_TDM_TX_1
, 0, 1},
759 [QUINARY_TDM_RX_2
] = { AFE_PORT_ID_QUINARY_TDM_RX_2
,
760 QUINARY_TDM_RX_2
, 1, 1},
761 [QUINARY_TDM_TX_2
] = { AFE_PORT_ID_QUINARY_TDM_TX_2
,
762 QUINARY_TDM_TX_2
, 0, 1},
763 [QUINARY_TDM_RX_3
] = { AFE_PORT_ID_QUINARY_TDM_RX_3
,
764 QUINARY_TDM_RX_3
, 1, 1},
765 [QUINARY_TDM_TX_3
] = { AFE_PORT_ID_QUINARY_TDM_TX_3
,
766 QUINARY_TDM_TX_3
, 0, 1},
767 [QUINARY_TDM_RX_4
] = { AFE_PORT_ID_QUINARY_TDM_RX_4
,
768 QUINARY_TDM_RX_4
, 1, 1},
769 [QUINARY_TDM_TX_4
] = { AFE_PORT_ID_QUINARY_TDM_TX_4
,
770 QUINARY_TDM_TX_4
, 0, 1},
771 [QUINARY_TDM_RX_5
] = { AFE_PORT_ID_QUINARY_TDM_RX_5
,
772 QUINARY_TDM_RX_5
, 1, 1},
773 [QUINARY_TDM_TX_5
] = { AFE_PORT_ID_QUINARY_TDM_TX_5
,
774 QUINARY_TDM_TX_5
, 0, 1},
775 [QUINARY_TDM_RX_6
] = { AFE_PORT_ID_QUINARY_TDM_RX_6
,
776 QUINARY_TDM_RX_6
, 1, 1},
777 [QUINARY_TDM_TX_6
] = { AFE_PORT_ID_QUINARY_TDM_TX_6
,
778 QUINARY_TDM_TX_6
, 0, 1},
779 [QUINARY_TDM_RX_7
] = { AFE_PORT_ID_QUINARY_TDM_RX_7
,
780 QUINARY_TDM_RX_7
, 1, 1},
781 [QUINARY_TDM_TX_7
] = { AFE_PORT_ID_QUINARY_TDM_TX_7
,
782 QUINARY_TDM_TX_7
, 0, 1},
783 [DISPLAY_PORT_RX
] = { AFE_PORT_ID_HDMI_OVER_DP_RX
,
784 DISPLAY_PORT_RX
, 1, 1},
785 [WSA_CODEC_DMA_RX_0
] = { AFE_PORT_ID_WSA_CODEC_DMA_RX_0
,
786 WSA_CODEC_DMA_RX_0
, 1, 1},
787 [WSA_CODEC_DMA_TX_0
] = { AFE_PORT_ID_WSA_CODEC_DMA_TX_0
,
788 WSA_CODEC_DMA_TX_0
, 0, 1},
789 [WSA_CODEC_DMA_RX_1
] = { AFE_PORT_ID_WSA_CODEC_DMA_RX_1
,
790 WSA_CODEC_DMA_RX_1
, 1, 1},
791 [WSA_CODEC_DMA_TX_1
] = { AFE_PORT_ID_WSA_CODEC_DMA_TX_1
,
792 WSA_CODEC_DMA_TX_1
, 0, 1},
793 [WSA_CODEC_DMA_TX_2
] = { AFE_PORT_ID_WSA_CODEC_DMA_TX_2
,
794 WSA_CODEC_DMA_TX_2
, 0, 1},
795 [VA_CODEC_DMA_TX_0
] = { AFE_PORT_ID_VA_CODEC_DMA_TX_0
,
796 VA_CODEC_DMA_TX_0
, 0, 1},
797 [VA_CODEC_DMA_TX_1
] = { AFE_PORT_ID_VA_CODEC_DMA_TX_1
,
798 VA_CODEC_DMA_TX_1
, 0, 1},
799 [VA_CODEC_DMA_TX_2
] = { AFE_PORT_ID_VA_CODEC_DMA_TX_2
,
800 VA_CODEC_DMA_TX_2
, 0, 1},
801 [RX_CODEC_DMA_RX_0
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_0
,
802 RX_CODEC_DMA_RX_0
, 1, 1},
803 [TX_CODEC_DMA_TX_0
] = { AFE_PORT_ID_TX_CODEC_DMA_TX_0
,
804 TX_CODEC_DMA_TX_0
, 0, 1},
805 [RX_CODEC_DMA_RX_1
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_1
,
806 RX_CODEC_DMA_RX_1
, 1, 1},
807 [TX_CODEC_DMA_TX_1
] = { AFE_PORT_ID_TX_CODEC_DMA_TX_1
,
808 TX_CODEC_DMA_TX_1
, 0, 1},
809 [RX_CODEC_DMA_RX_2
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_2
,
810 RX_CODEC_DMA_RX_2
, 1, 1},
811 [TX_CODEC_DMA_TX_2
] = { AFE_PORT_ID_TX_CODEC_DMA_TX_2
,
812 TX_CODEC_DMA_TX_2
, 0, 1},
813 [RX_CODEC_DMA_RX_3
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_3
,
814 RX_CODEC_DMA_RX_3
, 1, 1},
815 [TX_CODEC_DMA_TX_3
] = { AFE_PORT_ID_TX_CODEC_DMA_TX_3
,
816 TX_CODEC_DMA_TX_3
, 0, 1},
817 [RX_CODEC_DMA_RX_4
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_4
,
818 RX_CODEC_DMA_RX_4
, 1, 1},
819 [TX_CODEC_DMA_TX_4
] = { AFE_PORT_ID_TX_CODEC_DMA_TX_4
,
820 TX_CODEC_DMA_TX_4
, 0, 1},
821 [RX_CODEC_DMA_RX_5
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_5
,
822 RX_CODEC_DMA_RX_5
, 1, 1},
823 [TX_CODEC_DMA_TX_5
] = { AFE_PORT_ID_TX_CODEC_DMA_TX_5
,
824 TX_CODEC_DMA_TX_5
, 0, 1},
825 [RX_CODEC_DMA_RX_6
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_6
,
826 RX_CODEC_DMA_RX_6
, 1, 1},
827 [RX_CODEC_DMA_RX_7
] = { AFE_PORT_ID_RX_CODEC_DMA_RX_7
,
828 RX_CODEC_DMA_RX_7
, 1, 1},
831 static void q6afe_port_free(struct kref
*ref
)
833 struct q6afe_port
*port
;
837 port
= container_of(ref
, struct q6afe_port
, refcount
);
839 spin_lock_irqsave(&afe
->port_list_lock
, flags
);
840 list_del(&port
->node
);
841 spin_unlock_irqrestore(&afe
->port_list_lock
, flags
);
846 static struct q6afe_port
*q6afe_find_port(struct q6afe
*afe
, int token
)
848 struct q6afe_port
*p
= NULL
;
849 struct q6afe_port
*ret
= NULL
;
852 spin_lock_irqsave(&afe
->port_list_lock
, flags
);
853 list_for_each_entry(p
, &afe
->port_list
, node
)
854 if (p
->token
== token
) {
856 kref_get(&p
->refcount
);
860 spin_unlock_irqrestore(&afe
->port_list_lock
, flags
);
864 static int q6afe_callback(struct apr_device
*adev
, struct apr_resp_pkt
*data
)
866 struct q6afe
*afe
= dev_get_drvdata(&adev
->dev
);
867 struct aprv2_ibasic_rsp_result_t
*res
;
868 struct apr_hdr
*hdr
= &data
->hdr
;
869 struct q6afe_port
*port
;
871 if (!data
->payload_size
)
875 switch (hdr
->opcode
) {
876 case APR_BASIC_RSP_RESULT
: {
878 dev_err(afe
->dev
, "cmd = 0x%x returned error = 0x%x\n",
879 res
->opcode
, res
->status
);
881 switch (res
->opcode
) {
882 case AFE_PORT_CMD_SET_PARAM_V2
:
883 case AFE_PORT_CMD_DEVICE_STOP
:
884 case AFE_PORT_CMD_DEVICE_START
:
885 case AFE_SVC_CMD_SET_PARAM
:
886 port
= q6afe_find_port(afe
, hdr
->token
);
889 wake_up(&port
->wait
);
890 kref_put(&port
->refcount
, q6afe_port_free
);
891 } else if (hdr
->token
== AFE_CLK_TOKEN
) {
897 dev_err(afe
->dev
, "Unknown cmd 0x%x\n", res
->opcode
);
902 case AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST
:
903 afe
->result
.opcode
= hdr
->opcode
;
904 afe
->result
.status
= res
->status
;
915 * q6afe_get_port_id() - Get port id from a given port index
919 * Return: Will be an negative on error or valid port_id on success
921 int q6afe_get_port_id(int index
)
923 if (index
< 0 || index
>= AFE_PORT_MAX
)
926 return port_maps
[index
].port_id
;
928 EXPORT_SYMBOL_GPL(q6afe_get_port_id
);
930 static int afe_apr_send_pkt(struct q6afe
*afe
, struct apr_pkt
*pkt
,
931 struct q6afe_port
*port
, uint32_t rsp_opcode
)
933 wait_queue_head_t
*wait
= &port
->wait
;
934 struct aprv2_ibasic_rsp_result_t
*result
;
937 mutex_lock(&afe
->lock
);
940 result
= &port
->result
;
942 result
= &afe
->result
;
949 ret
= apr_send_pkt(afe
->apr
, pkt
);
951 dev_err(afe
->dev
, "packet not transmitted (%d)\n", ret
);
956 ret
= wait_event_timeout(*wait
, (result
->opcode
== rsp_opcode
),
957 msecs_to_jiffies(TIMEOUT_MS
));
960 } else if (result
->status
> 0) {
961 dev_err(afe
->dev
, "DSP returned error[%x]\n",
969 mutex_unlock(&afe
->lock
);
974 static int q6afe_set_param(struct q6afe
*afe
, struct q6afe_port
*port
,
975 void *data
, int param_id
, int module_id
, int psize
,
978 struct afe_svc_cmd_set_param
*param
;
979 struct afe_port_param_data_v2
*pdata
;
984 pkt_size
= APR_HDR_SIZE
+ sizeof(*param
) + sizeof(*pdata
) + psize
;
985 p
= kzalloc(pkt_size
, GFP_KERNEL
);
990 param
= p
+ APR_HDR_SIZE
;
991 pdata
= p
+ APR_HDR_SIZE
+ sizeof(*param
);
992 pl
= p
+ APR_HDR_SIZE
+ sizeof(*param
) + sizeof(*pdata
);
993 memcpy(pl
, data
, psize
);
995 pkt
->hdr
.hdr_field
= APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD
,
996 APR_HDR_LEN(APR_HDR_SIZE
),
998 pkt
->hdr
.pkt_size
= pkt_size
;
999 pkt
->hdr
.src_port
= 0;
1000 pkt
->hdr
.dest_port
= 0;
1001 pkt
->hdr
.token
= token
;
1002 pkt
->hdr
.opcode
= AFE_SVC_CMD_SET_PARAM
;
1004 param
->payload_size
= sizeof(*pdata
) + psize
;
1005 param
->payload_address_lsw
= 0x00;
1006 param
->payload_address_msw
= 0x00;
1007 param
->mem_map_handle
= 0x00;
1008 pdata
->module_id
= module_id
;
1009 pdata
->param_id
= param_id
;
1010 pdata
->param_size
= psize
;
1012 ret
= afe_apr_send_pkt(afe
, pkt
, port
, AFE_SVC_CMD_SET_PARAM
);
1014 dev_err(afe
->dev
, "AFE set params failed %d\n", ret
);
1020 static int q6afe_port_set_param(struct q6afe_port
*port
, void *data
,
1021 int param_id
, int module_id
, int psize
)
1023 return q6afe_set_param(port
->afe
, port
, data
, param_id
, module_id
,
1024 psize
, port
->token
);
1027 static int q6afe_port_set_param_v2(struct q6afe_port
*port
, void *data
,
1028 int param_id
, int module_id
, int psize
)
1030 struct afe_port_cmd_set_param_v2
*param
;
1031 struct afe_port_param_data_v2
*pdata
;
1032 struct q6afe
*afe
= port
->afe
;
1033 struct apr_pkt
*pkt
;
1034 u16 port_id
= port
->id
;
1038 pkt_size
= APR_HDR_SIZE
+ sizeof(*param
) + sizeof(*pdata
) + psize
;
1039 p
= kzalloc(pkt_size
, GFP_KERNEL
);
1044 param
= p
+ APR_HDR_SIZE
;
1045 pdata
= p
+ APR_HDR_SIZE
+ sizeof(*param
);
1046 pl
= p
+ APR_HDR_SIZE
+ sizeof(*param
) + sizeof(*pdata
);
1047 memcpy(pl
, data
, psize
);
1049 pkt
->hdr
.hdr_field
= APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD
,
1050 APR_HDR_LEN(APR_HDR_SIZE
),
1052 pkt
->hdr
.pkt_size
= pkt_size
;
1053 pkt
->hdr
.src_port
= 0;
1054 pkt
->hdr
.dest_port
= 0;
1055 pkt
->hdr
.token
= port
->token
;
1056 pkt
->hdr
.opcode
= AFE_PORT_CMD_SET_PARAM_V2
;
1058 param
->port_id
= port_id
;
1059 param
->payload_size
= sizeof(*pdata
) + psize
;
1060 param
->payload_address_lsw
= 0x00;
1061 param
->payload_address_msw
= 0x00;
1062 param
->mem_map_handle
= 0x00;
1063 pdata
->module_id
= module_id
;
1064 pdata
->param_id
= param_id
;
1065 pdata
->param_size
= psize
;
1067 ret
= afe_apr_send_pkt(afe
, pkt
, port
, AFE_PORT_CMD_SET_PARAM_V2
);
1069 dev_err(afe
->dev
, "AFE enable for port 0x%x failed %d\n",
1076 static int q6afe_port_set_lpass_clock(struct q6afe_port
*port
,
1077 struct afe_clk_cfg
*cfg
)
1079 return q6afe_port_set_param_v2(port
, cfg
,
1080 AFE_PARAM_ID_LPAIF_CLK_CONFIG
,
1081 AFE_MODULE_AUDIO_DEV_INTERFACE
,
1085 static int q6afe_set_lpass_clock_v2(struct q6afe_port
*port
,
1086 struct afe_clk_set
*cfg
)
1088 return q6afe_port_set_param(port
, cfg
, AFE_PARAM_ID_CLOCK_SET
,
1089 AFE_MODULE_CLOCK_SET
, sizeof(*cfg
));
1092 static int q6afe_set_digital_codec_core_clock(struct q6afe_port
*port
,
1093 struct afe_digital_clk_cfg
*cfg
)
1095 return q6afe_port_set_param_v2(port
, cfg
,
1096 AFE_PARAM_ID_INT_DIGITAL_CDC_CLK_CONFIG
,
1097 AFE_MODULE_AUDIO_DEV_INTERFACE
,
1101 int q6afe_set_lpass_clock(struct device
*dev
, int clk_id
, int attri
,
1102 int clk_root
, unsigned int freq
)
1104 struct q6afe
*afe
= dev_get_drvdata(dev
->parent
);
1105 struct afe_clk_set cset
= {0,};
1107 cset
.clk_set_minor_version
= AFE_API_VERSION_CLOCK_SET
;
1108 cset
.clk_id
= clk_id
;
1109 cset
.clk_freq_in_hz
= freq
;
1110 cset
.clk_attri
= attri
;
1111 cset
.clk_root
= clk_root
;
1112 cset
.enable
= !!freq
;
1114 return q6afe_set_param(afe
, NULL
, &cset
, AFE_PARAM_ID_CLOCK_SET
,
1115 AFE_MODULE_CLOCK_SET
, sizeof(cset
),
1118 EXPORT_SYMBOL_GPL(q6afe_set_lpass_clock
);
1120 int q6afe_port_set_sysclk(struct q6afe_port
*port
, int clk_id
,
1121 int clk_src
, int clk_root
,
1122 unsigned int freq
, int dir
)
1124 struct afe_clk_cfg ccfg
= {0,};
1125 struct afe_clk_set cset
= {0,};
1126 struct afe_digital_clk_cfg dcfg
= {0,};
1131 dcfg
.i2s_cfg_minor_version
= AFE_API_VERSION_I2S_CONFIG
;
1132 dcfg
.clk_val
= freq
;
1133 dcfg
.clk_root
= clk_root
;
1134 ret
= q6afe_set_digital_codec_core_clock(port
, &dcfg
);
1137 ccfg
.i2s_cfg_minor_version
= AFE_API_VERSION_I2S_CONFIG
;
1138 ccfg
.clk_val1
= freq
;
1139 ccfg
.clk_src
= clk_src
;
1140 ccfg
.clk_root
= clk_root
;
1141 ccfg
.clk_set_mode
= Q6AFE_LPASS_MODE_CLK1_VALID
;
1142 ret
= q6afe_port_set_lpass_clock(port
, &ccfg
);
1146 ccfg
.i2s_cfg_minor_version
= AFE_API_VERSION_I2S_CONFIG
;
1147 ccfg
.clk_val2
= freq
;
1148 ccfg
.clk_src
= clk_src
;
1149 ccfg
.clk_root
= clk_root
;
1150 ccfg
.clk_set_mode
= Q6AFE_LPASS_MODE_CLK2_VALID
;
1151 ret
= q6afe_port_set_lpass_clock(port
, &ccfg
);
1153 case Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT
... Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR
:
1154 case Q6AFE_LPASS_CLK_ID_MCLK_1
... Q6AFE_LPASS_CLK_ID_INT_MCLK_1
:
1155 case Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT
... Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT
:
1156 case Q6AFE_LPASS_CLK_ID_WSA_CORE_MCLK
... Q6AFE_LPASS_CLK_ID_VA_CORE_2X_MCLK
:
1157 cset
.clk_set_minor_version
= AFE_API_VERSION_CLOCK_SET
;
1158 cset
.clk_id
= clk_id
;
1159 cset
.clk_freq_in_hz
= freq
;
1160 cset
.clk_attri
= clk_src
;
1161 cset
.clk_root
= clk_root
;
1162 cset
.enable
= !!freq
;
1163 ret
= q6afe_set_lpass_clock_v2(port
, &cset
);
1172 EXPORT_SYMBOL_GPL(q6afe_port_set_sysclk
);
1175 * q6afe_port_stop() - Stop a afe port
1177 * @port: Instance of port to stop
1179 * Return: Will be an negative on packet size on success.
1181 int q6afe_port_stop(struct q6afe_port
*port
)
1183 struct afe_port_cmd_device_stop
*stop
;
1184 struct q6afe
*afe
= port
->afe
;
1185 struct apr_pkt
*pkt
;
1186 int port_id
= port
->id
;
1188 int index
, pkt_size
;
1192 index
= port
->token
;
1193 if (index
< 0 || index
>= AFE_PORT_MAX
) {
1194 dev_err(afe
->dev
, "AFE port index[%d] invalid!\n", index
);
1198 pkt_size
= APR_HDR_SIZE
+ sizeof(*stop
);
1199 p
= kzalloc(pkt_size
, GFP_KERNEL
);
1204 stop
= p
+ APR_HDR_SIZE
;
1206 pkt
->hdr
.hdr_field
= APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD
,
1207 APR_HDR_LEN(APR_HDR_SIZE
),
1209 pkt
->hdr
.pkt_size
= pkt_size
;
1210 pkt
->hdr
.src_port
= 0;
1211 pkt
->hdr
.dest_port
= 0;
1212 pkt
->hdr
.token
= index
;
1213 pkt
->hdr
.opcode
= AFE_PORT_CMD_DEVICE_STOP
;
1214 stop
->port_id
= port_id
;
1217 ret
= afe_apr_send_pkt(afe
, pkt
, port
, AFE_PORT_CMD_DEVICE_STOP
);
1219 dev_err(afe
->dev
, "AFE close failed %d\n", ret
);
1224 EXPORT_SYMBOL_GPL(q6afe_port_stop
);
1227 * q6afe_slim_port_prepare() - Prepare slim afe port.
1229 * @port: Instance of afe port
1230 * @cfg: SLIM configuration for the afe port
1233 void q6afe_slim_port_prepare(struct q6afe_port
*port
,
1234 struct q6afe_slim_cfg
*cfg
)
1236 union afe_port_config
*pcfg
= &port
->port_cfg
;
1238 pcfg
->slim_cfg
.sb_cfg_minor_version
= AFE_API_VERSION_SLIMBUS_CONFIG
;
1239 pcfg
->slim_cfg
.sample_rate
= cfg
->sample_rate
;
1240 pcfg
->slim_cfg
.bit_width
= cfg
->bit_width
;
1241 pcfg
->slim_cfg
.num_channels
= cfg
->num_channels
;
1242 pcfg
->slim_cfg
.data_format
= cfg
->data_format
;
1243 pcfg
->slim_cfg
.shared_ch_mapping
[0] = cfg
->ch_mapping
[0];
1244 pcfg
->slim_cfg
.shared_ch_mapping
[1] = cfg
->ch_mapping
[1];
1245 pcfg
->slim_cfg
.shared_ch_mapping
[2] = cfg
->ch_mapping
[2];
1246 pcfg
->slim_cfg
.shared_ch_mapping
[3] = cfg
->ch_mapping
[3];
1249 EXPORT_SYMBOL_GPL(q6afe_slim_port_prepare
);
1252 * q6afe_tdm_port_prepare() - Prepare tdm afe port.
1254 * @port: Instance of afe port
1255 * @cfg: TDM configuration for the afe port
1258 void q6afe_tdm_port_prepare(struct q6afe_port
*port
,
1259 struct q6afe_tdm_cfg
*cfg
)
1261 union afe_port_config
*pcfg
= &port
->port_cfg
;
1263 pcfg
->tdm_cfg
.tdm_cfg_minor_version
= AFE_API_VERSION_TDM_CONFIG
;
1264 pcfg
->tdm_cfg
.num_channels
= cfg
->num_channels
;
1265 pcfg
->tdm_cfg
.sample_rate
= cfg
->sample_rate
;
1266 pcfg
->tdm_cfg
.bit_width
= cfg
->bit_width
;
1267 pcfg
->tdm_cfg
.data_format
= cfg
->data_format
;
1268 pcfg
->tdm_cfg
.sync_mode
= cfg
->sync_mode
;
1269 pcfg
->tdm_cfg
.sync_src
= cfg
->sync_src
;
1270 pcfg
->tdm_cfg
.nslots_per_frame
= cfg
->nslots_per_frame
;
1272 pcfg
->tdm_cfg
.slot_width
= cfg
->slot_width
;
1273 pcfg
->tdm_cfg
.slot_mask
= cfg
->slot_mask
;
1274 port
->scfg
= kzalloc(sizeof(*port
->scfg
), GFP_KERNEL
);
1278 port
->scfg
->minor_version
= AFE_API_VERSION_SLOT_MAPPING_CONFIG
;
1279 port
->scfg
->num_channels
= cfg
->num_channels
;
1280 port
->scfg
->bitwidth
= cfg
->bit_width
;
1281 port
->scfg
->data_align_type
= cfg
->data_align_type
;
1282 memcpy(port
->scfg
->ch_mapping
, cfg
->ch_mapping
,
1283 sizeof(u16
) * AFE_PORT_MAX_AUDIO_CHAN_CNT
);
1285 EXPORT_SYMBOL_GPL(q6afe_tdm_port_prepare
);
1288 * q6afe_hdmi_port_prepare() - Prepare hdmi afe port.
1290 * @port: Instance of afe port
1291 * @cfg: HDMI configuration for the afe port
1294 void q6afe_hdmi_port_prepare(struct q6afe_port
*port
,
1295 struct q6afe_hdmi_cfg
*cfg
)
1297 union afe_port_config
*pcfg
= &port
->port_cfg
;
1299 pcfg
->hdmi_multi_ch
.hdmi_cfg_minor_version
=
1300 AFE_API_VERSION_HDMI_CONFIG
;
1301 pcfg
->hdmi_multi_ch
.datatype
= cfg
->datatype
;
1302 pcfg
->hdmi_multi_ch
.channel_allocation
= cfg
->channel_allocation
;
1303 pcfg
->hdmi_multi_ch
.sample_rate
= cfg
->sample_rate
;
1304 pcfg
->hdmi_multi_ch
.bit_width
= cfg
->bit_width
;
1306 EXPORT_SYMBOL_GPL(q6afe_hdmi_port_prepare
);
1309 * q6afe_i2s_port_prepare() - Prepare i2s afe port.
1311 * @port: Instance of afe port
1312 * @cfg: I2S configuration for the afe port
1313 * Return: Will be an negative on error and zero on success.
1315 int q6afe_i2s_port_prepare(struct q6afe_port
*port
, struct q6afe_i2s_cfg
*cfg
)
1317 union afe_port_config
*pcfg
= &port
->port_cfg
;
1318 struct device
*dev
= port
->afe
->dev
;
1321 pcfg
->i2s_cfg
.i2s_cfg_minor_version
= AFE_API_VERSION_I2S_CONFIG
;
1322 pcfg
->i2s_cfg
.sample_rate
= cfg
->sample_rate
;
1323 pcfg
->i2s_cfg
.bit_width
= cfg
->bit_width
;
1324 pcfg
->i2s_cfg
.data_format
= AFE_LINEAR_PCM_DATA
;
1326 switch (cfg
->fmt
& SND_SOC_DAIFMT_MASTER_MASK
) {
1327 case SND_SOC_DAIFMT_CBS_CFS
:
1328 pcfg
->i2s_cfg
.ws_src
= AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL
;
1330 case SND_SOC_DAIFMT_CBM_CFM
:
1332 pcfg
->i2s_cfg
.ws_src
= AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL
;
1338 num_sd_lines
= hweight_long(cfg
->sd_line_mask
);
1340 switch (num_sd_lines
) {
1342 dev_err(dev
, "no line is assigned\n");
1345 switch (cfg
->sd_line_mask
) {
1346 case AFE_PORT_I2S_SD0_MASK
:
1347 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_SD0
;
1349 case AFE_PORT_I2S_SD1_MASK
:
1350 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_SD1
;
1352 case AFE_PORT_I2S_SD2_MASK
:
1353 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_SD2
;
1355 case AFE_PORT_I2S_SD3_MASK
:
1356 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_SD3
;
1359 dev_err(dev
, "Invalid SD lines\n");
1364 switch (cfg
->sd_line_mask
) {
1365 case AFE_PORT_I2S_SD0_1_MASK
:
1366 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_QUAD01
;
1368 case AFE_PORT_I2S_SD2_3_MASK
:
1369 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_QUAD23
;
1372 dev_err(dev
, "Invalid SD lines\n");
1377 switch (cfg
->sd_line_mask
) {
1378 case AFE_PORT_I2S_SD0_1_2_MASK
:
1379 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_6CHS
;
1382 dev_err(dev
, "Invalid SD lines\n");
1387 switch (cfg
->sd_line_mask
) {
1388 case AFE_PORT_I2S_SD0_1_2_3_MASK
:
1389 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_8CHS
;
1393 dev_err(dev
, "Invalid SD lines\n");
1398 dev_err(dev
, "Invalid SD lines\n");
1402 switch (cfg
->num_channels
) {
1405 switch (pcfg
->i2s_cfg
.channel_mode
) {
1406 case AFE_PORT_I2S_QUAD01
:
1407 case AFE_PORT_I2S_6CHS
:
1408 case AFE_PORT_I2S_8CHS
:
1409 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_SD0
;
1411 case AFE_PORT_I2S_QUAD23
:
1412 pcfg
->i2s_cfg
.channel_mode
= AFE_PORT_I2S_SD2
;
1416 if (cfg
->num_channels
== 2)
1417 pcfg
->i2s_cfg
.mono_stereo
= AFE_PORT_I2S_STEREO
;
1419 pcfg
->i2s_cfg
.mono_stereo
= AFE_PORT_I2S_MONO
;
1424 if (pcfg
->i2s_cfg
.channel_mode
< AFE_PORT_I2S_QUAD01
) {
1425 dev_err(dev
, "Invalid Channel mode\n");
1431 if (pcfg
->i2s_cfg
.channel_mode
< AFE_PORT_I2S_6CHS
) {
1432 dev_err(dev
, "Invalid Channel mode\n");
1438 if (pcfg
->i2s_cfg
.channel_mode
< AFE_PORT_I2S_8CHS
) {
1439 dev_err(dev
, "Invalid Channel mode\n");
1449 EXPORT_SYMBOL_GPL(q6afe_i2s_port_prepare
);
1452 * q6afe_dam_port_prepare() - Prepare dma afe port.
1454 * @port: Instance of afe port
1455 * @cfg: DMA configuration for the afe port
1458 void q6afe_cdc_dma_port_prepare(struct q6afe_port
*port
,
1459 struct q6afe_cdc_dma_cfg
*cfg
)
1461 union afe_port_config
*pcfg
= &port
->port_cfg
;
1462 struct afe_param_id_cdc_dma_cfg
*dma_cfg
= &pcfg
->dma_cfg
;
1464 dma_cfg
->cdc_dma_cfg_minor_version
= AFE_API_VERSION_CODEC_DMA_CONFIG
;
1465 dma_cfg
->sample_rate
= cfg
->sample_rate
;
1466 dma_cfg
->bit_width
= cfg
->bit_width
;
1467 dma_cfg
->data_format
= cfg
->data_format
;
1468 dma_cfg
->num_channels
= cfg
->num_channels
;
1469 if (!cfg
->active_channels_mask
)
1470 dma_cfg
->active_channels_mask
= (1 << cfg
->num_channels
) - 1;
1472 EXPORT_SYMBOL_GPL(q6afe_cdc_dma_port_prepare
);
1474 * q6afe_port_start() - Start a afe port
1476 * @port: Instance of port to start
1478 * Return: Will be an negative on packet size on success.
1480 int q6afe_port_start(struct q6afe_port
*port
)
1482 struct afe_port_cmd_device_start
*start
;
1483 struct q6afe
*afe
= port
->afe
;
1484 int port_id
= port
->id
;
1485 int ret
, param_id
= port
->cfg_type
;
1486 struct apr_pkt
*pkt
;
1490 ret
= q6afe_port_set_param_v2(port
, &port
->port_cfg
, param_id
,
1491 AFE_MODULE_AUDIO_DEV_INTERFACE
,
1492 sizeof(port
->port_cfg
));
1494 dev_err(afe
->dev
, "AFE enable for port 0x%x failed %d\n",
1500 ret
= q6afe_port_set_param_v2(port
, port
->scfg
,
1501 AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG
,
1502 AFE_MODULE_TDM
, sizeof(*port
->scfg
));
1504 dev_err(afe
->dev
, "AFE enable for port 0x%x failed %d\n",
1510 pkt_size
= APR_HDR_SIZE
+ sizeof(*start
);
1511 p
= kzalloc(pkt_size
, GFP_KERNEL
);
1516 start
= p
+ APR_HDR_SIZE
;
1518 pkt
->hdr
.hdr_field
= APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD
,
1519 APR_HDR_LEN(APR_HDR_SIZE
),
1521 pkt
->hdr
.pkt_size
= pkt_size
;
1522 pkt
->hdr
.src_port
= 0;
1523 pkt
->hdr
.dest_port
= 0;
1524 pkt
->hdr
.token
= port
->token
;
1525 pkt
->hdr
.opcode
= AFE_PORT_CMD_DEVICE_START
;
1527 start
->port_id
= port_id
;
1529 ret
= afe_apr_send_pkt(afe
, pkt
, port
, AFE_PORT_CMD_DEVICE_START
);
1531 dev_err(afe
->dev
, "AFE enable for port 0x%x failed %d\n",
1537 EXPORT_SYMBOL_GPL(q6afe_port_start
);
1540 * q6afe_port_get_from_id() - Get port instance from a port id
1542 * @dev: Pointer to afe child device.
1545 * Return: Will be an error pointer on error or a valid afe port
1548 struct q6afe_port
*q6afe_port_get_from_id(struct device
*dev
, int id
)
1551 struct q6afe
*afe
= dev_get_drvdata(dev
->parent
);
1552 struct q6afe_port
*port
;
1553 unsigned long flags
;
1556 if (id
< 0 || id
>= AFE_PORT_MAX
) {
1557 dev_err(dev
, "AFE port token[%d] invalid!\n", id
);
1558 return ERR_PTR(-EINVAL
);
1561 /* if port is multiple times bind/unbind before callback finishes */
1562 port
= q6afe_find_port(afe
, id
);
1564 dev_err(dev
, "AFE Port already open\n");
1568 port_id
= port_maps
[id
].port_id
;
1571 case AFE_PORT_ID_MULTICHAN_HDMI_RX
:
1572 case AFE_PORT_ID_HDMI_OVER_DP_RX
:
1573 cfg_type
= AFE_PARAM_ID_HDMI_CONFIG
;
1575 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX
:
1576 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX
:
1577 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX
:
1578 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX
:
1579 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX
:
1580 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX
:
1581 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX
:
1582 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX
:
1583 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX
:
1584 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX
:
1585 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX
:
1586 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX
:
1587 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX
:
1588 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX
:
1589 cfg_type
= AFE_PARAM_ID_SLIMBUS_CONFIG
;
1592 case AFE_PORT_ID_PRIMARY_MI2S_RX
:
1593 case AFE_PORT_ID_PRIMARY_MI2S_TX
:
1594 case AFE_PORT_ID_SECONDARY_MI2S_RX
:
1595 case AFE_PORT_ID_SECONDARY_MI2S_TX
:
1596 case AFE_PORT_ID_TERTIARY_MI2S_RX
:
1597 case AFE_PORT_ID_TERTIARY_MI2S_TX
:
1598 case AFE_PORT_ID_QUATERNARY_MI2S_RX
:
1599 case AFE_PORT_ID_QUATERNARY_MI2S_TX
:
1600 cfg_type
= AFE_PARAM_ID_I2S_CONFIG
;
1602 case AFE_PORT_ID_PRIMARY_TDM_RX
... AFE_PORT_ID_QUINARY_TDM_TX_7
:
1603 cfg_type
= AFE_PARAM_ID_TDM_CONFIG
;
1605 case AFE_PORT_ID_WSA_CODEC_DMA_RX_0
... AFE_PORT_ID_RX_CODEC_DMA_RX_7
:
1606 cfg_type
= AFE_PARAM_ID_CODEC_DMA_CONFIG
;
1609 dev_err(dev
, "Invalid port id 0x%x\n", port_id
);
1610 return ERR_PTR(-EINVAL
);
1613 port
= kzalloc(sizeof(*port
), GFP_KERNEL
);
1615 return ERR_PTR(-ENOMEM
);
1617 init_waitqueue_head(&port
->wait
);
1622 port
->cfg_type
= cfg_type
;
1623 kref_init(&port
->refcount
);
1625 spin_lock_irqsave(&afe
->port_list_lock
, flags
);
1626 list_add_tail(&port
->node
, &afe
->port_list
);
1627 spin_unlock_irqrestore(&afe
->port_list_lock
, flags
);
1632 EXPORT_SYMBOL_GPL(q6afe_port_get_from_id
);
1635 * q6afe_port_put() - Release port reference
1637 * @port: Instance of port to put
1639 void q6afe_port_put(struct q6afe_port
*port
)
1641 kref_put(&port
->refcount
, q6afe_port_free
);
1643 EXPORT_SYMBOL_GPL(q6afe_port_put
);
1645 int q6afe_unvote_lpass_core_hw(struct device
*dev
, uint32_t hw_block_id
,
1646 uint32_t client_handle
)
1648 struct q6afe
*afe
= dev_get_drvdata(dev
->parent
);
1649 struct afe_cmd_remote_lpass_core_hw_devote_request
*vote_cfg
;
1650 struct apr_pkt
*pkt
;
1655 pkt_size
= APR_HDR_SIZE
+ sizeof(*vote_cfg
);
1656 p
= kzalloc(pkt_size
, GFP_KERNEL
);
1661 vote_cfg
= p
+ APR_HDR_SIZE
;
1663 pkt
->hdr
.hdr_field
= APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD
,
1664 APR_HDR_LEN(APR_HDR_SIZE
),
1666 pkt
->hdr
.pkt_size
= pkt_size
;
1667 pkt
->hdr
.src_port
= 0;
1668 pkt
->hdr
.dest_port
= 0;
1669 pkt
->hdr
.token
= hw_block_id
;
1670 pkt
->hdr
.opcode
= AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST
;
1671 vote_cfg
->hw_block_id
= hw_block_id
;
1672 vote_cfg
->client_handle
= client_handle
;
1674 ret
= apr_send_pkt(afe
->apr
, pkt
);
1676 dev_err(afe
->dev
, "AFE failed to unvote (%d)\n", hw_block_id
);
1681 EXPORT_SYMBOL(q6afe_unvote_lpass_core_hw
);
1683 int q6afe_vote_lpass_core_hw(struct device
*dev
, uint32_t hw_block_id
,
1684 char *client_name
, uint32_t *client_handle
)
1686 struct q6afe
*afe
= dev_get_drvdata(dev
->parent
);
1687 struct afe_cmd_remote_lpass_core_hw_vote_request
*vote_cfg
;
1688 struct apr_pkt
*pkt
;
1693 pkt_size
= APR_HDR_SIZE
+ sizeof(*vote_cfg
);
1694 p
= kzalloc(pkt_size
, GFP_KERNEL
);
1699 vote_cfg
= p
+ APR_HDR_SIZE
;
1701 pkt
->hdr
.hdr_field
= APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD
,
1702 APR_HDR_LEN(APR_HDR_SIZE
),
1704 pkt
->hdr
.pkt_size
= pkt_size
;
1705 pkt
->hdr
.src_port
= 0;
1706 pkt
->hdr
.dest_port
= 0;
1707 pkt
->hdr
.token
= hw_block_id
;
1708 pkt
->hdr
.opcode
= AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST
;
1709 vote_cfg
->hw_block_id
= hw_block_id
;
1710 strlcpy(vote_cfg
->client_name
, client_name
,
1711 sizeof(vote_cfg
->client_name
));
1713 ret
= afe_apr_send_pkt(afe
, pkt
, NULL
,
1714 AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST
);
1716 dev_err(afe
->dev
, "AFE failed to vote (%d)\n", hw_block_id
);
1722 EXPORT_SYMBOL(q6afe_vote_lpass_core_hw
);
1724 static int q6afe_probe(struct apr_device
*adev
)
1727 struct device
*dev
= &adev
->dev
;
1729 afe
= devm_kzalloc(dev
, sizeof(*afe
), GFP_KERNEL
);
1733 q6core_get_svc_api_info(adev
->svc_id
, &afe
->ainfo
);
1735 mutex_init(&afe
->lock
);
1736 init_waitqueue_head(&afe
->wait
);
1738 INIT_LIST_HEAD(&afe
->port_list
);
1739 spin_lock_init(&afe
->port_list_lock
);
1741 dev_set_drvdata(dev
, afe
);
1743 return devm_of_platform_populate(dev
);
1747 static const struct of_device_id q6afe_device_id
[] = {
1748 { .compatible
= "qcom,q6afe" },
1751 MODULE_DEVICE_TABLE(of
, q6afe_device_id
);
1754 static struct apr_driver qcom_q6afe_driver
= {
1755 .probe
= q6afe_probe
,
1756 .callback
= q6afe_callback
,
1758 .name
= "qcom-q6afe",
1759 .of_match_table
= of_match_ptr(q6afe_device_id
),
1764 module_apr_driver(qcom_q6afe_driver
);
1765 MODULE_DESCRIPTION("Q6 Audio Front End");
1766 MODULE_LICENSE("GPL v2");