~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/qcom/qdsp6/q6afe.c

Version: ~ [ linux-5.5 ] ~ [ linux-5.4.15 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.98 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.167 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.211 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.211 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp