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