blob: 9be62cf1f50dd9e9284baf7705fc6bf6d56d6241 [file] [log] [blame]
Laxminath Kasam468ece32017-11-28 12:40:22 +05301/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/device.h>
16#include <linux/platform_device.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053017#include <linux/bitops.h>
18#include <linux/slab.h>
19#include <linux/clk.h>
20#include <linux/of_device.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053024#include <sound/pcm_params.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053025#include <dsp/apr_audio-v2.h>
26#include <dsp/q6afe-v2.h>
Cong Tang76c7e642019-02-26 15:08:55 +080027#include <dsp/q6core.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053028#include "msm-dai-q6-v2.h"
29#include "codecs/core.h"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053030
31#define MSM_DAI_PRI_AUXPCM_DT_DEV_ID 1
32#define MSM_DAI_SEC_AUXPCM_DT_DEV_ID 2
33#define MSM_DAI_TERT_AUXPCM_DT_DEV_ID 3
34#define MSM_DAI_QUAT_AUXPCM_DT_DEV_ID 4
Rohit Kumara5077932017-09-10 22:05:05 +053035#define MSM_DAI_QUIN_AUXPCM_DT_DEV_ID 5
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053036
Manisha Agarwal472fc1e2018-11-04 15:46:02 +053037#define MSM_DAI_TWS_CHANNEL_MODE_ONE 1
38#define MSM_DAI_TWS_CHANNEL_MODE_TWO 2
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053039
40#define spdif_clock_value(rate) (2*rate*32*2)
41#define CHANNEL_STATUS_SIZE 24
42#define CHANNEL_STATUS_MASK_INIT 0x0
43#define CHANNEL_STATUS_MASK 0x4
44#define AFE_API_VERSION_CLOCK_SET 1
45
46#define DAI_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \
47 SNDRV_PCM_FMTBIT_S24_LE | \
48 SNDRV_PCM_FMTBIT_S32_LE)
49
50enum {
51 ENC_FMT_NONE,
Aniket Kumar Lataf8664712018-02-22 14:46:09 -080052 DEC_FMT_NONE = ENC_FMT_NONE,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053053 ENC_FMT_SBC = ASM_MEDIA_FMT_SBC,
54 ENC_FMT_AAC_V2 = ASM_MEDIA_FMT_AAC_V2,
55 ENC_FMT_APTX = ASM_MEDIA_FMT_APTX,
56 ENC_FMT_APTX_HD = ASM_MEDIA_FMT_APTX_HD,
Preetam Singh Ranawat54028492017-09-04 11:42:26 +053057 ENC_FMT_CELT = ASM_MEDIA_FMT_CELT,
Preetam Singh Ranawat0a087af2017-10-25 15:02:28 +053058 ENC_FMT_LDAC = ASM_MEDIA_FMT_LDAC,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053059};
60
61enum {
62 SPKR_1,
63 SPKR_2,
64};
65
66static const struct afe_clk_set lpass_clk_set_default = {
67 AFE_API_VERSION_CLOCK_SET,
68 Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT,
69 Q6AFE_LPASS_OSR_CLK_2_P048_MHZ,
70 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
71 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
72 0,
73};
74
75static const struct afe_clk_cfg lpass_clk_cfg_default = {
76 AFE_API_VERSION_I2S_CONFIG,
77 Q6AFE_LPASS_OSR_CLK_2_P048_MHZ,
78 0,
79 Q6AFE_LPASS_CLK_SRC_INTERNAL,
80 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
81 Q6AFE_LPASS_MODE_CLK1_VALID,
82 0,
83};
84enum {
85 STATUS_PORT_STARTED, /* track if AFE port has started */
86 /* track AFE Tx port status for bi-directional transfers */
87 STATUS_TX_PORT,
88 /* track AFE Rx port status for bi-directional transfers */
89 STATUS_RX_PORT,
90 STATUS_MAX
91};
92
93enum {
94 RATE_8KHZ,
95 RATE_16KHZ,
96 RATE_MAX_NUM_OF_AUX_PCM_RATES,
97};
98
99enum {
100 IDX_PRIMARY_TDM_RX_0,
101 IDX_PRIMARY_TDM_RX_1,
102 IDX_PRIMARY_TDM_RX_2,
103 IDX_PRIMARY_TDM_RX_3,
104 IDX_PRIMARY_TDM_RX_4,
105 IDX_PRIMARY_TDM_RX_5,
106 IDX_PRIMARY_TDM_RX_6,
107 IDX_PRIMARY_TDM_RX_7,
108 IDX_PRIMARY_TDM_TX_0,
109 IDX_PRIMARY_TDM_TX_1,
110 IDX_PRIMARY_TDM_TX_2,
111 IDX_PRIMARY_TDM_TX_3,
112 IDX_PRIMARY_TDM_TX_4,
113 IDX_PRIMARY_TDM_TX_5,
114 IDX_PRIMARY_TDM_TX_6,
115 IDX_PRIMARY_TDM_TX_7,
116 IDX_SECONDARY_TDM_RX_0,
117 IDX_SECONDARY_TDM_RX_1,
118 IDX_SECONDARY_TDM_RX_2,
119 IDX_SECONDARY_TDM_RX_3,
120 IDX_SECONDARY_TDM_RX_4,
121 IDX_SECONDARY_TDM_RX_5,
122 IDX_SECONDARY_TDM_RX_6,
123 IDX_SECONDARY_TDM_RX_7,
124 IDX_SECONDARY_TDM_TX_0,
125 IDX_SECONDARY_TDM_TX_1,
126 IDX_SECONDARY_TDM_TX_2,
127 IDX_SECONDARY_TDM_TX_3,
128 IDX_SECONDARY_TDM_TX_4,
129 IDX_SECONDARY_TDM_TX_5,
130 IDX_SECONDARY_TDM_TX_6,
131 IDX_SECONDARY_TDM_TX_7,
132 IDX_TERTIARY_TDM_RX_0,
133 IDX_TERTIARY_TDM_RX_1,
134 IDX_TERTIARY_TDM_RX_2,
135 IDX_TERTIARY_TDM_RX_3,
136 IDX_TERTIARY_TDM_RX_4,
137 IDX_TERTIARY_TDM_RX_5,
138 IDX_TERTIARY_TDM_RX_6,
139 IDX_TERTIARY_TDM_RX_7,
140 IDX_TERTIARY_TDM_TX_0,
141 IDX_TERTIARY_TDM_TX_1,
142 IDX_TERTIARY_TDM_TX_2,
143 IDX_TERTIARY_TDM_TX_3,
144 IDX_TERTIARY_TDM_TX_4,
145 IDX_TERTIARY_TDM_TX_5,
146 IDX_TERTIARY_TDM_TX_6,
147 IDX_TERTIARY_TDM_TX_7,
148 IDX_QUATERNARY_TDM_RX_0,
149 IDX_QUATERNARY_TDM_RX_1,
150 IDX_QUATERNARY_TDM_RX_2,
151 IDX_QUATERNARY_TDM_RX_3,
152 IDX_QUATERNARY_TDM_RX_4,
153 IDX_QUATERNARY_TDM_RX_5,
154 IDX_QUATERNARY_TDM_RX_6,
155 IDX_QUATERNARY_TDM_RX_7,
156 IDX_QUATERNARY_TDM_TX_0,
157 IDX_QUATERNARY_TDM_TX_1,
158 IDX_QUATERNARY_TDM_TX_2,
159 IDX_QUATERNARY_TDM_TX_3,
160 IDX_QUATERNARY_TDM_TX_4,
161 IDX_QUATERNARY_TDM_TX_5,
162 IDX_QUATERNARY_TDM_TX_6,
163 IDX_QUATERNARY_TDM_TX_7,
Rohit Kumara5077932017-09-10 22:05:05 +0530164 IDX_QUINARY_TDM_RX_0,
165 IDX_QUINARY_TDM_RX_1,
166 IDX_QUINARY_TDM_RX_2,
167 IDX_QUINARY_TDM_RX_3,
168 IDX_QUINARY_TDM_RX_4,
169 IDX_QUINARY_TDM_RX_5,
170 IDX_QUINARY_TDM_RX_6,
171 IDX_QUINARY_TDM_RX_7,
172 IDX_QUINARY_TDM_TX_0,
173 IDX_QUINARY_TDM_TX_1,
174 IDX_QUINARY_TDM_TX_2,
175 IDX_QUINARY_TDM_TX_3,
176 IDX_QUINARY_TDM_TX_4,
177 IDX_QUINARY_TDM_TX_5,
178 IDX_QUINARY_TDM_TX_6,
179 IDX_QUINARY_TDM_TX_7,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530180 IDX_TDM_MAX,
181};
182
183enum {
184 IDX_GROUP_PRIMARY_TDM_RX,
185 IDX_GROUP_PRIMARY_TDM_TX,
186 IDX_GROUP_SECONDARY_TDM_RX,
187 IDX_GROUP_SECONDARY_TDM_TX,
188 IDX_GROUP_TERTIARY_TDM_RX,
189 IDX_GROUP_TERTIARY_TDM_TX,
190 IDX_GROUP_QUATERNARY_TDM_RX,
191 IDX_GROUP_QUATERNARY_TDM_TX,
Rohit Kumara5077932017-09-10 22:05:05 +0530192 IDX_GROUP_QUINARY_TDM_RX,
193 IDX_GROUP_QUINARY_TDM_TX,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530194 IDX_GROUP_TDM_MAX,
195};
196
197struct msm_dai_q6_dai_data {
198 DECLARE_BITMAP(status_mask, STATUS_MAX);
199 DECLARE_BITMAP(hwfree_status, STATUS_MAX);
200 u32 rate;
201 u32 channels;
202 u32 bitwidth;
203 u32 cal_mode;
204 u32 afe_in_channels;
205 u16 afe_in_bitformat;
206 struct afe_enc_config enc_config;
Aniket Kumar Lataf8664712018-02-22 14:46:09 -0800207 struct afe_dec_config dec_config;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530208 union afe_port_config port_config;
209 u16 vi_feed_mono;
210};
211
212struct msm_dai_q6_spdif_dai_data {
213 DECLARE_BITMAP(status_mask, STATUS_MAX);
214 u32 rate;
215 u32 channels;
216 u32 bitwidth;
217 struct afe_spdif_port_config spdif_port;
218};
219
220struct msm_dai_q6_mi2s_dai_config {
221 u16 pdata_mi2s_lines;
222 struct msm_dai_q6_dai_data mi2s_dai_data;
223};
224
225struct msm_dai_q6_mi2s_dai_data {
226 struct msm_dai_q6_mi2s_dai_config tx_dai;
227 struct msm_dai_q6_mi2s_dai_config rx_dai;
228};
229
230struct msm_dai_q6_auxpcm_dai_data {
231 /* BITMAP to track Rx and Tx port usage count */
232 DECLARE_BITMAP(auxpcm_port_status, STATUS_MAX);
233 struct mutex rlock; /* auxpcm dev resource lock */
234 u16 rx_pid; /* AUXPCM RX AFE port ID */
235 u16 tx_pid; /* AUXPCM TX AFE port ID */
236 u16 afe_clk_ver;
237 struct afe_clk_cfg clk_cfg; /* hold LPASS clock configuration */
238 struct afe_clk_set clk_set; /* hold LPASS clock configuration */
239 struct msm_dai_q6_dai_data bdai_data; /* incoporate base DAI data */
240};
241
Ashish Jain757e1452018-04-30 20:58:04 +0530242static union afe_port_group_config group_cfg_tx;
Bala Kishore Patia0575102018-05-01 12:37:51 +0530243static union afe_port_group_config group_cfg_rx;
Ashish Jain757e1452018-04-30 20:58:04 +0530244
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530245struct msm_dai_q6_tdm_dai_data {
246 DECLARE_BITMAP(status_mask, STATUS_MAX);
247 u32 rate;
248 u32 channels;
249 u32 bitwidth;
250 u32 num_group_ports;
Ashish Jain757e1452018-04-30 20:58:04 +0530251 bool afe_ebit_unsupported;
Surendar karka23677262018-04-30 22:52:08 +0530252 bool sec_port_enable;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530253 struct afe_clk_set clk_set; /* hold LPASS clock config. */
254 union afe_port_group_config group_cfg; /* hold tdm group config */
255 struct afe_tdm_port_config port_cfg; /* hold tdm config */
256};
257
Ashish Jain757e1452018-04-30 20:58:04 +0530258static bool afe_ebit_unsupported;
Surendar karka23677262018-04-30 22:52:08 +0530259static bool tdm_sec_port_enable;
Ashish Jain757e1452018-04-30 20:58:04 +0530260
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530261/* MI2S format field for AFE_PORT_CMD_I2S_CONFIG command
262 * 0: linear PCM
263 * 1: non-linear PCM
264 * 2: PCM data in IEC 60968 container
265 * 3: compressed data in IEC 60958 container
266 */
267static const char *const mi2s_format[] = {
268 "LPCM",
269 "Compr",
270 "LPCM-60958",
271 "Compr-60958"
272};
273
274static const char *const mi2s_vi_feed_mono[] = {
275 "Left",
276 "Right",
277};
278
279static const struct soc_enum mi2s_config_enum[] = {
280 SOC_ENUM_SINGLE_EXT(4, mi2s_format),
281 SOC_ENUM_SINGLE_EXT(2, mi2s_vi_feed_mono),
282};
283
284static const char *const sb_format[] = {
285 "UNPACKED",
286 "PACKED_16B",
287 "DSD_DOP",
288};
289
290static const struct soc_enum sb_config_enum[] = {
291 SOC_ENUM_SINGLE_EXT(3, sb_format),
292};
293
294static const char *const tdm_data_format[] = {
295 "LPCM",
296 "Compr",
297 "Gen Compr"
298};
299
300static const char *const tdm_header_type[] = {
301 "Invalid",
302 "Default",
303 "Entertainment",
304};
305
306static const struct soc_enum tdm_config_enum[] = {
307 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_data_format), tdm_data_format),
308 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_header_type), tdm_header_type),
309};
310
311static DEFINE_MUTEX(tdm_mutex);
312
313static atomic_t tdm_group_ref[IDX_GROUP_TDM_MAX];
314
315/* cache of group cfg per parent node */
316static struct afe_param_id_group_device_tdm_cfg tdm_group_cfg = {
317 AFE_API_VERSION_GROUP_DEVICE_TDM_CONFIG,
318 AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_RX,
319 0,
320 {AFE_PORT_ID_QUATERNARY_TDM_RX,
321 AFE_PORT_ID_QUATERNARY_TDM_RX_1,
322 AFE_PORT_ID_QUATERNARY_TDM_RX_2,
323 AFE_PORT_ID_QUATERNARY_TDM_RX_3,
324 AFE_PORT_ID_QUATERNARY_TDM_RX_4,
325 AFE_PORT_ID_QUATERNARY_TDM_RX_5,
326 AFE_PORT_ID_QUATERNARY_TDM_RX_6,
327 AFE_PORT_ID_QUATERNARY_TDM_RX_7},
328 8,
329 48000,
330 32,
331 8,
332 32,
333 0xFF,
334};
335
336static u32 num_tdm_group_ports;
337
338static struct afe_clk_set tdm_clk_set = {
339 AFE_API_VERSION_CLOCK_SET,
340 Q6AFE_LPASS_CLK_ID_QUAD_TDM_EBIT,
341 Q6AFE_LPASS_IBIT_CLK_DISABLE,
342 Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO,
343 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
344 0,
345};
346
347int msm_dai_q6_get_group_idx(u16 id)
348{
349 switch (id) {
350 case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX:
351 case AFE_PORT_ID_PRIMARY_TDM_RX:
352 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
353 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
354 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
355 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
356 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
357 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
358 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
359 return IDX_GROUP_PRIMARY_TDM_RX;
360 case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX:
361 case AFE_PORT_ID_PRIMARY_TDM_TX:
362 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
363 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
364 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
365 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
366 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
367 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
368 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
369 return IDX_GROUP_PRIMARY_TDM_TX;
370 case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_RX:
371 case AFE_PORT_ID_SECONDARY_TDM_RX:
372 case AFE_PORT_ID_SECONDARY_TDM_RX_1:
373 case AFE_PORT_ID_SECONDARY_TDM_RX_2:
374 case AFE_PORT_ID_SECONDARY_TDM_RX_3:
375 case AFE_PORT_ID_SECONDARY_TDM_RX_4:
376 case AFE_PORT_ID_SECONDARY_TDM_RX_5:
377 case AFE_PORT_ID_SECONDARY_TDM_RX_6:
378 case AFE_PORT_ID_SECONDARY_TDM_RX_7:
379 return IDX_GROUP_SECONDARY_TDM_RX;
380 case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_TX:
381 case AFE_PORT_ID_SECONDARY_TDM_TX:
382 case AFE_PORT_ID_SECONDARY_TDM_TX_1:
383 case AFE_PORT_ID_SECONDARY_TDM_TX_2:
384 case AFE_PORT_ID_SECONDARY_TDM_TX_3:
385 case AFE_PORT_ID_SECONDARY_TDM_TX_4:
386 case AFE_PORT_ID_SECONDARY_TDM_TX_5:
387 case AFE_PORT_ID_SECONDARY_TDM_TX_6:
388 case AFE_PORT_ID_SECONDARY_TDM_TX_7:
389 return IDX_GROUP_SECONDARY_TDM_TX;
390 case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_RX:
391 case AFE_PORT_ID_TERTIARY_TDM_RX:
392 case AFE_PORT_ID_TERTIARY_TDM_RX_1:
393 case AFE_PORT_ID_TERTIARY_TDM_RX_2:
394 case AFE_PORT_ID_TERTIARY_TDM_RX_3:
395 case AFE_PORT_ID_TERTIARY_TDM_RX_4:
396 case AFE_PORT_ID_TERTIARY_TDM_RX_5:
397 case AFE_PORT_ID_TERTIARY_TDM_RX_6:
398 case AFE_PORT_ID_TERTIARY_TDM_RX_7:
399 return IDX_GROUP_TERTIARY_TDM_RX;
400 case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_TX:
401 case AFE_PORT_ID_TERTIARY_TDM_TX:
402 case AFE_PORT_ID_TERTIARY_TDM_TX_1:
403 case AFE_PORT_ID_TERTIARY_TDM_TX_2:
404 case AFE_PORT_ID_TERTIARY_TDM_TX_3:
405 case AFE_PORT_ID_TERTIARY_TDM_TX_4:
406 case AFE_PORT_ID_TERTIARY_TDM_TX_5:
407 case AFE_PORT_ID_TERTIARY_TDM_TX_6:
408 case AFE_PORT_ID_TERTIARY_TDM_TX_7:
409 return IDX_GROUP_TERTIARY_TDM_TX;
410 case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_RX:
411 case AFE_PORT_ID_QUATERNARY_TDM_RX:
412 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
413 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
414 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
415 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
416 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
417 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
418 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
419 return IDX_GROUP_QUATERNARY_TDM_RX;
420 case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_TX:
421 case AFE_PORT_ID_QUATERNARY_TDM_TX:
422 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
423 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
424 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
425 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
426 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
427 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
428 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
429 return IDX_GROUP_QUATERNARY_TDM_TX;
Rohit Kumara5077932017-09-10 22:05:05 +0530430 case AFE_GROUP_DEVICE_ID_QUINARY_TDM_RX:
431 case AFE_PORT_ID_QUINARY_TDM_RX:
432 case AFE_PORT_ID_QUINARY_TDM_RX_1:
433 case AFE_PORT_ID_QUINARY_TDM_RX_2:
434 case AFE_PORT_ID_QUINARY_TDM_RX_3:
435 case AFE_PORT_ID_QUINARY_TDM_RX_4:
436 case AFE_PORT_ID_QUINARY_TDM_RX_5:
437 case AFE_PORT_ID_QUINARY_TDM_RX_6:
438 case AFE_PORT_ID_QUINARY_TDM_RX_7:
439 return IDX_GROUP_QUINARY_TDM_RX;
440 case AFE_GROUP_DEVICE_ID_QUINARY_TDM_TX:
441 case AFE_PORT_ID_QUINARY_TDM_TX:
442 case AFE_PORT_ID_QUINARY_TDM_TX_1:
443 case AFE_PORT_ID_QUINARY_TDM_TX_2:
444 case AFE_PORT_ID_QUINARY_TDM_TX_3:
445 case AFE_PORT_ID_QUINARY_TDM_TX_4:
446 case AFE_PORT_ID_QUINARY_TDM_TX_5:
447 case AFE_PORT_ID_QUINARY_TDM_TX_6:
448 case AFE_PORT_ID_QUINARY_TDM_TX_7:
449 return IDX_GROUP_QUINARY_TDM_TX;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530450 default: return -EINVAL;
451 }
452}
453
454int msm_dai_q6_get_port_idx(u16 id)
455{
456 switch (id) {
457 case AFE_PORT_ID_PRIMARY_TDM_RX:
458 return IDX_PRIMARY_TDM_RX_0;
459 case AFE_PORT_ID_PRIMARY_TDM_TX:
460 return IDX_PRIMARY_TDM_TX_0;
461 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
462 return IDX_PRIMARY_TDM_RX_1;
463 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
464 return IDX_PRIMARY_TDM_TX_1;
465 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
466 return IDX_PRIMARY_TDM_RX_2;
467 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
468 return IDX_PRIMARY_TDM_TX_2;
469 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
470 return IDX_PRIMARY_TDM_RX_3;
471 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
472 return IDX_PRIMARY_TDM_TX_3;
473 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
474 return IDX_PRIMARY_TDM_RX_4;
475 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
476 return IDX_PRIMARY_TDM_TX_4;
477 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
478 return IDX_PRIMARY_TDM_RX_5;
479 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
480 return IDX_PRIMARY_TDM_TX_5;
481 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
482 return IDX_PRIMARY_TDM_RX_6;
483 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
484 return IDX_PRIMARY_TDM_TX_6;
485 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
486 return IDX_PRIMARY_TDM_RX_7;
487 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
488 return IDX_PRIMARY_TDM_TX_7;
489 case AFE_PORT_ID_SECONDARY_TDM_RX:
490 return IDX_SECONDARY_TDM_RX_0;
491 case AFE_PORT_ID_SECONDARY_TDM_TX:
492 return IDX_SECONDARY_TDM_TX_0;
493 case AFE_PORT_ID_SECONDARY_TDM_RX_1:
494 return IDX_SECONDARY_TDM_RX_1;
495 case AFE_PORT_ID_SECONDARY_TDM_TX_1:
496 return IDX_SECONDARY_TDM_TX_1;
497 case AFE_PORT_ID_SECONDARY_TDM_RX_2:
498 return IDX_SECONDARY_TDM_RX_2;
499 case AFE_PORT_ID_SECONDARY_TDM_TX_2:
500 return IDX_SECONDARY_TDM_TX_2;
501 case AFE_PORT_ID_SECONDARY_TDM_RX_3:
502 return IDX_SECONDARY_TDM_RX_3;
503 case AFE_PORT_ID_SECONDARY_TDM_TX_3:
504 return IDX_SECONDARY_TDM_TX_3;
505 case AFE_PORT_ID_SECONDARY_TDM_RX_4:
506 return IDX_SECONDARY_TDM_RX_4;
507 case AFE_PORT_ID_SECONDARY_TDM_TX_4:
508 return IDX_SECONDARY_TDM_TX_4;
509 case AFE_PORT_ID_SECONDARY_TDM_RX_5:
510 return IDX_SECONDARY_TDM_RX_5;
511 case AFE_PORT_ID_SECONDARY_TDM_TX_5:
512 return IDX_SECONDARY_TDM_TX_5;
513 case AFE_PORT_ID_SECONDARY_TDM_RX_6:
514 return IDX_SECONDARY_TDM_RX_6;
515 case AFE_PORT_ID_SECONDARY_TDM_TX_6:
516 return IDX_SECONDARY_TDM_TX_6;
517 case AFE_PORT_ID_SECONDARY_TDM_RX_7:
518 return IDX_SECONDARY_TDM_RX_7;
519 case AFE_PORT_ID_SECONDARY_TDM_TX_7:
520 return IDX_SECONDARY_TDM_TX_7;
521 case AFE_PORT_ID_TERTIARY_TDM_RX:
522 return IDX_TERTIARY_TDM_RX_0;
523 case AFE_PORT_ID_TERTIARY_TDM_TX:
524 return IDX_TERTIARY_TDM_TX_0;
525 case AFE_PORT_ID_TERTIARY_TDM_RX_1:
526 return IDX_TERTIARY_TDM_RX_1;
527 case AFE_PORT_ID_TERTIARY_TDM_TX_1:
528 return IDX_TERTIARY_TDM_TX_1;
529 case AFE_PORT_ID_TERTIARY_TDM_RX_2:
530 return IDX_TERTIARY_TDM_RX_2;
531 case AFE_PORT_ID_TERTIARY_TDM_TX_2:
532 return IDX_TERTIARY_TDM_TX_2;
533 case AFE_PORT_ID_TERTIARY_TDM_RX_3:
534 return IDX_TERTIARY_TDM_RX_3;
535 case AFE_PORT_ID_TERTIARY_TDM_TX_3:
536 return IDX_TERTIARY_TDM_TX_3;
537 case AFE_PORT_ID_TERTIARY_TDM_RX_4:
538 return IDX_TERTIARY_TDM_RX_4;
539 case AFE_PORT_ID_TERTIARY_TDM_TX_4:
540 return IDX_TERTIARY_TDM_TX_4;
541 case AFE_PORT_ID_TERTIARY_TDM_RX_5:
542 return IDX_TERTIARY_TDM_RX_5;
543 case AFE_PORT_ID_TERTIARY_TDM_TX_5:
544 return IDX_TERTIARY_TDM_TX_5;
545 case AFE_PORT_ID_TERTIARY_TDM_RX_6:
546 return IDX_TERTIARY_TDM_RX_6;
547 case AFE_PORT_ID_TERTIARY_TDM_TX_6:
548 return IDX_TERTIARY_TDM_TX_6;
549 case AFE_PORT_ID_TERTIARY_TDM_RX_7:
550 return IDX_TERTIARY_TDM_RX_7;
551 case AFE_PORT_ID_TERTIARY_TDM_TX_7:
552 return IDX_TERTIARY_TDM_TX_7;
553 case AFE_PORT_ID_QUATERNARY_TDM_RX:
554 return IDX_QUATERNARY_TDM_RX_0;
555 case AFE_PORT_ID_QUATERNARY_TDM_TX:
556 return IDX_QUATERNARY_TDM_TX_0;
557 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
558 return IDX_QUATERNARY_TDM_RX_1;
559 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
560 return IDX_QUATERNARY_TDM_TX_1;
561 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
562 return IDX_QUATERNARY_TDM_RX_2;
563 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
564 return IDX_QUATERNARY_TDM_TX_2;
565 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
566 return IDX_QUATERNARY_TDM_RX_3;
567 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
568 return IDX_QUATERNARY_TDM_TX_3;
569 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
570 return IDX_QUATERNARY_TDM_RX_4;
571 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
572 return IDX_QUATERNARY_TDM_TX_4;
573 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
574 return IDX_QUATERNARY_TDM_RX_5;
575 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
576 return IDX_QUATERNARY_TDM_TX_5;
577 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
578 return IDX_QUATERNARY_TDM_RX_6;
579 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
580 return IDX_QUATERNARY_TDM_TX_6;
581 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
582 return IDX_QUATERNARY_TDM_RX_7;
583 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
584 return IDX_QUATERNARY_TDM_TX_7;
Rohit Kumara5077932017-09-10 22:05:05 +0530585 case AFE_PORT_ID_QUINARY_TDM_RX:
586 return IDX_QUINARY_TDM_RX_0;
587 case AFE_PORT_ID_QUINARY_TDM_TX:
588 return IDX_QUINARY_TDM_TX_0;
589 case AFE_PORT_ID_QUINARY_TDM_RX_1:
590 return IDX_QUINARY_TDM_RX_1;
591 case AFE_PORT_ID_QUINARY_TDM_TX_1:
592 return IDX_QUINARY_TDM_TX_1;
593 case AFE_PORT_ID_QUINARY_TDM_RX_2:
594 return IDX_QUINARY_TDM_RX_2;
595 case AFE_PORT_ID_QUINARY_TDM_TX_2:
596 return IDX_QUINARY_TDM_TX_2;
597 case AFE_PORT_ID_QUINARY_TDM_RX_3:
598 return IDX_QUINARY_TDM_RX_3;
599 case AFE_PORT_ID_QUINARY_TDM_TX_3:
600 return IDX_QUINARY_TDM_TX_3;
601 case AFE_PORT_ID_QUINARY_TDM_RX_4:
602 return IDX_QUINARY_TDM_RX_4;
603 case AFE_PORT_ID_QUINARY_TDM_TX_4:
604 return IDX_QUINARY_TDM_TX_4;
605 case AFE_PORT_ID_QUINARY_TDM_RX_5:
606 return IDX_QUINARY_TDM_RX_5;
607 case AFE_PORT_ID_QUINARY_TDM_TX_5:
608 return IDX_QUINARY_TDM_TX_5;
609 case AFE_PORT_ID_QUINARY_TDM_RX_6:
610 return IDX_QUINARY_TDM_RX_6;
611 case AFE_PORT_ID_QUINARY_TDM_TX_6:
612 return IDX_QUINARY_TDM_TX_6;
613 case AFE_PORT_ID_QUINARY_TDM_RX_7:
614 return IDX_QUINARY_TDM_RX_7;
615 case AFE_PORT_ID_QUINARY_TDM_TX_7:
616 return IDX_QUINARY_TDM_TX_7;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530617 default: return -EINVAL;
618 }
619}
620
621static u16 msm_dai_q6_max_num_slot(int frame_rate)
622{
623 /* Max num of slots is bits per frame divided
624 * by bits per sample which is 16
625 */
626 switch (frame_rate) {
627 case AFE_PORT_PCM_BITS_PER_FRAME_8:
628 return 0;
629 case AFE_PORT_PCM_BITS_PER_FRAME_16:
630 return 1;
631 case AFE_PORT_PCM_BITS_PER_FRAME_32:
632 return 2;
633 case AFE_PORT_PCM_BITS_PER_FRAME_64:
634 return 4;
635 case AFE_PORT_PCM_BITS_PER_FRAME_128:
636 return 8;
637 case AFE_PORT_PCM_BITS_PER_FRAME_256:
638 return 16;
639 default:
640 pr_err("%s Invalid bits per frame %d\n",
641 __func__, frame_rate);
642 return 0;
643 }
644}
645
646static int msm_dai_q6_dai_add_route(struct snd_soc_dai *dai)
647{
648 struct snd_soc_dapm_route intercon;
649 struct snd_soc_dapm_context *dapm;
650
651 if (!dai) {
652 pr_err("%s: Invalid params dai\n", __func__);
653 return -EINVAL;
654 }
655 if (!dai->driver) {
656 pr_err("%s: Invalid params dai driver\n", __func__);
657 return -EINVAL;
658 }
659 dapm = snd_soc_component_get_dapm(dai->component);
660 memset(&intercon, 0, sizeof(intercon));
661 if (dai->driver->playback.stream_name &&
662 dai->driver->playback.aif_name) {
663 dev_dbg(dai->dev, "%s: add route for widget %s",
664 __func__, dai->driver->playback.stream_name);
665 intercon.source = dai->driver->playback.aif_name;
666 intercon.sink = dai->driver->playback.stream_name;
667 dev_dbg(dai->dev, "%s: src %s sink %s\n",
668 __func__, intercon.source, intercon.sink);
669 snd_soc_dapm_add_routes(dapm, &intercon, 1);
670 }
671 if (dai->driver->capture.stream_name &&
672 dai->driver->capture.aif_name) {
673 dev_dbg(dai->dev, "%s: add route for widget %s",
674 __func__, dai->driver->capture.stream_name);
675 intercon.sink = dai->driver->capture.aif_name;
676 intercon.source = dai->driver->capture.stream_name;
677 dev_dbg(dai->dev, "%s: src %s sink %s\n",
678 __func__, intercon.source, intercon.sink);
679 snd_soc_dapm_add_routes(dapm, &intercon, 1);
680 }
681 return 0;
682}
683
684static int msm_dai_q6_auxpcm_hw_params(
685 struct snd_pcm_substream *substream,
686 struct snd_pcm_hw_params *params,
687 struct snd_soc_dai *dai)
688{
689 struct msm_dai_q6_auxpcm_dai_data *aux_dai_data =
690 dev_get_drvdata(dai->dev);
691 struct msm_dai_q6_dai_data *dai_data = &aux_dai_data->bdai_data;
692 struct msm_dai_auxpcm_pdata *auxpcm_pdata =
693 (struct msm_dai_auxpcm_pdata *) dai->dev->platform_data;
694 int rc = 0, slot_mapping_copy_len = 0;
695
696 if (params_channels(params) != 1 || (params_rate(params) != 8000 &&
697 params_rate(params) != 16000)) {
698 dev_err(dai->dev, "%s: invalid param chan %d rate %d\n",
699 __func__, params_channels(params), params_rate(params));
700 return -EINVAL;
701 }
702
703 mutex_lock(&aux_dai_data->rlock);
704
705 if (test_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status) ||
706 test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status)) {
707 /* AUXPCM DAI in use */
708 if (dai_data->rate != params_rate(params)) {
709 dev_err(dai->dev, "%s: rate mismatch of running DAI\n",
710 __func__);
711 rc = -EINVAL;
712 }
713 mutex_unlock(&aux_dai_data->rlock);
714 return rc;
715 }
716
717 dai_data->channels = params_channels(params);
718 dai_data->rate = params_rate(params);
719
720 if (dai_data->rate == 8000) {
721 dai_data->port_config.pcm.pcm_cfg_minor_version =
722 AFE_API_VERSION_PCM_CONFIG;
723 dai_data->port_config.pcm.aux_mode = auxpcm_pdata->mode_8k.mode;
724 dai_data->port_config.pcm.sync_src = auxpcm_pdata->mode_8k.sync;
725 dai_data->port_config.pcm.frame_setting =
726 auxpcm_pdata->mode_8k.frame;
727 dai_data->port_config.pcm.quantype =
728 auxpcm_pdata->mode_8k.quant;
729 dai_data->port_config.pcm.ctrl_data_out_enable =
730 auxpcm_pdata->mode_8k.data;
731 dai_data->port_config.pcm.sample_rate = dai_data->rate;
732 dai_data->port_config.pcm.num_channels = dai_data->channels;
733 dai_data->port_config.pcm.bit_width = 16;
734 if (ARRAY_SIZE(dai_data->port_config.pcm.slot_number_mapping) <=
735 auxpcm_pdata->mode_8k.num_slots)
736 slot_mapping_copy_len =
737 ARRAY_SIZE(
738 dai_data->port_config.pcm.slot_number_mapping)
739 * sizeof(uint16_t);
740 else
741 slot_mapping_copy_len = auxpcm_pdata->mode_8k.num_slots
742 * sizeof(uint16_t);
743
744 if (auxpcm_pdata->mode_8k.slot_mapping) {
745 memcpy(dai_data->port_config.pcm.slot_number_mapping,
746 auxpcm_pdata->mode_8k.slot_mapping,
747 slot_mapping_copy_len);
748 } else {
749 dev_err(dai->dev, "%s 8khz slot mapping is NULL\n",
750 __func__);
751 mutex_unlock(&aux_dai_data->rlock);
752 return -EINVAL;
753 }
754 } else {
755 dai_data->port_config.pcm.pcm_cfg_minor_version =
756 AFE_API_VERSION_PCM_CONFIG;
757 dai_data->port_config.pcm.aux_mode =
758 auxpcm_pdata->mode_16k.mode;
759 dai_data->port_config.pcm.sync_src =
760 auxpcm_pdata->mode_16k.sync;
761 dai_data->port_config.pcm.frame_setting =
762 auxpcm_pdata->mode_16k.frame;
763 dai_data->port_config.pcm.quantype =
764 auxpcm_pdata->mode_16k.quant;
765 dai_data->port_config.pcm.ctrl_data_out_enable =
766 auxpcm_pdata->mode_16k.data;
767 dai_data->port_config.pcm.sample_rate = dai_data->rate;
768 dai_data->port_config.pcm.num_channels = dai_data->channels;
769 dai_data->port_config.pcm.bit_width = 16;
770 if (ARRAY_SIZE(dai_data->port_config.pcm.slot_number_mapping) <=
771 auxpcm_pdata->mode_16k.num_slots)
772 slot_mapping_copy_len =
773 ARRAY_SIZE(
774 dai_data->port_config.pcm.slot_number_mapping)
775 * sizeof(uint16_t);
776 else
777 slot_mapping_copy_len = auxpcm_pdata->mode_16k.num_slots
778 * sizeof(uint16_t);
779
780 if (auxpcm_pdata->mode_16k.slot_mapping) {
781 memcpy(dai_data->port_config.pcm.slot_number_mapping,
782 auxpcm_pdata->mode_16k.slot_mapping,
783 slot_mapping_copy_len);
784 } else {
785 dev_err(dai->dev, "%s 16khz slot mapping is NULL\n",
786 __func__);
787 mutex_unlock(&aux_dai_data->rlock);
788 return -EINVAL;
789 }
790 }
791
792 dev_dbg(dai->dev, "%s: aux_mode 0x%x sync_src 0x%x frame_setting 0x%x\n",
793 __func__, dai_data->port_config.pcm.aux_mode,
794 dai_data->port_config.pcm.sync_src,
795 dai_data->port_config.pcm.frame_setting);
796 dev_dbg(dai->dev, "%s: qtype 0x%x dout 0x%x num_map[0] 0x%x\n"
797 "num_map[1] 0x%x num_map[2] 0x%x num_map[3] 0x%x\n",
798 __func__, dai_data->port_config.pcm.quantype,
799 dai_data->port_config.pcm.ctrl_data_out_enable,
800 dai_data->port_config.pcm.slot_number_mapping[0],
801 dai_data->port_config.pcm.slot_number_mapping[1],
802 dai_data->port_config.pcm.slot_number_mapping[2],
803 dai_data->port_config.pcm.slot_number_mapping[3]);
804
805 mutex_unlock(&aux_dai_data->rlock);
806 return rc;
807}
808
809static int msm_dai_q6_auxpcm_set_clk(
810 struct msm_dai_q6_auxpcm_dai_data *aux_dai_data,
811 u16 port_id, bool enable)
812{
813 int rc;
814
815 pr_debug("%s: afe_clk_ver: %d, port_id: %d, enable: %d\n", __func__,
816 aux_dai_data->afe_clk_ver, port_id, enable);
817 if (aux_dai_data->afe_clk_ver == AFE_CLK_VERSION_V2) {
818 aux_dai_data->clk_set.enable = enable;
819 rc = afe_set_lpass_clock_v2(port_id,
820 &aux_dai_data->clk_set);
821 } else {
822 if (!enable)
823 aux_dai_data->clk_cfg.clk_val1 = 0;
824 rc = afe_set_lpass_clock(port_id,
825 &aux_dai_data->clk_cfg);
826 }
827 return rc;
828}
829
830static void msm_dai_q6_auxpcm_shutdown(struct snd_pcm_substream *substream,
831 struct snd_soc_dai *dai)
832{
833 int rc = 0;
834 struct msm_dai_q6_auxpcm_dai_data *aux_dai_data =
835 dev_get_drvdata(dai->dev);
836
837 mutex_lock(&aux_dai_data->rlock);
838
839 if (!(test_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status) ||
840 test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status))) {
841 dev_dbg(dai->dev, "%s(): dai->id %d PCM ports already closed\n",
842 __func__, dai->id);
843 goto exit;
844 }
845
846 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
847 if (test_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status))
848 clear_bit(STATUS_TX_PORT,
849 aux_dai_data->auxpcm_port_status);
850 else {
851 dev_dbg(dai->dev, "%s: PCM_TX port already closed\n",
852 __func__);
853 goto exit;
854 }
855 } else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
856 if (test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status))
857 clear_bit(STATUS_RX_PORT,
858 aux_dai_data->auxpcm_port_status);
859 else {
860 dev_dbg(dai->dev, "%s: PCM_RX port already closed\n",
861 __func__);
862 goto exit;
863 }
864 }
865 if (test_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status) ||
866 test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status)) {
867 dev_dbg(dai->dev, "%s: cannot shutdown PCM ports\n",
868 __func__);
869 goto exit;
870 }
871
872 dev_dbg(dai->dev, "%s: dai->id = %d closing PCM AFE ports\n",
873 __func__, dai->id);
874
875 rc = afe_close(aux_dai_data->rx_pid); /* can block */
876 if (rc < 0)
877 dev_err(dai->dev, "fail to close PCM_RX AFE port\n");
878
879 rc = afe_close(aux_dai_data->tx_pid);
880 if (rc < 0)
881 dev_err(dai->dev, "fail to close AUX PCM TX port\n");
882
883 msm_dai_q6_auxpcm_set_clk(aux_dai_data, aux_dai_data->rx_pid, false);
884 msm_dai_q6_auxpcm_set_clk(aux_dai_data, aux_dai_data->tx_pid, false);
885exit:
886 mutex_unlock(&aux_dai_data->rlock);
887}
888
889static int msm_dai_q6_auxpcm_prepare(struct snd_pcm_substream *substream,
890 struct snd_soc_dai *dai)
891{
892 struct msm_dai_q6_auxpcm_dai_data *aux_dai_data =
893 dev_get_drvdata(dai->dev);
894 struct msm_dai_q6_dai_data *dai_data = &aux_dai_data->bdai_data;
895 struct msm_dai_auxpcm_pdata *auxpcm_pdata = NULL;
896 int rc = 0;
897 u32 pcm_clk_rate;
898
899 auxpcm_pdata = dai->dev->platform_data;
900 mutex_lock(&aux_dai_data->rlock);
901
902 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
903 if (test_bit(STATUS_TX_PORT,
904 aux_dai_data->auxpcm_port_status)) {
905 dev_dbg(dai->dev, "%s: PCM_TX port already ON\n",
906 __func__);
907 goto exit;
908 } else
909 set_bit(STATUS_TX_PORT,
910 aux_dai_data->auxpcm_port_status);
911 } else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
912 if (test_bit(STATUS_RX_PORT,
913 aux_dai_data->auxpcm_port_status)) {
914 dev_dbg(dai->dev, "%s: PCM_RX port already ON\n",
915 __func__);
916 goto exit;
917 } else
918 set_bit(STATUS_RX_PORT,
919 aux_dai_data->auxpcm_port_status);
920 }
921 if (test_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status) &&
922 test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status)) {
923 dev_dbg(dai->dev, "%s: PCM ports already set\n", __func__);
924 goto exit;
925 }
926
927 dev_dbg(dai->dev, "%s: dai->id:%d opening afe ports\n",
928 __func__, dai->id);
929
930 rc = afe_q6_interface_prepare();
931 if (rc < 0) {
932 dev_err(dai->dev, "fail to open AFE APR\n");
933 goto fail;
934 }
935
936 /*
937 * For AUX PCM Interface the below sequence of clk
938 * settings and afe_open is a strict requirement.
939 *
940 * Also using afe_open instead of afe_port_start_nowait
941 * to make sure the port is open before deasserting the
942 * clock line. This is required because pcm register is
943 * not written before clock deassert. Hence the hw does
944 * not get updated with new setting if the below clock
945 * assert/deasset and afe_open sequence is not followed.
946 */
947
948 if (dai_data->rate == 8000) {
949 pcm_clk_rate = auxpcm_pdata->mode_8k.pcm_clk_rate;
950 } else if (dai_data->rate == 16000) {
951 pcm_clk_rate = (auxpcm_pdata->mode_16k.pcm_clk_rate);
952 } else {
953 dev_err(dai->dev, "%s: Invalid AUX PCM rate %d\n", __func__,
954 dai_data->rate);
955 rc = -EINVAL;
956 goto fail;
957 }
958 if (aux_dai_data->afe_clk_ver == AFE_CLK_VERSION_V2) {
959 memcpy(&aux_dai_data->clk_set, &lpass_clk_set_default,
960 sizeof(struct afe_clk_set));
961 aux_dai_data->clk_set.clk_freq_in_hz = pcm_clk_rate;
962
963 switch (dai->id) {
964 case MSM_DAI_PRI_AUXPCM_DT_DEV_ID:
965 if (pcm_clk_rate)
966 aux_dai_data->clk_set.clk_id =
967 Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT;
968 else
969 aux_dai_data->clk_set.clk_id =
970 Q6AFE_LPASS_CLK_ID_PRI_PCM_EBIT;
971 break;
972 case MSM_DAI_SEC_AUXPCM_DT_DEV_ID:
973 if (pcm_clk_rate)
974 aux_dai_data->clk_set.clk_id =
975 Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT;
976 else
977 aux_dai_data->clk_set.clk_id =
978 Q6AFE_LPASS_CLK_ID_SEC_PCM_EBIT;
979 break;
980 case MSM_DAI_TERT_AUXPCM_DT_DEV_ID:
981 if (pcm_clk_rate)
982 aux_dai_data->clk_set.clk_id =
983 Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT;
984 else
985 aux_dai_data->clk_set.clk_id =
986 Q6AFE_LPASS_CLK_ID_TER_PCM_EBIT;
987 break;
988 case MSM_DAI_QUAT_AUXPCM_DT_DEV_ID:
989 if (pcm_clk_rate)
990 aux_dai_data->clk_set.clk_id =
991 Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT;
992 else
993 aux_dai_data->clk_set.clk_id =
994 Q6AFE_LPASS_CLK_ID_QUAD_PCM_EBIT;
995 break;
Rohit Kumara5077932017-09-10 22:05:05 +0530996 case MSM_DAI_QUIN_AUXPCM_DT_DEV_ID:
997 if (pcm_clk_rate)
998 aux_dai_data->clk_set.clk_id =
999 Q6AFE_LPASS_CLK_ID_QUIN_PCM_IBIT;
1000 else
1001 aux_dai_data->clk_set.clk_id =
1002 Q6AFE_LPASS_CLK_ID_QUIN_PCM_EBIT;
1003 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301004 default:
1005 dev_err(dai->dev, "%s: AUXPCM id: %d not supported\n",
1006 __func__, dai->id);
1007 break;
1008 }
1009 } else {
1010 memcpy(&aux_dai_data->clk_cfg, &lpass_clk_cfg_default,
1011 sizeof(struct afe_clk_cfg));
1012 aux_dai_data->clk_cfg.clk_val1 = pcm_clk_rate;
1013 }
1014
1015 rc = msm_dai_q6_auxpcm_set_clk(aux_dai_data,
1016 aux_dai_data->rx_pid, true);
1017 if (rc < 0) {
1018 dev_err(dai->dev,
1019 "%s:afe_set_lpass_clock on RX pcm_src_clk failed\n",
1020 __func__);
1021 goto fail;
1022 }
1023
1024 rc = msm_dai_q6_auxpcm_set_clk(aux_dai_data,
1025 aux_dai_data->tx_pid, true);
1026 if (rc < 0) {
1027 dev_err(dai->dev,
1028 "%s:afe_set_lpass_clock on TX pcm_src_clk failed\n",
1029 __func__);
1030 goto fail;
1031 }
1032
1033 afe_open(aux_dai_data->rx_pid, &dai_data->port_config, dai_data->rate);
1034 afe_open(aux_dai_data->tx_pid, &dai_data->port_config, dai_data->rate);
1035 goto exit;
1036
1037fail:
1038 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
1039 clear_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status);
1040 else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1041 clear_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status);
1042
1043exit:
1044 mutex_unlock(&aux_dai_data->rlock);
1045 return rc;
1046}
1047
1048static int msm_dai_q6_auxpcm_trigger(struct snd_pcm_substream *substream,
1049 int cmd, struct snd_soc_dai *dai)
1050{
1051 int rc = 0;
1052
1053 pr_debug("%s:port:%d cmd:%d\n",
1054 __func__, dai->id, cmd);
1055
1056 switch (cmd) {
1057
1058 case SNDRV_PCM_TRIGGER_START:
1059 case SNDRV_PCM_TRIGGER_RESUME:
1060 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1061 /* afe_open will be called from prepare */
1062 return 0;
1063
1064 case SNDRV_PCM_TRIGGER_STOP:
1065 case SNDRV_PCM_TRIGGER_SUSPEND:
1066 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1067 return 0;
1068
1069 default:
1070 pr_err("%s: cmd %d\n", __func__, cmd);
1071 rc = -EINVAL;
1072 }
1073
1074 return rc;
1075
1076}
1077
1078static int msm_dai_q6_dai_auxpcm_remove(struct snd_soc_dai *dai)
1079{
1080 struct msm_dai_q6_auxpcm_dai_data *aux_dai_data;
1081 int rc;
1082
1083 aux_dai_data = dev_get_drvdata(dai->dev);
1084
1085 dev_dbg(dai->dev, "%s: dai->id %d closing afe\n",
1086 __func__, dai->id);
1087
1088 if (test_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status) ||
1089 test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status)) {
1090 rc = afe_close(aux_dai_data->rx_pid); /* can block */
1091 if (rc < 0)
1092 dev_err(dai->dev, "fail to close AUXPCM RX AFE port\n");
1093 rc = afe_close(aux_dai_data->tx_pid);
1094 if (rc < 0)
1095 dev_err(dai->dev, "fail to close AUXPCM TX AFE port\n");
1096 clear_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status);
1097 clear_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status);
1098 }
1099 msm_dai_q6_auxpcm_set_clk(aux_dai_data, aux_dai_data->rx_pid, false);
1100 msm_dai_q6_auxpcm_set_clk(aux_dai_data, aux_dai_data->tx_pid, false);
1101 return 0;
1102}
1103
1104static int msm_dai_q6_aux_pcm_probe(struct snd_soc_dai *dai)
1105{
1106 int rc = 0;
1107
1108 if (!dai) {
1109 pr_err("%s: Invalid params dai\n", __func__);
1110 return -EINVAL;
1111 }
1112 if (!dai->dev) {
1113 pr_err("%s: Invalid params dai dev\n", __func__);
1114 return -EINVAL;
1115 }
1116 if (!dai->driver->id) {
1117 dev_warn(dai->dev, "DAI driver id is not set\n");
1118 return -EINVAL;
1119 }
1120 dai->id = dai->driver->id;
1121 rc = msm_dai_q6_dai_add_route(dai);
1122 return rc;
1123}
1124
1125static struct snd_soc_dai_ops msm_dai_q6_auxpcm_ops = {
1126 .prepare = msm_dai_q6_auxpcm_prepare,
1127 .trigger = msm_dai_q6_auxpcm_trigger,
1128 .hw_params = msm_dai_q6_auxpcm_hw_params,
1129 .shutdown = msm_dai_q6_auxpcm_shutdown,
1130};
1131
1132static const struct snd_soc_component_driver
1133 msm_dai_q6_aux_pcm_dai_component = {
1134 .name = "msm-auxpcm-dev",
1135};
1136
1137static struct snd_soc_dai_driver msm_dai_q6_aux_pcm_dai[] = {
1138 {
1139 .playback = {
1140 .stream_name = "AUX PCM Playback",
1141 .aif_name = "AUX_PCM_RX",
1142 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
1143 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1144 .channels_min = 1,
1145 .channels_max = 1,
1146 .rate_max = 16000,
1147 .rate_min = 8000,
1148 },
1149 .capture = {
1150 .stream_name = "AUX PCM Capture",
1151 .aif_name = "AUX_PCM_TX",
1152 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
1153 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1154 .channels_min = 1,
1155 .channels_max = 1,
1156 .rate_max = 16000,
1157 .rate_min = 8000,
1158 },
1159 .id = MSM_DAI_PRI_AUXPCM_DT_DEV_ID,
1160 .ops = &msm_dai_q6_auxpcm_ops,
1161 .probe = msm_dai_q6_aux_pcm_probe,
1162 .remove = msm_dai_q6_dai_auxpcm_remove,
1163 },
1164 {
1165 .playback = {
1166 .stream_name = "Sec AUX PCM Playback",
1167 .aif_name = "SEC_AUX_PCM_RX",
1168 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
1169 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1170 .channels_min = 1,
1171 .channels_max = 1,
1172 .rate_max = 16000,
1173 .rate_min = 8000,
1174 },
1175 .capture = {
1176 .stream_name = "Sec AUX PCM Capture",
1177 .aif_name = "SEC_AUX_PCM_TX",
1178 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
1179 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1180 .channels_min = 1,
1181 .channels_max = 1,
1182 .rate_max = 16000,
1183 .rate_min = 8000,
1184 },
1185 .id = MSM_DAI_SEC_AUXPCM_DT_DEV_ID,
1186 .ops = &msm_dai_q6_auxpcm_ops,
1187 .probe = msm_dai_q6_aux_pcm_probe,
1188 .remove = msm_dai_q6_dai_auxpcm_remove,
1189 },
1190 {
1191 .playback = {
1192 .stream_name = "Tert AUX PCM Playback",
1193 .aif_name = "TERT_AUX_PCM_RX",
1194 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
1195 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1196 .channels_min = 1,
1197 .channels_max = 1,
1198 .rate_max = 16000,
1199 .rate_min = 8000,
1200 },
1201 .capture = {
1202 .stream_name = "Tert AUX PCM Capture",
1203 .aif_name = "TERT_AUX_PCM_TX",
1204 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
1205 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1206 .channels_min = 1,
1207 .channels_max = 1,
1208 .rate_max = 16000,
1209 .rate_min = 8000,
1210 },
1211 .id = MSM_DAI_TERT_AUXPCM_DT_DEV_ID,
1212 .ops = &msm_dai_q6_auxpcm_ops,
1213 .probe = msm_dai_q6_aux_pcm_probe,
1214 .remove = msm_dai_q6_dai_auxpcm_remove,
1215 },
1216 {
1217 .playback = {
1218 .stream_name = "Quat AUX PCM Playback",
1219 .aif_name = "QUAT_AUX_PCM_RX",
1220 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
1221 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1222 .channels_min = 1,
1223 .channels_max = 1,
1224 .rate_max = 16000,
1225 .rate_min = 8000,
1226 },
1227 .capture = {
1228 .stream_name = "Quat AUX PCM Capture",
1229 .aif_name = "QUAT_AUX_PCM_TX",
1230 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
1231 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1232 .channels_min = 1,
1233 .channels_max = 1,
1234 .rate_max = 16000,
1235 .rate_min = 8000,
1236 },
1237 .id = MSM_DAI_QUAT_AUXPCM_DT_DEV_ID,
1238 .ops = &msm_dai_q6_auxpcm_ops,
1239 .probe = msm_dai_q6_aux_pcm_probe,
1240 .remove = msm_dai_q6_dai_auxpcm_remove,
1241 },
Rohit Kumara5077932017-09-10 22:05:05 +05301242 {
1243 .playback = {
1244 .stream_name = "Quin AUX PCM Playback",
1245 .aif_name = "QUIN_AUX_PCM_RX",
1246 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
1247 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1248 .channels_min = 1,
1249 .channels_max = 1,
1250 .rate_max = 16000,
1251 .rate_min = 8000,
1252 },
1253 .capture = {
1254 .stream_name = "Quin AUX PCM Capture",
1255 .aif_name = "QUIN_AUX_PCM_TX",
1256 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
1257 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1258 .channels_min = 1,
1259 .channels_max = 1,
1260 .rate_max = 16000,
1261 .rate_min = 8000,
1262 },
1263 .id = MSM_DAI_QUIN_AUXPCM_DT_DEV_ID,
1264 .ops = &msm_dai_q6_auxpcm_ops,
1265 .probe = msm_dai_q6_aux_pcm_probe,
1266 .remove = msm_dai_q6_dai_auxpcm_remove,
1267 },
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301268};
1269
1270static int msm_dai_q6_spdif_format_put(struct snd_kcontrol *kcontrol,
1271 struct snd_ctl_elem_value *ucontrol)
1272{
1273
1274 struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data;
1275 int value = ucontrol->value.integer.value[0];
1276
1277 dai_data->spdif_port.cfg.data_format = value;
1278 pr_debug("%s: value = %d\n", __func__, value);
1279 return 0;
1280}
1281
1282static int msm_dai_q6_spdif_format_get(struct snd_kcontrol *kcontrol,
1283 struct snd_ctl_elem_value *ucontrol)
1284{
1285
1286 struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data;
1287
1288 ucontrol->value.integer.value[0] =
1289 dai_data->spdif_port.cfg.data_format;
1290 return 0;
1291}
1292
1293static const char * const spdif_format[] = {
1294 "LPCM",
1295 "Compr"
1296};
1297
1298static const struct soc_enum spdif_config_enum[] = {
1299 SOC_ENUM_SINGLE_EXT(2, spdif_format),
1300};
1301
1302static int msm_dai_q6_spdif_chstatus_put(struct snd_kcontrol *kcontrol,
1303 struct snd_ctl_elem_value *ucontrol)
1304{
1305 struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data;
1306 int ret = 0;
1307
1308 dai_data->spdif_port.ch_status.status_type =
1309 AFE_API_VERSION_SPDIF_CH_STATUS_CONFIG;
1310 memset(dai_data->spdif_port.ch_status.status_mask,
1311 CHANNEL_STATUS_MASK_INIT, CHANNEL_STATUS_SIZE);
1312 dai_data->spdif_port.ch_status.status_mask[0] =
1313 CHANNEL_STATUS_MASK;
1314
1315 memcpy(dai_data->spdif_port.ch_status.status_bits,
1316 ucontrol->value.iec958.status, CHANNEL_STATUS_SIZE);
1317
1318 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
1319 pr_debug("%s: Port already started. Dynamic update\n",
1320 __func__);
1321 ret = afe_send_spdif_ch_status_cfg(
1322 &dai_data->spdif_port.ch_status,
1323 AFE_PORT_ID_SPDIF_RX);
1324 }
1325 return ret;
1326}
1327
1328static int msm_dai_q6_spdif_chstatus_get(struct snd_kcontrol *kcontrol,
1329 struct snd_ctl_elem_value *ucontrol)
1330{
1331
1332 struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data;
1333
1334 memcpy(ucontrol->value.iec958.status,
1335 dai_data->spdif_port.ch_status.status_bits,
1336 CHANNEL_STATUS_SIZE);
1337 return 0;
1338}
1339
1340static int msm_dai_q6_spdif_chstatus_info(struct snd_kcontrol *kcontrol,
1341 struct snd_ctl_elem_info *uinfo)
1342{
1343 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1344 uinfo->count = 1;
1345 return 0;
1346}
1347
1348static const struct snd_kcontrol_new spdif_config_controls[] = {
1349 {
1350 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1351 SNDRV_CTL_ELEM_ACCESS_INACTIVE),
1352 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1353 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
1354 .info = msm_dai_q6_spdif_chstatus_info,
1355 .get = msm_dai_q6_spdif_chstatus_get,
1356 .put = msm_dai_q6_spdif_chstatus_put,
1357 },
1358 SOC_ENUM_EXT("SPDIF RX Format", spdif_config_enum[0],
1359 msm_dai_q6_spdif_format_get,
1360 msm_dai_q6_spdif_format_put)
1361};
1362
1363
1364static int msm_dai_q6_spdif_hw_params(struct snd_pcm_substream *substream,
1365 struct snd_pcm_hw_params *params,
1366 struct snd_soc_dai *dai)
1367{
1368 struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dai->dev);
1369
1370 dai->id = AFE_PORT_ID_SPDIF_RX;
1371 dai_data->channels = params_channels(params);
1372 dai_data->spdif_port.cfg.num_channels = dai_data->channels;
1373 switch (params_format(params)) {
1374 case SNDRV_PCM_FORMAT_S16_LE:
1375 dai_data->spdif_port.cfg.bit_width = 16;
1376 break;
1377 case SNDRV_PCM_FORMAT_S24_LE:
1378 case SNDRV_PCM_FORMAT_S24_3LE:
1379 dai_data->spdif_port.cfg.bit_width = 24;
1380 break;
1381 default:
1382 pr_err("%s: format %d\n",
1383 __func__, params_format(params));
1384 return -EINVAL;
1385 }
1386
1387 dai_data->rate = params_rate(params);
1388 dai_data->bitwidth = dai_data->spdif_port.cfg.bit_width;
1389 dai_data->spdif_port.cfg.sample_rate = dai_data->rate;
1390 dai_data->spdif_port.cfg.spdif_cfg_minor_version =
1391 AFE_API_VERSION_SPDIF_CONFIG;
1392 dev_dbg(dai->dev, " channel %d sample rate %d bit width %d\n",
1393 dai_data->channels, dai_data->rate,
1394 dai_data->spdif_port.cfg.bit_width);
1395 dai_data->spdif_port.cfg.reserved = 0;
1396 return 0;
1397}
1398
1399static void msm_dai_q6_spdif_shutdown(struct snd_pcm_substream *substream,
1400 struct snd_soc_dai *dai)
1401{
1402 struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dai->dev);
1403 int rc = 0;
1404
1405 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
1406 pr_info("%s: afe port not started. dai_data->status_mask = %ld\n",
1407 __func__, *dai_data->status_mask);
1408 return;
1409 }
1410
1411 rc = afe_close(dai->id);
1412 if (rc < 0)
1413 dev_err(dai->dev, "fail to close AFE port\n");
1414
1415 pr_debug("%s: dai_data->status_mask = %ld\n", __func__,
1416 *dai_data->status_mask);
1417
1418 clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
1419}
1420
1421
1422static int msm_dai_q6_spdif_prepare(struct snd_pcm_substream *substream,
1423 struct snd_soc_dai *dai)
1424{
1425 struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dai->dev);
1426 int rc = 0;
1427
1428 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
1429 rc = afe_spdif_port_start(dai->id, &dai_data->spdif_port,
1430 dai_data->rate);
1431 if (rc < 0)
1432 dev_err(dai->dev, "fail to open AFE port 0x%x\n",
1433 dai->id);
1434 else
1435 set_bit(STATUS_PORT_STARTED,
1436 dai_data->status_mask);
1437 }
1438
1439 return rc;
1440}
1441
1442static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai)
1443{
1444 struct msm_dai_q6_spdif_dai_data *dai_data;
1445 const struct snd_kcontrol_new *kcontrol;
1446 int rc = 0;
1447 struct snd_soc_dapm_route intercon;
1448 struct snd_soc_dapm_context *dapm;
1449
1450 if (!dai) {
1451 pr_err("%s: dai not found!!\n", __func__);
1452 return -EINVAL;
1453 }
1454 dai_data = kzalloc(sizeof(struct msm_dai_q6_spdif_dai_data),
1455 GFP_KERNEL);
1456
1457 if (!dai_data) {
1458 dev_err(dai->dev, "DAI-%d: fail to allocate dai data\n",
1459 AFE_PORT_ID_SPDIF_RX);
1460 rc = -ENOMEM;
1461 } else
1462 dev_set_drvdata(dai->dev, dai_data);
1463
1464 kcontrol = &spdif_config_controls[1];
1465 dapm = snd_soc_component_get_dapm(dai->component);
1466
1467 rc = snd_ctl_add(dai->component->card->snd_card,
1468 snd_ctl_new1(kcontrol, dai_data));
1469
1470 memset(&intercon, 0, sizeof(intercon));
1471 if (!rc && dai && dai->driver) {
1472 if (dai->driver->playback.stream_name &&
1473 dai->driver->playback.aif_name) {
1474 dev_dbg(dai->dev, "%s: add route for widget %s",
1475 __func__, dai->driver->playback.stream_name);
1476 intercon.source = dai->driver->playback.aif_name;
1477 intercon.sink = dai->driver->playback.stream_name;
1478 dev_dbg(dai->dev, "%s: src %s sink %s\n",
1479 __func__, intercon.source, intercon.sink);
1480 snd_soc_dapm_add_routes(dapm, &intercon, 1);
1481 }
1482 if (dai->driver->capture.stream_name &&
1483 dai->driver->capture.aif_name) {
1484 dev_dbg(dai->dev, "%s: add route for widget %s",
1485 __func__, dai->driver->capture.stream_name);
1486 intercon.sink = dai->driver->capture.aif_name;
1487 intercon.source = dai->driver->capture.stream_name;
1488 dev_dbg(dai->dev, "%s: src %s sink %s\n",
1489 __func__, intercon.source, intercon.sink);
1490 snd_soc_dapm_add_routes(dapm, &intercon, 1);
1491 }
1492 }
1493 return rc;
1494}
1495
1496static int msm_dai_q6_spdif_dai_remove(struct snd_soc_dai *dai)
1497{
1498 struct msm_dai_q6_spdif_dai_data *dai_data;
1499 int rc;
1500
1501 dai_data = dev_get_drvdata(dai->dev);
1502
1503 /* If AFE port is still up, close it */
1504 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
1505 rc = afe_close(dai->id); /* can block */
1506 if (rc < 0)
1507 dev_err(dai->dev, "fail to close AFE port\n");
1508
1509 clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
1510 }
1511 kfree(dai_data);
1512
1513 return 0;
1514}
1515
1516
1517static struct snd_soc_dai_ops msm_dai_q6_spdif_ops = {
1518 .prepare = msm_dai_q6_spdif_prepare,
1519 .hw_params = msm_dai_q6_spdif_hw_params,
1520 .shutdown = msm_dai_q6_spdif_shutdown,
1521};
1522
1523static struct snd_soc_dai_driver msm_dai_q6_spdif_spdif_rx_dai = {
1524 .playback = {
1525 .stream_name = "SPDIF Playback",
1526 .aif_name = "SPDIF_RX",
1527 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
1528 SNDRV_PCM_RATE_16000,
1529 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
1530 .channels_min = 1,
1531 .channels_max = 4,
1532 .rate_min = 8000,
1533 .rate_max = 48000,
1534 },
1535 .ops = &msm_dai_q6_spdif_ops,
1536 .probe = msm_dai_q6_spdif_dai_probe,
1537 .remove = msm_dai_q6_spdif_dai_remove,
1538};
1539
1540static const struct snd_soc_component_driver msm_dai_spdif_q6_component = {
1541 .name = "msm-dai-q6-spdif",
1542};
1543
1544static int msm_dai_q6_prepare(struct snd_pcm_substream *substream,
1545 struct snd_soc_dai *dai)
1546{
1547 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
1548 int rc = 0;
1549
1550 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
1551 if (dai_data->enc_config.format != ENC_FMT_NONE) {
1552 int bitwidth = 0;
1553
Aniket Kumar Lataf8664712018-02-22 14:46:09 -08001554 switch (dai_data->afe_in_bitformat) {
1555 case SNDRV_PCM_FORMAT_S32_LE:
1556 bitwidth = 32;
1557 break;
1558 case SNDRV_PCM_FORMAT_S24_LE:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301559 bitwidth = 24;
Aniket Kumar Lataf8664712018-02-22 14:46:09 -08001560 break;
1561 case SNDRV_PCM_FORMAT_S16_LE:
1562 default:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301563 bitwidth = 16;
Aniket Kumar Lataf8664712018-02-22 14:46:09 -08001564 break;
1565 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301566 pr_debug("%s: calling AFE_PORT_START_V2 with enc_format: %d\n",
1567 __func__, dai_data->enc_config.format);
1568 rc = afe_port_start_v2(dai->id, &dai_data->port_config,
1569 dai_data->rate,
1570 dai_data->afe_in_channels,
1571 bitwidth,
Aniket Kumar Lataf8664712018-02-22 14:46:09 -08001572 &dai_data->enc_config, NULL);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301573 if (rc < 0)
1574 pr_err("%s: afe_port_start_v2 failed error: %d\n",
1575 __func__, rc);
Aniket Kumar Lataf8664712018-02-22 14:46:09 -08001576 } else if (dai_data->dec_config.format != DEC_FMT_NONE) {
1577 /*
1578 * A dummy Tx session is established in LPASS to
1579 * get the link statistics from BTSoC.
1580 * Depacketizer extracts the bit rate levels and
1581 * transmits them to the encoder on the Rx path.
1582 * Since this is a dummy decoder - channels, bit
1583 * width are sent as 0 and encoder config is NULL.
1584 * This could be updated in the future if there is
1585 * a complete Tx path set up that uses this decoder.
1586 */
1587 rc = afe_port_start_v2(dai->id, &dai_data->port_config,
1588 dai_data->rate, 0, 0, NULL,
1589 &dai_data->dec_config);
1590 if (rc < 0) {
1591 pr_err("%s: fail to open AFE port 0x%x\n",
1592 __func__, dai->id);
1593 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301594 } else {
1595 rc = afe_port_start(dai->id, &dai_data->port_config,
1596 dai_data->rate);
1597 }
1598 if (rc < 0)
1599 dev_err(dai->dev, "fail to open AFE port 0x%x\n",
1600 dai->id);
1601 else
1602 set_bit(STATUS_PORT_STARTED,
1603 dai_data->status_mask);
1604 }
1605 return rc;
1606}
1607
1608static int msm_dai_q6_cdc_hw_params(struct snd_pcm_hw_params *params,
1609 struct snd_soc_dai *dai, int stream)
1610{
1611 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
1612
1613 dai_data->channels = params_channels(params);
1614 switch (dai_data->channels) {
1615 case 2:
1616 dai_data->port_config.i2s.mono_stereo = MSM_AFE_STEREO;
1617 break;
1618 case 1:
1619 dai_data->port_config.i2s.mono_stereo = MSM_AFE_MONO;
1620 break;
1621 default:
1622 return -EINVAL;
1623 pr_err("%s: err channels %d\n",
1624 __func__, dai_data->channels);
1625 break;
1626 }
1627
1628 switch (params_format(params)) {
1629 case SNDRV_PCM_FORMAT_S16_LE:
1630 case SNDRV_PCM_FORMAT_SPECIAL:
1631 dai_data->port_config.i2s.bit_width = 16;
1632 break;
1633 case SNDRV_PCM_FORMAT_S24_LE:
1634 case SNDRV_PCM_FORMAT_S24_3LE:
1635 dai_data->port_config.i2s.bit_width = 24;
1636 break;
1637 default:
1638 pr_err("%s: format %d\n",
1639 __func__, params_format(params));
1640 return -EINVAL;
1641 }
1642
1643 dai_data->rate = params_rate(params);
1644 dai_data->port_config.i2s.sample_rate = dai_data->rate;
1645 dai_data->port_config.i2s.i2s_cfg_minor_version =
1646 AFE_API_VERSION_I2S_CONFIG;
1647 dai_data->port_config.i2s.data_format = AFE_LINEAR_PCM_DATA;
1648 dev_dbg(dai->dev, " channel %d sample rate %d entered\n",
1649 dai_data->channels, dai_data->rate);
1650
1651 dai_data->port_config.i2s.channel_mode = 1;
1652 return 0;
1653}
1654
1655static u8 num_of_bits_set(u8 sd_line_mask)
1656{
1657 u8 num_bits_set = 0;
1658
1659 while (sd_line_mask) {
1660 num_bits_set++;
1661 sd_line_mask = sd_line_mask & (sd_line_mask - 1);
1662 }
1663 return num_bits_set;
1664}
1665
1666static int msm_dai_q6_i2s_hw_params(struct snd_pcm_hw_params *params,
1667 struct snd_soc_dai *dai, int stream)
1668{
1669 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
1670 struct msm_i2s_data *i2s_pdata =
1671 (struct msm_i2s_data *) dai->dev->platform_data;
1672
1673 dai_data->channels = params_channels(params);
1674 if (num_of_bits_set(i2s_pdata->sd_lines) == 1) {
1675 switch (dai_data->channels) {
1676 case 2:
1677 dai_data->port_config.i2s.mono_stereo = MSM_AFE_STEREO;
1678 break;
1679 case 1:
1680 dai_data->port_config.i2s.mono_stereo = MSM_AFE_MONO;
1681 break;
1682 default:
1683 pr_warn("%s: greater than stereo has not been validated %d",
1684 __func__, dai_data->channels);
1685 break;
1686 }
1687 }
1688 dai_data->rate = params_rate(params);
1689 dai_data->port_config.i2s.sample_rate = dai_data->rate;
1690 dai_data->port_config.i2s.i2s_cfg_minor_version =
1691 AFE_API_VERSION_I2S_CONFIG;
1692 dai_data->port_config.i2s.data_format = AFE_LINEAR_PCM_DATA;
1693 /* Q6 only supports 16 as now */
1694 dai_data->port_config.i2s.bit_width = 16;
1695 dai_data->port_config.i2s.channel_mode = 1;
1696
1697 return 0;
1698}
1699
1700static int msm_dai_q6_slim_bus_hw_params(struct snd_pcm_hw_params *params,
1701 struct snd_soc_dai *dai, int stream)
1702{
1703 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
1704
1705 dai_data->channels = params_channels(params);
1706 dai_data->rate = params_rate(params);
1707
1708 switch (params_format(params)) {
1709 case SNDRV_PCM_FORMAT_S16_LE:
1710 case SNDRV_PCM_FORMAT_SPECIAL:
1711 dai_data->port_config.slim_sch.bit_width = 16;
1712 break;
1713 case SNDRV_PCM_FORMAT_S24_LE:
1714 case SNDRV_PCM_FORMAT_S24_3LE:
1715 dai_data->port_config.slim_sch.bit_width = 24;
1716 break;
1717 case SNDRV_PCM_FORMAT_S32_LE:
1718 dai_data->port_config.slim_sch.bit_width = 32;
1719 break;
1720 default:
1721 pr_err("%s: format %d\n",
1722 __func__, params_format(params));
1723 return -EINVAL;
1724 }
1725
1726 dai_data->port_config.slim_sch.sb_cfg_minor_version =
1727 AFE_API_VERSION_SLIMBUS_CONFIG;
1728 dai_data->port_config.slim_sch.sample_rate = dai_data->rate;
1729 dai_data->port_config.slim_sch.num_channels = dai_data->channels;
1730
1731 switch (dai->id) {
1732 case SLIMBUS_7_RX:
1733 case SLIMBUS_7_TX:
1734 case SLIMBUS_8_RX:
1735 case SLIMBUS_8_TX:
1736 dai_data->port_config.slim_sch.slimbus_dev_id =
1737 AFE_SLIMBUS_DEVICE_2;
1738 break;
1739 default:
1740 dai_data->port_config.slim_sch.slimbus_dev_id =
1741 AFE_SLIMBUS_DEVICE_1;
1742 break;
1743 }
1744
1745 dev_dbg(dai->dev, "%s:slimbus_dev_id[%hu] bit_wd[%hu] format[%hu]\n"
1746 "num_channel %hu shared_ch_mapping[0] %hu\n"
1747 "slave_port_mapping[1] %hu slave_port_mapping[2] %hu\n"
1748 "sample_rate %d\n", __func__,
1749 dai_data->port_config.slim_sch.slimbus_dev_id,
1750 dai_data->port_config.slim_sch.bit_width,
1751 dai_data->port_config.slim_sch.data_format,
1752 dai_data->port_config.slim_sch.num_channels,
1753 dai_data->port_config.slim_sch.shared_ch_mapping[0],
1754 dai_data->port_config.slim_sch.shared_ch_mapping[1],
1755 dai_data->port_config.slim_sch.shared_ch_mapping[2],
1756 dai_data->rate);
1757
1758 return 0;
1759}
1760
1761static int msm_dai_q6_usb_audio_hw_params(struct snd_pcm_hw_params *params,
1762 struct snd_soc_dai *dai, int stream)
1763{
1764 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
1765
1766 dai_data->channels = params_channels(params);
1767 dai_data->rate = params_rate(params);
1768
1769 switch (params_format(params)) {
1770 case SNDRV_PCM_FORMAT_S16_LE:
1771 case SNDRV_PCM_FORMAT_SPECIAL:
1772 dai_data->port_config.usb_audio.bit_width = 16;
1773 break;
1774 case SNDRV_PCM_FORMAT_S24_LE:
1775 case SNDRV_PCM_FORMAT_S24_3LE:
1776 dai_data->port_config.usb_audio.bit_width = 24;
1777 break;
1778 case SNDRV_PCM_FORMAT_S32_LE:
1779 dai_data->port_config.usb_audio.bit_width = 32;
1780 break;
1781
1782 default:
1783 dev_err(dai->dev, "%s: invalid format %d\n",
1784 __func__, params_format(params));
1785 return -EINVAL;
1786 }
1787 dai_data->port_config.usb_audio.cfg_minor_version =
1788 AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG;
1789 dai_data->port_config.usb_audio.num_channels = dai_data->channels;
1790 dai_data->port_config.usb_audio.sample_rate = dai_data->rate;
1791
1792 dev_dbg(dai->dev, "%s: dev_id[0x%x] bit_wd[%hu] format[%hu]\n"
1793 "num_channel %hu sample_rate %d\n", __func__,
1794 dai_data->port_config.usb_audio.dev_token,
1795 dai_data->port_config.usb_audio.bit_width,
1796 dai_data->port_config.usb_audio.data_format,
1797 dai_data->port_config.usb_audio.num_channels,
1798 dai_data->port_config.usb_audio.sample_rate);
1799
1800 return 0;
1801}
1802
1803static int msm_dai_q6_bt_fm_hw_params(struct snd_pcm_hw_params *params,
1804 struct snd_soc_dai *dai, int stream)
1805{
1806 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
1807
1808 dai_data->channels = params_channels(params);
1809 dai_data->rate = params_rate(params);
1810
1811 dev_dbg(dai->dev, "channels %d sample rate %d entered\n",
1812 dai_data->channels, dai_data->rate);
1813
1814 memset(&dai_data->port_config, 0, sizeof(dai_data->port_config));
1815
1816 pr_debug("%s: setting bt_fm parameters\n", __func__);
1817
1818 dai_data->port_config.int_bt_fm.bt_fm_cfg_minor_version =
1819 AFE_API_VERSION_INTERNAL_BT_FM_CONFIG;
1820 dai_data->port_config.int_bt_fm.num_channels = dai_data->channels;
1821 dai_data->port_config.int_bt_fm.sample_rate = dai_data->rate;
1822 dai_data->port_config.int_bt_fm.bit_width = 16;
1823
1824 return 0;
1825}
1826
1827static int msm_dai_q6_afe_rtproxy_hw_params(struct snd_pcm_hw_params *params,
1828 struct snd_soc_dai *dai)
1829{
1830 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
1831
1832 dai_data->rate = params_rate(params);
1833 dai_data->port_config.rtproxy.num_channels = params_channels(params);
1834 dai_data->port_config.rtproxy.sample_rate = params_rate(params);
1835
1836 pr_debug("channel %d entered,dai_id: %d,rate: %d\n",
1837 dai_data->port_config.rtproxy.num_channels, dai->id, dai_data->rate);
1838
1839 dai_data->port_config.rtproxy.rt_proxy_cfg_minor_version =
1840 AFE_API_VERSION_RT_PROXY_CONFIG;
1841 dai_data->port_config.rtproxy.bit_width = 16; /* Q6 only supports 16 */
1842 dai_data->port_config.rtproxy.interleaved = 1;
1843 dai_data->port_config.rtproxy.frame_size = params_period_bytes(params);
1844 dai_data->port_config.rtproxy.jitter_allowance =
1845 dai_data->port_config.rtproxy.frame_size/2;
1846 dai_data->port_config.rtproxy.low_water_mark = 0;
1847 dai_data->port_config.rtproxy.high_water_mark = 0;
1848
1849 return 0;
1850}
1851
1852static int msm_dai_q6_pseudo_port_hw_params(struct snd_pcm_hw_params *params,
1853 struct snd_soc_dai *dai, int stream)
1854{
1855 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
1856
1857 dai_data->channels = params_channels(params);
1858 dai_data->rate = params_rate(params);
1859
1860 /* Q6 only supports 16 as now */
1861 dai_data->port_config.pseudo_port.pseud_port_cfg_minor_version =
1862 AFE_API_VERSION_PSEUDO_PORT_CONFIG;
1863 dai_data->port_config.pseudo_port.num_channels =
1864 params_channels(params);
1865 dai_data->port_config.pseudo_port.bit_width = 16;
1866 dai_data->port_config.pseudo_port.data_format = 0;
1867 dai_data->port_config.pseudo_port.timing_mode =
1868 AFE_PSEUDOPORT_TIMING_MODE_TIMER;
1869 dai_data->port_config.pseudo_port.sample_rate = params_rate(params);
1870
1871 dev_dbg(dai->dev, "%s: bit_wd[%hu] num_channels [%hu] format[%hu]\n"
1872 "timing Mode %hu sample_rate %d\n", __func__,
1873 dai_data->port_config.pseudo_port.bit_width,
1874 dai_data->port_config.pseudo_port.num_channels,
1875 dai_data->port_config.pseudo_port.data_format,
1876 dai_data->port_config.pseudo_port.timing_mode,
1877 dai_data->port_config.pseudo_port.sample_rate);
1878
1879 return 0;
1880}
1881
1882/* Current implementation assumes hw_param is called once
1883 * This may not be the case but what to do when ADM and AFE
1884 * port are already opened and parameter changes
1885 */
1886static int msm_dai_q6_hw_params(struct snd_pcm_substream *substream,
1887 struct snd_pcm_hw_params *params,
1888 struct snd_soc_dai *dai)
1889{
1890 int rc = 0;
1891
1892 switch (dai->id) {
1893 case PRIMARY_I2S_TX:
1894 case PRIMARY_I2S_RX:
1895 case SECONDARY_I2S_RX:
1896 rc = msm_dai_q6_cdc_hw_params(params, dai, substream->stream);
1897 break;
1898 case MI2S_RX:
1899 rc = msm_dai_q6_i2s_hw_params(params, dai, substream->stream);
1900 break;
1901 case SLIMBUS_0_RX:
1902 case SLIMBUS_1_RX:
1903 case SLIMBUS_2_RX:
1904 case SLIMBUS_3_RX:
1905 case SLIMBUS_4_RX:
1906 case SLIMBUS_5_RX:
1907 case SLIMBUS_6_RX:
1908 case SLIMBUS_7_RX:
1909 case SLIMBUS_8_RX:
1910 case SLIMBUS_0_TX:
1911 case SLIMBUS_1_TX:
1912 case SLIMBUS_2_TX:
1913 case SLIMBUS_3_TX:
1914 case SLIMBUS_4_TX:
1915 case SLIMBUS_5_TX:
1916 case SLIMBUS_6_TX:
1917 case SLIMBUS_7_TX:
1918 case SLIMBUS_8_TX:
1919 rc = msm_dai_q6_slim_bus_hw_params(params, dai,
1920 substream->stream);
1921 break;
1922 case INT_BT_SCO_RX:
1923 case INT_BT_SCO_TX:
1924 case INT_BT_A2DP_RX:
1925 case INT_FM_RX:
1926 case INT_FM_TX:
1927 rc = msm_dai_q6_bt_fm_hw_params(params, dai, substream->stream);
1928 break;
1929 case AFE_PORT_ID_USB_RX:
1930 case AFE_PORT_ID_USB_TX:
1931 rc = msm_dai_q6_usb_audio_hw_params(params, dai,
1932 substream->stream);
1933 break;
1934 case RT_PROXY_DAI_001_TX:
1935 case RT_PROXY_DAI_001_RX:
1936 case RT_PROXY_DAI_002_TX:
1937 case RT_PROXY_DAI_002_RX:
1938 rc = msm_dai_q6_afe_rtproxy_hw_params(params, dai);
1939 break;
1940 case VOICE_PLAYBACK_TX:
1941 case VOICE2_PLAYBACK_TX:
1942 case VOICE_RECORD_RX:
1943 case VOICE_RECORD_TX:
1944 rc = msm_dai_q6_pseudo_port_hw_params(params,
1945 dai, substream->stream);
1946 break;
1947 default:
1948 dev_err(dai->dev, "invalid AFE port ID 0x%x\n", dai->id);
1949 rc = -EINVAL;
1950 break;
1951 }
1952
1953 return rc;
1954}
1955
1956static void msm_dai_q6_shutdown(struct snd_pcm_substream *substream,
1957 struct snd_soc_dai *dai)
1958{
1959 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
1960 int rc = 0;
1961
1962 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
1963 pr_debug("%s: stop pseudo port:%d\n", __func__, dai->id);
1964 rc = afe_close(dai->id); /* can block */
1965 if (rc < 0)
1966 dev_err(dai->dev, "fail to close AFE port\n");
1967 pr_debug("%s: dai_data->status_mask = %ld\n", __func__,
1968 *dai_data->status_mask);
1969 clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
1970 }
1971}
1972
1973static int msm_dai_q6_cdc_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1974{
1975 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
1976
1977 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1978 case SND_SOC_DAIFMT_CBS_CFS:
1979 dai_data->port_config.i2s.ws_src = 1; /* CPU is master */
1980 break;
1981 case SND_SOC_DAIFMT_CBM_CFM:
1982 dai_data->port_config.i2s.ws_src = 0; /* CPU is slave */
1983 break;
1984 default:
1985 pr_err("%s: fmt 0x%x\n",
1986 __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
1987 return -EINVAL;
1988 }
1989
1990 return 0;
1991}
1992
1993static int msm_dai_q6_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1994{
1995 int rc = 0;
1996
1997 dev_dbg(dai->dev, "%s: id = %d fmt[%d]\n", __func__,
1998 dai->id, fmt);
1999 switch (dai->id) {
2000 case PRIMARY_I2S_TX:
2001 case PRIMARY_I2S_RX:
2002 case MI2S_RX:
2003 case SECONDARY_I2S_RX:
2004 rc = msm_dai_q6_cdc_set_fmt(dai, fmt);
2005 break;
2006 default:
2007 dev_err(dai->dev, "invalid cpu_dai id 0x%x\n", dai->id);
2008 rc = -EINVAL;
2009 break;
2010 }
2011
2012 return rc;
2013}
2014
2015static int msm_dai_q6_set_channel_map(struct snd_soc_dai *dai,
2016 unsigned int tx_num, unsigned int *tx_slot,
2017 unsigned int rx_num, unsigned int *rx_slot)
2018
2019{
2020 int rc = 0;
2021 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
2022 unsigned int i = 0;
2023
2024 dev_dbg(dai->dev, "%s: id = %d\n", __func__, dai->id);
2025 switch (dai->id) {
2026 case SLIMBUS_0_RX:
2027 case SLIMBUS_1_RX:
2028 case SLIMBUS_2_RX:
2029 case SLIMBUS_3_RX:
2030 case SLIMBUS_4_RX:
2031 case SLIMBUS_5_RX:
2032 case SLIMBUS_6_RX:
2033 case SLIMBUS_7_RX:
2034 case SLIMBUS_8_RX:
2035 /*
2036 * channel number to be between 128 and 255.
2037 * For RX port use channel numbers
2038 * from 138 to 144 for pre-Taiko
2039 * from 144 to 159 for Taiko
2040 */
2041 if (!rx_slot) {
2042 pr_err("%s: rx slot not found\n", __func__);
2043 return -EINVAL;
2044 }
2045 if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
2046 pr_err("%s: invalid rx num %d\n", __func__, rx_num);
2047 return -EINVAL;
2048 }
2049
2050 for (i = 0; i < rx_num; i++) {
2051 dai_data->port_config.slim_sch.shared_ch_mapping[i] =
2052 rx_slot[i];
2053 pr_debug("%s: find number of channels[%d] ch[%d]\n",
2054 __func__, i, rx_slot[i]);
2055 }
2056 dai_data->port_config.slim_sch.num_channels = rx_num;
2057 pr_debug("%s: SLIMBUS_%d_RX cnt[%d] ch[%d %d]\n", __func__,
2058 (dai->id - SLIMBUS_0_RX) / 2, rx_num,
2059 dai_data->port_config.slim_sch.shared_ch_mapping[0],
2060 dai_data->port_config.slim_sch.shared_ch_mapping[1]);
2061
2062 break;
2063 case SLIMBUS_0_TX:
2064 case SLIMBUS_1_TX:
2065 case SLIMBUS_2_TX:
2066 case SLIMBUS_3_TX:
2067 case SLIMBUS_4_TX:
2068 case SLIMBUS_5_TX:
2069 case SLIMBUS_6_TX:
2070 case SLIMBUS_7_TX:
2071 case SLIMBUS_8_TX:
2072 /*
2073 * channel number to be between 128 and 255.
2074 * For TX port use channel numbers
2075 * from 128 to 137 for pre-Taiko
2076 * from 128 to 143 for Taiko
2077 */
2078 if (!tx_slot) {
2079 pr_err("%s: tx slot not found\n", __func__);
2080 return -EINVAL;
2081 }
2082 if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
2083 pr_err("%s: invalid tx num %d\n", __func__, tx_num);
2084 return -EINVAL;
2085 }
2086
2087 for (i = 0; i < tx_num; i++) {
2088 dai_data->port_config.slim_sch.shared_ch_mapping[i] =
2089 tx_slot[i];
2090 pr_debug("%s: find number of channels[%d] ch[%d]\n",
2091 __func__, i, tx_slot[i]);
2092 }
2093 dai_data->port_config.slim_sch.num_channels = tx_num;
2094 pr_debug("%s:SLIMBUS_%d_TX cnt[%d] ch[%d %d]\n", __func__,
2095 (dai->id - SLIMBUS_0_TX) / 2, tx_num,
2096 dai_data->port_config.slim_sch.shared_ch_mapping[0],
2097 dai_data->port_config.slim_sch.shared_ch_mapping[1]);
2098 break;
2099 default:
2100 dev_err(dai->dev, "invalid cpu_dai id 0x%x\n", dai->id);
2101 rc = -EINVAL;
2102 break;
2103 }
2104 return rc;
2105}
2106
2107static struct snd_soc_dai_ops msm_dai_q6_ops = {
2108 .prepare = msm_dai_q6_prepare,
2109 .hw_params = msm_dai_q6_hw_params,
2110 .shutdown = msm_dai_q6_shutdown,
2111 .set_fmt = msm_dai_q6_set_fmt,
2112 .set_channel_map = msm_dai_q6_set_channel_map,
2113};
2114
2115/*
2116 * For single CPU DAI registration, the dai id needs to be
2117 * set explicitly in the dai probe as ASoC does not read
2118 * the cpu->driver->id field rather it assigns the dai id
2119 * from the device name that is in the form %s.%d. This dai
2120 * id should be assigned to back-end AFE port id and used
2121 * during dai prepare. For multiple dai registration, it
2122 * is not required to call this function, however the dai->
2123 * driver->id field must be defined and set to corresponding
2124 * AFE Port id.
2125 */
2126static inline void msm_dai_q6_set_dai_id(struct snd_soc_dai *dai)
2127{
2128 if (!dai->driver->id) {
2129 dev_warn(dai->dev, "DAI driver id is not set\n");
2130 return;
2131 }
2132 dai->id = dai->driver->id;
2133}
2134
2135static int msm_dai_q6_cal_info_put(struct snd_kcontrol *kcontrol,
2136 struct snd_ctl_elem_value *ucontrol)
2137{
2138 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2139 u16 port_id = ((struct soc_enum *)
2140 kcontrol->private_value)->reg;
2141
2142 dai_data->cal_mode = ucontrol->value.integer.value[0];
2143 pr_debug("%s: setting cal_mode to %d\n",
2144 __func__, dai_data->cal_mode);
2145 afe_set_cal_mode(port_id, dai_data->cal_mode);
2146
2147 return 0;
2148}
2149
2150static int msm_dai_q6_cal_info_get(struct snd_kcontrol *kcontrol,
2151 struct snd_ctl_elem_value *ucontrol)
2152{
2153 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2154
2155 ucontrol->value.integer.value[0] = dai_data->cal_mode;
2156 return 0;
2157}
2158
2159static int msm_dai_q6_sb_format_put(struct snd_kcontrol *kcontrol,
2160 struct snd_ctl_elem_value *ucontrol)
2161{
2162 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2163 int value = ucontrol->value.integer.value[0];
2164
2165 if (dai_data) {
2166 dai_data->port_config.slim_sch.data_format = value;
2167 pr_debug("%s: format = %d\n", __func__, value);
2168 }
2169
2170 return 0;
2171}
2172
2173static int msm_dai_q6_sb_format_get(struct snd_kcontrol *kcontrol,
2174 struct snd_ctl_elem_value *ucontrol)
2175{
2176 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2177
2178 if (dai_data)
2179 ucontrol->value.integer.value[0] =
2180 dai_data->port_config.slim_sch.data_format;
2181
2182 return 0;
2183}
2184
2185static int msm_dai_q6_usb_audio_cfg_put(struct snd_kcontrol *kcontrol,
2186 struct snd_ctl_elem_value *ucontrol)
2187{
2188 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2189 u32 val = ucontrol->value.integer.value[0];
2190
2191 if (dai_data) {
2192 dai_data->port_config.usb_audio.dev_token = val;
2193 pr_debug("%s: dev_token = 0x%x\n", __func__,
2194 dai_data->port_config.usb_audio.dev_token);
2195 } else {
2196 pr_err("%s: dai_data is NULL\n", __func__);
2197 }
2198
2199 return 0;
2200}
2201
2202static int msm_dai_q6_usb_audio_cfg_get(struct snd_kcontrol *kcontrol,
2203 struct snd_ctl_elem_value *ucontrol)
2204{
2205 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2206
2207 if (dai_data) {
2208 ucontrol->value.integer.value[0] =
2209 dai_data->port_config.usb_audio.dev_token;
2210 pr_debug("%s: dev_token = 0x%x\n", __func__,
2211 dai_data->port_config.usb_audio.dev_token);
2212 } else {
2213 pr_err("%s: dai_data is NULL\n", __func__);
2214 }
2215
2216 return 0;
2217}
2218
2219static int msm_dai_q6_usb_audio_endian_cfg_put(struct snd_kcontrol *kcontrol,
2220 struct snd_ctl_elem_value *ucontrol)
2221{
2222 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2223 u32 val = ucontrol->value.integer.value[0];
2224
2225 if (dai_data) {
2226 dai_data->port_config.usb_audio.endian = val;
2227 pr_debug("%s: endian = 0x%x\n", __func__,
2228 dai_data->port_config.usb_audio.endian);
2229 } else {
2230 pr_err("%s: dai_data is NULL\n", __func__);
2231 return -EINVAL;
2232 }
2233
2234 return 0;
2235}
2236
2237static int msm_dai_q6_usb_audio_endian_cfg_get(struct snd_kcontrol *kcontrol,
2238 struct snd_ctl_elem_value *ucontrol)
2239{
2240 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2241
2242 if (dai_data) {
2243 ucontrol->value.integer.value[0] =
2244 dai_data->port_config.usb_audio.endian;
2245 pr_debug("%s: endian = 0x%x\n", __func__,
2246 dai_data->port_config.usb_audio.endian);
2247 } else {
2248 pr_err("%s: dai_data is NULL\n", __func__);
2249 return -EINVAL;
2250 }
2251
2252 return 0;
2253}
2254
Haynes Mathew George7ed9b512018-02-28 18:18:09 -08002255static int msm_dai_q6_usb_audio_svc_interval_put(struct snd_kcontrol *kcontrol,
2256 struct snd_ctl_elem_value *ucontrol)
2257{
2258 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2259 u32 val = ucontrol->value.integer.value[0];
2260
2261 if (!dai_data) {
2262 pr_err("%s: dai_data is NULL\n", __func__);
2263 return -EINVAL;
2264 }
2265 dai_data->port_config.usb_audio.service_interval = val;
2266 pr_debug("%s: new service interval = %u\n", __func__,
2267 dai_data->port_config.usb_audio.service_interval);
2268 return 0;
2269}
2270
2271static int msm_dai_q6_usb_audio_svc_interval_get(struct snd_kcontrol *kcontrol,
2272 struct snd_ctl_elem_value *ucontrol)
2273{
2274 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2275
2276 if (!dai_data) {
2277 pr_err("%s: dai_data is NULL\n", __func__);
2278 return -EINVAL;
2279 }
2280 ucontrol->value.integer.value[0] =
2281 dai_data->port_config.usb_audio.service_interval;
2282 pr_debug("%s: service interval = %d\n", __func__,
2283 dai_data->port_config.usb_audio.service_interval);
2284 return 0;
2285}
2286
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302287static int msm_dai_q6_afe_enc_cfg_info(struct snd_kcontrol *kcontrol,
2288 struct snd_ctl_elem_info *uinfo)
2289{
2290 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
2291 uinfo->count = sizeof(struct afe_enc_config);
2292
2293 return 0;
2294}
2295
2296static int msm_dai_q6_afe_enc_cfg_get(struct snd_kcontrol *kcontrol,
2297 struct snd_ctl_elem_value *ucontrol)
2298{
2299 int ret = 0;
2300 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2301
2302 if (dai_data) {
2303 int format_size = sizeof(dai_data->enc_config.format);
2304
Aniket Kumar Lataf8664712018-02-22 14:46:09 -08002305 pr_debug("%s: encoder config for %d format\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302306 __func__, dai_data->enc_config.format);
2307 memcpy(ucontrol->value.bytes.data,
2308 &dai_data->enc_config.format,
2309 format_size);
2310 switch (dai_data->enc_config.format) {
2311 case ENC_FMT_SBC:
2312 memcpy(ucontrol->value.bytes.data + format_size,
2313 &dai_data->enc_config.data,
2314 sizeof(struct asm_sbc_enc_cfg_t));
2315 break;
2316 case ENC_FMT_AAC_V2:
2317 memcpy(ucontrol->value.bytes.data + format_size,
2318 &dai_data->enc_config.data,
2319 sizeof(struct asm_aac_enc_cfg_v2_t));
2320 break;
2321 case ENC_FMT_APTX:
Preetam Singh Ranawat899b78b2017-09-07 12:36:06 -07002322 memcpy(ucontrol->value.bytes.data + format_size,
2323 &dai_data->enc_config.data,
2324 sizeof(struct asm_aptx_enc_cfg_t));
2325 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302326 case ENC_FMT_APTX_HD:
2327 memcpy(ucontrol->value.bytes.data + format_size,
2328 &dai_data->enc_config.data,
Preetam Singh Ranawat54028492017-09-04 11:42:26 +05302329 sizeof(struct asm_custom_enc_cfg_t));
2330 break;
2331 case ENC_FMT_CELT:
2332 memcpy(ucontrol->value.bytes.data + format_size,
2333 &dai_data->enc_config.data,
2334 sizeof(struct asm_celt_enc_cfg_t));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302335 break;
Preetam Singh Ranawat0a087af2017-10-25 15:02:28 +05302336 case ENC_FMT_LDAC:
2337 memcpy(ucontrol->value.bytes.data + format_size,
2338 &dai_data->enc_config.data,
2339 sizeof(struct asm_ldac_enc_cfg_t));
2340 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302341 default:
2342 pr_debug("%s: unknown format = %d\n",
2343 __func__, dai_data->enc_config.format);
2344 ret = -EINVAL;
2345 break;
2346 }
2347 }
2348
2349 return ret;
2350}
2351
2352static int msm_dai_q6_afe_enc_cfg_put(struct snd_kcontrol *kcontrol,
2353 struct snd_ctl_elem_value *ucontrol)
2354{
2355 int ret = 0;
2356 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2357
2358 if (dai_data) {
2359 int format_size = sizeof(dai_data->enc_config.format);
2360
2361 memset(&dai_data->enc_config, 0x0,
2362 sizeof(struct afe_enc_config));
2363 memcpy(&dai_data->enc_config.format,
2364 ucontrol->value.bytes.data,
2365 format_size);
2366 pr_debug("%s: Received encoder config for %d format\n",
2367 __func__, dai_data->enc_config.format);
2368 switch (dai_data->enc_config.format) {
2369 case ENC_FMT_SBC:
2370 memcpy(&dai_data->enc_config.data,
2371 ucontrol->value.bytes.data + format_size,
2372 sizeof(struct asm_sbc_enc_cfg_t));
2373 break;
2374 case ENC_FMT_AAC_V2:
2375 memcpy(&dai_data->enc_config.data,
2376 ucontrol->value.bytes.data + format_size,
2377 sizeof(struct asm_aac_enc_cfg_v2_t));
2378 break;
2379 case ENC_FMT_APTX:
Preetam Singh Ranawat899b78b2017-09-07 12:36:06 -07002380 memcpy(&dai_data->enc_config.data,
2381 ucontrol->value.bytes.data + format_size,
2382 sizeof(struct asm_aptx_enc_cfg_t));
2383 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302384 case ENC_FMT_APTX_HD:
2385 memcpy(&dai_data->enc_config.data,
2386 ucontrol->value.bytes.data + format_size,
Preetam Singh Ranawat54028492017-09-04 11:42:26 +05302387 sizeof(struct asm_custom_enc_cfg_t));
2388 break;
2389 case ENC_FMT_CELT:
2390 memcpy(&dai_data->enc_config.data,
2391 ucontrol->value.bytes.data + format_size,
2392 sizeof(struct asm_celt_enc_cfg_t));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302393 break;
Preetam Singh Ranawat0a087af2017-10-25 15:02:28 +05302394 case ENC_FMT_LDAC:
2395 memcpy(&dai_data->enc_config.data,
2396 ucontrol->value.bytes.data + format_size,
2397 sizeof(struct asm_ldac_enc_cfg_t));
2398 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302399 default:
2400 pr_debug("%s: Ignore enc config for unknown format = %d\n",
2401 __func__, dai_data->enc_config.format);
2402 ret = -EINVAL;
2403 break;
2404 }
2405 } else
2406 ret = -EINVAL;
2407
2408 return ret;
2409}
2410
2411static const char *const afe_input_chs_text[] = {"Zero", "One", "Two"};
2412
2413static const struct soc_enum afe_input_chs_enum[] = {
2414 SOC_ENUM_SINGLE_EXT(3, afe_input_chs_text),
2415};
2416
Aniket Kumar Lataf8664712018-02-22 14:46:09 -08002417static const char *const afe_input_bit_format_text[] = {"S16_LE", "S24_LE",
2418 "S32_LE"};
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302419
2420static const struct soc_enum afe_input_bit_format_enum[] = {
Aniket Kumar Lataf8664712018-02-22 14:46:09 -08002421 SOC_ENUM_SINGLE_EXT(3, afe_input_bit_format_text),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302422};
2423
Manisha Agarwal472fc1e2018-11-04 15:46:02 +05302424static const char *const tws_chs_mode_text[] = {"Zero", "One", "Two"};
2425
2426static const struct soc_enum tws_chs_mode_enum[] = {
2427 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tws_chs_mode_text), tws_chs_mode_text),
2428};
2429
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302430static int msm_dai_q6_afe_input_channel_get(struct snd_kcontrol *kcontrol,
2431 struct snd_ctl_elem_value *ucontrol)
2432{
2433 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2434
2435 if (dai_data) {
2436 ucontrol->value.integer.value[0] = dai_data->afe_in_channels;
2437 pr_debug("%s:afe input channel = %d\n",
2438 __func__, dai_data->afe_in_channels);
2439 }
2440
2441 return 0;
2442}
2443
2444static int msm_dai_q6_afe_input_channel_put(struct snd_kcontrol *kcontrol,
2445 struct snd_ctl_elem_value *ucontrol)
2446{
2447 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2448
2449 if (dai_data) {
2450 dai_data->afe_in_channels = ucontrol->value.integer.value[0];
2451 pr_debug("%s: updating afe input channel : %d\n",
2452 __func__, dai_data->afe_in_channels);
2453 }
2454
2455 return 0;
2456}
2457
Manisha Agarwal472fc1e2018-11-04 15:46:02 +05302458static int msm_dai_q6_tws_channel_mode_get(struct snd_kcontrol *kcontrol,
2459 struct snd_ctl_elem_value *ucontrol)
2460{
2461 struct snd_soc_dai *dai = kcontrol->private_data;
2462 struct msm_dai_q6_dai_data *dai_data = NULL;
2463
2464 if (dai)
2465 dai_data = dev_get_drvdata(dai->dev);
2466
2467 if (dai_data) {
2468 ucontrol->value.integer.value[0] =
2469 dai_data->enc_config.mono_mode;
2470 pr_debug("%s:tws channel mode = %d\n",
2471 __func__, dai_data->enc_config.mono_mode);
2472 }
2473
2474 return 0;
2475}
2476
2477static int msm_dai_q6_tws_channel_mode_put(struct snd_kcontrol *kcontrol,
2478 struct snd_ctl_elem_value *ucontrol)
2479{
2480 struct snd_soc_dai *dai = kcontrol->private_data;
2481 struct msm_dai_q6_dai_data *dai_data = NULL;
2482 int ret = 0;
2483
2484 if (dai)
2485 dai_data = dev_get_drvdata(dai->dev);
2486
2487 if (dai_data && (dai_data->enc_config.format == ENC_FMT_APTX)) {
2488 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
2489 ret = afe_set_tws_channel_mode(dai->id,
2490 ucontrol->value.integer.value[0]);
2491 if (ret < 0) {
2492 pr_err("%s: channel mode setting failed for TWS\n",
2493 __func__);
2494 goto exit;
2495 } else {
2496 pr_debug("%s: updating tws channel mode : %d\n",
2497 __func__, dai_data->enc_config.mono_mode);
2498 }
2499 }
2500 if (ucontrol->value.integer.value[0] ==
2501 MSM_DAI_TWS_CHANNEL_MODE_ONE ||
2502 ucontrol->value.integer.value[0] ==
2503 MSM_DAI_TWS_CHANNEL_MODE_TWO)
2504 dai_data->enc_config.mono_mode =
2505 ucontrol->value.integer.value[0];
2506 else
2507 return -EINVAL;
2508 }
2509exit:
2510 return ret;
2511}
2512
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302513static int msm_dai_q6_afe_input_bit_format_get(
2514 struct snd_kcontrol *kcontrol,
2515 struct snd_ctl_elem_value *ucontrol)
2516{
2517 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2518
2519 if (!dai_data) {
2520 pr_err("%s: Invalid dai data\n", __func__);
2521 return -EINVAL;
2522 }
2523
2524 switch (dai_data->afe_in_bitformat) {
Aniket Kumar Lataf8664712018-02-22 14:46:09 -08002525 case SNDRV_PCM_FORMAT_S32_LE:
2526 ucontrol->value.integer.value[0] = 2;
2527 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302528 case SNDRV_PCM_FORMAT_S24_LE:
2529 ucontrol->value.integer.value[0] = 1;
2530 break;
2531 case SNDRV_PCM_FORMAT_S16_LE:
2532 default:
2533 ucontrol->value.integer.value[0] = 0;
2534 break;
2535 }
2536 pr_debug("%s: afe input bit format : %ld\n",
2537 __func__, ucontrol->value.integer.value[0]);
2538
2539 return 0;
2540}
2541
2542static int msm_dai_q6_afe_input_bit_format_put(
2543 struct snd_kcontrol *kcontrol,
2544 struct snd_ctl_elem_value *ucontrol)
2545{
2546 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2547
2548 if (!dai_data) {
2549 pr_err("%s: Invalid dai data\n", __func__);
2550 return -EINVAL;
2551 }
2552 switch (ucontrol->value.integer.value[0]) {
Aniket Kumar Lataf8664712018-02-22 14:46:09 -08002553 case 2:
2554 dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S32_LE;
2555 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302556 case 1:
2557 dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S24_LE;
2558 break;
2559 case 0:
2560 default:
2561 dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S16_LE;
2562 break;
2563 }
2564 pr_debug("%s: updating afe input bit format : %d\n",
2565 __func__, dai_data->afe_in_bitformat);
2566
2567 return 0;
2568}
2569
Preetam Singh Ranawatf746a872017-10-20 18:13:14 +05302570static int msm_dai_q6_afe_scrambler_mode_get(
2571 struct snd_kcontrol *kcontrol,
2572 struct snd_ctl_elem_value *ucontrol)
2573{
2574 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2575
2576 if (!dai_data) {
2577 pr_err("%s: Invalid dai data\n", __func__);
2578 return -EINVAL;
2579 }
2580 ucontrol->value.integer.value[0] = dai_data->enc_config.scrambler_mode;
2581
2582 return 0;
2583}
2584
2585static int msm_dai_q6_afe_scrambler_mode_put(
2586 struct snd_kcontrol *kcontrol,
2587 struct snd_ctl_elem_value *ucontrol)
2588{
2589 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2590
2591 if (!dai_data) {
2592 pr_err("%s: Invalid dai data\n", __func__);
2593 return -EINVAL;
2594 }
2595 dai_data->enc_config.scrambler_mode = ucontrol->value.integer.value[0];
2596 pr_debug("%s: afe scrambler mode : %d\n",
2597 __func__, dai_data->enc_config.scrambler_mode);
2598 return 0;
2599}
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302600
2601static const struct snd_kcontrol_new afe_enc_config_controls[] = {
2602 {
2603 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
2604 SNDRV_CTL_ELEM_ACCESS_INACTIVE),
2605 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2606 .name = "SLIM_7_RX Encoder Config",
2607 .info = msm_dai_q6_afe_enc_cfg_info,
2608 .get = msm_dai_q6_afe_enc_cfg_get,
2609 .put = msm_dai_q6_afe_enc_cfg_put,
2610 },
2611 SOC_ENUM_EXT("AFE Input Channels", afe_input_chs_enum[0],
2612 msm_dai_q6_afe_input_channel_get,
2613 msm_dai_q6_afe_input_channel_put),
2614 SOC_ENUM_EXT("AFE Input Bit Format", afe_input_bit_format_enum[0],
2615 msm_dai_q6_afe_input_bit_format_get,
2616 msm_dai_q6_afe_input_bit_format_put),
Preetam Singh Ranawatf746a872017-10-20 18:13:14 +05302617 SOC_SINGLE_EXT("AFE Scrambler Mode",
2618 0, 0, 1, 0,
2619 msm_dai_q6_afe_scrambler_mode_get,
2620 msm_dai_q6_afe_scrambler_mode_put),
Manisha Agarwal472fc1e2018-11-04 15:46:02 +05302621 SOC_ENUM_EXT("TWS Channel Mode", tws_chs_mode_enum[0],
2622 msm_dai_q6_tws_channel_mode_get,
2623 msm_dai_q6_tws_channel_mode_put)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302624};
2625
Aniket Kumar Lataf8664712018-02-22 14:46:09 -08002626static int msm_dai_q6_afe_dec_cfg_info(struct snd_kcontrol *kcontrol,
2627 struct snd_ctl_elem_info *uinfo)
2628{
2629 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
2630 uinfo->count = sizeof(struct afe_dec_config);
2631
2632 return 0;
2633}
2634
2635static int msm_dai_q6_afe_dec_cfg_get(struct snd_kcontrol *kcontrol,
2636 struct snd_ctl_elem_value *ucontrol)
2637{
2638 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2639 int format_size = 0;
2640
2641 if (!dai_data) {
2642 pr_err("%s: Invalid dai data\n", __func__);
2643 return -EINVAL;
2644 }
2645
2646 format_size = sizeof(dai_data->dec_config.format);
2647 memcpy(ucontrol->value.bytes.data,
2648 &dai_data->dec_config.format,
2649 format_size);
2650 memcpy(ucontrol->value.bytes.data + format_size,
2651 &dai_data->dec_config.abr_dec_cfg,
2652 sizeof(struct afe_abr_dec_cfg_t));
2653
2654 return 0;
2655}
2656
2657static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol,
2658 struct snd_ctl_elem_value *ucontrol)
2659{
2660 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
2661 int format_size = 0;
2662
2663 if (!dai_data) {
2664 pr_err("%s: Invalid dai data\n", __func__);
2665 return -EINVAL;
2666 }
2667
2668 memset(&dai_data->dec_config, 0x0,
2669 sizeof(struct afe_dec_config));
2670 format_size = sizeof(dai_data->dec_config.format);
2671 memcpy(&dai_data->dec_config.format,
2672 ucontrol->value.bytes.data,
2673 format_size);
2674 memcpy(&dai_data->dec_config.abr_dec_cfg,
2675 ucontrol->value.bytes.data + format_size,
2676 sizeof(struct afe_abr_dec_cfg_t));
2677
2678 return 0;
2679}
2680
2681static const struct snd_kcontrol_new afe_dec_config_controls[] = {
2682 {
2683 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
2684 SNDRV_CTL_ELEM_ACCESS_INACTIVE),
2685 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2686 .name = "SLIM_7_TX Decoder Config",
2687 .info = msm_dai_q6_afe_dec_cfg_info,
2688 .get = msm_dai_q6_afe_dec_cfg_get,
2689 .put = msm_dai_q6_afe_dec_cfg_put,
2690 },
2691};
2692
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302693static int msm_dai_q6_slim_rx_drift_info(struct snd_kcontrol *kcontrol,
2694 struct snd_ctl_elem_info *uinfo)
2695{
2696 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
2697 uinfo->count = sizeof(struct afe_param_id_dev_timing_stats);
2698
2699 return 0;
2700}
2701
2702static int msm_dai_q6_slim_rx_drift_get(struct snd_kcontrol *kcontrol,
2703 struct snd_ctl_elem_value *ucontrol)
2704{
2705 int ret = -EINVAL;
2706 struct afe_param_id_dev_timing_stats timing_stats;
2707 struct snd_soc_dai *dai = kcontrol->private_data;
2708 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
2709
2710 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
2711 pr_err("%s: afe port not started. dai_data->status_mask = %ld\n",
2712 __func__, *dai_data->status_mask);
2713 goto done;
2714 }
2715
2716 memset(&timing_stats, 0, sizeof(struct afe_param_id_dev_timing_stats));
2717 ret = afe_get_av_dev_drift(&timing_stats, dai->id);
2718 if (ret) {
2719 pr_err("%s: Error getting AFE Drift for port %d, err=%d\n",
2720 __func__, dai->id, ret);
2721
2722 goto done;
2723 }
2724
2725 memcpy(ucontrol->value.bytes.data, (void *)&timing_stats,
2726 sizeof(struct afe_param_id_dev_timing_stats));
2727done:
2728 return ret;
2729}
2730
2731static const char * const afe_cal_mode_text[] = {
2732 "CAL_MODE_DEFAULT", "CAL_MODE_NONE"
2733};
2734
2735static const struct soc_enum slim_2_rx_enum =
2736 SOC_ENUM_SINGLE(SLIMBUS_2_RX, 0, ARRAY_SIZE(afe_cal_mode_text),
2737 afe_cal_mode_text);
2738
2739static const struct soc_enum rt_proxy_1_rx_enum =
2740 SOC_ENUM_SINGLE(RT_PROXY_PORT_001_RX, 0, ARRAY_SIZE(afe_cal_mode_text),
2741 afe_cal_mode_text);
2742
2743static const struct soc_enum rt_proxy_1_tx_enum =
2744 SOC_ENUM_SINGLE(RT_PROXY_PORT_001_TX, 0, ARRAY_SIZE(afe_cal_mode_text),
2745 afe_cal_mode_text);
2746
2747static const struct snd_kcontrol_new sb_config_controls[] = {
2748 SOC_ENUM_EXT("SLIM_4_TX Format", sb_config_enum[0],
2749 msm_dai_q6_sb_format_get,
2750 msm_dai_q6_sb_format_put),
2751 SOC_ENUM_EXT("SLIM_2_RX SetCalMode", slim_2_rx_enum,
2752 msm_dai_q6_cal_info_get,
2753 msm_dai_q6_cal_info_put),
2754 SOC_ENUM_EXT("SLIM_2_RX Format", sb_config_enum[0],
2755 msm_dai_q6_sb_format_get,
2756 msm_dai_q6_sb_format_put)
2757};
2758
2759static const struct snd_kcontrol_new rt_proxy_config_controls[] = {
2760 SOC_ENUM_EXT("RT_PROXY_1_RX SetCalMode", rt_proxy_1_rx_enum,
2761 msm_dai_q6_cal_info_get,
2762 msm_dai_q6_cal_info_put),
2763 SOC_ENUM_EXT("RT_PROXY_1_TX SetCalMode", rt_proxy_1_tx_enum,
2764 msm_dai_q6_cal_info_get,
2765 msm_dai_q6_cal_info_put),
2766};
2767
2768static const struct snd_kcontrol_new usb_audio_cfg_controls[] = {
2769 SOC_SINGLE_EXT("USB_AUDIO_RX dev_token", 0, 0, UINT_MAX, 0,
2770 msm_dai_q6_usb_audio_cfg_get,
2771 msm_dai_q6_usb_audio_cfg_put),
2772 SOC_SINGLE_EXT("USB_AUDIO_RX endian", 0, 0, 1, 0,
2773 msm_dai_q6_usb_audio_endian_cfg_get,
2774 msm_dai_q6_usb_audio_endian_cfg_put),
2775 SOC_SINGLE_EXT("USB_AUDIO_TX dev_token", 0, 0, UINT_MAX, 0,
2776 msm_dai_q6_usb_audio_cfg_get,
2777 msm_dai_q6_usb_audio_cfg_put),
2778 SOC_SINGLE_EXT("USB_AUDIO_TX endian", 0, 0, 1, 0,
2779 msm_dai_q6_usb_audio_endian_cfg_get,
2780 msm_dai_q6_usb_audio_endian_cfg_put),
Haynes Mathew George7ed9b512018-02-28 18:18:09 -08002781 SOC_SINGLE_EXT("USB_AUDIO_RX service_interval", SND_SOC_NOPM, 0,
2782 UINT_MAX, 0,
2783 msm_dai_q6_usb_audio_svc_interval_get,
2784 msm_dai_q6_usb_audio_svc_interval_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302785};
2786
2787static const struct snd_kcontrol_new avd_drift_config_controls[] = {
2788 {
2789 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2790 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2791 .name = "SLIMBUS_0_RX DRIFT",
2792 .info = msm_dai_q6_slim_rx_drift_info,
2793 .get = msm_dai_q6_slim_rx_drift_get,
2794 },
2795 {
2796 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2797 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2798 .name = "SLIMBUS_6_RX DRIFT",
2799 .info = msm_dai_q6_slim_rx_drift_info,
2800 .get = msm_dai_q6_slim_rx_drift_get,
2801 },
2802 {
2803 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2804 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2805 .name = "SLIMBUS_7_RX DRIFT",
2806 .info = msm_dai_q6_slim_rx_drift_info,
2807 .get = msm_dai_q6_slim_rx_drift_get,
2808 },
2809};
2810static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai)
2811{
2812 struct msm_dai_q6_dai_data *dai_data;
2813 int rc = 0;
2814
2815 if (!dai) {
2816 pr_err("%s: Invalid params dai\n", __func__);
2817 return -EINVAL;
2818 }
2819 if (!dai->dev) {
2820 pr_err("%s: Invalid params dai dev\n", __func__);
2821 return -EINVAL;
2822 }
2823
2824 dai_data = kzalloc(sizeof(struct msm_dai_q6_dai_data), GFP_KERNEL);
2825
2826 if (!dai_data)
2827 rc = -ENOMEM;
2828 else
2829 dev_set_drvdata(dai->dev, dai_data);
2830
2831 msm_dai_q6_set_dai_id(dai);
2832
2833 switch (dai->id) {
2834 case SLIMBUS_4_TX:
2835 rc = snd_ctl_add(dai->component->card->snd_card,
2836 snd_ctl_new1(&sb_config_controls[0],
2837 dai_data));
2838 break;
2839 case SLIMBUS_2_RX:
2840 rc = snd_ctl_add(dai->component->card->snd_card,
2841 snd_ctl_new1(&sb_config_controls[1],
2842 dai_data));
2843 rc = snd_ctl_add(dai->component->card->snd_card,
2844 snd_ctl_new1(&sb_config_controls[2],
2845 dai_data));
2846 break;
2847 case SLIMBUS_7_RX:
2848 rc = snd_ctl_add(dai->component->card->snd_card,
2849 snd_ctl_new1(&afe_enc_config_controls[0],
2850 dai_data));
2851 rc = snd_ctl_add(dai->component->card->snd_card,
2852 snd_ctl_new1(&afe_enc_config_controls[1],
2853 dai_data));
2854 rc = snd_ctl_add(dai->component->card->snd_card,
2855 snd_ctl_new1(&afe_enc_config_controls[2],
2856 dai_data));
2857 rc = snd_ctl_add(dai->component->card->snd_card,
Preetam Singh Ranawatf746a872017-10-20 18:13:14 +05302858 snd_ctl_new1(&afe_enc_config_controls[3],
2859 dai_data));
2860 rc = snd_ctl_add(dai->component->card->snd_card,
Manisha Agarwal472fc1e2018-11-04 15:46:02 +05302861 snd_ctl_new1(&afe_enc_config_controls[4],
2862 dai));
2863 rc = snd_ctl_add(dai->component->card->snd_card,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302864 snd_ctl_new1(&avd_drift_config_controls[2],
2865 dai));
2866 break;
Aniket Kumar Lataf8664712018-02-22 14:46:09 -08002867 case SLIMBUS_7_TX:
2868 rc = snd_ctl_add(dai->component->card->snd_card,
2869 snd_ctl_new1(&afe_dec_config_controls[0],
2870 dai_data));
2871 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302872 case RT_PROXY_DAI_001_RX:
2873 rc = snd_ctl_add(dai->component->card->snd_card,
2874 snd_ctl_new1(&rt_proxy_config_controls[0],
2875 dai_data));
2876 break;
2877 case RT_PROXY_DAI_001_TX:
2878 rc = snd_ctl_add(dai->component->card->snd_card,
2879 snd_ctl_new1(&rt_proxy_config_controls[1],
2880 dai_data));
2881 break;
2882 case AFE_PORT_ID_USB_RX:
2883 rc = snd_ctl_add(dai->component->card->snd_card,
2884 snd_ctl_new1(&usb_audio_cfg_controls[0],
2885 dai_data));
2886 rc = snd_ctl_add(dai->component->card->snd_card,
2887 snd_ctl_new1(&usb_audio_cfg_controls[1],
2888 dai_data));
Haynes Mathew George7ed9b512018-02-28 18:18:09 -08002889 rc = snd_ctl_add(dai->component->card->snd_card,
2890 snd_ctl_new1(&usb_audio_cfg_controls[4],
2891 dai_data));
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302892 break;
2893 case AFE_PORT_ID_USB_TX:
2894 rc = snd_ctl_add(dai->component->card->snd_card,
2895 snd_ctl_new1(&usb_audio_cfg_controls[2],
2896 dai_data));
2897 rc = snd_ctl_add(dai->component->card->snd_card,
2898 snd_ctl_new1(&usb_audio_cfg_controls[3],
2899 dai_data));
2900 break;
2901 case SLIMBUS_0_RX:
2902 rc = snd_ctl_add(dai->component->card->snd_card,
2903 snd_ctl_new1(&avd_drift_config_controls[0],
2904 dai));
2905 break;
2906 case SLIMBUS_6_RX:
2907 rc = snd_ctl_add(dai->component->card->snd_card,
2908 snd_ctl_new1(&avd_drift_config_controls[1],
2909 dai));
2910 break;
2911 }
2912 if (rc < 0)
2913 dev_err(dai->dev, "%s: err add config ctl, DAI = %s\n",
2914 __func__, dai->name);
2915
2916 rc = msm_dai_q6_dai_add_route(dai);
2917 return rc;
2918}
2919
2920static int msm_dai_q6_dai_remove(struct snd_soc_dai *dai)
2921{
2922 struct msm_dai_q6_dai_data *dai_data;
2923 int rc;
2924
2925 dai_data = dev_get_drvdata(dai->dev);
2926
2927 /* If AFE port is still up, close it */
2928 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
2929 pr_debug("%s: stop pseudo port:%d\n", __func__, dai->id);
2930 rc = afe_close(dai->id); /* can block */
2931 if (rc < 0)
2932 dev_err(dai->dev, "fail to close AFE port\n");
2933 clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
2934 }
2935 kfree(dai_data);
2936
2937 return 0;
2938}
2939
2940static struct snd_soc_dai_driver msm_dai_q6_afe_rx_dai[] = {
2941 {
2942 .playback = {
2943 .stream_name = "AFE Playback",
2944 .aif_name = "PCM_RX",
2945 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
2946 SNDRV_PCM_RATE_16000,
2947 .formats = SNDRV_PCM_FMTBIT_S16_LE |
2948 SNDRV_PCM_FMTBIT_S24_LE,
2949 .channels_min = 1,
2950 .channels_max = 2,
2951 .rate_min = 8000,
2952 .rate_max = 48000,
2953 },
2954 .ops = &msm_dai_q6_ops,
2955 .id = RT_PROXY_DAI_001_RX,
2956 .probe = msm_dai_q6_dai_probe,
2957 .remove = msm_dai_q6_dai_remove,
2958 },
2959 {
2960 .playback = {
2961 .stream_name = "AFE-PROXY RX",
2962 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
2963 SNDRV_PCM_RATE_16000,
2964 .formats = SNDRV_PCM_FMTBIT_S16_LE |
2965 SNDRV_PCM_FMTBIT_S24_LE,
2966 .channels_min = 1,
2967 .channels_max = 2,
2968 .rate_min = 8000,
2969 .rate_max = 48000,
2970 },
2971 .ops = &msm_dai_q6_ops,
2972 .id = RT_PROXY_DAI_002_RX,
2973 .probe = msm_dai_q6_dai_probe,
2974 .remove = msm_dai_q6_dai_remove,
2975 },
2976};
2977
Raja Mallik425e1d32018-05-20 19:21:10 +05302978static struct snd_soc_dai_driver msm_dai_q6_afe_lb_tx_dai[] = {
2979 {
2980 .capture = {
2981 .stream_name = "AFE Loopback Capture",
2982 .aif_name = "AFE_LOOPBACK_TX",
2983 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
2984 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
2985 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
2986 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
2987 SNDRV_PCM_RATE_192000,
2988 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
2989 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE |
2990 SNDRV_PCM_FMTBIT_S32_LE ),
2991 .channels_min = 1,
2992 .channels_max = 8,
2993 .rate_min = 8000,
2994 .rate_max = 192000,
2995 },
2996 .id = AFE_LOOPBACK_TX,
2997 .probe = msm_dai_q6_dai_probe,
2998 .remove = msm_dai_q6_dai_remove,
2999 },
3000};
3001
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303002static struct snd_soc_dai_driver msm_dai_q6_afe_tx_dai[] = {
3003 {
3004 .capture = {
3005 .stream_name = "AFE Capture",
3006 .aif_name = "PCM_TX",
3007 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
3008 SNDRV_PCM_RATE_16000,
3009 .formats = SNDRV_PCM_FMTBIT_S16_LE,
3010 .channels_min = 1,
3011 .channels_max = 8,
3012 .rate_min = 8000,
Raja Mallik425e1d32018-05-20 19:21:10 +05303013 .rate_max = 48000,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303014 },
3015 .ops = &msm_dai_q6_ops,
3016 .id = RT_PROXY_DAI_002_TX,
3017 .probe = msm_dai_q6_dai_probe,
3018 .remove = msm_dai_q6_dai_remove,
3019 },
3020 {
3021 .capture = {
3022 .stream_name = "AFE-PROXY TX",
3023 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
3024 SNDRV_PCM_RATE_16000,
3025 .formats = SNDRV_PCM_FMTBIT_S16_LE,
3026 .channels_min = 1,
3027 .channels_max = 8,
3028 .rate_min = 8000,
Raja Mallik425e1d32018-05-20 19:21:10 +05303029 .rate_max = 48000,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303030 },
3031 .ops = &msm_dai_q6_ops,
3032 .id = RT_PROXY_DAI_001_TX,
3033 .probe = msm_dai_q6_dai_probe,
3034 .remove = msm_dai_q6_dai_remove,
3035 },
3036};
3037
3038static struct snd_soc_dai_driver msm_dai_q6_bt_sco_rx_dai = {
3039 .playback = {
3040 .stream_name = "Internal BT-SCO Playback",
3041 .aif_name = "INT_BT_SCO_RX",
3042 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
3043 .formats = SNDRV_PCM_FMTBIT_S16_LE,
3044 .channels_min = 1,
3045 .channels_max = 1,
3046 .rate_max = 16000,
3047 .rate_min = 8000,
3048 },
3049 .ops = &msm_dai_q6_ops,
3050 .id = INT_BT_SCO_RX,
3051 .probe = msm_dai_q6_dai_probe,
3052 .remove = msm_dai_q6_dai_remove,
3053};
3054
3055static struct snd_soc_dai_driver msm_dai_q6_bt_a2dp_rx_dai = {
3056 .playback = {
3057 .stream_name = "Internal BT-A2DP Playback",
3058 .aif_name = "INT_BT_A2DP_RX",
3059 .rates = SNDRV_PCM_RATE_48000,
3060 .formats = SNDRV_PCM_FMTBIT_S16_LE,
3061 .channels_min = 1,
3062 .channels_max = 2,
3063 .rate_max = 48000,
3064 .rate_min = 48000,
3065 },
3066 .ops = &msm_dai_q6_ops,
3067 .id = INT_BT_A2DP_RX,
3068 .probe = msm_dai_q6_dai_probe,
3069 .remove = msm_dai_q6_dai_remove,
3070};
3071
3072static struct snd_soc_dai_driver msm_dai_q6_bt_sco_tx_dai = {
3073 .capture = {
3074 .stream_name = "Internal BT-SCO Capture",
3075 .aif_name = "INT_BT_SCO_TX",
3076 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
3077 .formats = SNDRV_PCM_FMTBIT_S16_LE,
3078 .channels_min = 1,
3079 .channels_max = 1,
3080 .rate_max = 16000,
3081 .rate_min = 8000,
3082 },
3083 .ops = &msm_dai_q6_ops,
3084 .id = INT_BT_SCO_TX,
3085 .probe = msm_dai_q6_dai_probe,
3086 .remove = msm_dai_q6_dai_remove,
3087};
3088
3089static struct snd_soc_dai_driver msm_dai_q6_fm_rx_dai = {
3090 .playback = {
3091 .stream_name = "Internal FM Playback",
3092 .aif_name = "INT_FM_RX",
3093 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
3094 SNDRV_PCM_RATE_16000,
3095 .formats = SNDRV_PCM_FMTBIT_S16_LE,
3096 .channels_min = 2,
3097 .channels_max = 2,
3098 .rate_max = 48000,
3099 .rate_min = 8000,
3100 },
3101 .ops = &msm_dai_q6_ops,
3102 .id = INT_FM_RX,
3103 .probe = msm_dai_q6_dai_probe,
3104 .remove = msm_dai_q6_dai_remove,
3105};
3106
3107static struct snd_soc_dai_driver msm_dai_q6_fm_tx_dai = {
3108 .capture = {
3109 .stream_name = "Internal FM Capture",
3110 .aif_name = "INT_FM_TX",
3111 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
3112 SNDRV_PCM_RATE_16000,
3113 .formats = SNDRV_PCM_FMTBIT_S16_LE,
3114 .channels_min = 2,
3115 .channels_max = 2,
3116 .rate_max = 48000,
3117 .rate_min = 8000,
3118 },
3119 .ops = &msm_dai_q6_ops,
3120 .id = INT_FM_TX,
3121 .probe = msm_dai_q6_dai_probe,
3122 .remove = msm_dai_q6_dai_remove,
3123};
3124
3125static struct snd_soc_dai_driver msm_dai_q6_voc_playback_dai[] = {
3126 {
3127 .playback = {
3128 .stream_name = "Voice Farend Playback",
3129 .aif_name = "VOICE_PLAYBACK_TX",
3130 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
3131 SNDRV_PCM_RATE_16000,
3132 .formats = SNDRV_PCM_FMTBIT_S16_LE,
3133 .channels_min = 1,
3134 .channels_max = 2,
3135 .rate_min = 8000,
3136 .rate_max = 48000,
3137 },
3138 .ops = &msm_dai_q6_ops,
3139 .id = VOICE_PLAYBACK_TX,
3140 .probe = msm_dai_q6_dai_probe,
3141 .remove = msm_dai_q6_dai_remove,
3142 },
3143 {
3144 .playback = {
3145 .stream_name = "Voice2 Farend Playback",
3146 .aif_name = "VOICE2_PLAYBACK_TX",
3147 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
3148 SNDRV_PCM_RATE_16000,
3149 .formats = SNDRV_PCM_FMTBIT_S16_LE,
3150 .channels_min = 1,
3151 .channels_max = 2,
3152 .rate_min = 8000,
3153 .rate_max = 48000,
3154 },
3155 .ops = &msm_dai_q6_ops,
3156 .id = VOICE2_PLAYBACK_TX,
3157 .probe = msm_dai_q6_dai_probe,
3158 .remove = msm_dai_q6_dai_remove,
3159 },
3160};
3161
3162static struct snd_soc_dai_driver msm_dai_q6_incall_record_dai[] = {
3163 {
3164 .capture = {
3165 .stream_name = "Voice Uplink Capture",
3166 .aif_name = "INCALL_RECORD_TX",
3167 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
3168 SNDRV_PCM_RATE_16000,
3169 .formats = SNDRV_PCM_FMTBIT_S16_LE,
3170 .channels_min = 1,
3171 .channels_max = 2,
3172 .rate_min = 8000,
3173 .rate_max = 48000,
3174 },
3175 .ops = &msm_dai_q6_ops,
3176 .id = VOICE_RECORD_TX,
3177 .probe = msm_dai_q6_dai_probe,
3178 .remove = msm_dai_q6_dai_remove,
3179 },
3180 {
3181 .capture = {
3182 .stream_name = "Voice Downlink Capture",
3183 .aif_name = "INCALL_RECORD_RX",
3184 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
3185 SNDRV_PCM_RATE_16000,
3186 .formats = SNDRV_PCM_FMTBIT_S16_LE,
3187 .channels_min = 1,
3188 .channels_max = 2,
3189 .rate_min = 8000,
3190 .rate_max = 48000,
3191 },
3192 .ops = &msm_dai_q6_ops,
3193 .id = VOICE_RECORD_RX,
3194 .probe = msm_dai_q6_dai_probe,
3195 .remove = msm_dai_q6_dai_remove,
3196 },
3197};
3198
3199static struct snd_soc_dai_driver msm_dai_q6_usb_rx_dai = {
3200 .playback = {
3201 .stream_name = "USB Audio Playback",
3202 .aif_name = "USB_AUDIO_RX",
3203 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
3204 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
3205 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
3206 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
3207 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
3208 SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 |
3209 SNDRV_PCM_RATE_384000,
3210 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
3211 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE,
3212 .channels_min = 1,
3213 .channels_max = 8,
3214 .rate_max = 384000,
3215 .rate_min = 8000,
3216 },
3217 .ops = &msm_dai_q6_ops,
3218 .id = AFE_PORT_ID_USB_RX,
3219 .probe = msm_dai_q6_dai_probe,
3220 .remove = msm_dai_q6_dai_remove,
3221};
3222
3223static struct snd_soc_dai_driver msm_dai_q6_usb_tx_dai = {
3224 .capture = {
3225 .stream_name = "USB Audio Capture",
3226 .aif_name = "USB_AUDIO_TX",
3227 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
3228 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
3229 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
3230 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
3231 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
3232 SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 |
3233 SNDRV_PCM_RATE_384000,
3234 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
3235 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE,
3236 .channels_min = 1,
3237 .channels_max = 8,
3238 .rate_max = 384000,
3239 .rate_min = 8000,
3240 },
3241 .ops = &msm_dai_q6_ops,
3242 .id = AFE_PORT_ID_USB_TX,
3243 .probe = msm_dai_q6_dai_probe,
3244 .remove = msm_dai_q6_dai_remove,
3245};
3246
3247static int msm_auxpcm_dev_probe(struct platform_device *pdev)
3248{
3249 struct msm_dai_q6_auxpcm_dai_data *dai_data;
3250 struct msm_dai_auxpcm_pdata *auxpcm_pdata;
3251 uint32_t val_array[RATE_MAX_NUM_OF_AUX_PCM_RATES];
3252 uint32_t val = 0;
3253 const char *intf_name;
3254 int rc = 0, i = 0, len = 0;
3255 const uint32_t *slot_mapping_array = NULL;
3256 u32 array_length = 0;
3257
3258 dai_data = kzalloc(sizeof(struct msm_dai_q6_auxpcm_dai_data),
3259 GFP_KERNEL);
3260 if (!dai_data)
3261 return -ENOMEM;
3262
3263 auxpcm_pdata = kzalloc(sizeof(struct msm_dai_auxpcm_pdata),
3264 GFP_KERNEL);
3265
3266 if (!auxpcm_pdata) {
3267 dev_err(&pdev->dev, "Failed to allocate memory for platform data\n");
3268 goto fail_pdata_nomem;
3269 }
3270
3271 dev_dbg(&pdev->dev, "%s: dev %pK, dai_data %pK, auxpcm_pdata %pK\n",
3272 __func__, &pdev->dev, dai_data, auxpcm_pdata);
3273
3274 rc = of_property_read_u32_array(pdev->dev.of_node,
3275 "qcom,msm-cpudai-auxpcm-mode",
3276 val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
3277 if (rc) {
3278 dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-mode missing in DT node\n",
3279 __func__);
3280 goto fail_invalid_dt;
3281 }
3282 auxpcm_pdata->mode_8k.mode = (u16)val_array[RATE_8KHZ];
3283 auxpcm_pdata->mode_16k.mode = (u16)val_array[RATE_16KHZ];
3284
3285 rc = of_property_read_u32_array(pdev->dev.of_node,
3286 "qcom,msm-cpudai-auxpcm-sync",
3287 val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
3288 if (rc) {
3289 dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-sync missing in DT node\n",
3290 __func__);
3291 goto fail_invalid_dt;
3292 }
3293 auxpcm_pdata->mode_8k.sync = (u16)val_array[RATE_8KHZ];
3294 auxpcm_pdata->mode_16k.sync = (u16)val_array[RATE_16KHZ];
3295
3296 rc = of_property_read_u32_array(pdev->dev.of_node,
3297 "qcom,msm-cpudai-auxpcm-frame",
3298 val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
3299
3300 if (rc) {
3301 dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-frame missing in DT node\n",
3302 __func__);
3303 goto fail_invalid_dt;
3304 }
3305 auxpcm_pdata->mode_8k.frame = (u16)val_array[RATE_8KHZ];
3306 auxpcm_pdata->mode_16k.frame = (u16)val_array[RATE_16KHZ];
3307
3308 rc = of_property_read_u32_array(pdev->dev.of_node,
3309 "qcom,msm-cpudai-auxpcm-quant",
3310 val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
3311 if (rc) {
3312 dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-quant missing in DT node\n",
3313 __func__);
3314 goto fail_invalid_dt;
3315 }
3316 auxpcm_pdata->mode_8k.quant = (u16)val_array[RATE_8KHZ];
3317 auxpcm_pdata->mode_16k.quant = (u16)val_array[RATE_16KHZ];
3318
3319 rc = of_property_read_u32_array(pdev->dev.of_node,
3320 "qcom,msm-cpudai-auxpcm-num-slots",
3321 val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
3322 if (rc) {
3323 dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-num-slots missing in DT node\n",
3324 __func__);
3325 goto fail_invalid_dt;
3326 }
3327 auxpcm_pdata->mode_8k.num_slots = (u16)val_array[RATE_8KHZ];
3328
3329 if (auxpcm_pdata->mode_8k.num_slots >
3330 msm_dai_q6_max_num_slot(auxpcm_pdata->mode_8k.frame)) {
3331 dev_err(&pdev->dev, "%s Max slots %d greater than DT node %d\n",
3332 __func__,
3333 msm_dai_q6_max_num_slot(auxpcm_pdata->mode_8k.frame),
3334 auxpcm_pdata->mode_8k.num_slots);
3335 rc = -EINVAL;
3336 goto fail_invalid_dt;
3337 }
3338 auxpcm_pdata->mode_16k.num_slots = (u16)val_array[RATE_16KHZ];
3339
3340 if (auxpcm_pdata->mode_16k.num_slots >
3341 msm_dai_q6_max_num_slot(auxpcm_pdata->mode_16k.frame)) {
3342 dev_err(&pdev->dev, "%s Max slots %d greater than DT node %d\n",
3343 __func__,
3344 msm_dai_q6_max_num_slot(auxpcm_pdata->mode_16k.frame),
3345 auxpcm_pdata->mode_16k.num_slots);
3346 rc = -EINVAL;
3347 goto fail_invalid_dt;
3348 }
3349
3350 slot_mapping_array = of_get_property(pdev->dev.of_node,
3351 "qcom,msm-cpudai-auxpcm-slot-mapping", &len);
3352
3353 if (slot_mapping_array == NULL) {
3354 dev_err(&pdev->dev, "%s slot_mapping_array is not valid\n",
3355 __func__);
3356 rc = -EINVAL;
3357 goto fail_invalid_dt;
3358 }
3359
3360 array_length = auxpcm_pdata->mode_8k.num_slots +
3361 auxpcm_pdata->mode_16k.num_slots;
3362
3363 if (len != sizeof(uint32_t) * array_length) {
3364 dev_err(&pdev->dev, "%s Length is %d and expected is %zd\n",
3365 __func__, len, sizeof(uint32_t) * array_length);
3366 rc = -EINVAL;
3367 goto fail_invalid_dt;
3368 }
3369
3370 auxpcm_pdata->mode_8k.slot_mapping =
3371 kzalloc(sizeof(uint16_t) *
3372 auxpcm_pdata->mode_8k.num_slots,
3373 GFP_KERNEL);
3374 if (!auxpcm_pdata->mode_8k.slot_mapping) {
3375 dev_err(&pdev->dev, "%s No mem for mode_8k slot mapping\n",
3376 __func__);
3377 rc = -ENOMEM;
3378 goto fail_invalid_dt;
3379 }
3380
3381 for (i = 0; i < auxpcm_pdata->mode_8k.num_slots; i++)
3382 auxpcm_pdata->mode_8k.slot_mapping[i] =
3383 (u16)be32_to_cpu(slot_mapping_array[i]);
3384
3385 auxpcm_pdata->mode_16k.slot_mapping =
3386 kzalloc(sizeof(uint16_t) *
3387 auxpcm_pdata->mode_16k.num_slots,
3388 GFP_KERNEL);
3389
3390 if (!auxpcm_pdata->mode_16k.slot_mapping) {
3391 dev_err(&pdev->dev, "%s No mem for mode_16k slot mapping\n",
3392 __func__);
3393 rc = -ENOMEM;
3394 goto fail_invalid_16k_slot_mapping;
3395 }
3396
3397 for (i = 0; i < auxpcm_pdata->mode_16k.num_slots; i++)
3398 auxpcm_pdata->mode_16k.slot_mapping[i] =
3399 (u16)be32_to_cpu(slot_mapping_array[i +
3400 auxpcm_pdata->mode_8k.num_slots]);
3401
3402 rc = of_property_read_u32_array(pdev->dev.of_node,
3403 "qcom,msm-cpudai-auxpcm-data",
3404 val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
3405 if (rc) {
3406 dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-data missing in DT node\n",
3407 __func__);
3408 goto fail_invalid_dt1;
3409 }
3410 auxpcm_pdata->mode_8k.data = (u16)val_array[RATE_8KHZ];
3411 auxpcm_pdata->mode_16k.data = (u16)val_array[RATE_16KHZ];
3412
3413 rc = of_property_read_u32_array(pdev->dev.of_node,
3414 "qcom,msm-cpudai-auxpcm-pcm-clk-rate",
3415 val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
3416 if (rc) {
3417 dev_err(&pdev->dev,
3418 "%s: qcom,msm-cpudai-auxpcm-pcm-clk-rate missing in DT\n",
3419 __func__);
3420 goto fail_invalid_dt1;
3421 }
3422 auxpcm_pdata->mode_8k.pcm_clk_rate = (int)val_array[RATE_8KHZ];
3423 auxpcm_pdata->mode_16k.pcm_clk_rate = (int)val_array[RATE_16KHZ];
3424
3425 rc = of_property_read_string(pdev->dev.of_node,
3426 "qcom,msm-auxpcm-interface", &intf_name);
3427 if (rc) {
3428 dev_err(&pdev->dev,
3429 "%s: qcom,msm-auxpcm-interface missing in DT node\n",
3430 __func__);
3431 goto fail_nodev_intf;
3432 }
3433
3434 if (!strcmp(intf_name, "primary")) {
3435 dai_data->rx_pid = AFE_PORT_ID_PRIMARY_PCM_RX;
3436 dai_data->tx_pid = AFE_PORT_ID_PRIMARY_PCM_TX;
3437 pdev->id = MSM_DAI_PRI_AUXPCM_DT_DEV_ID;
3438 i = 0;
3439 } else if (!strcmp(intf_name, "secondary")) {
3440 dai_data->rx_pid = AFE_PORT_ID_SECONDARY_PCM_RX;
3441 dai_data->tx_pid = AFE_PORT_ID_SECONDARY_PCM_TX;
3442 pdev->id = MSM_DAI_SEC_AUXPCM_DT_DEV_ID;
3443 i = 1;
3444 } else if (!strcmp(intf_name, "tertiary")) {
3445 dai_data->rx_pid = AFE_PORT_ID_TERTIARY_PCM_RX;
3446 dai_data->tx_pid = AFE_PORT_ID_TERTIARY_PCM_TX;
3447 pdev->id = MSM_DAI_TERT_AUXPCM_DT_DEV_ID;
3448 i = 2;
3449 } else if (!strcmp(intf_name, "quaternary")) {
3450 dai_data->rx_pid = AFE_PORT_ID_QUATERNARY_PCM_RX;
3451 dai_data->tx_pid = AFE_PORT_ID_QUATERNARY_PCM_TX;
3452 pdev->id = MSM_DAI_QUAT_AUXPCM_DT_DEV_ID;
3453 i = 3;
Rohit Kumara5077932017-09-10 22:05:05 +05303454 } else if (!strcmp(intf_name, "quinary")) {
3455 dai_data->rx_pid = AFE_PORT_ID_QUINARY_PCM_RX;
3456 dai_data->tx_pid = AFE_PORT_ID_QUINARY_PCM_TX;
3457 pdev->id = MSM_DAI_QUIN_AUXPCM_DT_DEV_ID;
3458 i = 4;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303459 } else {
3460 dev_err(&pdev->dev, "%s: invalid DT intf name %s\n",
3461 __func__, intf_name);
3462 goto fail_invalid_intf;
3463 }
3464 rc = of_property_read_u32(pdev->dev.of_node,
3465 "qcom,msm-cpudai-afe-clk-ver", &val);
3466 if (rc)
3467 dai_data->afe_clk_ver = AFE_CLK_VERSION_V1;
3468 else
3469 dai_data->afe_clk_ver = val;
3470
3471 mutex_init(&dai_data->rlock);
3472 dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));
3473
3474 dev_set_drvdata(&pdev->dev, dai_data);
3475 pdev->dev.platform_data = (void *) auxpcm_pdata;
3476
3477 rc = snd_soc_register_component(&pdev->dev,
3478 &msm_dai_q6_aux_pcm_dai_component,
3479 &msm_dai_q6_aux_pcm_dai[i], 1);
3480 if (rc) {
3481 dev_err(&pdev->dev, "%s: auxpcm dai reg failed, rc=%d\n",
3482 __func__, rc);
3483 goto fail_reg_dai;
3484 }
3485
3486 return rc;
3487
3488fail_reg_dai:
3489fail_invalid_intf:
3490fail_nodev_intf:
3491fail_invalid_dt1:
3492 kfree(auxpcm_pdata->mode_16k.slot_mapping);
3493fail_invalid_16k_slot_mapping:
3494 kfree(auxpcm_pdata->mode_8k.slot_mapping);
3495fail_invalid_dt:
3496 kfree(auxpcm_pdata);
3497fail_pdata_nomem:
3498 kfree(dai_data);
3499 return rc;
3500}
3501
3502static int msm_auxpcm_dev_remove(struct platform_device *pdev)
3503{
3504 struct msm_dai_q6_auxpcm_dai_data *dai_data;
3505
3506 dai_data = dev_get_drvdata(&pdev->dev);
3507
3508 snd_soc_unregister_component(&pdev->dev);
3509
3510 mutex_destroy(&dai_data->rlock);
3511 kfree(dai_data);
3512 kfree(pdev->dev.platform_data);
3513
3514 return 0;
3515}
3516
3517static const struct of_device_id msm_auxpcm_dev_dt_match[] = {
3518 { .compatible = "qcom,msm-auxpcm-dev", },
3519 {}
3520};
3521
3522
3523static struct platform_driver msm_auxpcm_dev_driver = {
3524 .probe = msm_auxpcm_dev_probe,
3525 .remove = msm_auxpcm_dev_remove,
3526 .driver = {
3527 .name = "msm-auxpcm-dev",
3528 .owner = THIS_MODULE,
3529 .of_match_table = msm_auxpcm_dev_dt_match,
3530 },
3531};
3532
3533static struct snd_soc_dai_driver msm_dai_q6_slimbus_rx_dai[] = {
3534 {
3535 .playback = {
3536 .stream_name = "Slimbus Playback",
3537 .aif_name = "SLIMBUS_0_RX",
3538 .rates = SNDRV_PCM_RATE_8000_384000,
3539 .formats = DAI_FORMATS_S16_S24_S32_LE,
3540 .channels_min = 1,
3541 .channels_max = 8,
3542 .rate_min = 8000,
3543 .rate_max = 384000,
3544 },
3545 .ops = &msm_dai_q6_ops,
3546 .id = SLIMBUS_0_RX,
3547 .probe = msm_dai_q6_dai_probe,
3548 .remove = msm_dai_q6_dai_remove,
3549 },
3550 {
3551 .playback = {
3552 .stream_name = "Slimbus1 Playback",
3553 .aif_name = "SLIMBUS_1_RX",
3554 .rates = SNDRV_PCM_RATE_8000_384000,
3555 .formats = DAI_FORMATS_S16_S24_S32_LE,
3556 .channels_min = 1,
3557 .channels_max = 2,
3558 .rate_min = 8000,
3559 .rate_max = 384000,
3560 },
3561 .ops = &msm_dai_q6_ops,
3562 .id = SLIMBUS_1_RX,
3563 .probe = msm_dai_q6_dai_probe,
3564 .remove = msm_dai_q6_dai_remove,
3565 },
3566 {
3567 .playback = {
3568 .stream_name = "Slimbus2 Playback",
3569 .aif_name = "SLIMBUS_2_RX",
3570 .rates = SNDRV_PCM_RATE_8000_384000,
3571 .formats = DAI_FORMATS_S16_S24_S32_LE,
3572 .channels_min = 1,
3573 .channels_max = 8,
3574 .rate_min = 8000,
3575 .rate_max = 384000,
3576 },
3577 .ops = &msm_dai_q6_ops,
3578 .id = SLIMBUS_2_RX,
3579 .probe = msm_dai_q6_dai_probe,
3580 .remove = msm_dai_q6_dai_remove,
3581 },
3582 {
3583 .playback = {
3584 .stream_name = "Slimbus3 Playback",
3585 .aif_name = "SLIMBUS_3_RX",
3586 .rates = SNDRV_PCM_RATE_8000_384000,
3587 .formats = DAI_FORMATS_S16_S24_S32_LE,
3588 .channels_min = 1,
3589 .channels_max = 2,
3590 .rate_min = 8000,
3591 .rate_max = 384000,
3592 },
3593 .ops = &msm_dai_q6_ops,
3594 .id = SLIMBUS_3_RX,
3595 .probe = msm_dai_q6_dai_probe,
3596 .remove = msm_dai_q6_dai_remove,
3597 },
3598 {
3599 .playback = {
3600 .stream_name = "Slimbus4 Playback",
3601 .aif_name = "SLIMBUS_4_RX",
3602 .rates = SNDRV_PCM_RATE_8000_384000,
3603 .formats = DAI_FORMATS_S16_S24_S32_LE,
3604 .channels_min = 1,
3605 .channels_max = 2,
3606 .rate_min = 8000,
3607 .rate_max = 384000,
3608 },
3609 .ops = &msm_dai_q6_ops,
3610 .id = SLIMBUS_4_RX,
3611 .probe = msm_dai_q6_dai_probe,
3612 .remove = msm_dai_q6_dai_remove,
3613 },
3614 {
3615 .playback = {
3616 .stream_name = "Slimbus6 Playback",
3617 .aif_name = "SLIMBUS_6_RX",
3618 .rates = SNDRV_PCM_RATE_8000_384000,
3619 .formats = DAI_FORMATS_S16_S24_S32_LE,
3620 .channels_min = 1,
3621 .channels_max = 2,
3622 .rate_min = 8000,
3623 .rate_max = 384000,
3624 },
3625 .ops = &msm_dai_q6_ops,
3626 .id = SLIMBUS_6_RX,
3627 .probe = msm_dai_q6_dai_probe,
3628 .remove = msm_dai_q6_dai_remove,
3629 },
3630 {
3631 .playback = {
3632 .stream_name = "Slimbus5 Playback",
3633 .aif_name = "SLIMBUS_5_RX",
3634 .rates = SNDRV_PCM_RATE_8000_384000,
3635 .formats = DAI_FORMATS_S16_S24_S32_LE,
3636 .channels_min = 1,
3637 .channels_max = 2,
3638 .rate_min = 8000,
3639 .rate_max = 384000,
3640 },
3641 .ops = &msm_dai_q6_ops,
3642 .id = SLIMBUS_5_RX,
3643 .probe = msm_dai_q6_dai_probe,
3644 .remove = msm_dai_q6_dai_remove,
3645 },
3646 {
3647 .playback = {
3648 .stream_name = "Slimbus7 Playback",
3649 .aif_name = "SLIMBUS_7_RX",
3650 .rates = SNDRV_PCM_RATE_8000_384000,
3651 .formats = DAI_FORMATS_S16_S24_S32_LE,
3652 .channels_min = 1,
3653 .channels_max = 8,
3654 .rate_min = 8000,
3655 .rate_max = 384000,
3656 },
3657 .ops = &msm_dai_q6_ops,
3658 .id = SLIMBUS_7_RX,
3659 .probe = msm_dai_q6_dai_probe,
3660 .remove = msm_dai_q6_dai_remove,
3661 },
3662 {
3663 .playback = {
3664 .stream_name = "Slimbus8 Playback",
3665 .aif_name = "SLIMBUS_8_RX",
3666 .rates = SNDRV_PCM_RATE_8000_384000,
3667 .formats = DAI_FORMATS_S16_S24_S32_LE,
3668 .channels_min = 1,
3669 .channels_max = 8,
3670 .rate_min = 8000,
3671 .rate_max = 384000,
3672 },
3673 .ops = &msm_dai_q6_ops,
3674 .id = SLIMBUS_8_RX,
3675 .probe = msm_dai_q6_dai_probe,
3676 .remove = msm_dai_q6_dai_remove,
3677 },
3678};
3679
3680static struct snd_soc_dai_driver msm_dai_q6_slimbus_tx_dai[] = {
3681 {
3682 .capture = {
3683 .stream_name = "Slimbus Capture",
3684 .aif_name = "SLIMBUS_0_TX",
3685 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
3686 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
3687 SNDRV_PCM_RATE_192000,
3688 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3689 SNDRV_PCM_FMTBIT_S24_LE |
3690 SNDRV_PCM_FMTBIT_S24_3LE,
3691 .channels_min = 1,
3692 .channels_max = 8,
3693 .rate_min = 8000,
3694 .rate_max = 192000,
3695 },
3696 .ops = &msm_dai_q6_ops,
3697 .id = SLIMBUS_0_TX,
3698 .probe = msm_dai_q6_dai_probe,
3699 .remove = msm_dai_q6_dai_remove,
3700 },
3701 {
3702 .capture = {
3703 .stream_name = "Slimbus1 Capture",
3704 .aif_name = "SLIMBUS_1_TX",
3705 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
3706 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
3707 SNDRV_PCM_RATE_192000,
3708 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3709 SNDRV_PCM_FMTBIT_S24_LE |
3710 SNDRV_PCM_FMTBIT_S24_3LE,
3711 .channels_min = 1,
3712 .channels_max = 2,
3713 .rate_min = 8000,
3714 .rate_max = 192000,
3715 },
3716 .ops = &msm_dai_q6_ops,
3717 .id = SLIMBUS_1_TX,
3718 .probe = msm_dai_q6_dai_probe,
3719 .remove = msm_dai_q6_dai_remove,
3720 },
3721 {
3722 .capture = {
3723 .stream_name = "Slimbus2 Capture",
3724 .aif_name = "SLIMBUS_2_TX",
3725 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
3726 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
3727 SNDRV_PCM_RATE_192000,
3728 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3729 SNDRV_PCM_FMTBIT_S24_LE,
3730 .channels_min = 1,
3731 .channels_max = 8,
3732 .rate_min = 8000,
3733 .rate_max = 192000,
3734 },
3735 .ops = &msm_dai_q6_ops,
3736 .id = SLIMBUS_2_TX,
3737 .probe = msm_dai_q6_dai_probe,
3738 .remove = msm_dai_q6_dai_remove,
3739 },
3740 {
3741 .capture = {
3742 .stream_name = "Slimbus3 Capture",
3743 .aif_name = "SLIMBUS_3_TX",
3744 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
3745 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
3746 SNDRV_PCM_RATE_192000,
3747 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3748 SNDRV_PCM_FMTBIT_S24_LE,
3749 .channels_min = 2,
3750 .channels_max = 4,
3751 .rate_min = 8000,
3752 .rate_max = 192000,
3753 },
3754 .ops = &msm_dai_q6_ops,
3755 .id = SLIMBUS_3_TX,
3756 .probe = msm_dai_q6_dai_probe,
3757 .remove = msm_dai_q6_dai_remove,
3758 },
3759 {
3760 .capture = {
3761 .stream_name = "Slimbus4 Capture",
3762 .aif_name = "SLIMBUS_4_TX",
3763 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
3764 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
3765 SNDRV_PCM_RATE_192000,
3766 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3767 SNDRV_PCM_FMTBIT_S24_LE |
3768 SNDRV_PCM_FMTBIT_S32_LE,
3769 .channels_min = 2,
3770 .channels_max = 4,
3771 .rate_min = 8000,
3772 .rate_max = 192000,
3773 },
3774 .ops = &msm_dai_q6_ops,
3775 .id = SLIMBUS_4_TX,
3776 .probe = msm_dai_q6_dai_probe,
3777 .remove = msm_dai_q6_dai_remove,
3778 },
3779 {
3780 .capture = {
3781 .stream_name = "Slimbus5 Capture",
3782 .aif_name = "SLIMBUS_5_TX",
3783 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
3784 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
3785 SNDRV_PCM_RATE_192000,
3786 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3787 SNDRV_PCM_FMTBIT_S24_LE,
3788 .channels_min = 1,
3789 .channels_max = 8,
3790 .rate_min = 8000,
3791 .rate_max = 192000,
3792 },
3793 .ops = &msm_dai_q6_ops,
3794 .id = SLIMBUS_5_TX,
3795 .probe = msm_dai_q6_dai_probe,
3796 .remove = msm_dai_q6_dai_remove,
3797 },
3798 {
3799 .capture = {
3800 .stream_name = "Slimbus6 Capture",
3801 .aif_name = "SLIMBUS_6_TX",
3802 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
3803 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
3804 SNDRV_PCM_RATE_192000,
3805 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3806 SNDRV_PCM_FMTBIT_S24_LE,
3807 .channels_min = 1,
3808 .channels_max = 2,
3809 .rate_min = 8000,
3810 .rate_max = 192000,
3811 },
3812 .ops = &msm_dai_q6_ops,
3813 .id = SLIMBUS_6_TX,
3814 .probe = msm_dai_q6_dai_probe,
3815 .remove = msm_dai_q6_dai_remove,
3816 },
3817 {
3818 .capture = {
3819 .stream_name = "Slimbus7 Capture",
3820 .aif_name = "SLIMBUS_7_TX",
3821 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
3822 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
3823 SNDRV_PCM_RATE_192000,
3824 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3825 SNDRV_PCM_FMTBIT_S24_LE |
3826 SNDRV_PCM_FMTBIT_S32_LE,
3827 .channels_min = 1,
3828 .channels_max = 8,
3829 .rate_min = 8000,
3830 .rate_max = 192000,
3831 },
3832 .ops = &msm_dai_q6_ops,
3833 .id = SLIMBUS_7_TX,
3834 .probe = msm_dai_q6_dai_probe,
3835 .remove = msm_dai_q6_dai_remove,
3836 },
3837 {
3838 .capture = {
3839 .stream_name = "Slimbus8 Capture",
3840 .aif_name = "SLIMBUS_8_TX",
3841 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
3842 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
3843 SNDRV_PCM_RATE_192000,
3844 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3845 SNDRV_PCM_FMTBIT_S24_LE |
3846 SNDRV_PCM_FMTBIT_S32_LE,
3847 .channels_min = 1,
3848 .channels_max = 8,
3849 .rate_min = 8000,
3850 .rate_max = 192000,
3851 },
3852 .ops = &msm_dai_q6_ops,
3853 .id = SLIMBUS_8_TX,
3854 .probe = msm_dai_q6_dai_probe,
3855 .remove = msm_dai_q6_dai_remove,
3856 },
3857};
3858
3859static int msm_dai_q6_mi2s_format_put(struct snd_kcontrol *kcontrol,
3860 struct snd_ctl_elem_value *ucontrol)
3861{
3862 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
3863 int value = ucontrol->value.integer.value[0];
3864
3865 dai_data->port_config.i2s.data_format = value;
3866 pr_debug("%s: value = %d, channel = %d, line = %d\n",
3867 __func__, value, dai_data->port_config.i2s.mono_stereo,
3868 dai_data->port_config.i2s.channel_mode);
3869 return 0;
3870}
3871
3872static int msm_dai_q6_mi2s_format_get(struct snd_kcontrol *kcontrol,
3873 struct snd_ctl_elem_value *ucontrol)
3874{
3875 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
3876
3877 ucontrol->value.integer.value[0] =
3878 dai_data->port_config.i2s.data_format;
3879 return 0;
3880}
3881
3882static int msm_dai_q6_mi2s_vi_feed_mono_put(struct snd_kcontrol *kcontrol,
3883 struct snd_ctl_elem_value *ucontrol)
3884{
3885 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
3886 int value = ucontrol->value.integer.value[0];
3887
3888 dai_data->vi_feed_mono = value;
3889 pr_debug("%s: value = %d\n", __func__, value);
3890 return 0;
3891}
3892
3893static int msm_dai_q6_mi2s_vi_feed_mono_get(struct snd_kcontrol *kcontrol,
3894 struct snd_ctl_elem_value *ucontrol)
3895{
3896 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
3897
3898 ucontrol->value.integer.value[0] = dai_data->vi_feed_mono;
3899 return 0;
3900}
3901
3902static const struct snd_kcontrol_new mi2s_config_controls[] = {
3903 SOC_ENUM_EXT("PRI MI2S RX Format", mi2s_config_enum[0],
3904 msm_dai_q6_mi2s_format_get,
3905 msm_dai_q6_mi2s_format_put),
3906 SOC_ENUM_EXT("SEC MI2S RX Format", mi2s_config_enum[0],
3907 msm_dai_q6_mi2s_format_get,
3908 msm_dai_q6_mi2s_format_put),
3909 SOC_ENUM_EXT("TERT MI2S RX Format", mi2s_config_enum[0],
3910 msm_dai_q6_mi2s_format_get,
3911 msm_dai_q6_mi2s_format_put),
3912 SOC_ENUM_EXT("QUAT MI2S RX Format", mi2s_config_enum[0],
3913 msm_dai_q6_mi2s_format_get,
3914 msm_dai_q6_mi2s_format_put),
3915 SOC_ENUM_EXT("QUIN MI2S RX Format", mi2s_config_enum[0],
3916 msm_dai_q6_mi2s_format_get,
3917 msm_dai_q6_mi2s_format_put),
3918 SOC_ENUM_EXT("PRI MI2S TX Format", mi2s_config_enum[0],
3919 msm_dai_q6_mi2s_format_get,
3920 msm_dai_q6_mi2s_format_put),
3921 SOC_ENUM_EXT("SEC MI2S TX Format", mi2s_config_enum[0],
3922 msm_dai_q6_mi2s_format_get,
3923 msm_dai_q6_mi2s_format_put),
3924 SOC_ENUM_EXT("TERT MI2S TX Format", mi2s_config_enum[0],
3925 msm_dai_q6_mi2s_format_get,
3926 msm_dai_q6_mi2s_format_put),
3927 SOC_ENUM_EXT("QUAT MI2S TX Format", mi2s_config_enum[0],
3928 msm_dai_q6_mi2s_format_get,
3929 msm_dai_q6_mi2s_format_put),
3930 SOC_ENUM_EXT("QUIN MI2S TX Format", mi2s_config_enum[0],
3931 msm_dai_q6_mi2s_format_get,
3932 msm_dai_q6_mi2s_format_put),
3933 SOC_ENUM_EXT("SENARY MI2S TX Format", mi2s_config_enum[0],
3934 msm_dai_q6_mi2s_format_get,
3935 msm_dai_q6_mi2s_format_put),
3936 SOC_ENUM_EXT("INT5 MI2S TX Format", mi2s_config_enum[0],
3937 msm_dai_q6_mi2s_format_get,
3938 msm_dai_q6_mi2s_format_put),
3939};
3940
3941static const struct snd_kcontrol_new mi2s_vi_feed_controls[] = {
3942 SOC_ENUM_EXT("INT5 MI2S VI MONO", mi2s_config_enum[1],
3943 msm_dai_q6_mi2s_vi_feed_mono_get,
3944 msm_dai_q6_mi2s_vi_feed_mono_put),
3945};
3946
3947static int msm_dai_q6_dai_mi2s_probe(struct snd_soc_dai *dai)
3948{
3949 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
3950 dev_get_drvdata(dai->dev);
3951 struct msm_mi2s_pdata *mi2s_pdata =
3952 (struct msm_mi2s_pdata *) dai->dev->platform_data;
3953 struct snd_kcontrol *kcontrol = NULL;
3954 int rc = 0;
3955 const struct snd_kcontrol_new *ctrl = NULL;
3956 const struct snd_kcontrol_new *vi_feed_ctrl = NULL;
3957
3958 dai->id = mi2s_pdata->intf_id;
3959
3960 if (mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.i2s.channel_mode) {
3961 if (dai->id == MSM_PRIM_MI2S)
3962 ctrl = &mi2s_config_controls[0];
3963 if (dai->id == MSM_SEC_MI2S)
3964 ctrl = &mi2s_config_controls[1];
3965 if (dai->id == MSM_TERT_MI2S)
3966 ctrl = &mi2s_config_controls[2];
3967 if (dai->id == MSM_QUAT_MI2S)
3968 ctrl = &mi2s_config_controls[3];
3969 if (dai->id == MSM_QUIN_MI2S)
3970 ctrl = &mi2s_config_controls[4];
3971 }
3972
3973 if (ctrl) {
3974 kcontrol = snd_ctl_new1(ctrl,
3975 &mi2s_dai_data->rx_dai.mi2s_dai_data);
3976 rc = snd_ctl_add(dai->component->card->snd_card, kcontrol);
3977 if (rc < 0) {
3978 dev_err(dai->dev, "%s: err add RX fmt ctl DAI = %s\n",
3979 __func__, dai->name);
3980 goto rtn;
3981 }
3982 }
3983
3984 ctrl = NULL;
3985 if (mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.channel_mode) {
3986 if (dai->id == MSM_PRIM_MI2S)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303987 ctrl = &mi2s_config_controls[5];
Rohit kumarb242df42017-10-16 15:37:05 +05303988 if (dai->id == MSM_SEC_MI2S)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303989 ctrl = &mi2s_config_controls[6];
Rohit kumarb242df42017-10-16 15:37:05 +05303990 if (dai->id == MSM_TERT_MI2S)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303991 ctrl = &mi2s_config_controls[7];
Rohit kumarb242df42017-10-16 15:37:05 +05303992 if (dai->id == MSM_QUAT_MI2S)
3993 ctrl = &mi2s_config_controls[8];
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303994 if (dai->id == MSM_QUIN_MI2S)
3995 ctrl = &mi2s_config_controls[9];
3996 if (dai->id == MSM_SENARY_MI2S)
3997 ctrl = &mi2s_config_controls[10];
3998 if (dai->id == MSM_INT5_MI2S)
3999 ctrl = &mi2s_config_controls[11];
4000 }
4001
4002 if (ctrl) {
4003 rc = snd_ctl_add(dai->component->card->snd_card,
4004 snd_ctl_new1(ctrl,
4005 &mi2s_dai_data->tx_dai.mi2s_dai_data));
4006 if (rc < 0) {
4007 if (kcontrol)
4008 snd_ctl_remove(dai->component->card->snd_card,
4009 kcontrol);
4010 dev_err(dai->dev, "%s: err add TX fmt ctl DAI = %s\n",
4011 __func__, dai->name);
4012 }
4013 }
4014
4015 if (dai->id == MSM_INT5_MI2S)
4016 vi_feed_ctrl = &mi2s_vi_feed_controls[0];
4017
4018 if (vi_feed_ctrl) {
4019 rc = snd_ctl_add(dai->component->card->snd_card,
4020 snd_ctl_new1(vi_feed_ctrl,
4021 &mi2s_dai_data->tx_dai.mi2s_dai_data));
4022
4023 if (rc < 0) {
4024 dev_err(dai->dev, "%s: err add TX vi feed channel ctl DAI = %s\n",
4025 __func__, dai->name);
4026 }
4027 }
4028
4029 rc = msm_dai_q6_dai_add_route(dai);
4030rtn:
4031 return rc;
4032}
4033
4034
4035static int msm_dai_q6_dai_mi2s_remove(struct snd_soc_dai *dai)
4036{
4037 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
4038 dev_get_drvdata(dai->dev);
4039 int rc;
4040
4041 /* If AFE port is still up, close it */
4042 if (test_bit(STATUS_PORT_STARTED,
4043 mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask)) {
4044 rc = afe_close(MI2S_RX); /* can block */
4045 if (rc < 0)
4046 dev_err(dai->dev, "fail to close MI2S_RX port\n");
4047 clear_bit(STATUS_PORT_STARTED,
4048 mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask);
4049 }
4050 if (test_bit(STATUS_PORT_STARTED,
4051 mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask)) {
4052 rc = afe_close(MI2S_TX); /* can block */
4053 if (rc < 0)
4054 dev_err(dai->dev, "fail to close MI2S_TX port\n");
4055 clear_bit(STATUS_PORT_STARTED,
4056 mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask);
4057 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304058 return 0;
4059}
4060
4061static int msm_dai_q6_mi2s_startup(struct snd_pcm_substream *substream,
4062 struct snd_soc_dai *dai)
4063{
4064
4065 return 0;
4066}
4067
4068
4069static int msm_mi2s_get_port_id(u32 mi2s_id, int stream, u16 *port_id)
4070{
4071 int ret = 0;
4072
4073 switch (stream) {
4074 case SNDRV_PCM_STREAM_PLAYBACK:
4075 switch (mi2s_id) {
4076 case MSM_PRIM_MI2S:
4077 *port_id = AFE_PORT_ID_PRIMARY_MI2S_RX;
4078 break;
4079 case MSM_SEC_MI2S:
4080 *port_id = AFE_PORT_ID_SECONDARY_MI2S_RX;
4081 break;
4082 case MSM_TERT_MI2S:
4083 *port_id = AFE_PORT_ID_TERTIARY_MI2S_RX;
4084 break;
4085 case MSM_QUAT_MI2S:
4086 *port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX;
4087 break;
4088 case MSM_SEC_MI2S_SD1:
4089 *port_id = AFE_PORT_ID_SECONDARY_MI2S_RX_SD1;
4090 break;
4091 case MSM_QUIN_MI2S:
4092 *port_id = AFE_PORT_ID_QUINARY_MI2S_RX;
4093 break;
4094 case MSM_INT0_MI2S:
4095 *port_id = AFE_PORT_ID_INT0_MI2S_RX;
4096 break;
4097 case MSM_INT1_MI2S:
4098 *port_id = AFE_PORT_ID_INT1_MI2S_RX;
4099 break;
4100 case MSM_INT2_MI2S:
4101 *port_id = AFE_PORT_ID_INT2_MI2S_RX;
4102 break;
4103 case MSM_INT3_MI2S:
4104 *port_id = AFE_PORT_ID_INT3_MI2S_RX;
4105 break;
4106 case MSM_INT4_MI2S:
4107 *port_id = AFE_PORT_ID_INT4_MI2S_RX;
4108 break;
4109 case MSM_INT5_MI2S:
4110 *port_id = AFE_PORT_ID_INT5_MI2S_RX;
4111 break;
4112 case MSM_INT6_MI2S:
4113 *port_id = AFE_PORT_ID_INT6_MI2S_RX;
4114 break;
4115 default:
4116 pr_err("%s: playback err id 0x%x\n",
4117 __func__, mi2s_id);
4118 ret = -1;
4119 break;
4120 }
4121 break;
4122 case SNDRV_PCM_STREAM_CAPTURE:
4123 switch (mi2s_id) {
4124 case MSM_PRIM_MI2S:
4125 *port_id = AFE_PORT_ID_PRIMARY_MI2S_TX;
4126 break;
4127 case MSM_SEC_MI2S:
4128 *port_id = AFE_PORT_ID_SECONDARY_MI2S_TX;
4129 break;
4130 case MSM_TERT_MI2S:
4131 *port_id = AFE_PORT_ID_TERTIARY_MI2S_TX;
4132 break;
4133 case MSM_QUAT_MI2S:
4134 *port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX;
4135 break;
4136 case MSM_QUIN_MI2S:
4137 *port_id = AFE_PORT_ID_QUINARY_MI2S_TX;
4138 break;
4139 case MSM_SENARY_MI2S:
4140 *port_id = AFE_PORT_ID_SENARY_MI2S_TX;
4141 break;
4142 case MSM_INT0_MI2S:
4143 *port_id = AFE_PORT_ID_INT0_MI2S_TX;
4144 break;
4145 case MSM_INT1_MI2S:
4146 *port_id = AFE_PORT_ID_INT1_MI2S_TX;
4147 break;
4148 case MSM_INT2_MI2S:
4149 *port_id = AFE_PORT_ID_INT2_MI2S_TX;
4150 break;
4151 case MSM_INT3_MI2S:
4152 *port_id = AFE_PORT_ID_INT3_MI2S_TX;
4153 break;
4154 case MSM_INT4_MI2S:
4155 *port_id = AFE_PORT_ID_INT4_MI2S_TX;
4156 break;
4157 case MSM_INT5_MI2S:
4158 *port_id = AFE_PORT_ID_INT5_MI2S_TX;
4159 break;
4160 case MSM_INT6_MI2S:
4161 *port_id = AFE_PORT_ID_INT6_MI2S_TX;
4162 break;
4163 default:
4164 pr_err("%s: capture err id 0x%x\n", __func__, mi2s_id);
4165 ret = -1;
4166 break;
4167 }
4168 break;
4169 default:
4170 pr_err("%s: default err %d\n", __func__, stream);
4171 ret = -1;
4172 break;
4173 }
4174 pr_debug("%s: port_id = 0x%x\n", __func__, *port_id);
4175 return ret;
4176}
4177
4178static int msm_dai_q6_mi2s_prepare(struct snd_pcm_substream *substream,
4179 struct snd_soc_dai *dai)
4180{
4181 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
4182 dev_get_drvdata(dai->dev);
4183 struct msm_dai_q6_dai_data *dai_data =
4184 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
4185 &mi2s_dai_data->rx_dai.mi2s_dai_data :
4186 &mi2s_dai_data->tx_dai.mi2s_dai_data);
4187 u16 port_id = 0;
4188 int rc = 0;
4189
4190 if (msm_mi2s_get_port_id(dai->id, substream->stream,
4191 &port_id) != 0) {
4192 dev_err(dai->dev, "%s: Invalid Port ID 0x%x\n",
4193 __func__, port_id);
4194 return -EINVAL;
4195 }
4196
4197 dev_dbg(dai->dev, "%s: dai id %d, afe port id = 0x%x\n"
4198 "dai_data->channels = %u sample_rate = %u\n", __func__,
4199 dai->id, port_id, dai_data->channels, dai_data->rate);
4200
4201 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
4202 /* PORT START should be set if prepare called
4203 * in active state.
4204 */
4205 rc = afe_port_start(port_id, &dai_data->port_config,
4206 dai_data->rate);
4207 if (rc < 0)
4208 dev_err(dai->dev, "fail to open AFE port 0x%x\n",
4209 dai->id);
4210 else
4211 set_bit(STATUS_PORT_STARTED,
4212 dai_data->status_mask);
4213 }
4214 if (!test_bit(STATUS_PORT_STARTED, dai_data->hwfree_status)) {
4215 set_bit(STATUS_PORT_STARTED, dai_data->hwfree_status);
4216 dev_dbg(dai->dev, "%s: set hwfree_status to started\n",
4217 __func__);
4218 }
4219 return rc;
4220}
4221
4222static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream,
4223 struct snd_pcm_hw_params *params,
4224 struct snd_soc_dai *dai)
4225{
4226 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
4227 dev_get_drvdata(dai->dev);
4228 struct msm_dai_q6_mi2s_dai_config *mi2s_dai_config =
4229 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
4230 &mi2s_dai_data->rx_dai : &mi2s_dai_data->tx_dai);
4231 struct msm_dai_q6_dai_data *dai_data = &mi2s_dai_config->mi2s_dai_data;
4232 struct afe_param_id_i2s_cfg *i2s = &dai_data->port_config.i2s;
4233
4234 dai_data->channels = params_channels(params);
4235 switch (dai_data->channels) {
4236 case 8:
4237 case 7:
4238 if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_8CHS)
4239 goto error_invalid_data;
4240 dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_8CHS;
4241 break;
4242 case 6:
4243 case 5:
4244 if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_6CHS)
4245 goto error_invalid_data;
4246 dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_6CHS;
4247 break;
4248 case 4:
4249 case 3:
4250 if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_QUAD01)
4251 goto error_invalid_data;
4252 if (mi2s_dai_config->pdata_mi2s_lines == AFE_PORT_I2S_QUAD23)
4253 dai_data->port_config.i2s.channel_mode =
4254 mi2s_dai_config->pdata_mi2s_lines;
4255 else
4256 dai_data->port_config.i2s.channel_mode =
4257 AFE_PORT_I2S_QUAD01;
4258 break;
4259 case 2:
4260 case 1:
4261 if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_SD0)
4262 goto error_invalid_data;
4263 switch (mi2s_dai_config->pdata_mi2s_lines) {
4264 case AFE_PORT_I2S_SD0:
4265 case AFE_PORT_I2S_SD1:
4266 case AFE_PORT_I2S_SD2:
4267 case AFE_PORT_I2S_SD3:
4268 dai_data->port_config.i2s.channel_mode =
4269 mi2s_dai_config->pdata_mi2s_lines;
4270 break;
4271 case AFE_PORT_I2S_QUAD01:
4272 case AFE_PORT_I2S_6CHS:
4273 case AFE_PORT_I2S_8CHS:
4274 if (dai_data->vi_feed_mono == SPKR_1)
4275 dai_data->port_config.i2s.channel_mode =
4276 AFE_PORT_I2S_SD0;
4277 else
4278 dai_data->port_config.i2s.channel_mode =
4279 AFE_PORT_I2S_SD1;
4280 break;
4281 case AFE_PORT_I2S_QUAD23:
4282 dai_data->port_config.i2s.channel_mode =
4283 AFE_PORT_I2S_SD2;
4284 break;
4285 }
4286 if (dai_data->channels == 2)
4287 dai_data->port_config.i2s.mono_stereo =
4288 MSM_AFE_CH_STEREO;
4289 else
4290 dai_data->port_config.i2s.mono_stereo = MSM_AFE_MONO;
4291 break;
4292 default:
4293 pr_err("%s: default err channels %d\n",
4294 __func__, dai_data->channels);
4295 goto error_invalid_data;
4296 }
4297 dai_data->rate = params_rate(params);
4298
4299 switch (params_format(params)) {
4300 case SNDRV_PCM_FORMAT_S16_LE:
4301 case SNDRV_PCM_FORMAT_SPECIAL:
4302 dai_data->port_config.i2s.bit_width = 16;
4303 dai_data->bitwidth = 16;
4304 break;
4305 case SNDRV_PCM_FORMAT_S24_LE:
4306 case SNDRV_PCM_FORMAT_S24_3LE:
4307 dai_data->port_config.i2s.bit_width = 24;
4308 dai_data->bitwidth = 24;
4309 break;
4310 default:
4311 pr_err("%s: format %d\n",
4312 __func__, params_format(params));
4313 return -EINVAL;
4314 }
4315
4316 dai_data->port_config.i2s.i2s_cfg_minor_version =
4317 AFE_API_VERSION_I2S_CONFIG;
4318 dai_data->port_config.i2s.sample_rate = dai_data->rate;
4319 if ((test_bit(STATUS_PORT_STARTED,
4320 mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask) &&
4321 test_bit(STATUS_PORT_STARTED,
4322 mi2s_dai_data->rx_dai.mi2s_dai_data.hwfree_status)) ||
4323 (test_bit(STATUS_PORT_STARTED,
4324 mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask) &&
4325 test_bit(STATUS_PORT_STARTED,
4326 mi2s_dai_data->tx_dai.mi2s_dai_data.hwfree_status))) {
4327 if ((mi2s_dai_data->tx_dai.mi2s_dai_data.rate !=
4328 mi2s_dai_data->rx_dai.mi2s_dai_data.rate) ||
4329 (mi2s_dai_data->rx_dai.mi2s_dai_data.bitwidth !=
4330 mi2s_dai_data->tx_dai.mi2s_dai_data.bitwidth)) {
4331 dev_err(dai->dev, "%s: Error mismatch in HW params\n"
4332 "Tx sample_rate = %u bit_width = %hu\n"
4333 "Rx sample_rate = %u bit_width = %hu\n"
4334 , __func__,
4335 mi2s_dai_data->tx_dai.mi2s_dai_data.rate,
4336 mi2s_dai_data->tx_dai.mi2s_dai_data.bitwidth,
4337 mi2s_dai_data->rx_dai.mi2s_dai_data.rate,
4338 mi2s_dai_data->rx_dai.mi2s_dai_data.bitwidth);
4339 return -EINVAL;
4340 }
4341 }
4342 dev_dbg(dai->dev, "%s: dai id %d dai_data->channels = %d\n"
4343 "sample_rate = %u i2s_cfg_minor_version = 0x%x\n"
4344 "bit_width = %hu channel_mode = 0x%x mono_stereo = %#x\n"
4345 "ws_src = 0x%x sample_rate = %u data_format = 0x%x\n"
4346 "reserved = %u\n", __func__, dai->id, dai_data->channels,
4347 dai_data->rate, i2s->i2s_cfg_minor_version, i2s->bit_width,
4348 i2s->channel_mode, i2s->mono_stereo, i2s->ws_src,
4349 i2s->sample_rate, i2s->data_format, i2s->reserved);
4350
4351 return 0;
4352
4353error_invalid_data:
4354 pr_err("%s: dai_data->channels = %d channel_mode = %d\n", __func__,
4355 dai_data->channels, dai_data->port_config.i2s.channel_mode);
4356 return -EINVAL;
4357}
4358
4359
4360static int msm_dai_q6_mi2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
4361{
4362 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
4363 dev_get_drvdata(dai->dev);
4364
4365 if (test_bit(STATUS_PORT_STARTED,
4366 mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask) ||
4367 test_bit(STATUS_PORT_STARTED,
4368 mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask)) {
4369 dev_err(dai->dev, "%s: err chg i2s mode while dai running",
4370 __func__);
4371 return -EPERM;
4372 }
4373
4374 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
4375 case SND_SOC_DAIFMT_CBS_CFS:
4376 mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.i2s.ws_src = 1;
4377 mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.ws_src = 1;
4378 break;
4379 case SND_SOC_DAIFMT_CBM_CFM:
4380 mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.i2s.ws_src = 0;
4381 mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.ws_src = 0;
4382 break;
4383 default:
4384 pr_err("%s: fmt %d\n",
4385 __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
4386 return -EINVAL;
4387 }
4388
4389 return 0;
4390}
4391
4392static int msm_dai_q6_mi2s_hw_free(struct snd_pcm_substream *substream,
4393 struct snd_soc_dai *dai)
4394{
4395 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
4396 dev_get_drvdata(dai->dev);
4397 struct msm_dai_q6_dai_data *dai_data =
4398 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
4399 &mi2s_dai_data->rx_dai.mi2s_dai_data :
4400 &mi2s_dai_data->tx_dai.mi2s_dai_data);
4401
4402 if (test_bit(STATUS_PORT_STARTED, dai_data->hwfree_status)) {
4403 clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status);
4404 dev_dbg(dai->dev, "%s: clear hwfree_status\n", __func__);
4405 }
4406 return 0;
4407}
4408
4409static void msm_dai_q6_mi2s_shutdown(struct snd_pcm_substream *substream,
4410 struct snd_soc_dai *dai)
4411{
4412 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
4413 dev_get_drvdata(dai->dev);
4414 struct msm_dai_q6_dai_data *dai_data =
4415 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
4416 &mi2s_dai_data->rx_dai.mi2s_dai_data :
4417 &mi2s_dai_data->tx_dai.mi2s_dai_data);
4418 u16 port_id = 0;
4419 int rc = 0;
4420
4421 if (msm_mi2s_get_port_id(dai->id, substream->stream,
4422 &port_id) != 0) {
4423 dev_err(dai->dev, "%s: Invalid Port ID 0x%x\n",
4424 __func__, port_id);
4425 }
4426
4427 dev_dbg(dai->dev, "%s: closing afe port id = 0x%x\n",
4428 __func__, port_id);
4429
4430 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
4431 rc = afe_close(port_id);
4432 if (rc < 0)
4433 dev_err(dai->dev, "fail to close AFE port\n");
4434 clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
4435 }
4436 if (test_bit(STATUS_PORT_STARTED, dai_data->hwfree_status))
4437 clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status);
4438}
4439
4440static struct snd_soc_dai_ops msm_dai_q6_mi2s_ops = {
4441 .startup = msm_dai_q6_mi2s_startup,
4442 .prepare = msm_dai_q6_mi2s_prepare,
4443 .hw_params = msm_dai_q6_mi2s_hw_params,
4444 .hw_free = msm_dai_q6_mi2s_hw_free,
4445 .set_fmt = msm_dai_q6_mi2s_set_fmt,
4446 .shutdown = msm_dai_q6_mi2s_shutdown,
4447};
4448
4449/* Channel min and max are initialized base on platform data */
4450static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = {
4451 {
4452 .playback = {
4453 .stream_name = "Primary MI2S Playback",
4454 .aif_name = "PRI_MI2S_RX",
4455 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4456 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4457 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4458 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4459 SNDRV_PCM_RATE_192000,
Raja Mallik425e1d32018-05-20 19:21:10 +05304460 .formats = (SNDRV_PCM_FMTBIT_S16_LE|
4461 SNDRV_PCM_FMTBIT_S24_LE |
4462 SNDRV_PCM_FMTBIT_S24_3LE |
4463 SNDRV_PCM_FMTBIT_S32_LE ),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304464 .rate_min = 8000,
4465 .rate_max = 192000,
4466 },
4467 .capture = {
4468 .stream_name = "Primary MI2S Capture",
4469 .aif_name = "PRI_MI2S_TX",
4470 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4471 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4472 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4473 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4474 SNDRV_PCM_RATE_192000,
4475 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4476 .rate_min = 8000,
4477 .rate_max = 192000,
4478 },
4479 .ops = &msm_dai_q6_mi2s_ops,
4480 .id = MSM_PRIM_MI2S,
4481 .probe = msm_dai_q6_dai_mi2s_probe,
4482 .remove = msm_dai_q6_dai_mi2s_remove,
4483 },
4484 {
4485 .playback = {
4486 .stream_name = "Secondary MI2S Playback",
4487 .aif_name = "SEC_MI2S_RX",
4488 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4489 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4490 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4491 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4492 SNDRV_PCM_RATE_192000,
4493 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4494 .rate_min = 8000,
4495 .rate_max = 192000,
4496 },
4497 .capture = {
4498 .stream_name = "Secondary MI2S Capture",
4499 .aif_name = "SEC_MI2S_TX",
4500 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4501 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4502 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4503 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4504 SNDRV_PCM_RATE_192000,
4505 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4506 .rate_min = 8000,
4507 .rate_max = 192000,
4508 },
4509 .ops = &msm_dai_q6_mi2s_ops,
4510 .id = MSM_SEC_MI2S,
4511 .probe = msm_dai_q6_dai_mi2s_probe,
4512 .remove = msm_dai_q6_dai_mi2s_remove,
4513 },
4514 {
4515 .playback = {
4516 .stream_name = "Tertiary MI2S Playback",
4517 .aif_name = "TERT_MI2S_RX",
4518 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4519 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4520 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4521 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4522 SNDRV_PCM_RATE_192000,
4523 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4524 .rate_min = 8000,
4525 .rate_max = 192000,
4526 },
4527 .capture = {
4528 .stream_name = "Tertiary MI2S Capture",
4529 .aif_name = "TERT_MI2S_TX",
4530 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4531 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4532 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4533 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4534 SNDRV_PCM_RATE_192000,
4535 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4536 .rate_min = 8000,
4537 .rate_max = 192000,
4538 },
4539 .ops = &msm_dai_q6_mi2s_ops,
4540 .id = MSM_TERT_MI2S,
4541 .probe = msm_dai_q6_dai_mi2s_probe,
4542 .remove = msm_dai_q6_dai_mi2s_remove,
4543 },
4544 {
4545 .playback = {
4546 .stream_name = "Quaternary MI2S Playback",
4547 .aif_name = "QUAT_MI2S_RX",
4548 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4549 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4550 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4551 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4552 SNDRV_PCM_RATE_192000,
4553 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4554 .rate_min = 8000,
4555 .rate_max = 192000,
4556 },
4557 .capture = {
4558 .stream_name = "Quaternary MI2S Capture",
4559 .aif_name = "QUAT_MI2S_TX",
4560 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4561 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4562 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4563 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4564 SNDRV_PCM_RATE_192000,
4565 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4566 .rate_min = 8000,
4567 .rate_max = 192000,
4568 },
4569 .ops = &msm_dai_q6_mi2s_ops,
4570 .id = MSM_QUAT_MI2S,
4571 .probe = msm_dai_q6_dai_mi2s_probe,
4572 .remove = msm_dai_q6_dai_mi2s_remove,
4573 },
4574 {
4575 .playback = {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304576 .stream_name = "Quinary MI2S Playback",
4577 .aif_name = "QUIN_MI2S_RX",
4578 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4579 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
4580 SNDRV_PCM_RATE_192000,
4581 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4582 .rate_min = 8000,
4583 .rate_max = 192000,
4584 },
4585 .capture = {
4586 .stream_name = "Quinary MI2S Capture",
4587 .aif_name = "QUIN_MI2S_TX",
4588 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4589 SNDRV_PCM_RATE_16000,
4590 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4591 .rate_min = 8000,
4592 .rate_max = 48000,
4593 },
4594 .ops = &msm_dai_q6_mi2s_ops,
4595 .id = MSM_QUIN_MI2S,
4596 .probe = msm_dai_q6_dai_mi2s_probe,
4597 .remove = msm_dai_q6_dai_mi2s_remove,
4598 },
4599 {
Rohit kumarb242df42017-10-16 15:37:05 +05304600 .playback = {
4601 .stream_name = "Secondary MI2S Playback SD1",
4602 .aif_name = "SEC_MI2S_RX_SD1",
4603 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4604 SNDRV_PCM_RATE_16000,
4605 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4606 .rate_min = 8000,
4607 .rate_max = 48000,
4608 },
4609 .id = MSM_SEC_MI2S_SD1,
4610 },
4611 {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304612 .capture = {
4613 .stream_name = "Senary_mi2s Capture",
4614 .aif_name = "SENARY_TX",
4615 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4616 SNDRV_PCM_RATE_16000,
4617 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4618 .rate_min = 8000,
4619 .rate_max = 48000,
4620 },
4621 .ops = &msm_dai_q6_mi2s_ops,
4622 .id = MSM_SENARY_MI2S,
4623 .probe = msm_dai_q6_dai_mi2s_probe,
4624 .remove = msm_dai_q6_dai_mi2s_remove,
4625 },
4626 {
4627 .playback = {
4628 .stream_name = "INT0 MI2S Playback",
4629 .aif_name = "INT0_MI2S_RX",
4630 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4631 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_44100 |
4632 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
4633 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4634 SNDRV_PCM_FMTBIT_S24_LE |
4635 SNDRV_PCM_FMTBIT_S24_3LE,
4636 .rate_min = 8000,
4637 .rate_max = 192000,
4638 },
4639 .capture = {
4640 .stream_name = "INT0 MI2S Capture",
4641 .aif_name = "INT0_MI2S_TX",
4642 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4643 SNDRV_PCM_RATE_16000,
4644 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4645 .rate_min = 8000,
4646 .rate_max = 48000,
4647 },
4648 .ops = &msm_dai_q6_mi2s_ops,
4649 .id = MSM_INT0_MI2S,
4650 .probe = msm_dai_q6_dai_mi2s_probe,
4651 .remove = msm_dai_q6_dai_mi2s_remove,
4652 },
4653 {
4654 .playback = {
4655 .stream_name = "INT1 MI2S Playback",
4656 .aif_name = "INT1_MI2S_RX",
4657 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4658 SNDRV_PCM_RATE_16000,
4659 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4660 SNDRV_PCM_FMTBIT_S24_LE |
4661 SNDRV_PCM_FMTBIT_S24_3LE,
4662 .rate_min = 8000,
4663 .rate_max = 48000,
4664 },
4665 .capture = {
4666 .stream_name = "INT1 MI2S Capture",
4667 .aif_name = "INT1_MI2S_TX",
4668 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4669 SNDRV_PCM_RATE_16000,
4670 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4671 .rate_min = 8000,
4672 .rate_max = 48000,
4673 },
4674 .ops = &msm_dai_q6_mi2s_ops,
4675 .id = MSM_INT1_MI2S,
4676 .probe = msm_dai_q6_dai_mi2s_probe,
4677 .remove = msm_dai_q6_dai_mi2s_remove,
4678 },
4679 {
4680 .playback = {
4681 .stream_name = "INT2 MI2S Playback",
4682 .aif_name = "INT2_MI2S_RX",
4683 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4684 SNDRV_PCM_RATE_16000,
4685 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4686 SNDRV_PCM_FMTBIT_S24_LE |
4687 SNDRV_PCM_FMTBIT_S24_3LE,
4688 .rate_min = 8000,
4689 .rate_max = 48000,
4690 },
4691 .capture = {
4692 .stream_name = "INT2 MI2S Capture",
4693 .aif_name = "INT2_MI2S_TX",
4694 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4695 SNDRV_PCM_RATE_16000,
4696 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4697 .rate_min = 8000,
4698 .rate_max = 48000,
4699 },
4700 .ops = &msm_dai_q6_mi2s_ops,
4701 .id = MSM_INT2_MI2S,
4702 .probe = msm_dai_q6_dai_mi2s_probe,
4703 .remove = msm_dai_q6_dai_mi2s_remove,
4704 },
4705 {
4706 .playback = {
4707 .stream_name = "INT3 MI2S Playback",
4708 .aif_name = "INT3_MI2S_RX",
4709 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4710 SNDRV_PCM_RATE_16000,
4711 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4712 SNDRV_PCM_FMTBIT_S24_LE |
4713 SNDRV_PCM_FMTBIT_S24_3LE,
4714 .rate_min = 8000,
4715 .rate_max = 48000,
4716 },
4717 .capture = {
4718 .stream_name = "INT3 MI2S Capture",
4719 .aif_name = "INT3_MI2S_TX",
4720 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4721 SNDRV_PCM_RATE_16000,
4722 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4723 .rate_min = 8000,
4724 .rate_max = 48000,
4725 },
4726 .ops = &msm_dai_q6_mi2s_ops,
4727 .id = MSM_INT3_MI2S,
4728 .probe = msm_dai_q6_dai_mi2s_probe,
4729 .remove = msm_dai_q6_dai_mi2s_remove,
4730 },
4731 {
4732 .playback = {
4733 .stream_name = "INT4 MI2S Playback",
4734 .aif_name = "INT4_MI2S_RX",
4735 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4736 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
4737 SNDRV_PCM_RATE_192000,
4738 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4739 SNDRV_PCM_FMTBIT_S24_LE |
4740 SNDRV_PCM_FMTBIT_S24_3LE,
4741 .rate_min = 8000,
4742 .rate_max = 192000,
4743 },
4744 .capture = {
4745 .stream_name = "INT4 MI2S Capture",
4746 .aif_name = "INT4_MI2S_TX",
4747 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4748 SNDRV_PCM_RATE_16000,
4749 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4750 .rate_min = 8000,
4751 .rate_max = 48000,
4752 },
4753 .ops = &msm_dai_q6_mi2s_ops,
4754 .id = MSM_INT4_MI2S,
4755 .probe = msm_dai_q6_dai_mi2s_probe,
4756 .remove = msm_dai_q6_dai_mi2s_remove,
4757 },
4758 {
4759 .playback = {
4760 .stream_name = "INT5 MI2S Playback",
4761 .aif_name = "INT5_MI2S_RX",
4762 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4763 SNDRV_PCM_RATE_16000,
4764 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4765 SNDRV_PCM_FMTBIT_S24_LE |
4766 SNDRV_PCM_FMTBIT_S24_3LE,
4767 .rate_min = 8000,
4768 .rate_max = 48000,
4769 },
4770 .capture = {
4771 .stream_name = "INT5 MI2S Capture",
4772 .aif_name = "INT5_MI2S_TX",
4773 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4774 SNDRV_PCM_RATE_16000,
4775 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4776 .rate_min = 8000,
4777 .rate_max = 48000,
4778 },
4779 .ops = &msm_dai_q6_mi2s_ops,
4780 .id = MSM_INT5_MI2S,
4781 .probe = msm_dai_q6_dai_mi2s_probe,
4782 .remove = msm_dai_q6_dai_mi2s_remove,
4783 },
4784 {
4785 .playback = {
4786 .stream_name = "INT6 MI2S Playback",
4787 .aif_name = "INT6_MI2S_RX",
4788 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4789 SNDRV_PCM_RATE_16000,
4790 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4791 SNDRV_PCM_FMTBIT_S24_LE |
4792 SNDRV_PCM_FMTBIT_S24_3LE,
4793 .rate_min = 8000,
4794 .rate_max = 48000,
4795 },
4796 .capture = {
4797 .stream_name = "INT6 MI2S Capture",
4798 .aif_name = "INT6_MI2S_TX",
4799 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4800 SNDRV_PCM_RATE_16000,
4801 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4802 .rate_min = 8000,
4803 .rate_max = 48000,
4804 },
4805 .ops = &msm_dai_q6_mi2s_ops,
4806 .id = MSM_INT6_MI2S,
4807 .probe = msm_dai_q6_dai_mi2s_probe,
4808 .remove = msm_dai_q6_dai_mi2s_remove,
4809 },
4810};
4811
4812
4813static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr,
4814 unsigned int *ch_cnt)
4815{
4816 u8 num_of_sd_lines;
4817
4818 num_of_sd_lines = num_of_bits_set(sd_lines);
4819 switch (num_of_sd_lines) {
4820 case 0:
4821 pr_debug("%s: no line is assigned\n", __func__);
4822 break;
4823 case 1:
4824 switch (sd_lines) {
4825 case MSM_MI2S_SD0:
4826 *config_ptr = AFE_PORT_I2S_SD0;
4827 break;
4828 case MSM_MI2S_SD1:
4829 *config_ptr = AFE_PORT_I2S_SD1;
4830 break;
4831 case MSM_MI2S_SD2:
4832 *config_ptr = AFE_PORT_I2S_SD2;
4833 break;
4834 case MSM_MI2S_SD3:
4835 *config_ptr = AFE_PORT_I2S_SD3;
4836 break;
4837 default:
4838 pr_err("%s: invalid SD lines %d\n",
4839 __func__, sd_lines);
4840 goto error_invalid_data;
4841 }
4842 break;
4843 case 2:
4844 switch (sd_lines) {
4845 case MSM_MI2S_SD0 | MSM_MI2S_SD1:
4846 *config_ptr = AFE_PORT_I2S_QUAD01;
4847 break;
4848 case MSM_MI2S_SD2 | MSM_MI2S_SD3:
4849 *config_ptr = AFE_PORT_I2S_QUAD23;
4850 break;
4851 default:
4852 pr_err("%s: invalid SD lines %d\n",
4853 __func__, sd_lines);
4854 goto error_invalid_data;
4855 }
4856 break;
4857 case 3:
4858 switch (sd_lines) {
4859 case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2:
4860 *config_ptr = AFE_PORT_I2S_6CHS;
4861 break;
4862 default:
4863 pr_err("%s: invalid SD lines %d\n",
4864 __func__, sd_lines);
4865 goto error_invalid_data;
4866 }
4867 break;
4868 case 4:
4869 switch (sd_lines) {
4870 case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3:
4871 *config_ptr = AFE_PORT_I2S_8CHS;
4872 break;
4873 default:
4874 pr_err("%s: invalid SD lines %d\n",
4875 __func__, sd_lines);
4876 goto error_invalid_data;
4877 }
4878 break;
4879 default:
4880 pr_err("%s: invalid SD lines %d\n", __func__, num_of_sd_lines);
4881 goto error_invalid_data;
4882 }
4883 *ch_cnt = num_of_sd_lines;
4884 return 0;
4885
4886error_invalid_data:
4887 pr_err("%s: invalid data\n", __func__);
4888 return -EINVAL;
4889}
4890
4891static int msm_dai_q6_mi2s_platform_data_validation(
4892 struct platform_device *pdev, struct snd_soc_dai_driver *dai_driver)
4893{
4894 struct msm_dai_q6_mi2s_dai_data *dai_data = dev_get_drvdata(&pdev->dev);
4895 struct msm_mi2s_pdata *mi2s_pdata =
4896 (struct msm_mi2s_pdata *) pdev->dev.platform_data;
4897 unsigned int ch_cnt;
4898 int rc = 0;
4899 u16 sd_line;
4900
4901 if (mi2s_pdata == NULL) {
4902 pr_err("%s: mi2s_pdata NULL", __func__);
4903 return -EINVAL;
4904 }
4905
4906 rc = msm_dai_q6_mi2s_get_lineconfig(mi2s_pdata->rx_sd_lines,
4907 &sd_line, &ch_cnt);
4908 if (rc < 0) {
4909 dev_err(&pdev->dev, "invalid MI2S RX sd line config\n");
4910 goto rtn;
4911 }
4912
4913 if (ch_cnt) {
4914 dai_data->rx_dai.mi2s_dai_data.port_config.i2s.channel_mode =
4915 sd_line;
4916 dai_data->rx_dai.pdata_mi2s_lines = sd_line;
4917 dai_driver->playback.channels_min = 1;
4918 dai_driver->playback.channels_max = ch_cnt << 1;
4919 } else {
4920 dai_driver->playback.channels_min = 0;
4921 dai_driver->playback.channels_max = 0;
4922 }
4923 rc = msm_dai_q6_mi2s_get_lineconfig(mi2s_pdata->tx_sd_lines,
4924 &sd_line, &ch_cnt);
4925 if (rc < 0) {
4926 dev_err(&pdev->dev, "invalid MI2S TX sd line config\n");
4927 goto rtn;
4928 }
4929
4930 if (ch_cnt) {
4931 dai_data->tx_dai.mi2s_dai_data.port_config.i2s.channel_mode =
4932 sd_line;
4933 dai_data->tx_dai.pdata_mi2s_lines = sd_line;
4934 dai_driver->capture.channels_min = 1;
4935 dai_driver->capture.channels_max = ch_cnt << 1;
4936 } else {
4937 dai_driver->capture.channels_min = 0;
4938 dai_driver->capture.channels_max = 0;
4939 }
4940
4941 dev_dbg(&pdev->dev, "%s: playback sdline 0x%x capture sdline 0x%x\n",
4942 __func__, dai_data->rx_dai.pdata_mi2s_lines,
4943 dai_data->tx_dai.pdata_mi2s_lines);
4944 dev_dbg(&pdev->dev, "%s: playback ch_max %d capture ch_mx %d\n",
4945 __func__, dai_driver->playback.channels_max,
4946 dai_driver->capture.channels_max);
4947rtn:
4948 return rc;
4949}
4950
4951static const struct snd_soc_component_driver msm_q6_mi2s_dai_component = {
4952 .name = "msm-dai-q6-mi2s",
4953};
4954static int msm_dai_q6_mi2s_dev_probe(struct platform_device *pdev)
4955{
4956 struct msm_dai_q6_mi2s_dai_data *dai_data;
4957 const char *q6_mi2s_dev_id = "qcom,msm-dai-q6-mi2s-dev-id";
4958 u32 tx_line = 0;
4959 u32 rx_line = 0;
4960 u32 mi2s_intf = 0;
4961 struct msm_mi2s_pdata *mi2s_pdata;
4962 int rc;
4963
4964 rc = of_property_read_u32(pdev->dev.of_node, q6_mi2s_dev_id,
4965 &mi2s_intf);
4966 if (rc) {
4967 dev_err(&pdev->dev,
4968 "%s: missing 0x%x in dt node\n", __func__, mi2s_intf);
4969 goto rtn;
4970 }
4971
4972 dev_dbg(&pdev->dev, "dev name %s dev id 0x%x\n", dev_name(&pdev->dev),
4973 mi2s_intf);
4974
4975 if ((mi2s_intf < MSM_MI2S_MIN || mi2s_intf > MSM_MI2S_MAX)
4976 || (mi2s_intf >= ARRAY_SIZE(msm_dai_q6_mi2s_dai))) {
4977 dev_err(&pdev->dev,
4978 "%s: Invalid MI2S ID %u from Device Tree\n",
4979 __func__, mi2s_intf);
4980 rc = -ENXIO;
4981 goto rtn;
4982 }
4983
4984 pdev->id = mi2s_intf;
4985
4986 mi2s_pdata = kzalloc(sizeof(struct msm_mi2s_pdata), GFP_KERNEL);
4987 if (!mi2s_pdata) {
4988 rc = -ENOMEM;
4989 goto rtn;
4990 }
4991
4992 rc = of_property_read_u32(pdev->dev.of_node, "qcom,msm-mi2s-rx-lines",
4993 &rx_line);
4994 if (rc) {
4995 dev_err(&pdev->dev, "%s: Rx line from DT file %s\n", __func__,
4996 "qcom,msm-mi2s-rx-lines");
4997 goto free_pdata;
4998 }
4999
5000 rc = of_property_read_u32(pdev->dev.of_node, "qcom,msm-mi2s-tx-lines",
5001 &tx_line);
5002 if (rc) {
5003 dev_err(&pdev->dev, "%s: Tx line from DT file %s\n", __func__,
5004 "qcom,msm-mi2s-tx-lines");
5005 goto free_pdata;
5006 }
5007 dev_dbg(&pdev->dev, "dev name %s Rx line 0x%x , Tx ine 0x%x\n",
5008 dev_name(&pdev->dev), rx_line, tx_line);
5009 mi2s_pdata->rx_sd_lines = rx_line;
5010 mi2s_pdata->tx_sd_lines = tx_line;
5011 mi2s_pdata->intf_id = mi2s_intf;
5012
5013 dai_data = kzalloc(sizeof(struct msm_dai_q6_mi2s_dai_data),
5014 GFP_KERNEL);
5015 if (!dai_data) {
5016 rc = -ENOMEM;
5017 goto free_pdata;
5018 } else
5019 dev_set_drvdata(&pdev->dev, dai_data);
5020
5021 pdev->dev.platform_data = mi2s_pdata;
5022
5023 rc = msm_dai_q6_mi2s_platform_data_validation(pdev,
5024 &msm_dai_q6_mi2s_dai[mi2s_intf]);
5025 if (rc < 0)
5026 goto free_dai_data;
5027
5028 rc = snd_soc_register_component(&pdev->dev, &msm_q6_mi2s_dai_component,
5029 &msm_dai_q6_mi2s_dai[mi2s_intf], 1);
5030 if (rc < 0)
5031 goto err_register;
5032 return 0;
5033
5034err_register:
5035 dev_err(&pdev->dev, "fail to msm_dai_q6_mi2s_dev_probe\n");
5036free_dai_data:
5037 kfree(dai_data);
5038free_pdata:
5039 kfree(mi2s_pdata);
5040rtn:
5041 return rc;
5042}
5043
5044static int msm_dai_q6_mi2s_dev_remove(struct platform_device *pdev)
5045{
5046 snd_soc_unregister_component(&pdev->dev);
5047 return 0;
5048}
5049
5050static const struct snd_soc_component_driver msm_dai_q6_component = {
5051 .name = "msm-dai-q6-dev",
5052};
5053
5054static int msm_dai_q6_dev_probe(struct platform_device *pdev)
5055{
5056 int rc, id, i, len;
5057 const char *q6_dev_id = "qcom,msm-dai-q6-dev-id";
5058 char stream_name[80];
5059
5060 rc = of_property_read_u32(pdev->dev.of_node, q6_dev_id, &id);
5061 if (rc) {
5062 dev_err(&pdev->dev,
5063 "%s: missing %s in dt node\n", __func__, q6_dev_id);
5064 return rc;
5065 }
5066
5067 pdev->id = id;
5068
5069 pr_debug("%s: dev name %s, id:%d\n", __func__,
5070 dev_name(&pdev->dev), pdev->id);
5071
5072 switch (id) {
5073 case SLIMBUS_0_RX:
5074 strlcpy(stream_name, "Slimbus Playback", 80);
5075 goto register_slim_playback;
5076 case SLIMBUS_2_RX:
5077 strlcpy(stream_name, "Slimbus2 Playback", 80);
5078 goto register_slim_playback;
5079 case SLIMBUS_1_RX:
5080 strlcpy(stream_name, "Slimbus1 Playback", 80);
5081 goto register_slim_playback;
5082 case SLIMBUS_3_RX:
5083 strlcpy(stream_name, "Slimbus3 Playback", 80);
5084 goto register_slim_playback;
5085 case SLIMBUS_4_RX:
5086 strlcpy(stream_name, "Slimbus4 Playback", 80);
5087 goto register_slim_playback;
5088 case SLIMBUS_5_RX:
5089 strlcpy(stream_name, "Slimbus5 Playback", 80);
5090 goto register_slim_playback;
5091 case SLIMBUS_6_RX:
5092 strlcpy(stream_name, "Slimbus6 Playback", 80);
5093 goto register_slim_playback;
5094 case SLIMBUS_7_RX:
5095 strlcpy(stream_name, "Slimbus7 Playback", sizeof(stream_name));
5096 goto register_slim_playback;
5097 case SLIMBUS_8_RX:
5098 strlcpy(stream_name, "Slimbus8 Playback", sizeof(stream_name));
5099 goto register_slim_playback;
5100register_slim_playback:
5101 rc = -ENODEV;
5102 len = strnlen(stream_name, 80);
5103 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_slimbus_rx_dai); i++) {
5104 if (msm_dai_q6_slimbus_rx_dai[i].playback.stream_name &&
5105 !strcmp(stream_name,
5106 msm_dai_q6_slimbus_rx_dai[i]
5107 .playback.stream_name)) {
5108 rc = snd_soc_register_component(&pdev->dev,
5109 &msm_dai_q6_component,
5110 &msm_dai_q6_slimbus_rx_dai[i], 1);
5111 break;
5112 }
5113 }
5114 if (rc)
5115 pr_err("%s: Device not found stream name %s\n",
5116 __func__, stream_name);
5117 break;
5118 case SLIMBUS_0_TX:
5119 strlcpy(stream_name, "Slimbus Capture", 80);
5120 goto register_slim_capture;
5121 case SLIMBUS_1_TX:
5122 strlcpy(stream_name, "Slimbus1 Capture", 80);
5123 goto register_slim_capture;
5124 case SLIMBUS_2_TX:
5125 strlcpy(stream_name, "Slimbus2 Capture", 80);
5126 goto register_slim_capture;
5127 case SLIMBUS_3_TX:
5128 strlcpy(stream_name, "Slimbus3 Capture", 80);
5129 goto register_slim_capture;
5130 case SLIMBUS_4_TX:
5131 strlcpy(stream_name, "Slimbus4 Capture", 80);
5132 goto register_slim_capture;
5133 case SLIMBUS_5_TX:
5134 strlcpy(stream_name, "Slimbus5 Capture", 80);
5135 goto register_slim_capture;
5136 case SLIMBUS_6_TX:
5137 strlcpy(stream_name, "Slimbus6 Capture", 80);
5138 goto register_slim_capture;
5139 case SLIMBUS_7_TX:
5140 strlcpy(stream_name, "Slimbus7 Capture", sizeof(stream_name));
5141 goto register_slim_capture;
5142 case SLIMBUS_8_TX:
5143 strlcpy(stream_name, "Slimbus8 Capture", sizeof(stream_name));
5144 goto register_slim_capture;
5145register_slim_capture:
5146 rc = -ENODEV;
5147 len = strnlen(stream_name, 80);
5148 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_slimbus_tx_dai); i++) {
5149 if (msm_dai_q6_slimbus_tx_dai[i].capture.stream_name &&
5150 !strcmp(stream_name,
5151 msm_dai_q6_slimbus_tx_dai[i]
5152 .capture.stream_name)) {
5153 rc = snd_soc_register_component(&pdev->dev,
5154 &msm_dai_q6_component,
5155 &msm_dai_q6_slimbus_tx_dai[i], 1);
5156 break;
5157 }
5158 }
5159 if (rc)
5160 pr_err("%s: Device not found stream name %s\n",
5161 __func__, stream_name);
5162 break;
Raja Mallik425e1d32018-05-20 19:21:10 +05305163 case AFE_LOOPBACK_TX:
5164 rc = snd_soc_register_component(&pdev->dev,
5165 &msm_dai_q6_component,
5166 &msm_dai_q6_afe_lb_tx_dai[0],
5167 1);
5168 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305169 case INT_BT_SCO_RX:
5170 rc = snd_soc_register_component(&pdev->dev,
5171 &msm_dai_q6_component, &msm_dai_q6_bt_sco_rx_dai, 1);
5172 break;
5173 case INT_BT_SCO_TX:
5174 rc = snd_soc_register_component(&pdev->dev,
5175 &msm_dai_q6_component, &msm_dai_q6_bt_sco_tx_dai, 1);
5176 break;
5177 case INT_BT_A2DP_RX:
5178 rc = snd_soc_register_component(&pdev->dev,
5179 &msm_dai_q6_component, &msm_dai_q6_bt_a2dp_rx_dai, 1);
5180 break;
5181 case INT_FM_RX:
5182 rc = snd_soc_register_component(&pdev->dev,
5183 &msm_dai_q6_component, &msm_dai_q6_fm_rx_dai, 1);
5184 break;
5185 case INT_FM_TX:
5186 rc = snd_soc_register_component(&pdev->dev,
5187 &msm_dai_q6_component, &msm_dai_q6_fm_tx_dai, 1);
5188 break;
5189 case AFE_PORT_ID_USB_RX:
5190 rc = snd_soc_register_component(&pdev->dev,
5191 &msm_dai_q6_component, &msm_dai_q6_usb_rx_dai, 1);
5192 break;
5193 case AFE_PORT_ID_USB_TX:
5194 rc = snd_soc_register_component(&pdev->dev,
5195 &msm_dai_q6_component, &msm_dai_q6_usb_tx_dai, 1);
5196 break;
5197 case RT_PROXY_DAI_001_RX:
5198 strlcpy(stream_name, "AFE Playback", 80);
5199 goto register_afe_playback;
5200 case RT_PROXY_DAI_002_RX:
5201 strlcpy(stream_name, "AFE-PROXY RX", 80);
5202register_afe_playback:
5203 rc = -ENODEV;
5204 len = strnlen(stream_name, 80);
5205 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_afe_rx_dai); i++) {
5206 if (msm_dai_q6_afe_rx_dai[i].playback.stream_name &&
5207 !strcmp(stream_name,
5208 msm_dai_q6_afe_rx_dai[i].playback.stream_name)) {
5209 rc = snd_soc_register_component(&pdev->dev,
5210 &msm_dai_q6_component,
5211 &msm_dai_q6_afe_rx_dai[i], 1);
5212 break;
5213 }
5214 }
5215 if (rc)
5216 pr_err("%s: Device not found stream name %s\n",
5217 __func__, stream_name);
5218 break;
5219 case RT_PROXY_DAI_001_TX:
5220 strlcpy(stream_name, "AFE-PROXY TX", 80);
5221 goto register_afe_capture;
5222 case RT_PROXY_DAI_002_TX:
5223 strlcpy(stream_name, "AFE Capture", 80);
5224register_afe_capture:
5225 rc = -ENODEV;
5226 len = strnlen(stream_name, 80);
5227 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_afe_tx_dai); i++) {
5228 if (msm_dai_q6_afe_tx_dai[i].capture.stream_name &&
5229 !strcmp(stream_name,
5230 msm_dai_q6_afe_tx_dai[i].capture.stream_name)) {
5231 rc = snd_soc_register_component(&pdev->dev,
5232 &msm_dai_q6_component,
5233 &msm_dai_q6_afe_tx_dai[i], 1);
5234 break;
5235 }
5236 }
5237 if (rc)
5238 pr_err("%s: Device not found stream name %s\n",
5239 __func__, stream_name);
5240 break;
5241 case VOICE_PLAYBACK_TX:
5242 strlcpy(stream_name, "Voice Farend Playback", 80);
5243 goto register_voice_playback;
5244 case VOICE2_PLAYBACK_TX:
5245 strlcpy(stream_name, "Voice2 Farend Playback", 80);
5246register_voice_playback:
5247 rc = -ENODEV;
5248 len = strnlen(stream_name, 80);
5249 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_voc_playback_dai); i++) {
5250 if (msm_dai_q6_voc_playback_dai[i].playback.stream_name
5251 && !strcmp(stream_name,
5252 msm_dai_q6_voc_playback_dai[i].playback.stream_name)) {
5253 rc = snd_soc_register_component(&pdev->dev,
5254 &msm_dai_q6_component,
5255 &msm_dai_q6_voc_playback_dai[i], 1);
5256 break;
5257 }
5258 }
5259 if (rc)
5260 pr_err("%s Device not found stream name %s\n",
5261 __func__, stream_name);
5262 break;
5263 case VOICE_RECORD_RX:
5264 strlcpy(stream_name, "Voice Downlink Capture", 80);
5265 goto register_uplink_capture;
5266 case VOICE_RECORD_TX:
5267 strlcpy(stream_name, "Voice Uplink Capture", 80);
5268register_uplink_capture:
5269 rc = -ENODEV;
5270 len = strnlen(stream_name, 80);
5271 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_incall_record_dai); i++) {
5272 if (msm_dai_q6_incall_record_dai[i].capture.stream_name
5273 && !strcmp(stream_name,
5274 msm_dai_q6_incall_record_dai[i].
5275 capture.stream_name)) {
5276 rc = snd_soc_register_component(&pdev->dev,
5277 &msm_dai_q6_component,
5278 &msm_dai_q6_incall_record_dai[i], 1);
5279 break;
5280 }
5281 }
5282 if (rc)
5283 pr_err("%s: Device not found stream name %s\n",
5284 __func__, stream_name);
5285 break;
5286
5287 default:
5288 rc = -ENODEV;
5289 break;
5290 }
5291
5292 return rc;
5293}
5294
5295static int msm_dai_q6_dev_remove(struct platform_device *pdev)
5296{
5297 snd_soc_unregister_component(&pdev->dev);
5298 return 0;
5299}
5300
5301static const struct of_device_id msm_dai_q6_dev_dt_match[] = {
5302 { .compatible = "qcom,msm-dai-q6-dev", },
5303 { }
5304};
5305MODULE_DEVICE_TABLE(of, msm_dai_q6_dev_dt_match);
5306
5307static struct platform_driver msm_dai_q6_dev = {
5308 .probe = msm_dai_q6_dev_probe,
5309 .remove = msm_dai_q6_dev_remove,
5310 .driver = {
5311 .name = "msm-dai-q6-dev",
5312 .owner = THIS_MODULE,
5313 .of_match_table = msm_dai_q6_dev_dt_match,
5314 },
5315};
5316
5317static int msm_dai_q6_probe(struct platform_device *pdev)
5318{
5319 int rc;
5320
5321 pr_debug("%s: dev name %s, id:%d\n", __func__,
5322 dev_name(&pdev->dev), pdev->id);
5323 rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
5324 if (rc) {
5325 dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n",
5326 __func__, rc);
5327 } else
5328 dev_dbg(&pdev->dev, "%s: added child node\n", __func__);
5329
5330 return rc;
5331}
5332
5333static int msm_dai_q6_remove(struct platform_device *pdev)
5334{
5335 return 0;
5336}
5337
5338static const struct of_device_id msm_dai_q6_dt_match[] = {
5339 { .compatible = "qcom,msm-dai-q6", },
5340 { }
5341};
5342MODULE_DEVICE_TABLE(of, msm_dai_q6_dt_match);
5343static struct platform_driver msm_dai_q6 = {
5344 .probe = msm_dai_q6_probe,
5345 .remove = msm_dai_q6_remove,
5346 .driver = {
5347 .name = "msm-dai-q6",
5348 .owner = THIS_MODULE,
5349 .of_match_table = msm_dai_q6_dt_match,
5350 },
5351};
5352
5353static int msm_dai_mi2s_q6_probe(struct platform_device *pdev)
5354{
5355 int rc;
5356
5357 rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
5358 if (rc) {
5359 dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n",
5360 __func__, rc);
5361 } else
5362 dev_dbg(&pdev->dev, "%s: added child node\n", __func__);
5363 return rc;
5364}
5365
5366static int msm_dai_mi2s_q6_remove(struct platform_device *pdev)
5367{
5368 return 0;
5369}
5370
5371static const struct of_device_id msm_dai_mi2s_dt_match[] = {
5372 { .compatible = "qcom,msm-dai-mi2s", },
5373 { }
5374};
5375
5376MODULE_DEVICE_TABLE(of, msm_dai_mi2s_dt_match);
5377
5378static struct platform_driver msm_dai_mi2s_q6 = {
5379 .probe = msm_dai_mi2s_q6_probe,
5380 .remove = msm_dai_mi2s_q6_remove,
5381 .driver = {
5382 .name = "msm-dai-mi2s",
5383 .owner = THIS_MODULE,
5384 .of_match_table = msm_dai_mi2s_dt_match,
5385 },
5386};
5387
5388static const struct of_device_id msm_dai_q6_mi2s_dev_dt_match[] = {
5389 { .compatible = "qcom,msm-dai-q6-mi2s", },
5390 { }
5391};
5392
5393MODULE_DEVICE_TABLE(of, msm_dai_q6_mi2s_dev_dt_match);
5394
5395static struct platform_driver msm_dai_q6_mi2s_driver = {
5396 .probe = msm_dai_q6_mi2s_dev_probe,
5397 .remove = msm_dai_q6_mi2s_dev_remove,
5398 .driver = {
5399 .name = "msm-dai-q6-mi2s",
5400 .owner = THIS_MODULE,
5401 .of_match_table = msm_dai_q6_mi2s_dev_dt_match,
5402 },
5403};
5404
5405static int msm_dai_q6_spdif_dev_probe(struct platform_device *pdev)
5406{
5407 int rc;
5408
5409 pdev->id = AFE_PORT_ID_SPDIF_RX;
5410
5411 pr_debug("%s: dev name %s, id:%d\n", __func__,
5412 dev_name(&pdev->dev), pdev->id);
5413
5414 rc = snd_soc_register_component(&pdev->dev,
5415 &msm_dai_spdif_q6_component,
5416 &msm_dai_q6_spdif_spdif_rx_dai, 1);
5417 return rc;
5418}
5419
5420static int msm_dai_q6_spdif_dev_remove(struct platform_device *pdev)
5421{
5422 snd_soc_unregister_component(&pdev->dev);
5423 return 0;
5424}
5425
5426static const struct of_device_id msm_dai_q6_spdif_dt_match[] = {
5427 {.compatible = "qcom,msm-dai-q6-spdif"},
5428 {}
5429};
5430MODULE_DEVICE_TABLE(of, msm_dai_q6_spdif_dt_match);
5431
5432static struct platform_driver msm_dai_q6_spdif_driver = {
5433 .probe = msm_dai_q6_spdif_dev_probe,
5434 .remove = msm_dai_q6_spdif_dev_remove,
5435 .driver = {
5436 .name = "msm-dai-q6-spdif",
5437 .owner = THIS_MODULE,
5438 .of_match_table = msm_dai_q6_spdif_dt_match,
5439 },
5440};
5441
5442static int msm_dai_q6_tdm_set_clk_param(u32 group_id,
5443 struct afe_clk_set *clk_set, u32 mode)
5444{
5445 switch (group_id) {
5446 case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX:
5447 case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX:
5448 if (mode)
5449 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT;
5450 else
5451 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_PRI_TDM_EBIT;
5452 break;
5453 case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_RX:
5454 case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_TX:
5455 if (mode)
5456 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT;
5457 else
5458 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_SEC_TDM_EBIT;
5459 break;
5460 case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_RX:
5461 case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_TX:
5462 if (mode)
5463 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT;
5464 else
5465 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_TER_TDM_EBIT;
5466 break;
5467 case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_RX:
5468 case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_TX:
5469 if (mode)
5470 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT;
5471 else
5472 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUAD_TDM_EBIT;
5473 break;
Rohit Kumara5077932017-09-10 22:05:05 +05305474 case AFE_GROUP_DEVICE_ID_QUINARY_TDM_RX:
5475 case AFE_GROUP_DEVICE_ID_QUINARY_TDM_TX:
5476 if (mode)
5477 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUIN_TDM_IBIT;
5478 else
5479 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT;
5480 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305481 default:
5482 return -EINVAL;
5483 }
5484 return 0;
5485}
5486
5487static int msm_dai_tdm_q6_probe(struct platform_device *pdev)
5488{
5489 int rc = 0;
5490 const uint32_t *port_id_array = NULL;
5491 uint32_t array_length = 0;
5492 int i = 0;
5493 int group_idx = 0;
5494 u32 clk_mode = 0;
5495
5496 /* extract tdm group info into static */
5497 rc = of_property_read_u32(pdev->dev.of_node,
5498 "qcom,msm-cpudai-tdm-group-id",
5499 (u32 *)&tdm_group_cfg.group_id);
5500 if (rc) {
5501 dev_err(&pdev->dev, "%s: Group ID from DT file %s\n",
5502 __func__, "qcom,msm-cpudai-tdm-group-id");
5503 goto rtn;
5504 }
5505 dev_dbg(&pdev->dev, "%s: Group ID from DT file 0x%x\n",
5506 __func__, tdm_group_cfg.group_id);
5507
5508 dev_info(&pdev->dev, "%s: dev_name: %s group_id: 0x%x\n",
5509 __func__, dev_name(&pdev->dev), tdm_group_cfg.group_id);
5510
5511 rc = of_property_read_u32(pdev->dev.of_node,
5512 "qcom,msm-cpudai-tdm-group-num-ports",
5513 &num_tdm_group_ports);
5514 if (rc) {
5515 dev_err(&pdev->dev, "%s: Group Num Ports from DT file %s\n",
5516 __func__, "qcom,msm-cpudai-tdm-group-num-ports");
5517 goto rtn;
5518 }
5519 dev_dbg(&pdev->dev, "%s: Group Num Ports from DT file 0x%x\n",
5520 __func__, num_tdm_group_ports);
5521
5522 if (num_tdm_group_ports > AFE_GROUP_DEVICE_NUM_PORTS) {
5523 dev_err(&pdev->dev, "%s Group Num Ports %d greater than Max %d\n",
5524 __func__, num_tdm_group_ports,
5525 AFE_GROUP_DEVICE_NUM_PORTS);
5526 rc = -EINVAL;
5527 goto rtn;
5528 }
5529
5530 port_id_array = of_get_property(pdev->dev.of_node,
5531 "qcom,msm-cpudai-tdm-group-port-id",
5532 &array_length);
5533 if (port_id_array == NULL) {
5534 dev_err(&pdev->dev, "%s port_id_array is not valid\n",
5535 __func__);
5536 rc = -EINVAL;
5537 goto rtn;
5538 }
5539 if (array_length != sizeof(uint32_t) * num_tdm_group_ports) {
5540 dev_err(&pdev->dev, "%s array_length is %d, expected is %zd\n",
5541 __func__, array_length,
5542 sizeof(uint32_t) * num_tdm_group_ports);
5543 rc = -EINVAL;
5544 goto rtn;
5545 }
5546
5547 for (i = 0; i < num_tdm_group_ports; i++)
5548 tdm_group_cfg.port_id[i] =
5549 (u16)be32_to_cpu(port_id_array[i]);
5550 /* Unused index should be filled with 0 or AFE_PORT_INVALID */
5551 for (i = num_tdm_group_ports; i < AFE_GROUP_DEVICE_NUM_PORTS; i++)
5552 tdm_group_cfg.port_id[i] =
5553 AFE_PORT_INVALID;
5554
5555 /* extract tdm clk info into static */
5556 rc = of_property_read_u32(pdev->dev.of_node,
5557 "qcom,msm-cpudai-tdm-clk-rate",
5558 &tdm_clk_set.clk_freq_in_hz);
5559 if (rc) {
5560 dev_err(&pdev->dev, "%s: Clk Rate from DT file %s\n",
5561 __func__, "qcom,msm-cpudai-tdm-clk-rate");
5562 goto rtn;
5563 }
5564 dev_dbg(&pdev->dev, "%s: Clk Rate from DT file %d\n",
5565 __func__, tdm_clk_set.clk_freq_in_hz);
5566
Cong Tang2b6adc82017-05-26 12:06:50 +08005567 /* initialize static tdm clk attribute to default value */
5568 tdm_clk_set.clk_attri = Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO;
5569
5570 /* extract tdm clk attribute into static */
5571 if (of_find_property(pdev->dev.of_node,
5572 "qcom,msm-cpudai-tdm-clk-attribute", NULL)) {
5573 rc = of_property_read_u16(pdev->dev.of_node,
5574 "qcom,msm-cpudai-tdm-clk-attribute",
5575 &tdm_clk_set.clk_attri);
5576 if (rc) {
5577 dev_err(&pdev->dev, "%s: value for clk attribute not found %s\n",
5578 __func__, "qcom,msm-cpudai-tdm-clk-attribute");
5579 goto rtn;
5580 }
5581 dev_dbg(&pdev->dev, "%s: clk attribute from DT file %d\n",
5582 __func__, tdm_clk_set.clk_attri);
5583 } else
5584 dev_dbg(&pdev->dev, "%s: clk attribute not found\n", __func__);
5585
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305586 /* extract tdm clk src master/slave info into static */
5587 rc = of_property_read_u32(pdev->dev.of_node,
5588 "qcom,msm-cpudai-tdm-clk-internal",
5589 &clk_mode);
5590 if (rc) {
5591 dev_err(&pdev->dev, "%s: Clk id from DT file %s\n",
5592 __func__, "qcom,msm-cpudai-tdm-clk-internal");
5593 goto rtn;
5594 }
5595 dev_dbg(&pdev->dev, "%s: Clk id from DT file %d\n",
5596 __func__, clk_mode);
5597
5598 rc = msm_dai_q6_tdm_set_clk_param(tdm_group_cfg.group_id,
5599 &tdm_clk_set, clk_mode);
5600 if (rc) {
5601 dev_err(&pdev->dev, "%s: group id not supported 0x%x\n",
5602 __func__, tdm_group_cfg.group_id);
5603 goto rtn;
5604 }
5605
Ashish Jain757e1452018-04-30 20:58:04 +05305606 afe_ebit_unsupported = of_property_read_bool(pdev->dev.of_node,
5607 "qcom,msm-cpudai-tdm-afe-ebit-unsupported");
5608
5609 dev_dbg(&pdev->dev, "afe_ebit_unsupported %d\n", afe_ebit_unsupported);
5610
Surendar karka23677262018-04-30 22:52:08 +05305611 tdm_sec_port_enable = of_property_read_bool(pdev->dev.of_node,
5612 "qcom,msm-cpudai-tdm-sec-port-enable");
5613
5614 dev_dbg(&pdev->dev, "%s: tdm_sec_port_enable %d\n", __func__, tdm_sec_port_enable);
5615
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305616 /* other initializations within device group */
5617 group_idx = msm_dai_q6_get_group_idx(tdm_group_cfg.group_id);
5618 if (group_idx < 0) {
5619 dev_err(&pdev->dev, "%s: group id 0x%x not supported\n",
5620 __func__, tdm_group_cfg.group_id);
5621 rc = -EINVAL;
5622 goto rtn;
5623 }
5624 atomic_set(&tdm_group_ref[group_idx], 0);
5625
5626 /* probe child node info */
5627 rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
5628 if (rc) {
5629 dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n",
5630 __func__, rc);
5631 goto rtn;
5632 } else
5633 dev_dbg(&pdev->dev, "%s: added child node\n", __func__);
5634
5635rtn:
5636 return rc;
5637}
5638
5639static int msm_dai_tdm_q6_remove(struct platform_device *pdev)
5640{
5641 return 0;
5642}
5643
5644static const struct of_device_id msm_dai_tdm_dt_match[] = {
5645 { .compatible = "qcom,msm-dai-tdm", },
5646 {}
5647};
5648
5649MODULE_DEVICE_TABLE(of, msm_dai_tdm_dt_match);
5650
5651static struct platform_driver msm_dai_tdm_q6 = {
5652 .probe = msm_dai_tdm_q6_probe,
5653 .remove = msm_dai_tdm_q6_remove,
5654 .driver = {
5655 .name = "msm-dai-tdm",
5656 .owner = THIS_MODULE,
5657 .of_match_table = msm_dai_tdm_dt_match,
5658 },
5659};
5660
5661static int msm_dai_q6_tdm_data_format_put(struct snd_kcontrol *kcontrol,
5662 struct snd_ctl_elem_value *ucontrol)
5663{
5664 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5665 int value = ucontrol->value.integer.value[0];
5666
5667 switch (value) {
5668 case 0:
5669 dai_data->port_cfg.tdm.data_format = AFE_LINEAR_PCM_DATA;
5670 break;
5671 case 1:
5672 dai_data->port_cfg.tdm.data_format = AFE_NON_LINEAR_DATA;
5673 break;
5674 case 2:
5675 dai_data->port_cfg.tdm.data_format = AFE_GENERIC_COMPRESSED;
5676 break;
5677 default:
5678 pr_err("%s: data_format invalid\n", __func__);
5679 break;
5680 }
5681 pr_debug("%s: data_format = %d\n",
5682 __func__, dai_data->port_cfg.tdm.data_format);
5683 return 0;
5684}
5685
5686static int msm_dai_q6_tdm_data_format_get(struct snd_kcontrol *kcontrol,
5687 struct snd_ctl_elem_value *ucontrol)
5688{
5689 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5690
5691 ucontrol->value.integer.value[0] =
5692 dai_data->port_cfg.tdm.data_format;
5693 pr_debug("%s: data_format = %d\n",
5694 __func__, dai_data->port_cfg.tdm.data_format);
5695 return 0;
5696}
5697
5698static int msm_dai_q6_tdm_header_type_put(struct snd_kcontrol *kcontrol,
5699 struct snd_ctl_elem_value *ucontrol)
5700{
5701 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5702 int value = ucontrol->value.integer.value[0];
5703
5704 dai_data->port_cfg.custom_tdm_header.header_type = value;
5705 pr_debug("%s: header_type = %d\n",
5706 __func__,
5707 dai_data->port_cfg.custom_tdm_header.header_type);
5708 return 0;
5709}
5710
5711static int msm_dai_q6_tdm_header_type_get(struct snd_kcontrol *kcontrol,
5712 struct snd_ctl_elem_value *ucontrol)
5713{
5714 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5715
5716 ucontrol->value.integer.value[0] =
5717 dai_data->port_cfg.custom_tdm_header.header_type;
5718 pr_debug("%s: header_type = %d\n",
5719 __func__,
5720 dai_data->port_cfg.custom_tdm_header.header_type);
5721 return 0;
5722}
5723
5724static int msm_dai_q6_tdm_header_put(struct snd_kcontrol *kcontrol,
5725 struct snd_ctl_elem_value *ucontrol)
5726{
5727 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5728 int i = 0;
5729
5730 for (i = 0; i < AFE_CUSTOM_TDM_HEADER_MAX_CNT; i++) {
5731 dai_data->port_cfg.custom_tdm_header.header[i] =
5732 (u16)ucontrol->value.integer.value[i];
5733 pr_debug("%s: header #%d = 0x%x\n",
5734 __func__, i,
5735 dai_data->port_cfg.custom_tdm_header.header[i]);
5736 }
5737 return 0;
5738}
5739
5740static int msm_dai_q6_tdm_header_get(struct snd_kcontrol *kcontrol,
5741 struct snd_ctl_elem_value *ucontrol)
5742{
5743 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5744 int i = 0;
5745
5746 for (i = 0; i < AFE_CUSTOM_TDM_HEADER_MAX_CNT; i++) {
5747 ucontrol->value.integer.value[i] =
5748 dai_data->port_cfg.custom_tdm_header.header[i];
5749 pr_debug("%s: header #%d = 0x%x\n",
5750 __func__, i,
5751 dai_data->port_cfg.custom_tdm_header.header[i]);
5752 }
5753 return 0;
5754}
5755
5756static const struct snd_kcontrol_new tdm_config_controls_data_format[] = {
5757 SOC_ENUM_EXT("PRI_TDM_RX_0 Data Format", tdm_config_enum[0],
5758 msm_dai_q6_tdm_data_format_get,
5759 msm_dai_q6_tdm_data_format_put),
5760 SOC_ENUM_EXT("PRI_TDM_RX_1 Data Format", tdm_config_enum[0],
5761 msm_dai_q6_tdm_data_format_get,
5762 msm_dai_q6_tdm_data_format_put),
5763 SOC_ENUM_EXT("PRI_TDM_RX_2 Data Format", tdm_config_enum[0],
5764 msm_dai_q6_tdm_data_format_get,
5765 msm_dai_q6_tdm_data_format_put),
5766 SOC_ENUM_EXT("PRI_TDM_RX_3 Data Format", tdm_config_enum[0],
5767 msm_dai_q6_tdm_data_format_get,
5768 msm_dai_q6_tdm_data_format_put),
5769 SOC_ENUM_EXT("PRI_TDM_RX_4 Data Format", tdm_config_enum[0],
5770 msm_dai_q6_tdm_data_format_get,
5771 msm_dai_q6_tdm_data_format_put),
5772 SOC_ENUM_EXT("PRI_TDM_RX_5 Data Format", tdm_config_enum[0],
5773 msm_dai_q6_tdm_data_format_get,
5774 msm_dai_q6_tdm_data_format_put),
5775 SOC_ENUM_EXT("PRI_TDM_RX_6 Data Format", tdm_config_enum[0],
5776 msm_dai_q6_tdm_data_format_get,
5777 msm_dai_q6_tdm_data_format_put),
5778 SOC_ENUM_EXT("PRI_TDM_RX_7 Data Format", tdm_config_enum[0],
5779 msm_dai_q6_tdm_data_format_get,
5780 msm_dai_q6_tdm_data_format_put),
5781 SOC_ENUM_EXT("PRI_TDM_TX_0 Data Format", tdm_config_enum[0],
5782 msm_dai_q6_tdm_data_format_get,
5783 msm_dai_q6_tdm_data_format_put),
5784 SOC_ENUM_EXT("PRI_TDM_TX_1 Data Format", tdm_config_enum[0],
5785 msm_dai_q6_tdm_data_format_get,
5786 msm_dai_q6_tdm_data_format_put),
5787 SOC_ENUM_EXT("PRI_TDM_TX_2 Data Format", tdm_config_enum[0],
5788 msm_dai_q6_tdm_data_format_get,
5789 msm_dai_q6_tdm_data_format_put),
5790 SOC_ENUM_EXT("PRI_TDM_TX_3 Data Format", tdm_config_enum[0],
5791 msm_dai_q6_tdm_data_format_get,
5792 msm_dai_q6_tdm_data_format_put),
5793 SOC_ENUM_EXT("PRI_TDM_TX_4 Data Format", tdm_config_enum[0],
5794 msm_dai_q6_tdm_data_format_get,
5795 msm_dai_q6_tdm_data_format_put),
5796 SOC_ENUM_EXT("PRI_TDM_TX_5 Data Format", tdm_config_enum[0],
5797 msm_dai_q6_tdm_data_format_get,
5798 msm_dai_q6_tdm_data_format_put),
5799 SOC_ENUM_EXT("PRI_TDM_TX_6 Data Format", tdm_config_enum[0],
5800 msm_dai_q6_tdm_data_format_get,
5801 msm_dai_q6_tdm_data_format_put),
5802 SOC_ENUM_EXT("PRI_TDM_TX_7 Data Format", tdm_config_enum[0],
5803 msm_dai_q6_tdm_data_format_get,
5804 msm_dai_q6_tdm_data_format_put),
5805 SOC_ENUM_EXT("SEC_TDM_RX_0 Data Format", tdm_config_enum[0],
5806 msm_dai_q6_tdm_data_format_get,
5807 msm_dai_q6_tdm_data_format_put),
5808 SOC_ENUM_EXT("SEC_TDM_RX_1 Data Format", tdm_config_enum[0],
5809 msm_dai_q6_tdm_data_format_get,
5810 msm_dai_q6_tdm_data_format_put),
5811 SOC_ENUM_EXT("SEC_TDM_RX_2 Data Format", tdm_config_enum[0],
5812 msm_dai_q6_tdm_data_format_get,
5813 msm_dai_q6_tdm_data_format_put),
5814 SOC_ENUM_EXT("SEC_TDM_RX_3 Data Format", tdm_config_enum[0],
5815 msm_dai_q6_tdm_data_format_get,
5816 msm_dai_q6_tdm_data_format_put),
5817 SOC_ENUM_EXT("SEC_TDM_RX_4 Data Format", tdm_config_enum[0],
5818 msm_dai_q6_tdm_data_format_get,
5819 msm_dai_q6_tdm_data_format_put),
5820 SOC_ENUM_EXT("SEC_TDM_RX_5 Data Format", tdm_config_enum[0],
5821 msm_dai_q6_tdm_data_format_get,
5822 msm_dai_q6_tdm_data_format_put),
5823 SOC_ENUM_EXT("SEC_TDM_RX_6 Data Format", tdm_config_enum[0],
5824 msm_dai_q6_tdm_data_format_get,
5825 msm_dai_q6_tdm_data_format_put),
5826 SOC_ENUM_EXT("SEC_TDM_RX_7 Data Format", tdm_config_enum[0],
5827 msm_dai_q6_tdm_data_format_get,
5828 msm_dai_q6_tdm_data_format_put),
5829 SOC_ENUM_EXT("SEC_TDM_TX_0 Data Format", tdm_config_enum[0],
5830 msm_dai_q6_tdm_data_format_get,
5831 msm_dai_q6_tdm_data_format_put),
5832 SOC_ENUM_EXT("SEC_TDM_TX_1 Data Format", tdm_config_enum[0],
5833 msm_dai_q6_tdm_data_format_get,
5834 msm_dai_q6_tdm_data_format_put),
5835 SOC_ENUM_EXT("SEC_TDM_TX_2 Data Format", tdm_config_enum[0],
5836 msm_dai_q6_tdm_data_format_get,
5837 msm_dai_q6_tdm_data_format_put),
5838 SOC_ENUM_EXT("SEC_TDM_TX_3 Data Format", tdm_config_enum[0],
5839 msm_dai_q6_tdm_data_format_get,
5840 msm_dai_q6_tdm_data_format_put),
5841 SOC_ENUM_EXT("SEC_TDM_TX_4 Data Format", tdm_config_enum[0],
5842 msm_dai_q6_tdm_data_format_get,
5843 msm_dai_q6_tdm_data_format_put),
5844 SOC_ENUM_EXT("SEC_TDM_TX_5 Data Format", tdm_config_enum[0],
5845 msm_dai_q6_tdm_data_format_get,
5846 msm_dai_q6_tdm_data_format_put),
5847 SOC_ENUM_EXT("SEC_TDM_TX_6 Data Format", tdm_config_enum[0],
5848 msm_dai_q6_tdm_data_format_get,
5849 msm_dai_q6_tdm_data_format_put),
5850 SOC_ENUM_EXT("SEC_TDM_TX_7 Data Format", tdm_config_enum[0],
5851 msm_dai_q6_tdm_data_format_get,
5852 msm_dai_q6_tdm_data_format_put),
5853 SOC_ENUM_EXT("TERT_TDM_RX_0 Data Format", tdm_config_enum[0],
5854 msm_dai_q6_tdm_data_format_get,
5855 msm_dai_q6_tdm_data_format_put),
5856 SOC_ENUM_EXT("TERT_TDM_RX_1 Data Format", tdm_config_enum[0],
5857 msm_dai_q6_tdm_data_format_get,
5858 msm_dai_q6_tdm_data_format_put),
5859 SOC_ENUM_EXT("TERT_TDM_RX_2 Data Format", tdm_config_enum[0],
5860 msm_dai_q6_tdm_data_format_get,
5861 msm_dai_q6_tdm_data_format_put),
5862 SOC_ENUM_EXT("TERT_TDM_RX_3 Data Format", tdm_config_enum[0],
5863 msm_dai_q6_tdm_data_format_get,
5864 msm_dai_q6_tdm_data_format_put),
5865 SOC_ENUM_EXT("TERT_TDM_RX_4 Data Format", tdm_config_enum[0],
5866 msm_dai_q6_tdm_data_format_get,
5867 msm_dai_q6_tdm_data_format_put),
5868 SOC_ENUM_EXT("TERT_TDM_RX_5 Data Format", tdm_config_enum[0],
5869 msm_dai_q6_tdm_data_format_get,
5870 msm_dai_q6_tdm_data_format_put),
5871 SOC_ENUM_EXT("TERT_TDM_RX_6 Data Format", tdm_config_enum[0],
5872 msm_dai_q6_tdm_data_format_get,
5873 msm_dai_q6_tdm_data_format_put),
5874 SOC_ENUM_EXT("TERT_TDM_RX_7 Data Format", tdm_config_enum[0],
5875 msm_dai_q6_tdm_data_format_get,
5876 msm_dai_q6_tdm_data_format_put),
5877 SOC_ENUM_EXT("TERT_TDM_TX_0 Data Format", tdm_config_enum[0],
5878 msm_dai_q6_tdm_data_format_get,
5879 msm_dai_q6_tdm_data_format_put),
5880 SOC_ENUM_EXT("TERT_TDM_TX_1 Data Format", tdm_config_enum[0],
5881 msm_dai_q6_tdm_data_format_get,
5882 msm_dai_q6_tdm_data_format_put),
5883 SOC_ENUM_EXT("TERT_TDM_TX_2 Data Format", tdm_config_enum[0],
5884 msm_dai_q6_tdm_data_format_get,
5885 msm_dai_q6_tdm_data_format_put),
5886 SOC_ENUM_EXT("TERT_TDM_TX_3 Data Format", tdm_config_enum[0],
5887 msm_dai_q6_tdm_data_format_get,
5888 msm_dai_q6_tdm_data_format_put),
5889 SOC_ENUM_EXT("TERT_TDM_TX_4 Data Format", tdm_config_enum[0],
5890 msm_dai_q6_tdm_data_format_get,
5891 msm_dai_q6_tdm_data_format_put),
5892 SOC_ENUM_EXT("TERT_TDM_TX_5 Data Format", tdm_config_enum[0],
5893 msm_dai_q6_tdm_data_format_get,
5894 msm_dai_q6_tdm_data_format_put),
5895 SOC_ENUM_EXT("TERT_TDM_TX_6 Data Format", tdm_config_enum[0],
5896 msm_dai_q6_tdm_data_format_get,
5897 msm_dai_q6_tdm_data_format_put),
5898 SOC_ENUM_EXT("TERT_TDM_TX_7 Data Format", tdm_config_enum[0],
5899 msm_dai_q6_tdm_data_format_get,
5900 msm_dai_q6_tdm_data_format_put),
5901 SOC_ENUM_EXT("QUAT_TDM_RX_0 Data Format", tdm_config_enum[0],
5902 msm_dai_q6_tdm_data_format_get,
5903 msm_dai_q6_tdm_data_format_put),
5904 SOC_ENUM_EXT("QUAT_TDM_RX_1 Data Format", tdm_config_enum[0],
5905 msm_dai_q6_tdm_data_format_get,
5906 msm_dai_q6_tdm_data_format_put),
5907 SOC_ENUM_EXT("QUAT_TDM_RX_2 Data Format", tdm_config_enum[0],
5908 msm_dai_q6_tdm_data_format_get,
5909 msm_dai_q6_tdm_data_format_put),
5910 SOC_ENUM_EXT("QUAT_TDM_RX_3 Data Format", tdm_config_enum[0],
5911 msm_dai_q6_tdm_data_format_get,
5912 msm_dai_q6_tdm_data_format_put),
5913 SOC_ENUM_EXT("QUAT_TDM_RX_4 Data Format", tdm_config_enum[0],
5914 msm_dai_q6_tdm_data_format_get,
5915 msm_dai_q6_tdm_data_format_put),
5916 SOC_ENUM_EXT("QUAT_TDM_RX_5 Data Format", tdm_config_enum[0],
5917 msm_dai_q6_tdm_data_format_get,
5918 msm_dai_q6_tdm_data_format_put),
5919 SOC_ENUM_EXT("QUAT_TDM_RX_6 Data Format", tdm_config_enum[0],
5920 msm_dai_q6_tdm_data_format_get,
5921 msm_dai_q6_tdm_data_format_put),
5922 SOC_ENUM_EXT("QUAT_TDM_RX_7 Data Format", tdm_config_enum[0],
5923 msm_dai_q6_tdm_data_format_get,
5924 msm_dai_q6_tdm_data_format_put),
5925 SOC_ENUM_EXT("QUAT_TDM_TX_0 Data Format", tdm_config_enum[0],
5926 msm_dai_q6_tdm_data_format_get,
5927 msm_dai_q6_tdm_data_format_put),
5928 SOC_ENUM_EXT("QUAT_TDM_TX_1 Data Format", tdm_config_enum[0],
5929 msm_dai_q6_tdm_data_format_get,
5930 msm_dai_q6_tdm_data_format_put),
5931 SOC_ENUM_EXT("QUAT_TDM_TX_2 Data Format", tdm_config_enum[0],
5932 msm_dai_q6_tdm_data_format_get,
5933 msm_dai_q6_tdm_data_format_put),
5934 SOC_ENUM_EXT("QUAT_TDM_TX_3 Data Format", tdm_config_enum[0],
5935 msm_dai_q6_tdm_data_format_get,
5936 msm_dai_q6_tdm_data_format_put),
5937 SOC_ENUM_EXT("QUAT_TDM_TX_4 Data Format", tdm_config_enum[0],
5938 msm_dai_q6_tdm_data_format_get,
5939 msm_dai_q6_tdm_data_format_put),
5940 SOC_ENUM_EXT("QUAT_TDM_TX_5 Data Format", tdm_config_enum[0],
5941 msm_dai_q6_tdm_data_format_get,
5942 msm_dai_q6_tdm_data_format_put),
5943 SOC_ENUM_EXT("QUAT_TDM_TX_6 Data Format", tdm_config_enum[0],
5944 msm_dai_q6_tdm_data_format_get,
5945 msm_dai_q6_tdm_data_format_put),
5946 SOC_ENUM_EXT("QUAT_TDM_TX_7 Data Format", tdm_config_enum[0],
5947 msm_dai_q6_tdm_data_format_get,
5948 msm_dai_q6_tdm_data_format_put),
Rohit Kumara5077932017-09-10 22:05:05 +05305949 SOC_ENUM_EXT("QUIN_TDM_RX_0 Data Format", tdm_config_enum[0],
5950 msm_dai_q6_tdm_data_format_get,
5951 msm_dai_q6_tdm_data_format_put),
5952 SOC_ENUM_EXT("QUIN_TDM_RX_1 Data Format", tdm_config_enum[0],
5953 msm_dai_q6_tdm_data_format_get,
5954 msm_dai_q6_tdm_data_format_put),
5955 SOC_ENUM_EXT("QUIN_TDM_RX_2 Data Format", tdm_config_enum[0],
5956 msm_dai_q6_tdm_data_format_get,
5957 msm_dai_q6_tdm_data_format_put),
5958 SOC_ENUM_EXT("QUIN_TDM_RX_3 Data Format", tdm_config_enum[0],
5959 msm_dai_q6_tdm_data_format_get,
5960 msm_dai_q6_tdm_data_format_put),
5961 SOC_ENUM_EXT("QUIN_TDM_RX_4 Data Format", tdm_config_enum[0],
5962 msm_dai_q6_tdm_data_format_get,
5963 msm_dai_q6_tdm_data_format_put),
5964 SOC_ENUM_EXT("QUIN_TDM_RX_5 Data Format", tdm_config_enum[0],
5965 msm_dai_q6_tdm_data_format_get,
5966 msm_dai_q6_tdm_data_format_put),
5967 SOC_ENUM_EXT("QUIN_TDM_RX_6 Data Format", tdm_config_enum[0],
5968 msm_dai_q6_tdm_data_format_get,
5969 msm_dai_q6_tdm_data_format_put),
5970 SOC_ENUM_EXT("QUIN_TDM_RX_7 Data Format", tdm_config_enum[0],
5971 msm_dai_q6_tdm_data_format_get,
5972 msm_dai_q6_tdm_data_format_put),
5973 SOC_ENUM_EXT("QUIN_TDM_TX_0 Data Format", tdm_config_enum[0],
5974 msm_dai_q6_tdm_data_format_get,
5975 msm_dai_q6_tdm_data_format_put),
5976 SOC_ENUM_EXT("QUIN_TDM_TX_1 Data Format", tdm_config_enum[0],
5977 msm_dai_q6_tdm_data_format_get,
5978 msm_dai_q6_tdm_data_format_put),
5979 SOC_ENUM_EXT("QUIN_TDM_TX_2 Data Format", tdm_config_enum[0],
5980 msm_dai_q6_tdm_data_format_get,
5981 msm_dai_q6_tdm_data_format_put),
5982 SOC_ENUM_EXT("QUIN_TDM_TX_3 Data Format", tdm_config_enum[0],
5983 msm_dai_q6_tdm_data_format_get,
5984 msm_dai_q6_tdm_data_format_put),
5985 SOC_ENUM_EXT("QUIN_TDM_TX_4 Data Format", tdm_config_enum[0],
5986 msm_dai_q6_tdm_data_format_get,
5987 msm_dai_q6_tdm_data_format_put),
5988 SOC_ENUM_EXT("QUIN_TDM_TX_5 Data Format", tdm_config_enum[0],
5989 msm_dai_q6_tdm_data_format_get,
5990 msm_dai_q6_tdm_data_format_put),
5991 SOC_ENUM_EXT("QUIN_TDM_TX_6 Data Format", tdm_config_enum[0],
5992 msm_dai_q6_tdm_data_format_get,
5993 msm_dai_q6_tdm_data_format_put),
5994 SOC_ENUM_EXT("QUIN_TDM_TX_7 Data Format", tdm_config_enum[0],
5995 msm_dai_q6_tdm_data_format_get,
5996 msm_dai_q6_tdm_data_format_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305997};
5998
5999static const struct snd_kcontrol_new tdm_config_controls_header_type[] = {
6000 SOC_ENUM_EXT("PRI_TDM_RX_0 Header Type", tdm_config_enum[1],
6001 msm_dai_q6_tdm_header_type_get,
6002 msm_dai_q6_tdm_header_type_put),
6003 SOC_ENUM_EXT("PRI_TDM_RX_1 Header Type", tdm_config_enum[1],
6004 msm_dai_q6_tdm_header_type_get,
6005 msm_dai_q6_tdm_header_type_put),
6006 SOC_ENUM_EXT("PRI_TDM_RX_2 Header Type", tdm_config_enum[1],
6007 msm_dai_q6_tdm_header_type_get,
6008 msm_dai_q6_tdm_header_type_put),
6009 SOC_ENUM_EXT("PRI_TDM_RX_3 Header Type", tdm_config_enum[1],
6010 msm_dai_q6_tdm_header_type_get,
6011 msm_dai_q6_tdm_header_type_put),
6012 SOC_ENUM_EXT("PRI_TDM_RX_4 Header Type", tdm_config_enum[1],
6013 msm_dai_q6_tdm_header_type_get,
6014 msm_dai_q6_tdm_header_type_put),
6015 SOC_ENUM_EXT("PRI_TDM_RX_5 Header Type", tdm_config_enum[1],
6016 msm_dai_q6_tdm_header_type_get,
6017 msm_dai_q6_tdm_header_type_put),
6018 SOC_ENUM_EXT("PRI_TDM_RX_6 Header Type", tdm_config_enum[1],
6019 msm_dai_q6_tdm_header_type_get,
6020 msm_dai_q6_tdm_header_type_put),
6021 SOC_ENUM_EXT("PRI_TDM_RX_7 Header Type", tdm_config_enum[1],
6022 msm_dai_q6_tdm_header_type_get,
6023 msm_dai_q6_tdm_header_type_put),
6024 SOC_ENUM_EXT("PRI_TDM_TX_0 Header Type", tdm_config_enum[1],
6025 msm_dai_q6_tdm_header_type_get,
6026 msm_dai_q6_tdm_header_type_put),
6027 SOC_ENUM_EXT("PRI_TDM_TX_1 Header Type", tdm_config_enum[1],
6028 msm_dai_q6_tdm_header_type_get,
6029 msm_dai_q6_tdm_header_type_put),
6030 SOC_ENUM_EXT("PRI_TDM_TX_2 Header Type", tdm_config_enum[1],
6031 msm_dai_q6_tdm_header_type_get,
6032 msm_dai_q6_tdm_header_type_put),
6033 SOC_ENUM_EXT("PRI_TDM_TX_3 Header Type", tdm_config_enum[1],
6034 msm_dai_q6_tdm_header_type_get,
6035 msm_dai_q6_tdm_header_type_put),
6036 SOC_ENUM_EXT("PRI_TDM_TX_4 Header Type", tdm_config_enum[1],
6037 msm_dai_q6_tdm_header_type_get,
6038 msm_dai_q6_tdm_header_type_put),
6039 SOC_ENUM_EXT("PRI_TDM_TX_5 Header Type", tdm_config_enum[1],
6040 msm_dai_q6_tdm_header_type_get,
6041 msm_dai_q6_tdm_header_type_put),
6042 SOC_ENUM_EXT("PRI_TDM_TX_6 Header Type", tdm_config_enum[1],
6043 msm_dai_q6_tdm_header_type_get,
6044 msm_dai_q6_tdm_header_type_put),
6045 SOC_ENUM_EXT("PRI_TDM_TX_7 Header Type", tdm_config_enum[1],
6046 msm_dai_q6_tdm_header_type_get,
6047 msm_dai_q6_tdm_header_type_put),
6048 SOC_ENUM_EXT("SEC_TDM_RX_0 Header Type", tdm_config_enum[1],
6049 msm_dai_q6_tdm_header_type_get,
6050 msm_dai_q6_tdm_header_type_put),
6051 SOC_ENUM_EXT("SEC_TDM_RX_1 Header Type", tdm_config_enum[1],
6052 msm_dai_q6_tdm_header_type_get,
6053 msm_dai_q6_tdm_header_type_put),
6054 SOC_ENUM_EXT("SEC_TDM_RX_2 Header Type", tdm_config_enum[1],
6055 msm_dai_q6_tdm_header_type_get,
6056 msm_dai_q6_tdm_header_type_put),
6057 SOC_ENUM_EXT("SEC_TDM_RX_3 Header Type", tdm_config_enum[1],
6058 msm_dai_q6_tdm_header_type_get,
6059 msm_dai_q6_tdm_header_type_put),
6060 SOC_ENUM_EXT("SEC_TDM_RX_4 Header Type", tdm_config_enum[1],
6061 msm_dai_q6_tdm_header_type_get,
6062 msm_dai_q6_tdm_header_type_put),
6063 SOC_ENUM_EXT("SEC_TDM_RX_5 Header Type", tdm_config_enum[1],
6064 msm_dai_q6_tdm_header_type_get,
6065 msm_dai_q6_tdm_header_type_put),
6066 SOC_ENUM_EXT("SEC_TDM_RX_6 Header Type", tdm_config_enum[1],
6067 msm_dai_q6_tdm_header_type_get,
6068 msm_dai_q6_tdm_header_type_put),
6069 SOC_ENUM_EXT("SEC_TDM_RX_7 Header Type", tdm_config_enum[1],
6070 msm_dai_q6_tdm_header_type_get,
6071 msm_dai_q6_tdm_header_type_put),
6072 SOC_ENUM_EXT("SEC_TDM_TX_0 Header Type", tdm_config_enum[1],
6073 msm_dai_q6_tdm_header_type_get,
6074 msm_dai_q6_tdm_header_type_put),
6075 SOC_ENUM_EXT("SEC_TDM_TX_1 Header Type", tdm_config_enum[1],
6076 msm_dai_q6_tdm_header_type_get,
6077 msm_dai_q6_tdm_header_type_put),
6078 SOC_ENUM_EXT("SEC_TDM_TX_2 Header Type", tdm_config_enum[1],
6079 msm_dai_q6_tdm_header_type_get,
6080 msm_dai_q6_tdm_header_type_put),
6081 SOC_ENUM_EXT("SEC_TDM_TX_3 Header Type", tdm_config_enum[1],
6082 msm_dai_q6_tdm_header_type_get,
6083 msm_dai_q6_tdm_header_type_put),
6084 SOC_ENUM_EXT("SEC_TDM_TX_4 Header Type", tdm_config_enum[1],
6085 msm_dai_q6_tdm_header_type_get,
6086 msm_dai_q6_tdm_header_type_put),
6087 SOC_ENUM_EXT("SEC_TDM_TX_5 Header Type", tdm_config_enum[1],
6088 msm_dai_q6_tdm_header_type_get,
6089 msm_dai_q6_tdm_header_type_put),
6090 SOC_ENUM_EXT("SEC_TDM_TX_6 Header Type", tdm_config_enum[1],
6091 msm_dai_q6_tdm_header_type_get,
6092 msm_dai_q6_tdm_header_type_put),
6093 SOC_ENUM_EXT("SEC_TDM_TX_7 Header Type", tdm_config_enum[1],
6094 msm_dai_q6_tdm_header_type_get,
6095 msm_dai_q6_tdm_header_type_put),
6096 SOC_ENUM_EXT("TERT_TDM_RX_0 Header Type", tdm_config_enum[1],
6097 msm_dai_q6_tdm_header_type_get,
6098 msm_dai_q6_tdm_header_type_put),
6099 SOC_ENUM_EXT("TERT_TDM_RX_1 Header Type", tdm_config_enum[1],
6100 msm_dai_q6_tdm_header_type_get,
6101 msm_dai_q6_tdm_header_type_put),
6102 SOC_ENUM_EXT("TERT_TDM_RX_2 Header Type", tdm_config_enum[1],
6103 msm_dai_q6_tdm_header_type_get,
6104 msm_dai_q6_tdm_header_type_put),
6105 SOC_ENUM_EXT("TERT_TDM_RX_3 Header Type", tdm_config_enum[1],
6106 msm_dai_q6_tdm_header_type_get,
6107 msm_dai_q6_tdm_header_type_put),
6108 SOC_ENUM_EXT("TERT_TDM_RX_4 Header Type", tdm_config_enum[1],
6109 msm_dai_q6_tdm_header_type_get,
6110 msm_dai_q6_tdm_header_type_put),
6111 SOC_ENUM_EXT("TERT_TDM_RX_5 Header Type", tdm_config_enum[1],
6112 msm_dai_q6_tdm_header_type_get,
6113 msm_dai_q6_tdm_header_type_put),
6114 SOC_ENUM_EXT("TERT_TDM_RX_6 Header Type", tdm_config_enum[1],
6115 msm_dai_q6_tdm_header_type_get,
6116 msm_dai_q6_tdm_header_type_put),
6117 SOC_ENUM_EXT("TERT_TDM_RX_7 Header Type", tdm_config_enum[1],
6118 msm_dai_q6_tdm_header_type_get,
6119 msm_dai_q6_tdm_header_type_put),
6120 SOC_ENUM_EXT("TERT_TDM_TX_0 Header Type", tdm_config_enum[1],
6121 msm_dai_q6_tdm_header_type_get,
6122 msm_dai_q6_tdm_header_type_put),
6123 SOC_ENUM_EXT("TERT_TDM_TX_1 Header Type", tdm_config_enum[1],
6124 msm_dai_q6_tdm_header_type_get,
6125 msm_dai_q6_tdm_header_type_put),
6126 SOC_ENUM_EXT("TERT_TDM_TX_2 Header Type", tdm_config_enum[1],
6127 msm_dai_q6_tdm_header_type_get,
6128 msm_dai_q6_tdm_header_type_put),
6129 SOC_ENUM_EXT("TERT_TDM_TX_3 Header Type", tdm_config_enum[1],
6130 msm_dai_q6_tdm_header_type_get,
6131 msm_dai_q6_tdm_header_type_put),
6132 SOC_ENUM_EXT("TERT_TDM_TX_4 Header Type", tdm_config_enum[1],
6133 msm_dai_q6_tdm_header_type_get,
6134 msm_dai_q6_tdm_header_type_put),
6135 SOC_ENUM_EXT("TERT_TDM_TX_5 Header Type", tdm_config_enum[1],
6136 msm_dai_q6_tdm_header_type_get,
6137 msm_dai_q6_tdm_header_type_put),
6138 SOC_ENUM_EXT("TERT_TDM_TX_6 Header Type", tdm_config_enum[1],
6139 msm_dai_q6_tdm_header_type_get,
6140 msm_dai_q6_tdm_header_type_put),
6141 SOC_ENUM_EXT("TERT_TDM_TX_7 Header Type", tdm_config_enum[1],
6142 msm_dai_q6_tdm_header_type_get,
6143 msm_dai_q6_tdm_header_type_put),
6144 SOC_ENUM_EXT("QUAT_TDM_RX_0 Header Type", tdm_config_enum[1],
6145 msm_dai_q6_tdm_header_type_get,
6146 msm_dai_q6_tdm_header_type_put),
6147 SOC_ENUM_EXT("QUAT_TDM_RX_1 Header Type", tdm_config_enum[1],
6148 msm_dai_q6_tdm_header_type_get,
6149 msm_dai_q6_tdm_header_type_put),
6150 SOC_ENUM_EXT("QUAT_TDM_RX_2 Header Type", tdm_config_enum[1],
6151 msm_dai_q6_tdm_header_type_get,
6152 msm_dai_q6_tdm_header_type_put),
6153 SOC_ENUM_EXT("QUAT_TDM_RX_3 Header Type", tdm_config_enum[1],
6154 msm_dai_q6_tdm_header_type_get,
6155 msm_dai_q6_tdm_header_type_put),
6156 SOC_ENUM_EXT("QUAT_TDM_RX_4 Header Type", tdm_config_enum[1],
6157 msm_dai_q6_tdm_header_type_get,
6158 msm_dai_q6_tdm_header_type_put),
6159 SOC_ENUM_EXT("QUAT_TDM_RX_5 Header Type", tdm_config_enum[1],
6160 msm_dai_q6_tdm_header_type_get,
6161 msm_dai_q6_tdm_header_type_put),
6162 SOC_ENUM_EXT("QUAT_TDM_RX_6 Header Type", tdm_config_enum[1],
6163 msm_dai_q6_tdm_header_type_get,
6164 msm_dai_q6_tdm_header_type_put),
6165 SOC_ENUM_EXT("QUAT_TDM_RX_7 Header Type", tdm_config_enum[1],
6166 msm_dai_q6_tdm_header_type_get,
6167 msm_dai_q6_tdm_header_type_put),
6168 SOC_ENUM_EXT("QUAT_TDM_TX_0 Header Type", tdm_config_enum[1],
6169 msm_dai_q6_tdm_header_type_get,
6170 msm_dai_q6_tdm_header_type_put),
6171 SOC_ENUM_EXT("QUAT_TDM_TX_1 Header Type", tdm_config_enum[1],
6172 msm_dai_q6_tdm_header_type_get,
6173 msm_dai_q6_tdm_header_type_put),
6174 SOC_ENUM_EXT("QUAT_TDM_TX_2 Header Type", tdm_config_enum[1],
6175 msm_dai_q6_tdm_header_type_get,
6176 msm_dai_q6_tdm_header_type_put),
6177 SOC_ENUM_EXT("QUAT_TDM_TX_3 Header Type", tdm_config_enum[1],
6178 msm_dai_q6_tdm_header_type_get,
6179 msm_dai_q6_tdm_header_type_put),
6180 SOC_ENUM_EXT("QUAT_TDM_TX_4 Header Type", tdm_config_enum[1],
6181 msm_dai_q6_tdm_header_type_get,
6182 msm_dai_q6_tdm_header_type_put),
6183 SOC_ENUM_EXT("QUAT_TDM_TX_5 Header Type", tdm_config_enum[1],
6184 msm_dai_q6_tdm_header_type_get,
6185 msm_dai_q6_tdm_header_type_put),
6186 SOC_ENUM_EXT("QUAT_TDM_TX_6 Header Type", tdm_config_enum[1],
6187 msm_dai_q6_tdm_header_type_get,
6188 msm_dai_q6_tdm_header_type_put),
6189 SOC_ENUM_EXT("QUAT_TDM_TX_7 Header Type", tdm_config_enum[1],
6190 msm_dai_q6_tdm_header_type_get,
6191 msm_dai_q6_tdm_header_type_put),
Rohit Kumara5077932017-09-10 22:05:05 +05306192 SOC_ENUM_EXT("QUIN_TDM_RX_0 Header Type", tdm_config_enum[1],
6193 msm_dai_q6_tdm_header_type_get,
6194 msm_dai_q6_tdm_header_type_put),
6195 SOC_ENUM_EXT("QUIN_TDM_RX_1 Header Type", tdm_config_enum[1],
6196 msm_dai_q6_tdm_header_type_get,
6197 msm_dai_q6_tdm_header_type_put),
6198 SOC_ENUM_EXT("QUIN_TDM_RX_2 Header Type", tdm_config_enum[1],
6199 msm_dai_q6_tdm_header_type_get,
6200 msm_dai_q6_tdm_header_type_put),
6201 SOC_ENUM_EXT("QUIN_TDM_RX_3 Header Type", tdm_config_enum[1],
6202 msm_dai_q6_tdm_header_type_get,
6203 msm_dai_q6_tdm_header_type_put),
6204 SOC_ENUM_EXT("QUIN_TDM_RX_4 Header Type", tdm_config_enum[1],
6205 msm_dai_q6_tdm_header_type_get,
6206 msm_dai_q6_tdm_header_type_put),
6207 SOC_ENUM_EXT("QUIN_TDM_RX_5 Header Type", tdm_config_enum[1],
6208 msm_dai_q6_tdm_header_type_get,
6209 msm_dai_q6_tdm_header_type_put),
6210 SOC_ENUM_EXT("QUIN_TDM_RX_6 Header Type", tdm_config_enum[1],
6211 msm_dai_q6_tdm_header_type_get,
6212 msm_dai_q6_tdm_header_type_put),
6213 SOC_ENUM_EXT("QUIN_TDM_RX_7 Header Type", tdm_config_enum[1],
6214 msm_dai_q6_tdm_header_type_get,
6215 msm_dai_q6_tdm_header_type_put),
6216 SOC_ENUM_EXT("QUIN_TDM_TX_0 Header Type", tdm_config_enum[1],
6217 msm_dai_q6_tdm_header_type_get,
6218 msm_dai_q6_tdm_header_type_put),
6219 SOC_ENUM_EXT("QUIN_TDM_TX_1 Header Type", tdm_config_enum[1],
6220 msm_dai_q6_tdm_header_type_get,
6221 msm_dai_q6_tdm_header_type_put),
6222 SOC_ENUM_EXT("QUIN_TDM_TX_2 Header Type", tdm_config_enum[1],
6223 msm_dai_q6_tdm_header_type_get,
6224 msm_dai_q6_tdm_header_type_put),
6225 SOC_ENUM_EXT("QUIN_TDM_TX_3 Header Type", tdm_config_enum[1],
6226 msm_dai_q6_tdm_header_type_get,
6227 msm_dai_q6_tdm_header_type_put),
6228 SOC_ENUM_EXT("QUIN_TDM_TX_4 Header Type", tdm_config_enum[1],
6229 msm_dai_q6_tdm_header_type_get,
6230 msm_dai_q6_tdm_header_type_put),
6231 SOC_ENUM_EXT("QUIN_TDM_TX_5 Header Type", tdm_config_enum[1],
6232 msm_dai_q6_tdm_header_type_get,
6233 msm_dai_q6_tdm_header_type_put),
6234 SOC_ENUM_EXT("QUIN_TDM_TX_6 Header Type", tdm_config_enum[1],
6235 msm_dai_q6_tdm_header_type_get,
6236 msm_dai_q6_tdm_header_type_put),
6237 SOC_ENUM_EXT("QUIN_TDM_TX_7 Header Type", tdm_config_enum[1],
6238 msm_dai_q6_tdm_header_type_get,
6239 msm_dai_q6_tdm_header_type_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306240};
6241
6242static const struct snd_kcontrol_new tdm_config_controls_header[] = {
6243 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_0 Header",
6244 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6245 msm_dai_q6_tdm_header_get,
6246 msm_dai_q6_tdm_header_put),
6247 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_1 Header",
6248 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6249 msm_dai_q6_tdm_header_get,
6250 msm_dai_q6_tdm_header_put),
6251 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_2 Header",
6252 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6253 msm_dai_q6_tdm_header_get,
6254 msm_dai_q6_tdm_header_put),
6255 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_3 Header",
6256 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6257 msm_dai_q6_tdm_header_get,
6258 msm_dai_q6_tdm_header_put),
6259 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_4 Header",
6260 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6261 msm_dai_q6_tdm_header_get,
6262 msm_dai_q6_tdm_header_put),
6263 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_5 Header",
6264 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6265 msm_dai_q6_tdm_header_get,
6266 msm_dai_q6_tdm_header_put),
6267 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_6 Header",
6268 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6269 msm_dai_q6_tdm_header_get,
6270 msm_dai_q6_tdm_header_put),
6271 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_7 Header",
6272 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6273 msm_dai_q6_tdm_header_get,
6274 msm_dai_q6_tdm_header_put),
6275 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_0 Header",
6276 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6277 msm_dai_q6_tdm_header_get,
6278 msm_dai_q6_tdm_header_put),
6279 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_1 Header",
6280 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6281 msm_dai_q6_tdm_header_get,
6282 msm_dai_q6_tdm_header_put),
6283 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_2 Header",
6284 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6285 msm_dai_q6_tdm_header_get,
6286 msm_dai_q6_tdm_header_put),
6287 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_3 Header",
6288 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6289 msm_dai_q6_tdm_header_get,
6290 msm_dai_q6_tdm_header_put),
6291 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_4 Header",
6292 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6293 msm_dai_q6_tdm_header_get,
6294 msm_dai_q6_tdm_header_put),
6295 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_5 Header",
6296 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6297 msm_dai_q6_tdm_header_get,
6298 msm_dai_q6_tdm_header_put),
6299 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_6 Header",
6300 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6301 msm_dai_q6_tdm_header_get,
6302 msm_dai_q6_tdm_header_put),
6303 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_7 Header",
6304 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6305 msm_dai_q6_tdm_header_get,
6306 msm_dai_q6_tdm_header_put),
6307 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_0 Header",
6308 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6309 msm_dai_q6_tdm_header_get,
6310 msm_dai_q6_tdm_header_put),
6311 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_1 Header",
6312 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6313 msm_dai_q6_tdm_header_get,
6314 msm_dai_q6_tdm_header_put),
6315 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_2 Header",
6316 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6317 msm_dai_q6_tdm_header_get,
6318 msm_dai_q6_tdm_header_put),
6319 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_3 Header",
6320 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6321 msm_dai_q6_tdm_header_get,
6322 msm_dai_q6_tdm_header_put),
6323 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_4 Header",
6324 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6325 msm_dai_q6_tdm_header_get,
6326 msm_dai_q6_tdm_header_put),
6327 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_5 Header",
6328 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6329 msm_dai_q6_tdm_header_get,
6330 msm_dai_q6_tdm_header_put),
6331 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_6 Header",
6332 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6333 msm_dai_q6_tdm_header_get,
6334 msm_dai_q6_tdm_header_put),
6335 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_7 Header",
6336 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6337 msm_dai_q6_tdm_header_get,
6338 msm_dai_q6_tdm_header_put),
6339 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_0 Header",
6340 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6341 msm_dai_q6_tdm_header_get,
6342 msm_dai_q6_tdm_header_put),
6343 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_1 Header",
6344 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6345 msm_dai_q6_tdm_header_get,
6346 msm_dai_q6_tdm_header_put),
6347 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_2 Header",
6348 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6349 msm_dai_q6_tdm_header_get,
6350 msm_dai_q6_tdm_header_put),
6351 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_3 Header",
6352 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6353 msm_dai_q6_tdm_header_get,
6354 msm_dai_q6_tdm_header_put),
6355 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_4 Header",
6356 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6357 msm_dai_q6_tdm_header_get,
6358 msm_dai_q6_tdm_header_put),
6359 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_5 Header",
6360 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6361 msm_dai_q6_tdm_header_get,
6362 msm_dai_q6_tdm_header_put),
6363 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_6 Header",
6364 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6365 msm_dai_q6_tdm_header_get,
6366 msm_dai_q6_tdm_header_put),
6367 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_7 Header",
6368 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6369 msm_dai_q6_tdm_header_get,
6370 msm_dai_q6_tdm_header_put),
6371 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_0 Header",
6372 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6373 msm_dai_q6_tdm_header_get,
6374 msm_dai_q6_tdm_header_put),
6375 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_1 Header",
6376 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6377 msm_dai_q6_tdm_header_get,
6378 msm_dai_q6_tdm_header_put),
6379 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_2 Header",
6380 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6381 msm_dai_q6_tdm_header_get,
6382 msm_dai_q6_tdm_header_put),
6383 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_3 Header",
6384 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6385 msm_dai_q6_tdm_header_get,
6386 msm_dai_q6_tdm_header_put),
6387 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_4 Header",
6388 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6389 msm_dai_q6_tdm_header_get,
6390 msm_dai_q6_tdm_header_put),
6391 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_5 Header",
6392 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6393 msm_dai_q6_tdm_header_get,
6394 msm_dai_q6_tdm_header_put),
6395 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_6 Header",
6396 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6397 msm_dai_q6_tdm_header_get,
6398 msm_dai_q6_tdm_header_put),
6399 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_7 Header",
6400 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6401 msm_dai_q6_tdm_header_get,
6402 msm_dai_q6_tdm_header_put),
6403 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_0 Header",
6404 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6405 msm_dai_q6_tdm_header_get,
6406 msm_dai_q6_tdm_header_put),
6407 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_1 Header",
6408 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6409 msm_dai_q6_tdm_header_get,
6410 msm_dai_q6_tdm_header_put),
6411 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_2 Header",
6412 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6413 msm_dai_q6_tdm_header_get,
6414 msm_dai_q6_tdm_header_put),
6415 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_3 Header",
6416 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6417 msm_dai_q6_tdm_header_get,
6418 msm_dai_q6_tdm_header_put),
6419 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_4 Header",
6420 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6421 msm_dai_q6_tdm_header_get,
6422 msm_dai_q6_tdm_header_put),
6423 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_5 Header",
6424 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6425 msm_dai_q6_tdm_header_get,
6426 msm_dai_q6_tdm_header_put),
6427 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_6 Header",
6428 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6429 msm_dai_q6_tdm_header_get,
6430 msm_dai_q6_tdm_header_put),
6431 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_7 Header",
6432 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6433 msm_dai_q6_tdm_header_get,
6434 msm_dai_q6_tdm_header_put),
6435 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_0 Header",
6436 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6437 msm_dai_q6_tdm_header_get,
6438 msm_dai_q6_tdm_header_put),
6439 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_1 Header",
6440 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6441 msm_dai_q6_tdm_header_get,
6442 msm_dai_q6_tdm_header_put),
6443 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_2 Header",
6444 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6445 msm_dai_q6_tdm_header_get,
6446 msm_dai_q6_tdm_header_put),
6447 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_3 Header",
6448 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6449 msm_dai_q6_tdm_header_get,
6450 msm_dai_q6_tdm_header_put),
6451 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_4 Header",
6452 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6453 msm_dai_q6_tdm_header_get,
6454 msm_dai_q6_tdm_header_put),
6455 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_5 Header",
6456 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6457 msm_dai_q6_tdm_header_get,
6458 msm_dai_q6_tdm_header_put),
6459 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_6 Header",
6460 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6461 msm_dai_q6_tdm_header_get,
6462 msm_dai_q6_tdm_header_put),
6463 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_7 Header",
6464 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6465 msm_dai_q6_tdm_header_get,
6466 msm_dai_q6_tdm_header_put),
6467 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_0 Header",
6468 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6469 msm_dai_q6_tdm_header_get,
6470 msm_dai_q6_tdm_header_put),
6471 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_1 Header",
6472 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6473 msm_dai_q6_tdm_header_get,
6474 msm_dai_q6_tdm_header_put),
6475 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_2 Header",
6476 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6477 msm_dai_q6_tdm_header_get,
6478 msm_dai_q6_tdm_header_put),
6479 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_3 Header",
6480 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6481 msm_dai_q6_tdm_header_get,
6482 msm_dai_q6_tdm_header_put),
6483 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_4 Header",
6484 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6485 msm_dai_q6_tdm_header_get,
6486 msm_dai_q6_tdm_header_put),
6487 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_5 Header",
6488 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6489 msm_dai_q6_tdm_header_get,
6490 msm_dai_q6_tdm_header_put),
6491 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_6 Header",
6492 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6493 msm_dai_q6_tdm_header_get,
6494 msm_dai_q6_tdm_header_put),
6495 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_7 Header",
6496 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6497 msm_dai_q6_tdm_header_get,
6498 msm_dai_q6_tdm_header_put),
Rohit Kumara5077932017-09-10 22:05:05 +05306499 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_0 Header",
6500 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6501 msm_dai_q6_tdm_header_get,
6502 msm_dai_q6_tdm_header_put),
6503 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_1 Header",
6504 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6505 msm_dai_q6_tdm_header_get,
6506 msm_dai_q6_tdm_header_put),
6507 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_2 Header",
6508 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6509 msm_dai_q6_tdm_header_get,
6510 msm_dai_q6_tdm_header_put),
6511 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_3 Header",
6512 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6513 msm_dai_q6_tdm_header_get,
6514 msm_dai_q6_tdm_header_put),
6515 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_4 Header",
6516 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6517 msm_dai_q6_tdm_header_get,
6518 msm_dai_q6_tdm_header_put),
6519 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_5 Header",
6520 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6521 msm_dai_q6_tdm_header_get,
6522 msm_dai_q6_tdm_header_put),
6523 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_6 Header",
6524 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6525 msm_dai_q6_tdm_header_get,
6526 msm_dai_q6_tdm_header_put),
6527 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_7 Header",
6528 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6529 msm_dai_q6_tdm_header_get,
6530 msm_dai_q6_tdm_header_put),
6531 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_0 Header",
6532 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6533 msm_dai_q6_tdm_header_get,
6534 msm_dai_q6_tdm_header_put),
6535 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_1 Header",
6536 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6537 msm_dai_q6_tdm_header_get,
6538 msm_dai_q6_tdm_header_put),
6539 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_2 Header",
6540 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6541 msm_dai_q6_tdm_header_get,
6542 msm_dai_q6_tdm_header_put),
6543 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_3 Header",
6544 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6545 msm_dai_q6_tdm_header_get,
6546 msm_dai_q6_tdm_header_put),
6547 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_4 Header",
6548 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6549 msm_dai_q6_tdm_header_get,
6550 msm_dai_q6_tdm_header_put),
6551 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_5 Header",
6552 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6553 msm_dai_q6_tdm_header_get,
6554 msm_dai_q6_tdm_header_put),
6555 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_6 Header",
6556 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6557 msm_dai_q6_tdm_header_get,
6558 msm_dai_q6_tdm_header_put),
6559 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_7 Header",
6560 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6561 msm_dai_q6_tdm_header_get,
6562 msm_dai_q6_tdm_header_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306563};
6564
6565static int msm_dai_q6_tdm_set_clk(
6566 struct msm_dai_q6_tdm_dai_data *dai_data,
6567 u16 port_id, bool enable)
6568{
6569 int rc = 0;
6570
Ashish Jain757e1452018-04-30 20:58:04 +05306571 pr_debug("dai_data->group_cfg.tdm_cfg.group_id = %d : %d\n",
6572 dai_data->group_cfg.tdm_cfg.group_id,
6573 dai_data->clk_set.clk_freq_in_hz);
6574
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306575 dai_data->clk_set.enable = enable;
6576
6577 rc = afe_set_lpass_clock_v2(port_id,
6578 &dai_data->clk_set);
6579 if (rc < 0)
6580 pr_err("%s: afe lpass clock failed, err:%d\n",
6581 __func__, rc);
6582
6583 return rc;
6584}
6585
6586static int msm_dai_q6_dai_tdm_probe(struct snd_soc_dai *dai)
6587{
6588 int rc = 0;
6589 struct msm_dai_q6_tdm_dai_data *tdm_dai_data =
6590 dev_get_drvdata(dai->dev);
6591 struct snd_kcontrol *data_format_kcontrol = NULL;
6592 struct snd_kcontrol *header_type_kcontrol = NULL;
6593 struct snd_kcontrol *header_kcontrol = NULL;
6594 int port_idx = 0;
6595 const struct snd_kcontrol_new *data_format_ctrl = NULL;
6596 const struct snd_kcontrol_new *header_type_ctrl = NULL;
6597 const struct snd_kcontrol_new *header_ctrl = NULL;
6598
6599 msm_dai_q6_set_dai_id(dai);
6600
6601 port_idx = msm_dai_q6_get_port_idx(dai->id);
6602 if (port_idx < 0) {
6603 dev_err(dai->dev, "%s port id 0x%x not supported\n",
6604 __func__, dai->id);
6605 rc = -EINVAL;
6606 goto rtn;
6607 }
6608
6609 data_format_ctrl =
6610 &tdm_config_controls_data_format[port_idx];
6611 header_type_ctrl =
6612 &tdm_config_controls_header_type[port_idx];
6613 header_ctrl =
6614 &tdm_config_controls_header[port_idx];
6615
6616 if (data_format_ctrl) {
6617 data_format_kcontrol = snd_ctl_new1(data_format_ctrl,
6618 tdm_dai_data);
6619 rc = snd_ctl_add(dai->component->card->snd_card,
6620 data_format_kcontrol);
6621 if (rc < 0) {
6622 dev_err(dai->dev, "%s: err add data format ctrl DAI = %s\n",
6623 __func__, dai->name);
6624 goto rtn;
6625 }
6626 }
6627
6628 if (header_type_ctrl) {
6629 header_type_kcontrol = snd_ctl_new1(header_type_ctrl,
6630 tdm_dai_data);
6631 rc = snd_ctl_add(dai->component->card->snd_card,
6632 header_type_kcontrol);
6633 if (rc < 0) {
6634 if (data_format_kcontrol)
6635 snd_ctl_remove(dai->component->card->snd_card,
6636 data_format_kcontrol);
6637 dev_err(dai->dev, "%s: err add header type ctrl DAI = %s\n",
6638 __func__, dai->name);
6639 goto rtn;
6640 }
6641 }
6642
6643 if (header_ctrl) {
6644 header_kcontrol = snd_ctl_new1(header_ctrl,
6645 tdm_dai_data);
6646 rc = snd_ctl_add(dai->component->card->snd_card,
6647 header_kcontrol);
6648 if (rc < 0) {
6649 if (header_type_kcontrol)
6650 snd_ctl_remove(dai->component->card->snd_card,
6651 header_type_kcontrol);
6652 if (data_format_kcontrol)
6653 snd_ctl_remove(dai->component->card->snd_card,
6654 data_format_kcontrol);
6655 dev_err(dai->dev, "%s: err add header ctrl DAI = %s\n",
6656 __func__, dai->name);
6657 goto rtn;
6658 }
6659 }
6660
6661 rc = msm_dai_q6_dai_add_route(dai);
6662
6663rtn:
6664 return rc;
6665}
6666
6667
6668static int msm_dai_q6_dai_tdm_remove(struct snd_soc_dai *dai)
6669{
6670 int rc = 0;
6671 struct msm_dai_q6_tdm_dai_data *tdm_dai_data =
6672 dev_get_drvdata(dai->dev);
6673 u16 group_id = tdm_dai_data->group_cfg.tdm_cfg.group_id;
6674 int group_idx = 0;
6675 atomic_t *group_ref = NULL;
6676
6677 group_idx = msm_dai_q6_get_group_idx(dai->id);
6678 if (group_idx < 0) {
6679 dev_err(dai->dev, "%s port id 0x%x not supported\n",
6680 __func__, dai->id);
6681 return -EINVAL;
6682 }
6683
6684 group_ref = &tdm_group_ref[group_idx];
6685
6686 /* If AFE port is still up, close it */
6687 if (test_bit(STATUS_PORT_STARTED, tdm_dai_data->status_mask)) {
6688 rc = afe_close(dai->id); /* can block */
6689 if (rc < 0) {
6690 dev_err(dai->dev, "%s: fail to close AFE port 0x%x\n",
6691 __func__, dai->id);
6692 }
6693 atomic_dec(group_ref);
6694 clear_bit(STATUS_PORT_STARTED,
6695 tdm_dai_data->status_mask);
6696
6697 if (atomic_read(group_ref) == 0) {
6698 rc = afe_port_group_enable(group_id,
6699 NULL, false);
6700 if (rc < 0) {
6701 dev_err(dai->dev, "fail to disable AFE group 0x%x\n",
6702 group_id);
6703 }
Bala Kishore Pati11276eb2018-05-01 09:29:08 +05306704 if (!(tdm_dai_data->afe_ebit_unsupported &&
6705 !tdm_dai_data->clk_set.clk_freq_in_hz)) {
6706 rc = msm_dai_q6_tdm_set_clk(tdm_dai_data,
6707 dai->id, false);
6708 if (rc < 0) {
6709 dev_err(dai->dev,
6710 "%s: fail to disable AFE clk 0x%x\n",
6711 __func__, dai->id);
6712 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306713 }
6714 }
6715 }
6716
6717 return 0;
6718}
6719
6720static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai,
6721 unsigned int tx_mask,
6722 unsigned int rx_mask,
6723 int slots, int slot_width)
6724{
6725 int rc = 0;
6726 struct msm_dai_q6_tdm_dai_data *dai_data =
6727 dev_get_drvdata(dai->dev);
6728 struct afe_param_id_group_device_tdm_cfg *tdm_group =
6729 &dai_data->group_cfg.tdm_cfg;
6730 unsigned int cap_mask;
6731
6732 dev_dbg(dai->dev, "%s: dai id = 0x%x\n", __func__, dai->id);
6733
6734 /* HW only supports 16 and 32 bit slot width configuration */
6735 if ((slot_width != 16) && (slot_width != 32)) {
6736 dev_err(dai->dev, "%s: invalid slot_width %d\n",
6737 __func__, slot_width);
6738 return -EINVAL;
6739 }
6740
Xiaoyu Ye1cb5ce02017-09-12 18:19:08 -07006741 /* HW supports 1-32 slots configuration. Typical: 1, 2, 4, 8, 16, 32 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306742 switch (slots) {
6743 case 2:
6744 cap_mask = 0x03;
6745 break;
Xiaoyu Ye1cb5ce02017-09-12 18:19:08 -07006746 case 4:
6747 cap_mask = 0x0F;
6748 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306749 case 8:
6750 cap_mask = 0xFF;
6751 break;
6752 case 16:
6753 cap_mask = 0xFFFF;
6754 break;
Cong Tang76c7e642019-02-26 15:08:55 +08006755 case 32:
6756 cap_mask = 0xFFFFFFFF;
6757 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306758 default:
6759 dev_err(dai->dev, "%s: invalid slots %d\n",
6760 __func__, slots);
6761 return -EINVAL;
6762 }
6763
6764 switch (dai->id) {
6765 case AFE_PORT_ID_PRIMARY_TDM_RX:
6766 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
6767 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
6768 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
6769 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
6770 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
6771 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
6772 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
6773 case AFE_PORT_ID_SECONDARY_TDM_RX:
6774 case AFE_PORT_ID_SECONDARY_TDM_RX_1:
6775 case AFE_PORT_ID_SECONDARY_TDM_RX_2:
6776 case AFE_PORT_ID_SECONDARY_TDM_RX_3:
6777 case AFE_PORT_ID_SECONDARY_TDM_RX_4:
6778 case AFE_PORT_ID_SECONDARY_TDM_RX_5:
6779 case AFE_PORT_ID_SECONDARY_TDM_RX_6:
6780 case AFE_PORT_ID_SECONDARY_TDM_RX_7:
6781 case AFE_PORT_ID_TERTIARY_TDM_RX:
6782 case AFE_PORT_ID_TERTIARY_TDM_RX_1:
6783 case AFE_PORT_ID_TERTIARY_TDM_RX_2:
6784 case AFE_PORT_ID_TERTIARY_TDM_RX_3:
6785 case AFE_PORT_ID_TERTIARY_TDM_RX_4:
6786 case AFE_PORT_ID_TERTIARY_TDM_RX_5:
6787 case AFE_PORT_ID_TERTIARY_TDM_RX_6:
6788 case AFE_PORT_ID_TERTIARY_TDM_RX_7:
6789 case AFE_PORT_ID_QUATERNARY_TDM_RX:
6790 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
6791 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
6792 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
6793 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
6794 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
6795 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
6796 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
Rohit Kumara5077932017-09-10 22:05:05 +05306797 case AFE_PORT_ID_QUINARY_TDM_RX:
6798 case AFE_PORT_ID_QUINARY_TDM_RX_1:
6799 case AFE_PORT_ID_QUINARY_TDM_RX_2:
6800 case AFE_PORT_ID_QUINARY_TDM_RX_3:
6801 case AFE_PORT_ID_QUINARY_TDM_RX_4:
6802 case AFE_PORT_ID_QUINARY_TDM_RX_5:
6803 case AFE_PORT_ID_QUINARY_TDM_RX_6:
6804 case AFE_PORT_ID_QUINARY_TDM_RX_7:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306805 tdm_group->nslots_per_frame = slots;
6806 tdm_group->slot_width = slot_width;
6807 tdm_group->slot_mask = rx_mask & cap_mask;
Ashish Jain757e1452018-04-30 20:58:04 +05306808 dev_dbg(dai->dev, "%s:Rx:tdm_group->nslots_per_frame %d\n"
6809 "tdm_group->slot_width %d\n"
6810 "tdm_group->slot_mask %d\n", __func__,
6811 tdm_group->nslots_per_frame,
6812 tdm_group->slot_width, tdm_group->slot_mask);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306813 break;
6814 case AFE_PORT_ID_PRIMARY_TDM_TX:
6815 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
6816 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
6817 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
6818 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
6819 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
6820 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
6821 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
6822 case AFE_PORT_ID_SECONDARY_TDM_TX:
6823 case AFE_PORT_ID_SECONDARY_TDM_TX_1:
6824 case AFE_PORT_ID_SECONDARY_TDM_TX_2:
6825 case AFE_PORT_ID_SECONDARY_TDM_TX_3:
6826 case AFE_PORT_ID_SECONDARY_TDM_TX_4:
6827 case AFE_PORT_ID_SECONDARY_TDM_TX_5:
6828 case AFE_PORT_ID_SECONDARY_TDM_TX_6:
6829 case AFE_PORT_ID_SECONDARY_TDM_TX_7:
6830 case AFE_PORT_ID_TERTIARY_TDM_TX:
6831 case AFE_PORT_ID_TERTIARY_TDM_TX_1:
6832 case AFE_PORT_ID_TERTIARY_TDM_TX_2:
6833 case AFE_PORT_ID_TERTIARY_TDM_TX_3:
6834 case AFE_PORT_ID_TERTIARY_TDM_TX_4:
6835 case AFE_PORT_ID_TERTIARY_TDM_TX_5:
6836 case AFE_PORT_ID_TERTIARY_TDM_TX_6:
6837 case AFE_PORT_ID_TERTIARY_TDM_TX_7:
6838 case AFE_PORT_ID_QUATERNARY_TDM_TX:
6839 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
6840 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
6841 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
6842 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
6843 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
6844 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
6845 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
Rohit Kumara5077932017-09-10 22:05:05 +05306846 case AFE_PORT_ID_QUINARY_TDM_TX:
6847 case AFE_PORT_ID_QUINARY_TDM_TX_1:
6848 case AFE_PORT_ID_QUINARY_TDM_TX_2:
6849 case AFE_PORT_ID_QUINARY_TDM_TX_3:
6850 case AFE_PORT_ID_QUINARY_TDM_TX_4:
6851 case AFE_PORT_ID_QUINARY_TDM_TX_5:
6852 case AFE_PORT_ID_QUINARY_TDM_TX_6:
6853 case AFE_PORT_ID_QUINARY_TDM_TX_7:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306854 tdm_group->nslots_per_frame = slots;
6855 tdm_group->slot_width = slot_width;
6856 tdm_group->slot_mask = tx_mask & cap_mask;
Ashish Jain757e1452018-04-30 20:58:04 +05306857 dev_dbg(dai->dev, "%s:Tx:tdm_group->nslots_per_frame %d\n"
6858 "tdm_group->slot_width %d,tdm_group->slot_mask %d\n"
6859 "tx%d\n", __func__, tdm_group->nslots_per_frame,
6860 tdm_group->slot_width, tdm_group->slot_mask, tx_mask);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306861 break;
6862 default:
6863 dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
6864 __func__, dai->id);
6865 return -EINVAL;
6866 }
6867
6868 return rc;
6869}
6870
Cong Tang2b6adc82017-05-26 12:06:50 +08006871static int msm_dai_q6_tdm_set_sysclk(struct snd_soc_dai *dai,
6872 int clk_id, unsigned int freq, int dir)
6873{
6874 struct msm_dai_q6_tdm_dai_data *dai_data =
6875 dev_get_drvdata(dai->dev);
6876
Xiaoyu Ye5e7ef9c2017-10-16 19:40:38 -07006877 if ((dai->id >= AFE_PORT_ID_PRIMARY_TDM_RX) &&
6878 (dai->id <= AFE_PORT_ID_QUINARY_TDM_TX_7)) {
Cong Tang2b6adc82017-05-26 12:06:50 +08006879 dai_data->clk_set.clk_freq_in_hz = freq;
Xiaoyu Ye5e7ef9c2017-10-16 19:40:38 -07006880 } else {
6881 dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
6882 __func__, dai->id);
Cong Tang2b6adc82017-05-26 12:06:50 +08006883 return -EINVAL;
6884 }
6885
6886 dev_dbg(dai->dev, "%s: dai id = 0x%x, group clk_freq = %d\n",
6887 __func__, dai->id, freq);
6888 return 0;
6889}
6890
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306891static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai,
6892 unsigned int tx_num, unsigned int *tx_slot,
6893 unsigned int rx_num, unsigned int *rx_slot)
6894{
6895 int rc = 0;
6896 struct msm_dai_q6_tdm_dai_data *dai_data =
6897 dev_get_drvdata(dai->dev);
6898 struct afe_param_id_slot_mapping_cfg *slot_mapping =
6899 &dai_data->port_cfg.slot_mapping;
Cong Tang76c7e642019-02-26 15:08:55 +08006900 struct afe_param_id_slot_mapping_cfg_v2 *slot_mapping_v2 =
6901 &dai_data->port_cfg.slot_mapping_v2;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306902 int i = 0;
6903
6904 dev_dbg(dai->dev, "%s: dai id = 0x%x\n", __func__, dai->id);
6905
6906 switch (dai->id) {
6907 case AFE_PORT_ID_PRIMARY_TDM_RX:
6908 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
6909 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
6910 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
6911 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
6912 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
6913 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
6914 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
6915 case AFE_PORT_ID_SECONDARY_TDM_RX:
6916 case AFE_PORT_ID_SECONDARY_TDM_RX_1:
6917 case AFE_PORT_ID_SECONDARY_TDM_RX_2:
6918 case AFE_PORT_ID_SECONDARY_TDM_RX_3:
6919 case AFE_PORT_ID_SECONDARY_TDM_RX_4:
6920 case AFE_PORT_ID_SECONDARY_TDM_RX_5:
6921 case AFE_PORT_ID_SECONDARY_TDM_RX_6:
6922 case AFE_PORT_ID_SECONDARY_TDM_RX_7:
6923 case AFE_PORT_ID_TERTIARY_TDM_RX:
6924 case AFE_PORT_ID_TERTIARY_TDM_RX_1:
6925 case AFE_PORT_ID_TERTIARY_TDM_RX_2:
6926 case AFE_PORT_ID_TERTIARY_TDM_RX_3:
6927 case AFE_PORT_ID_TERTIARY_TDM_RX_4:
6928 case AFE_PORT_ID_TERTIARY_TDM_RX_5:
6929 case AFE_PORT_ID_TERTIARY_TDM_RX_6:
6930 case AFE_PORT_ID_TERTIARY_TDM_RX_7:
6931 case AFE_PORT_ID_QUATERNARY_TDM_RX:
6932 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
6933 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
6934 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
6935 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
6936 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
6937 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
6938 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
Rohit Kumara5077932017-09-10 22:05:05 +05306939 case AFE_PORT_ID_QUINARY_TDM_RX:
6940 case AFE_PORT_ID_QUINARY_TDM_RX_1:
6941 case AFE_PORT_ID_QUINARY_TDM_RX_2:
6942 case AFE_PORT_ID_QUINARY_TDM_RX_3:
6943 case AFE_PORT_ID_QUINARY_TDM_RX_4:
6944 case AFE_PORT_ID_QUINARY_TDM_RX_5:
6945 case AFE_PORT_ID_QUINARY_TDM_RX_6:
6946 case AFE_PORT_ID_QUINARY_TDM_RX_7:
Cong Tang76c7e642019-02-26 15:08:55 +08006947 if (q6core_get_avcs_api_version_per_service(
6948 APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V3) {
6949 if (!rx_slot) {
6950 dev_err(dai->dev, "%s: rx slot not found\n",
6951 __func__);
6952 return -EINVAL;
6953 }
6954 if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT_V2) {
6955 dev_err(dai->dev, "%s: invalid rx num %d\n",
6956 __func__,
6957 rx_num);
6958 return -EINVAL;
6959 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306960
Cong Tang76c7e642019-02-26 15:08:55 +08006961 for (i = 0; i < rx_num; i++)
6962 slot_mapping_v2->offset[i] = rx_slot[i];
6963 for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT_V2;
6964 i++)
6965 slot_mapping_v2->offset[i] =
6966 AFE_SLOT_MAPPING_OFFSET_INVALID;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306967
Cong Tang76c7e642019-02-26 15:08:55 +08006968 slot_mapping_v2->num_channel = rx_num;
6969 } else {
6970 if (!rx_slot) {
6971 dev_err(dai->dev, "%s: rx slot not found\n",
6972 __func__);
6973 return -EINVAL;
6974 }
6975 if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
6976 dev_err(dai->dev, "%s: invalid rx num %d\n",
6977 __func__,
6978 rx_num);
6979 return -EINVAL;
6980 }
6981
6982 for (i = 0; i < rx_num; i++)
6983 slot_mapping->offset[i] = rx_slot[i];
6984 for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
6985 slot_mapping->offset[i] =
6986 AFE_SLOT_MAPPING_OFFSET_INVALID;
6987
6988 slot_mapping->num_channel = rx_num;
6989 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306990 break;
6991 case AFE_PORT_ID_PRIMARY_TDM_TX:
6992 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
6993 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
6994 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
6995 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
6996 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
6997 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
6998 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
6999 case AFE_PORT_ID_SECONDARY_TDM_TX:
7000 case AFE_PORT_ID_SECONDARY_TDM_TX_1:
7001 case AFE_PORT_ID_SECONDARY_TDM_TX_2:
7002 case AFE_PORT_ID_SECONDARY_TDM_TX_3:
7003 case AFE_PORT_ID_SECONDARY_TDM_TX_4:
7004 case AFE_PORT_ID_SECONDARY_TDM_TX_5:
7005 case AFE_PORT_ID_SECONDARY_TDM_TX_6:
7006 case AFE_PORT_ID_SECONDARY_TDM_TX_7:
7007 case AFE_PORT_ID_TERTIARY_TDM_TX:
7008 case AFE_PORT_ID_TERTIARY_TDM_TX_1:
7009 case AFE_PORT_ID_TERTIARY_TDM_TX_2:
7010 case AFE_PORT_ID_TERTIARY_TDM_TX_3:
7011 case AFE_PORT_ID_TERTIARY_TDM_TX_4:
7012 case AFE_PORT_ID_TERTIARY_TDM_TX_5:
7013 case AFE_PORT_ID_TERTIARY_TDM_TX_6:
7014 case AFE_PORT_ID_TERTIARY_TDM_TX_7:
7015 case AFE_PORT_ID_QUATERNARY_TDM_TX:
7016 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
7017 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
7018 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
7019 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
7020 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
7021 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
7022 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
Rohit Kumara5077932017-09-10 22:05:05 +05307023 case AFE_PORT_ID_QUINARY_TDM_TX:
7024 case AFE_PORT_ID_QUINARY_TDM_TX_1:
7025 case AFE_PORT_ID_QUINARY_TDM_TX_2:
7026 case AFE_PORT_ID_QUINARY_TDM_TX_3:
7027 case AFE_PORT_ID_QUINARY_TDM_TX_4:
7028 case AFE_PORT_ID_QUINARY_TDM_TX_5:
7029 case AFE_PORT_ID_QUINARY_TDM_TX_6:
7030 case AFE_PORT_ID_QUINARY_TDM_TX_7:
Cong Tang76c7e642019-02-26 15:08:55 +08007031 if (q6core_get_avcs_api_version_per_service(
7032 APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V3) {
7033 if (!tx_slot) {
7034 dev_err(dai->dev, "%s: tx slot not found\n",
7035 __func__);
7036 return -EINVAL;
7037 }
7038 if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT_V2) {
7039 dev_err(dai->dev, "%s: invalid tx num %d\n",
7040 __func__,
7041 tx_num);
7042 return -EINVAL;
7043 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307044
Cong Tang76c7e642019-02-26 15:08:55 +08007045 for (i = 0; i < tx_num; i++)
7046 slot_mapping_v2->offset[i] = tx_slot[i];
7047 for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT_V2;
7048 i++)
7049 slot_mapping_v2->offset[i] =
7050 AFE_SLOT_MAPPING_OFFSET_INVALID;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307051
Cong Tang76c7e642019-02-26 15:08:55 +08007052 slot_mapping_v2->num_channel = tx_num;
7053 } else {
7054 if (!tx_slot) {
7055 dev_err(dai->dev, "%s: tx slot not found\n",
7056 __func__);
7057 return -EINVAL;
7058 }
7059 if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
7060 dev_err(dai->dev, "%s: invalid tx num %d\n",
7061 __func__,
7062 tx_num);
7063 return -EINVAL;
7064 }
7065
7066 for (i = 0; i < tx_num; i++)
7067 slot_mapping->offset[i] = tx_slot[i];
7068 for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
7069 slot_mapping->offset[i] =
7070 AFE_SLOT_MAPPING_OFFSET_INVALID;
7071
7072 slot_mapping->num_channel = tx_num;
7073 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307074 break;
7075 default:
7076 dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
7077 __func__, dai->id);
7078 return -EINVAL;
7079 }
7080
7081 return rc;
7082}
7083
7084static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream,
7085 struct snd_pcm_hw_params *params,
7086 struct snd_soc_dai *dai)
7087{
7088 struct msm_dai_q6_tdm_dai_data *dai_data =
7089 dev_get_drvdata(dai->dev);
7090
7091 struct afe_param_id_group_device_tdm_cfg *tdm_group =
7092 &dai_data->group_cfg.tdm_cfg;
7093 struct afe_param_id_tdm_cfg *tdm =
7094 &dai_data->port_cfg.tdm;
7095 struct afe_param_id_slot_mapping_cfg *slot_mapping =
7096 &dai_data->port_cfg.slot_mapping;
Cong Tang76c7e642019-02-26 15:08:55 +08007097 struct afe_param_id_slot_mapping_cfg_v2 *slot_mapping_v2 =
7098 &dai_data->port_cfg.slot_mapping_v2;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307099 struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header =
7100 &dai_data->port_cfg.custom_tdm_header;
7101
7102 pr_debug("%s: dev_name: %s\n",
7103 __func__, dev_name(dai->dev));
7104
7105 if ((params_channels(params) == 0) ||
Cong Tang76c7e642019-02-26 15:08:55 +08007106 (params_channels(params) > 32)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307107 dev_err(dai->dev, "%s: invalid param channels %d\n",
7108 __func__, params_channels(params));
7109 return -EINVAL;
7110 }
7111 switch (params_format(params)) {
7112 case SNDRV_PCM_FORMAT_S16_LE:
7113 dai_data->bitwidth = 16;
7114 break;
7115 case SNDRV_PCM_FORMAT_S24_LE:
7116 case SNDRV_PCM_FORMAT_S24_3LE:
7117 dai_data->bitwidth = 24;
7118 break;
7119 case SNDRV_PCM_FORMAT_S32_LE:
7120 dai_data->bitwidth = 32;
7121 break;
7122 default:
7123 dev_err(dai->dev, "%s: invalid param format 0x%x\n",
7124 __func__, params_format(params));
7125 return -EINVAL;
7126 }
7127 dai_data->channels = params_channels(params);
7128 dai_data->rate = params_rate(params);
7129
7130 /*
7131 * update tdm group config param
7132 * NOTE: group config is set to the same as slot config.
7133 */
7134 tdm_group->bit_width = tdm_group->slot_width;
7135 tdm_group->num_channels = tdm_group->nslots_per_frame;
7136 tdm_group->sample_rate = dai_data->rate;
7137
7138 pr_debug("%s: TDM GROUP:\n"
7139 "num_channels=%d sample_rate=%d bit_width=%d\n"
7140 "nslots_per_frame=%d slot_width=%d slot_mask=0x%x\n",
7141 __func__,
7142 tdm_group->num_channels,
7143 tdm_group->sample_rate,
7144 tdm_group->bit_width,
7145 tdm_group->nslots_per_frame,
7146 tdm_group->slot_width,
7147 tdm_group->slot_mask);
7148 pr_debug("%s: TDM GROUP:\n"
7149 "port_id[0]=0x%x port_id[1]=0x%x port_id[2]=0x%x port_id[3]=0x%x\n"
7150 "port_id[4]=0x%x port_id[5]=0x%x port_id[6]=0x%x port_id[7]=0x%x\n",
7151 __func__,
7152 tdm_group->port_id[0],
7153 tdm_group->port_id[1],
7154 tdm_group->port_id[2],
7155 tdm_group->port_id[3],
7156 tdm_group->port_id[4],
7157 tdm_group->port_id[5],
7158 tdm_group->port_id[6],
7159 tdm_group->port_id[7]);
7160
7161 /*
7162 * update tdm config param
7163 * NOTE: channels/rate/bitwidth are per stream property
7164 */
7165 tdm->num_channels = dai_data->channels;
7166 tdm->sample_rate = dai_data->rate;
7167 tdm->bit_width = dai_data->bitwidth;
7168 /*
7169 * port slot config is the same as group slot config
7170 * port slot mask should be set according to offset
7171 */
7172 tdm->nslots_per_frame = tdm_group->nslots_per_frame;
7173 tdm->slot_width = tdm_group->slot_width;
7174 tdm->slot_mask = tdm_group->slot_mask;
7175
7176 pr_debug("%s: TDM:\n"
7177 "num_channels=%d sample_rate=%d bit_width=%d\n"
7178 "nslots_per_frame=%d slot_width=%d slot_mask=0x%x\n"
7179 "data_format=0x%x sync_mode=0x%x sync_src=0x%x\n"
7180 "data_out=0x%x invert_sync=0x%x data_delay=0x%x\n",
7181 __func__,
7182 tdm->num_channels,
7183 tdm->sample_rate,
7184 tdm->bit_width,
7185 tdm->nslots_per_frame,
7186 tdm->slot_width,
7187 tdm->slot_mask,
7188 tdm->data_format,
7189 tdm->sync_mode,
7190 tdm->sync_src,
7191 tdm->ctrl_data_out_enable,
7192 tdm->ctrl_invert_sync_pulse,
7193 tdm->ctrl_sync_data_delay);
Cong Tang76c7e642019-02-26 15:08:55 +08007194 if (q6core_get_avcs_api_version_per_service(
7195 APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V3) {
7196 /*
7197 * update slot mapping v2 config param
7198 * NOTE: channels/rate/bitwidth are per stream property
7199 */
7200 slot_mapping_v2->bitwidth = dai_data->bitwidth;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307201
Cong Tang76c7e642019-02-26 15:08:55 +08007202 pr_debug("%s: SLOT MAPPING_V2:\n"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307203 "num_channel=%d bitwidth=%d data_align=0x%x\n",
7204 __func__,
Cong Tang76c7e642019-02-26 15:08:55 +08007205 slot_mapping_v2->num_channel,
7206 slot_mapping_v2->bitwidth,
7207 slot_mapping_v2->data_align_type);
7208 pr_debug("%s: SLOT MAPPING V2:\n"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307209 "offset[0]=0x%x offset[1]=0x%x offset[2]=0x%x offset[3]=0x%x\n"
Cong Tang76c7e642019-02-26 15:08:55 +08007210 "offset[4]=0x%x offset[5]=0x%x offset[6]=0x%x offset[7]=0x%x\n"
7211 "offset[8]=0x%x offset[9]=0x%x offset[10]=0x%x offset[11]=0x%x\n"
7212 "offset[12]=0x%x offset[13]=0x%x offset[14]=0x%x offset[15]=0x%x\n"
7213 "offset[16]=0x%x offset[17]=0x%x offset[18]=0x%x offset[19]=0x%x\n"
7214 "offset[20]=0x%x offset[21]=0x%x offset[22]=0x%x offset[23]=0x%x\n"
7215 "offset[24]=0x%x offset[25]=0x%x offset[26]=0x%x offset[27]=0x%x\n"
7216 "offset[28]=0x%x offset[29]=0x%x offset[30]=0x%x offset[31]=0x%x\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307217 __func__,
Cong Tang76c7e642019-02-26 15:08:55 +08007218 slot_mapping_v2->offset[0],
7219 slot_mapping_v2->offset[1],
7220 slot_mapping_v2->offset[2],
7221 slot_mapping_v2->offset[3],
7222 slot_mapping_v2->offset[4],
7223 slot_mapping_v2->offset[5],
7224 slot_mapping_v2->offset[6],
7225 slot_mapping_v2->offset[7],
7226 slot_mapping_v2->offset[8],
7227 slot_mapping_v2->offset[9],
7228 slot_mapping_v2->offset[10],
7229 slot_mapping_v2->offset[11],
7230 slot_mapping_v2->offset[12],
7231 slot_mapping_v2->offset[13],
7232 slot_mapping_v2->offset[14],
7233 slot_mapping_v2->offset[15],
7234 slot_mapping_v2->offset[16],
7235 slot_mapping_v2->offset[17],
7236 slot_mapping_v2->offset[18],
7237 slot_mapping_v2->offset[19],
7238 slot_mapping_v2->offset[20],
7239 slot_mapping_v2->offset[21],
7240 slot_mapping_v2->offset[22],
7241 slot_mapping_v2->offset[23],
7242 slot_mapping_v2->offset[24],
7243 slot_mapping_v2->offset[25],
7244 slot_mapping_v2->offset[26],
7245 slot_mapping_v2->offset[27],
7246 slot_mapping_v2->offset[28],
7247 slot_mapping_v2->offset[29],
7248 slot_mapping_v2->offset[30],
7249 slot_mapping_v2->offset[31]);
7250 } else {
7251 /*
7252 * update slot mapping config param
7253 * NOTE: channels/rate/bitwidth are per stream property
7254 */
7255 slot_mapping->bitwidth = dai_data->bitwidth;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307256
Cong Tang76c7e642019-02-26 15:08:55 +08007257 pr_debug("%s: SLOT MAPPING:\n"
7258 "num_channel=%d bitwidth=%d data_align=0x%x\n",
7259 __func__,
7260 slot_mapping->num_channel,
7261 slot_mapping->bitwidth,
7262 slot_mapping->data_align_type);
7263 pr_debug("%s: SLOT MAPPING:\n"
7264 "offset[0]=0x%x offset[1]=0x%x offset[2]=0x%x offset[3]=0x%x\n"
7265 "offset[4]=0x%x offset[5]=0x%x offset[6]=0x%x offset[7]=0x%x\n",
7266 __func__,
7267 slot_mapping->offset[0],
7268 slot_mapping->offset[1],
7269 slot_mapping->offset[2],
7270 slot_mapping->offset[3],
7271 slot_mapping->offset[4],
7272 slot_mapping->offset[5],
7273 slot_mapping->offset[6],
7274 slot_mapping->offset[7]);
7275 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307276 /*
7277 * update custom header config param
7278 * NOTE: channels/rate/bitwidth are per playback stream property.
7279 * custom tdm header only applicable to playback stream.
7280 */
7281 if (custom_tdm_header->header_type !=
7282 AFE_CUSTOM_TDM_HEADER_TYPE_INVALID) {
7283 pr_debug("%s: CUSTOM TDM HEADER:\n"
7284 "start_offset=0x%x header_width=%d\n"
7285 "num_frame_repeat=%d header_type=0x%x\n",
7286 __func__,
7287 custom_tdm_header->start_offset,
7288 custom_tdm_header->header_width,
7289 custom_tdm_header->num_frame_repeat,
7290 custom_tdm_header->header_type);
7291 pr_debug("%s: CUSTOM TDM HEADER:\n"
7292 "header[0]=0x%x header[1]=0x%x header[2]=0x%x header[3]=0x%x\n"
7293 "header[4]=0x%x header[5]=0x%x header[6]=0x%x header[7]=0x%x\n",
7294 __func__,
7295 custom_tdm_header->header[0],
7296 custom_tdm_header->header[1],
7297 custom_tdm_header->header[2],
7298 custom_tdm_header->header[3],
7299 custom_tdm_header->header[4],
7300 custom_tdm_header->header[5],
7301 custom_tdm_header->header[6],
7302 custom_tdm_header->header[7]);
7303 }
7304
Bala Kishore Patia0575102018-05-01 12:37:51 +05307305 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
7306 group_cfg_tx.tdm_cfg.num_channels =
7307 dai_data->group_cfg.tdm_cfg.num_channels;
7308 group_cfg_tx.tdm_cfg.sample_rate =
7309 dai_data->group_cfg.tdm_cfg.sample_rate;
7310 group_cfg_tx.tdm_cfg.bit_width =
7311 dai_data->group_cfg.tdm_cfg.bit_width;
7312 group_cfg_tx.tdm_cfg.nslots_per_frame =
7313 dai_data->group_cfg.tdm_cfg.nslots_per_frame;
7314 group_cfg_tx.tdm_cfg.slot_width =
7315 dai_data->group_cfg.tdm_cfg.slot_width;
7316 group_cfg_tx.tdm_cfg.slot_mask =
7317 dai_data->group_cfg.tdm_cfg.slot_mask;
7318 } else {
7319 group_cfg_rx.tdm_cfg.num_channels =
7320 dai_data->group_cfg.tdm_cfg.num_channels;
7321 group_cfg_rx.tdm_cfg.sample_rate =
7322 dai_data->group_cfg.tdm_cfg.sample_rate;
7323 group_cfg_rx.tdm_cfg.bit_width =
7324 dai_data->group_cfg.tdm_cfg.bit_width;
7325 group_cfg_rx.tdm_cfg.nslots_per_frame =
7326 dai_data->group_cfg.tdm_cfg.nslots_per_frame;
7327 group_cfg_rx.tdm_cfg.slot_width =
7328 dai_data->group_cfg.tdm_cfg.slot_width;
7329 group_cfg_rx.tdm_cfg.slot_mask =
7330 dai_data->group_cfg.tdm_cfg.slot_mask;
7331 }
Ashish Jain757e1452018-04-30 20:58:04 +05307332
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307333 return 0;
7334}
7335
7336static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream,
7337 struct snd_soc_dai *dai)
7338{
7339 int rc = 0;
7340 struct msm_dai_q6_tdm_dai_data *dai_data =
7341 dev_get_drvdata(dai->dev);
7342 u16 group_id = dai_data->group_cfg.tdm_cfg.group_id;
Bala Kishore Patia0575102018-05-01 12:37:51 +05307343 u16 sec_group_id = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307344 int group_idx = 0;
Bala Kishore Patia0575102018-05-01 12:37:51 +05307345 int sec_group_idx = 0;
Ashish Jain757e1452018-04-30 20:58:04 +05307346 u16 prim_port_id = 0;
7347 u16 sec_port_id = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307348 atomic_t *group_ref = NULL;
Bala Kishore Patia0575102018-05-01 12:37:51 +05307349 atomic_t *sec_group_ref = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307350
7351 group_idx = msm_dai_q6_get_group_idx(dai->id);
7352 if (group_idx < 0) {
7353 dev_err(dai->dev, "%s port id 0x%x not supported\n",
7354 __func__, dai->id);
7355 return -EINVAL;
7356 }
7357
7358 mutex_lock(&tdm_mutex);
7359
7360 group_ref = &tdm_group_ref[group_idx];
7361
7362 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
7363 /* PORT START should be set if prepare called
7364 * in active state.
7365 */
7366 if (atomic_read(group_ref) == 0) {
7367 /* TX and RX share the same clk.
7368 * AFE clk is enabled per group to simplify the logic.
7369 * DSP will monitor the clk count.
7370 */
Ashish Jain757e1452018-04-30 20:58:04 +05307371 if (!(dai_data->afe_ebit_unsupported &&
7372 !dai_data->clk_set.clk_freq_in_hz)) {
7373
7374 rc = msm_dai_q6_tdm_set_clk(dai_data,
7375 dai->id, true);
7376 if (rc < 0) {
Bala Kishore Patia0575102018-05-01 12:37:51 +05307377 dev_err(dai->dev,
7378 "%s: AFE CLK enable fail 0x%x\n",
Ashish Jain757e1452018-04-30 20:58:04 +05307379 __func__, dai->id);
7380 goto rtn;
7381 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307382 }
7383
7384 /*
7385 * if only one port, don't do group enable as there
7386 * is no group need for only one port
7387 */
7388 if (dai_data->num_group_ports > 1) {
Bala Kishore Patia0575102018-05-01 12:37:51 +05307389 dev_dbg(dai->dev, "%s:enable afe group\n",
Ashish Jain757e1452018-04-30 20:58:04 +05307390 __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307391 rc = afe_port_group_enable(group_id,
7392 &dai_data->group_cfg, true);
7393 if (rc < 0) {
7394 dev_err(dai->dev,
Ashish Jain757e1452018-04-30 20:58:04 +05307395 "%s: fail to enable grp %x\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307396 __func__, group_id);
7397 goto rtn;
7398 }
7399 }
7400 }
7401
Ashish Jain757e1452018-04-30 20:58:04 +05307402 /*
7403 * 8909 HW has a dependency where for Rx/Tx to work in TDM mode
7404 * We need to start a Tx or Rx port in the same group.
7405 * Hence for BG use TDM_TX when a RX session is requested and
7406 * use TDM_RX port when a TX session is requested as these ports
7407 * are unused as of now.
7408 */
7409
7410 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
7411 prim_port_id = dai->id;
Surendar karka23677262018-04-30 22:52:08 +05307412 if (dai_data->sec_port_enable) {
Ashish Jain757e1452018-04-30 20:58:04 +05307413 sec_port_id = AFE_PORT_ID_PRIMARY_TDM_TX;
Surendar karka59508d72018-05-01 09:09:58 +05307414 sec_group_ref = &tdm_group_ref[sec_group_idx];
7415 }
7416 if ((dai_data->num_group_ports > 1) &&
7417 (dai_data->sec_port_enable)) {
Bala Kishore Patia0575102018-05-01 12:37:51 +05307418 sec_group_id =
7419 AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX;
7420 sec_group_idx =
7421 msm_dai_q6_get_group_idx(sec_group_id);
7422 if (sec_group_idx < 0) {
7423 dev_err(dai->dev, "%s port id 0x%x\n"
7424 "not supported\n", __func__,
7425 sec_group_id);
7426 goto rtn;
7427 }
Bala Kishore Patia0575102018-05-01 12:37:51 +05307428 if (atomic_read(sec_group_ref) == 0) {
7429 rc = afe_port_group_enable(
7430 sec_group_id,
7431 &group_cfg_tx,
7432 true);
7433 if (rc < 0) {
7434 dev_err(dai->dev,
7435 "%s:failed to\n"
7436 "enable grp\n"
7437 "%x\n", __func__,
7438 group_id);
7439 goto rtn;
7440 }
7441 }
7442 }
Ashish Jain757e1452018-04-30 20:58:04 +05307443 } else {
7444 prim_port_id = dai->id;
Surendar karka23677262018-04-30 22:52:08 +05307445 if (dai_data->sec_port_enable) {
Ashish Jain757e1452018-04-30 20:58:04 +05307446 sec_port_id = AFE_PORT_ID_PRIMARY_TDM_RX;
Surendar karka59508d72018-05-01 09:09:58 +05307447 sec_group_ref = &tdm_group_ref[sec_group_idx];
7448 }
7449 if ((dai_data->num_group_ports > 1) &&
7450 (dai_data->sec_port_enable)) {
Bala Kishore Patia0575102018-05-01 12:37:51 +05307451 sec_group_id =
7452 AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX;
7453 sec_group_idx =
7454 msm_dai_q6_get_group_idx(sec_group_id);
7455 if (sec_group_idx < 0) {
7456 dev_err(dai->dev, "%s port id 0x%x\n"
7457 " not supported\n", __func__,
7458 sec_group_id);
7459 goto rtn;
7460 }
Bala Kishore Patia0575102018-05-01 12:37:51 +05307461 if (atomic_read(sec_group_ref) == 0) {
7462 rc = afe_port_group_enable(
7463 sec_group_id,
7464 &group_cfg_rx,
7465 true);
7466 if (rc < 0) {
7467 dev_err(dai->dev,
7468 "%s:failed to\n"
7469 "enable grp\n"
7470 "%x\n", __func__,
7471 group_id);
7472 goto rtn;
7473 }
7474 }
7475 }
Ashish Jain757e1452018-04-30 20:58:04 +05307476 }
7477 dev_dbg(dai->dev, "\n%s:open prim port id %d TDM rate: %d\n"
7478 "dai_data->port_cfg.tdm.slot_mask %x\n"
7479 "dai_data->port_cfg.tdm.nslots_per_frame:%x\n",
7480 __func__, prim_port_id,
7481 dai_data->port_cfg.tdm.num_channels,
7482 dai_data->port_cfg.tdm.slot_mask,
7483 dai_data->port_cfg.tdm.nslots_per_frame);
7484
7485 rc = afe_tdm_port_start(prim_port_id, &dai_data->port_cfg,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307486 dai_data->rate, dai_data->num_group_ports);
Ashish Jain757e1452018-04-30 20:58:04 +05307487
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307488 if (rc < 0) {
7489 if (atomic_read(group_ref) == 0) {
7490 afe_port_group_enable(group_id,
7491 NULL, false);
Ashish Jain757e1452018-04-30 20:58:04 +05307492 if (!(dai_data->afe_ebit_unsupported &&
7493 !dai_data->clk_set.clk_freq_in_hz))
7494 msm_dai_q6_tdm_set_clk(dai_data,
7495 dai->id, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307496 }
Ashish Jain757e1452018-04-30 20:58:04 +05307497 dev_err(dai->dev, "%s: open AFE port 0x%x\n",
7498 __func__, prim_port_id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307499 } else {
7500 set_bit(STATUS_PORT_STARTED,
7501 dai_data->status_mask);
7502 atomic_inc(group_ref);
Ashish Jain757e1452018-04-30 20:58:04 +05307503
7504 }
7505
7506 dai_data->port_cfg.tdm.num_channels = 1;
7507 dai_data->port_cfg.tdm.slot_mask = 1;
Ashish Jain757e1452018-04-30 20:58:04 +05307508
7509 dev_dbg(dai->dev, "\n%s:open sec port id %d TDM rate: %d\n"
7510 "dai_data->port_cfg.tdm.slot_mask %x\n"
7511 "dai_data->port_cfg.tdm.nslotsper_frame:%x\n", __func__,
7512 sec_port_id, dai_data->port_cfg.tdm.num_channels,
7513 dai_data->port_cfg.tdm.slot_mask,
7514 dai_data->port_cfg.tdm.nslots_per_frame);
7515
7516 if (sec_port_id != 0) {
7517 rc = afe_tdm_port_start(sec_port_id,
7518 &dai_data->port_cfg,
Surendar karka23677262018-04-30 22:52:08 +05307519 dai_data->rate,
7520 dai_data->num_group_ports);
Bala Kishore Patia0575102018-05-01 12:37:51 +05307521 if (rc < 0) {
Ashish Jain757e1452018-04-30 20:58:04 +05307522 if (atomic_read(group_ref) == 0) {
7523 afe_port_group_enable(group_id,
7524 NULL, false);
Bala Kishore Pati11276eb2018-05-01 09:29:08 +05307525 if (!(dai_data->afe_ebit_unsupported &&
7526 !dai_data->clk_set.clk_freq_in_hz))
Ashish Jain757e1452018-04-30 20:58:04 +05307527 msm_dai_q6_tdm_set_clk(dai_data,
Bala Kishore Pati11276eb2018-05-01 09:29:08 +05307528 dai->id, false);
Ashish Jain757e1452018-04-30 20:58:04 +05307529 }
7530 dev_err(dai->dev, "%s: fail AFE port 0x%x\n",
7531 __func__, sec_port_id);
7532 } else {
7533 set_bit(STATUS_PORT_STARTED,
7534 dai_data->status_mask);
Bala Kishore Patia0575102018-05-01 12:37:51 +05307535 atomic_inc(sec_group_ref);
Ashish Jain757e1452018-04-30 20:58:04 +05307536 }
7537
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307538 }
7539
7540 /* TODO: need to monitor PCM/MI2S/TDM HW status */
7541 /* NOTE: AFE should error out if HW resource contention */
7542
7543 }
7544
7545rtn:
7546 mutex_unlock(&tdm_mutex);
7547 return rc;
7548}
7549
7550static void msm_dai_q6_tdm_shutdown(struct snd_pcm_substream *substream,
7551 struct snd_soc_dai *dai)
7552{
7553 int rc = 0;
7554 struct msm_dai_q6_tdm_dai_data *dai_data =
7555 dev_get_drvdata(dai->dev);
7556 u16 group_id = dai_data->group_cfg.tdm_cfg.group_id;
Bala Kishore Patia0575102018-05-01 12:37:51 +05307557 u16 sec_group_id = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307558 int group_idx = 0;
Bala Kishore Patia0575102018-05-01 12:37:51 +05307559 int sec_group_idx = 0;
Ashish Jain757e1452018-04-30 20:58:04 +05307560 u16 prim_port_id = 0;
7561 u16 sec_port_id = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307562 atomic_t *group_ref = NULL;
Bala Kishore Patia0575102018-05-01 12:37:51 +05307563 atomic_t *sec_group_ref = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307564
7565 group_idx = msm_dai_q6_get_group_idx(dai->id);
7566 if (group_idx < 0) {
7567 dev_err(dai->dev, "%s port id 0x%x not supported\n",
7568 __func__, dai->id);
7569 return;
7570 }
7571
7572 mutex_lock(&tdm_mutex);
7573
7574 group_ref = &tdm_group_ref[group_idx];
7575
7576 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
Ashish Jain757e1452018-04-30 20:58:04 +05307577 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
7578 prim_port_id = dai->id;
Surendar karka23677262018-04-30 22:52:08 +05307579 if (dai_data->sec_port_enable) {
Ashish Jain757e1452018-04-30 20:58:04 +05307580 sec_port_id = AFE_PORT_ID_PRIMARY_TDM_TX;
Surendar karka59508d72018-05-01 09:09:58 +05307581 sec_group_ref = &tdm_group_ref[sec_group_idx];
7582 }
7583 if ((dai_data->num_group_ports > 1) &&
7584 (dai_data->sec_port_enable)) {
Bala Kishore Patia0575102018-05-01 12:37:51 +05307585 sec_group_id =
7586 AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX;
7587 sec_group_idx =
7588 msm_dai_q6_get_group_idx(sec_group_id);
7589 if (sec_group_idx < 0) {
7590 dev_err(dai->dev, "%s port id 0x%x\n"
7591 "not supported\n",
7592 __func__, sec_group_id);
7593 return;
7594 }
Bala Kishore Patia0575102018-05-01 12:37:51 +05307595 }
Ashish Jain757e1452018-04-30 20:58:04 +05307596 } else {
7597 prim_port_id = dai->id;
Surendar karka23677262018-04-30 22:52:08 +05307598 if (dai_data->sec_port_enable) {
Ashish Jain757e1452018-04-30 20:58:04 +05307599 sec_port_id = AFE_PORT_ID_PRIMARY_TDM_RX;
Surendar karka59508d72018-05-01 09:09:58 +05307600 sec_group_ref = &tdm_group_ref[sec_group_idx];
7601 }
7602 if ((dai_data->num_group_ports > 1) &&
7603 (dai_data->sec_port_enable)) {
Bala Kishore Patia0575102018-05-01 12:37:51 +05307604 sec_group_id =
7605 AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX;
7606 sec_group_idx =
7607 msm_dai_q6_get_group_idx(sec_group_id);
7608 if (sec_group_idx < 0) {
7609 dev_err(dai->dev, "%s port id 0x%x\n"
7610 "not supported\n",
7611 __func__, sec_group_id);
7612 return;
7613 }
Bala Kishore Patia0575102018-05-01 12:37:51 +05307614 }
Ashish Jain757e1452018-04-30 20:58:04 +05307615 }
7616
7617 rc = afe_close(prim_port_id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307618 if (rc < 0) {
7619 dev_err(dai->dev, "%s: fail to close AFE port 0x%x\n",
Ashish Jain757e1452018-04-30 20:58:04 +05307620 __func__, prim_port_id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307621 }
Ashish Jain757e1452018-04-30 20:58:04 +05307622
7623 if (sec_port_id != 0) {
7624 rc = afe_close(sec_port_id);
Bala Kishore Patia0575102018-05-01 12:37:51 +05307625 if (rc < 0) {
Ashish Jain757e1452018-04-30 20:58:04 +05307626 dev_err(dai->dev, "%s: fail AFE port 0x%x\n",
7627 __func__, sec_port_id);
7628 }
Bala Kishore Patia0575102018-05-01 12:37:51 +05307629 atomic_dec(sec_group_ref);
Ashish Jain757e1452018-04-30 20:58:04 +05307630 }
7631
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307632 atomic_dec(group_ref);
7633 clear_bit(STATUS_PORT_STARTED,
7634 dai_data->status_mask);
7635
7636 if (atomic_read(group_ref) == 0) {
7637 rc = afe_port_group_enable(group_id,
7638 NULL, false);
7639 if (rc < 0) {
Ashish Jain757e1452018-04-30 20:58:04 +05307640 dev_err(dai->dev,
7641 "%s: fail to disable grp 0x%x\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307642 __func__, group_id);
7643 }
Bala Kishore Pati11276eb2018-05-01 09:29:08 +05307644 if (!(dai_data->afe_ebit_unsupported &&
7645 !dai_data->clk_set.clk_freq_in_hz)) {
7646 rc = msm_dai_q6_tdm_set_clk(dai_data,
7647 dai->id, false);
7648 if (rc < 0) {
7649 dev_err(dai->dev,
Ashish Jain757e1452018-04-30 20:58:04 +05307650 "%s: fail to disable AFE clk 0x%x\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307651 __func__, dai->id);
Bala Kishore Pati11276eb2018-05-01 09:29:08 +05307652 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307653 }
7654 }
Surendar karka59508d72018-05-01 09:09:58 +05307655 if ((dai_data->num_group_ports > 1) &&
7656 (dai_data->sec_port_enable)) {
Bala Kishore Patia0575102018-05-01 12:37:51 +05307657 if (atomic_read(sec_group_ref) == 0) {
7658 rc = afe_port_group_enable(sec_group_id,
7659 NULL, false);
7660 if (rc < 0) {
7661 dev_err(dai->dev, "%s:failed to\n"
7662 "enable grp %x\n", __func__, group_id);
7663 }
7664 }
7665 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307666 /* TODO: need to monitor PCM/MI2S/TDM HW status */
7667 /* NOTE: AFE should error out if HW resource contention */
7668
7669 }
7670
7671 mutex_unlock(&tdm_mutex);
7672}
7673
7674static struct snd_soc_dai_ops msm_dai_q6_tdm_ops = {
7675 .prepare = msm_dai_q6_tdm_prepare,
7676 .hw_params = msm_dai_q6_tdm_hw_params,
7677 .set_tdm_slot = msm_dai_q6_tdm_set_tdm_slot,
7678 .set_channel_map = msm_dai_q6_tdm_set_channel_map,
Cong Tang2b6adc82017-05-26 12:06:50 +08007679 .set_sysclk = msm_dai_q6_tdm_set_sysclk,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307680 .shutdown = msm_dai_q6_tdm_shutdown,
7681};
7682
7683static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
7684 {
7685 .playback = {
7686 .stream_name = "Primary TDM0 Playback",
7687 .aif_name = "PRI_TDM_RX_0",
7688 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7689 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7690 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7691 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7692 SNDRV_PCM_FMTBIT_S24_LE |
7693 SNDRV_PCM_FMTBIT_S32_LE,
7694 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307695 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307696 .rate_min = 8000,
7697 .rate_max = 352800,
7698 },
7699 .ops = &msm_dai_q6_tdm_ops,
7700 .id = AFE_PORT_ID_PRIMARY_TDM_RX,
7701 .probe = msm_dai_q6_dai_tdm_probe,
7702 .remove = msm_dai_q6_dai_tdm_remove,
7703 },
7704 {
7705 .playback = {
7706 .stream_name = "Primary TDM1 Playback",
7707 .aif_name = "PRI_TDM_RX_1",
7708 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7709 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7710 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7711 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7712 SNDRV_PCM_FMTBIT_S24_LE |
7713 SNDRV_PCM_FMTBIT_S32_LE,
7714 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307715 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307716 .rate_min = 8000,
7717 .rate_max = 352800,
7718 },
7719 .ops = &msm_dai_q6_tdm_ops,
7720 .id = AFE_PORT_ID_PRIMARY_TDM_RX_1,
7721 .probe = msm_dai_q6_dai_tdm_probe,
7722 .remove = msm_dai_q6_dai_tdm_remove,
7723 },
7724 {
7725 .playback = {
7726 .stream_name = "Primary TDM2 Playback",
7727 .aif_name = "PRI_TDM_RX_2",
7728 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7729 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7730 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7731 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7732 SNDRV_PCM_FMTBIT_S24_LE |
7733 SNDRV_PCM_FMTBIT_S32_LE,
7734 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307735 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307736 .rate_min = 8000,
7737 .rate_max = 352800,
7738 },
7739 .ops = &msm_dai_q6_tdm_ops,
7740 .id = AFE_PORT_ID_PRIMARY_TDM_RX_2,
7741 .probe = msm_dai_q6_dai_tdm_probe,
7742 .remove = msm_dai_q6_dai_tdm_remove,
7743 },
7744 {
7745 .playback = {
7746 .stream_name = "Primary TDM3 Playback",
7747 .aif_name = "PRI_TDM_RX_3",
7748 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7749 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7750 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7751 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7752 SNDRV_PCM_FMTBIT_S24_LE |
7753 SNDRV_PCM_FMTBIT_S32_LE,
7754 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307755 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307756 .rate_min = 8000,
7757 .rate_max = 352800,
7758 },
7759 .ops = &msm_dai_q6_tdm_ops,
7760 .id = AFE_PORT_ID_PRIMARY_TDM_RX_3,
7761 .probe = msm_dai_q6_dai_tdm_probe,
7762 .remove = msm_dai_q6_dai_tdm_remove,
7763 },
7764 {
7765 .playback = {
7766 .stream_name = "Primary TDM4 Playback",
7767 .aif_name = "PRI_TDM_RX_4",
7768 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7769 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7770 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7771 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7772 SNDRV_PCM_FMTBIT_S24_LE |
7773 SNDRV_PCM_FMTBIT_S32_LE,
7774 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307775 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307776 .rate_min = 8000,
7777 .rate_max = 352800,
7778 },
7779 .ops = &msm_dai_q6_tdm_ops,
7780 .id = AFE_PORT_ID_PRIMARY_TDM_RX_4,
7781 .probe = msm_dai_q6_dai_tdm_probe,
7782 .remove = msm_dai_q6_dai_tdm_remove,
7783 },
7784 {
7785 .playback = {
7786 .stream_name = "Primary TDM5 Playback",
7787 .aif_name = "PRI_TDM_RX_5",
7788 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7789 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7790 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7791 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7792 SNDRV_PCM_FMTBIT_S24_LE |
7793 SNDRV_PCM_FMTBIT_S32_LE,
7794 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307795 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307796 .rate_min = 8000,
7797 .rate_max = 352800,
7798 },
7799 .ops = &msm_dai_q6_tdm_ops,
7800 .id = AFE_PORT_ID_PRIMARY_TDM_RX_5,
7801 .probe = msm_dai_q6_dai_tdm_probe,
7802 .remove = msm_dai_q6_dai_tdm_remove,
7803 },
7804 {
7805 .playback = {
7806 .stream_name = "Primary TDM6 Playback",
7807 .aif_name = "PRI_TDM_RX_6",
7808 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7809 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7810 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7811 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7812 SNDRV_PCM_FMTBIT_S24_LE |
7813 SNDRV_PCM_FMTBIT_S32_LE,
7814 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307815 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307816 .rate_min = 8000,
7817 .rate_max = 352800,
7818 },
7819 .ops = &msm_dai_q6_tdm_ops,
7820 .id = AFE_PORT_ID_PRIMARY_TDM_RX_6,
7821 .probe = msm_dai_q6_dai_tdm_probe,
7822 .remove = msm_dai_q6_dai_tdm_remove,
7823 },
7824 {
7825 .playback = {
7826 .stream_name = "Primary TDM7 Playback",
7827 .aif_name = "PRI_TDM_RX_7",
7828 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7829 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7830 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7831 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7832 SNDRV_PCM_FMTBIT_S24_LE |
7833 SNDRV_PCM_FMTBIT_S32_LE,
7834 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307835 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307836 .rate_min = 8000,
7837 .rate_max = 352800,
7838 },
7839 .ops = &msm_dai_q6_tdm_ops,
7840 .id = AFE_PORT_ID_PRIMARY_TDM_RX_7,
7841 .probe = msm_dai_q6_dai_tdm_probe,
7842 .remove = msm_dai_q6_dai_tdm_remove,
7843 },
7844 {
7845 .capture = {
7846 .stream_name = "Primary TDM0 Capture",
7847 .aif_name = "PRI_TDM_TX_0",
7848 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7849 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7850 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7851 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7852 SNDRV_PCM_FMTBIT_S24_LE |
7853 SNDRV_PCM_FMTBIT_S32_LE,
7854 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307855 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307856 .rate_min = 8000,
7857 .rate_max = 352800,
7858 },
7859 .ops = &msm_dai_q6_tdm_ops,
7860 .id = AFE_PORT_ID_PRIMARY_TDM_TX,
7861 .probe = msm_dai_q6_dai_tdm_probe,
7862 .remove = msm_dai_q6_dai_tdm_remove,
7863 },
7864 {
7865 .capture = {
7866 .stream_name = "Primary TDM1 Capture",
7867 .aif_name = "PRI_TDM_TX_1",
7868 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7869 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7870 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7871 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7872 SNDRV_PCM_FMTBIT_S24_LE |
7873 SNDRV_PCM_FMTBIT_S32_LE,
7874 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307875 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307876 .rate_min = 8000,
7877 .rate_max = 352800,
7878 },
7879 .ops = &msm_dai_q6_tdm_ops,
7880 .id = AFE_PORT_ID_PRIMARY_TDM_TX_1,
7881 .probe = msm_dai_q6_dai_tdm_probe,
7882 .remove = msm_dai_q6_dai_tdm_remove,
7883 },
7884 {
7885 .capture = {
7886 .stream_name = "Primary TDM2 Capture",
7887 .aif_name = "PRI_TDM_TX_2",
7888 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7889 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7890 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7891 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7892 SNDRV_PCM_FMTBIT_S24_LE |
7893 SNDRV_PCM_FMTBIT_S32_LE,
7894 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307895 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307896 .rate_min = 8000,
7897 .rate_max = 352800,
7898 },
7899 .ops = &msm_dai_q6_tdm_ops,
7900 .id = AFE_PORT_ID_PRIMARY_TDM_TX_2,
7901 .probe = msm_dai_q6_dai_tdm_probe,
7902 .remove = msm_dai_q6_dai_tdm_remove,
7903 },
7904 {
7905 .capture = {
7906 .stream_name = "Primary TDM3 Capture",
7907 .aif_name = "PRI_TDM_TX_3",
7908 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7909 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7910 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7911 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7912 SNDRV_PCM_FMTBIT_S24_LE |
7913 SNDRV_PCM_FMTBIT_S32_LE,
7914 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307915 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307916 .rate_min = 8000,
7917 .rate_max = 352800,
7918 },
7919 .ops = &msm_dai_q6_tdm_ops,
7920 .id = AFE_PORT_ID_PRIMARY_TDM_TX_3,
7921 .probe = msm_dai_q6_dai_tdm_probe,
7922 .remove = msm_dai_q6_dai_tdm_remove,
7923 },
7924 {
7925 .capture = {
7926 .stream_name = "Primary TDM4 Capture",
7927 .aif_name = "PRI_TDM_TX_4",
7928 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7929 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7930 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7931 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7932 SNDRV_PCM_FMTBIT_S24_LE |
7933 SNDRV_PCM_FMTBIT_S32_LE,
7934 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307935 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307936 .rate_min = 8000,
7937 .rate_max = 352800,
7938 },
7939 .ops = &msm_dai_q6_tdm_ops,
7940 .id = AFE_PORT_ID_PRIMARY_TDM_TX_4,
7941 .probe = msm_dai_q6_dai_tdm_probe,
7942 .remove = msm_dai_q6_dai_tdm_remove,
7943 },
7944 {
7945 .capture = {
7946 .stream_name = "Primary TDM5 Capture",
7947 .aif_name = "PRI_TDM_TX_5",
7948 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7949 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7950 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7951 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7952 SNDRV_PCM_FMTBIT_S24_LE |
7953 SNDRV_PCM_FMTBIT_S32_LE,
7954 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307955 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307956 .rate_min = 8000,
7957 .rate_max = 352800,
7958 },
7959 .ops = &msm_dai_q6_tdm_ops,
7960 .id = AFE_PORT_ID_PRIMARY_TDM_TX_5,
7961 .probe = msm_dai_q6_dai_tdm_probe,
7962 .remove = msm_dai_q6_dai_tdm_remove,
7963 },
7964 {
7965 .capture = {
7966 .stream_name = "Primary TDM6 Capture",
7967 .aif_name = "PRI_TDM_TX_6",
7968 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7969 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7970 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7971 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7972 SNDRV_PCM_FMTBIT_S24_LE |
7973 SNDRV_PCM_FMTBIT_S32_LE,
7974 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307975 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307976 .rate_min = 8000,
7977 .rate_max = 352800,
7978 },
7979 .ops = &msm_dai_q6_tdm_ops,
7980 .id = AFE_PORT_ID_PRIMARY_TDM_TX_6,
7981 .probe = msm_dai_q6_dai_tdm_probe,
7982 .remove = msm_dai_q6_dai_tdm_remove,
7983 },
7984 {
7985 .capture = {
7986 .stream_name = "Primary TDM7 Capture",
7987 .aif_name = "PRI_TDM_TX_7",
7988 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7989 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7990 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7991 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7992 SNDRV_PCM_FMTBIT_S24_LE |
7993 SNDRV_PCM_FMTBIT_S32_LE,
7994 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05307995 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307996 .rate_min = 8000,
7997 .rate_max = 352800,
7998 },
7999 .ops = &msm_dai_q6_tdm_ops,
8000 .id = AFE_PORT_ID_PRIMARY_TDM_TX_7,
8001 .probe = msm_dai_q6_dai_tdm_probe,
8002 .remove = msm_dai_q6_dai_tdm_remove,
8003 },
8004 {
8005 .playback = {
8006 .stream_name = "Secondary TDM0 Playback",
8007 .aif_name = "SEC_TDM_RX_0",
8008 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8009 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8010 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8011 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8012 SNDRV_PCM_FMTBIT_S24_LE |
8013 SNDRV_PCM_FMTBIT_S32_LE,
8014 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308015 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308016 .rate_min = 8000,
8017 .rate_max = 352800,
8018 },
8019 .ops = &msm_dai_q6_tdm_ops,
8020 .id = AFE_PORT_ID_SECONDARY_TDM_RX,
8021 .probe = msm_dai_q6_dai_tdm_probe,
8022 .remove = msm_dai_q6_dai_tdm_remove,
8023 },
8024 {
8025 .playback = {
8026 .stream_name = "Secondary TDM1 Playback",
8027 .aif_name = "SEC_TDM_RX_1",
8028 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8029 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8030 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8031 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8032 SNDRV_PCM_FMTBIT_S24_LE |
8033 SNDRV_PCM_FMTBIT_S32_LE,
8034 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308035 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308036 .rate_min = 8000,
8037 .rate_max = 352800,
8038 },
8039 .ops = &msm_dai_q6_tdm_ops,
8040 .id = AFE_PORT_ID_SECONDARY_TDM_RX_1,
8041 .probe = msm_dai_q6_dai_tdm_probe,
8042 .remove = msm_dai_q6_dai_tdm_remove,
8043 },
8044 {
8045 .playback = {
8046 .stream_name = "Secondary TDM2 Playback",
8047 .aif_name = "SEC_TDM_RX_2",
8048 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8049 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8050 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8051 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8052 SNDRV_PCM_FMTBIT_S24_LE |
8053 SNDRV_PCM_FMTBIT_S32_LE,
8054 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308055 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308056 .rate_min = 8000,
8057 .rate_max = 352800,
8058 },
8059 .ops = &msm_dai_q6_tdm_ops,
8060 .id = AFE_PORT_ID_SECONDARY_TDM_RX_2,
8061 .probe = msm_dai_q6_dai_tdm_probe,
8062 .remove = msm_dai_q6_dai_tdm_remove,
8063 },
8064 {
8065 .playback = {
8066 .stream_name = "Secondary TDM3 Playback",
8067 .aif_name = "SEC_TDM_RX_3",
8068 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8069 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8070 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8071 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8072 SNDRV_PCM_FMTBIT_S24_LE |
8073 SNDRV_PCM_FMTBIT_S32_LE,
8074 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308075 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308076 .rate_min = 8000,
8077 .rate_max = 352800,
8078 },
8079 .ops = &msm_dai_q6_tdm_ops,
8080 .id = AFE_PORT_ID_SECONDARY_TDM_RX_3,
8081 .probe = msm_dai_q6_dai_tdm_probe,
8082 .remove = msm_dai_q6_dai_tdm_remove,
8083 },
8084 {
8085 .playback = {
8086 .stream_name = "Secondary TDM4 Playback",
8087 .aif_name = "SEC_TDM_RX_4",
8088 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8089 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8090 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8091 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8092 SNDRV_PCM_FMTBIT_S24_LE |
8093 SNDRV_PCM_FMTBIT_S32_LE,
8094 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308095 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308096 .rate_min = 8000,
8097 .rate_max = 352800,
8098 },
8099 .ops = &msm_dai_q6_tdm_ops,
8100 .id = AFE_PORT_ID_SECONDARY_TDM_RX_4,
8101 .probe = msm_dai_q6_dai_tdm_probe,
8102 .remove = msm_dai_q6_dai_tdm_remove,
8103 },
8104 {
8105 .playback = {
8106 .stream_name = "Secondary TDM5 Playback",
8107 .aif_name = "SEC_TDM_RX_5",
8108 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8109 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8110 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8111 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8112 SNDRV_PCM_FMTBIT_S24_LE |
8113 SNDRV_PCM_FMTBIT_S32_LE,
8114 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308115 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308116 .rate_min = 8000,
8117 .rate_max = 352800,
8118 },
8119 .ops = &msm_dai_q6_tdm_ops,
8120 .id = AFE_PORT_ID_SECONDARY_TDM_RX_5,
8121 .probe = msm_dai_q6_dai_tdm_probe,
8122 .remove = msm_dai_q6_dai_tdm_remove,
8123 },
8124 {
8125 .playback = {
8126 .stream_name = "Secondary TDM6 Playback",
8127 .aif_name = "SEC_TDM_RX_6",
8128 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8129 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8130 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8131 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8132 SNDRV_PCM_FMTBIT_S24_LE |
8133 SNDRV_PCM_FMTBIT_S32_LE,
8134 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308135 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308136 .rate_min = 8000,
8137 .rate_max = 352800,
8138 },
8139 .ops = &msm_dai_q6_tdm_ops,
8140 .id = AFE_PORT_ID_SECONDARY_TDM_RX_6,
8141 .probe = msm_dai_q6_dai_tdm_probe,
8142 .remove = msm_dai_q6_dai_tdm_remove,
8143 },
8144 {
8145 .playback = {
8146 .stream_name = "Secondary TDM7 Playback",
8147 .aif_name = "SEC_TDM_RX_7",
8148 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8149 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8150 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8151 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8152 SNDRV_PCM_FMTBIT_S24_LE |
8153 SNDRV_PCM_FMTBIT_S32_LE,
8154 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308155 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308156 .rate_min = 8000,
8157 .rate_max = 352800,
8158 },
8159 .ops = &msm_dai_q6_tdm_ops,
8160 .id = AFE_PORT_ID_SECONDARY_TDM_RX_7,
8161 .probe = msm_dai_q6_dai_tdm_probe,
8162 .remove = msm_dai_q6_dai_tdm_remove,
8163 },
8164 {
8165 .capture = {
8166 .stream_name = "Secondary TDM0 Capture",
8167 .aif_name = "SEC_TDM_TX_0",
8168 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8169 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8170 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8171 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8172 SNDRV_PCM_FMTBIT_S24_LE |
8173 SNDRV_PCM_FMTBIT_S32_LE,
8174 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308175 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308176 .rate_min = 8000,
8177 .rate_max = 352800,
8178 },
8179 .ops = &msm_dai_q6_tdm_ops,
8180 .id = AFE_PORT_ID_SECONDARY_TDM_TX,
8181 .probe = msm_dai_q6_dai_tdm_probe,
8182 .remove = msm_dai_q6_dai_tdm_remove,
8183 },
8184 {
8185 .capture = {
8186 .stream_name = "Secondary TDM1 Capture",
8187 .aif_name = "SEC_TDM_TX_1",
8188 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8189 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8190 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8191 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8192 SNDRV_PCM_FMTBIT_S24_LE |
8193 SNDRV_PCM_FMTBIT_S32_LE,
8194 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308195 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308196 .rate_min = 8000,
8197 .rate_max = 352800,
8198 },
8199 .ops = &msm_dai_q6_tdm_ops,
8200 .id = AFE_PORT_ID_SECONDARY_TDM_TX_1,
8201 .probe = msm_dai_q6_dai_tdm_probe,
8202 .remove = msm_dai_q6_dai_tdm_remove,
8203 },
8204 {
8205 .capture = {
8206 .stream_name = "Secondary TDM2 Capture",
8207 .aif_name = "SEC_TDM_TX_2",
8208 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8209 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8210 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8211 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8212 SNDRV_PCM_FMTBIT_S24_LE |
8213 SNDRV_PCM_FMTBIT_S32_LE,
8214 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308215 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308216 .rate_min = 8000,
8217 .rate_max = 352800,
8218 },
8219 .ops = &msm_dai_q6_tdm_ops,
8220 .id = AFE_PORT_ID_SECONDARY_TDM_TX_2,
8221 .probe = msm_dai_q6_dai_tdm_probe,
8222 .remove = msm_dai_q6_dai_tdm_remove,
8223 },
8224 {
8225 .capture = {
8226 .stream_name = "Secondary TDM3 Capture",
8227 .aif_name = "SEC_TDM_TX_3",
8228 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8229 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8230 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8231 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8232 SNDRV_PCM_FMTBIT_S24_LE |
8233 SNDRV_PCM_FMTBIT_S32_LE,
8234 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308235 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308236 .rate_min = 8000,
8237 .rate_max = 352800,
8238 },
8239 .ops = &msm_dai_q6_tdm_ops,
8240 .id = AFE_PORT_ID_SECONDARY_TDM_TX_3,
8241 .probe = msm_dai_q6_dai_tdm_probe,
8242 .remove = msm_dai_q6_dai_tdm_remove,
8243 },
8244 {
8245 .capture = {
8246 .stream_name = "Secondary TDM4 Capture",
8247 .aif_name = "SEC_TDM_TX_4",
8248 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8249 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8250 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8251 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8252 SNDRV_PCM_FMTBIT_S24_LE |
8253 SNDRV_PCM_FMTBIT_S32_LE,
8254 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308255 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308256 .rate_min = 8000,
8257 .rate_max = 352800,
8258 },
8259 .ops = &msm_dai_q6_tdm_ops,
8260 .id = AFE_PORT_ID_SECONDARY_TDM_TX_4,
8261 .probe = msm_dai_q6_dai_tdm_probe,
8262 .remove = msm_dai_q6_dai_tdm_remove,
8263 },
8264 {
8265 .capture = {
8266 .stream_name = "Secondary TDM5 Capture",
8267 .aif_name = "SEC_TDM_TX_5",
8268 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8269 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8270 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8271 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8272 SNDRV_PCM_FMTBIT_S24_LE |
8273 SNDRV_PCM_FMTBIT_S32_LE,
8274 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308275 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308276 .rate_min = 8000,
8277 .rate_max = 352800,
8278 },
8279 .ops = &msm_dai_q6_tdm_ops,
8280 .id = AFE_PORT_ID_SECONDARY_TDM_TX_5,
8281 .probe = msm_dai_q6_dai_tdm_probe,
8282 .remove = msm_dai_q6_dai_tdm_remove,
8283 },
8284 {
8285 .capture = {
8286 .stream_name = "Secondary TDM6 Capture",
8287 .aif_name = "SEC_TDM_TX_6",
8288 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8289 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8290 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8291 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8292 SNDRV_PCM_FMTBIT_S24_LE |
8293 SNDRV_PCM_FMTBIT_S32_LE,
8294 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308295 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308296 .rate_min = 8000,
8297 .rate_max = 352800,
8298 },
8299 .ops = &msm_dai_q6_tdm_ops,
8300 .id = AFE_PORT_ID_SECONDARY_TDM_TX_6,
8301 .probe = msm_dai_q6_dai_tdm_probe,
8302 .remove = msm_dai_q6_dai_tdm_remove,
8303 },
8304 {
8305 .capture = {
8306 .stream_name = "Secondary TDM7 Capture",
8307 .aif_name = "SEC_TDM_TX_7",
8308 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8309 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8310 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8311 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8312 SNDRV_PCM_FMTBIT_S24_LE |
8313 SNDRV_PCM_FMTBIT_S32_LE,
8314 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308315 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308316 .rate_min = 8000,
8317 .rate_max = 352800,
8318 },
8319 .ops = &msm_dai_q6_tdm_ops,
8320 .id = AFE_PORT_ID_SECONDARY_TDM_TX_7,
8321 .probe = msm_dai_q6_dai_tdm_probe,
8322 .remove = msm_dai_q6_dai_tdm_remove,
8323 },
8324 {
8325 .playback = {
8326 .stream_name = "Tertiary TDM0 Playback",
8327 .aif_name = "TERT_TDM_RX_0",
8328 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8329 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8330 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8331 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8332 SNDRV_PCM_FMTBIT_S24_LE |
8333 SNDRV_PCM_FMTBIT_S32_LE,
8334 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308335 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308336 .rate_min = 8000,
8337 .rate_max = 352800,
8338 },
8339 .ops = &msm_dai_q6_tdm_ops,
8340 .id = AFE_PORT_ID_TERTIARY_TDM_RX,
8341 .probe = msm_dai_q6_dai_tdm_probe,
8342 .remove = msm_dai_q6_dai_tdm_remove,
8343 },
8344 {
8345 .playback = {
8346 .stream_name = "Tertiary TDM1 Playback",
8347 .aif_name = "TERT_TDM_RX_1",
8348 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8349 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8350 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8351 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8352 SNDRV_PCM_FMTBIT_S24_LE |
8353 SNDRV_PCM_FMTBIT_S32_LE,
8354 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308355 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308356 .rate_min = 8000,
8357 .rate_max = 352800,
8358 },
8359 .ops = &msm_dai_q6_tdm_ops,
8360 .id = AFE_PORT_ID_TERTIARY_TDM_RX_1,
8361 .probe = msm_dai_q6_dai_tdm_probe,
8362 .remove = msm_dai_q6_dai_tdm_remove,
8363 },
8364 {
8365 .playback = {
8366 .stream_name = "Tertiary TDM2 Playback",
8367 .aif_name = "TERT_TDM_RX_2",
8368 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8369 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8370 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8371 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8372 SNDRV_PCM_FMTBIT_S24_LE |
8373 SNDRV_PCM_FMTBIT_S32_LE,
8374 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308375 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308376 .rate_min = 8000,
8377 .rate_max = 352800,
8378 },
8379 .ops = &msm_dai_q6_tdm_ops,
8380 .id = AFE_PORT_ID_TERTIARY_TDM_RX_2,
8381 .probe = msm_dai_q6_dai_tdm_probe,
8382 .remove = msm_dai_q6_dai_tdm_remove,
8383 },
8384 {
8385 .playback = {
8386 .stream_name = "Tertiary TDM3 Playback",
8387 .aif_name = "TERT_TDM_RX_3",
8388 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8389 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8390 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8391 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8392 SNDRV_PCM_FMTBIT_S24_LE |
8393 SNDRV_PCM_FMTBIT_S32_LE,
8394 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308395 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308396 .rate_min = 8000,
8397 .rate_max = 352800,
8398 },
8399 .ops = &msm_dai_q6_tdm_ops,
8400 .id = AFE_PORT_ID_TERTIARY_TDM_RX_3,
8401 .probe = msm_dai_q6_dai_tdm_probe,
8402 .remove = msm_dai_q6_dai_tdm_remove,
8403 },
8404 {
8405 .playback = {
8406 .stream_name = "Tertiary TDM4 Playback",
8407 .aif_name = "TERT_TDM_RX_4",
8408 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8409 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8410 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8411 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8412 SNDRV_PCM_FMTBIT_S24_LE |
8413 SNDRV_PCM_FMTBIT_S32_LE,
8414 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308415 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308416 .rate_min = 8000,
8417 .rate_max = 352800,
8418 },
8419 .ops = &msm_dai_q6_tdm_ops,
8420 .id = AFE_PORT_ID_TERTIARY_TDM_RX_4,
8421 .probe = msm_dai_q6_dai_tdm_probe,
8422 .remove = msm_dai_q6_dai_tdm_remove,
8423 },
8424 {
8425 .playback = {
8426 .stream_name = "Tertiary TDM5 Playback",
8427 .aif_name = "TERT_TDM_RX_5",
8428 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8429 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8430 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8431 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8432 SNDRV_PCM_FMTBIT_S24_LE |
8433 SNDRV_PCM_FMTBIT_S32_LE,
8434 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308435 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308436 .rate_min = 8000,
8437 .rate_max = 352800,
8438 },
8439 .ops = &msm_dai_q6_tdm_ops,
8440 .id = AFE_PORT_ID_TERTIARY_TDM_RX_5,
8441 .probe = msm_dai_q6_dai_tdm_probe,
8442 .remove = msm_dai_q6_dai_tdm_remove,
8443 },
8444 {
8445 .playback = {
8446 .stream_name = "Tertiary TDM6 Playback",
8447 .aif_name = "TERT_TDM_RX_6",
8448 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8449 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8450 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8451 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8452 SNDRV_PCM_FMTBIT_S24_LE |
8453 SNDRV_PCM_FMTBIT_S32_LE,
8454 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308455 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308456 .rate_min = 8000,
8457 .rate_max = 352800,
8458 },
8459 .ops = &msm_dai_q6_tdm_ops,
8460 .id = AFE_PORT_ID_TERTIARY_TDM_RX_6,
8461 .probe = msm_dai_q6_dai_tdm_probe,
8462 .remove = msm_dai_q6_dai_tdm_remove,
8463 },
8464 {
8465 .playback = {
8466 .stream_name = "Tertiary TDM7 Playback",
8467 .aif_name = "TERT_TDM_RX_7",
8468 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8469 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8470 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8471 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8472 SNDRV_PCM_FMTBIT_S24_LE |
8473 SNDRV_PCM_FMTBIT_S32_LE,
8474 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308475 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308476 .rate_min = 8000,
8477 .rate_max = 352800,
8478 },
8479 .ops = &msm_dai_q6_tdm_ops,
8480 .id = AFE_PORT_ID_TERTIARY_TDM_RX_7,
8481 .probe = msm_dai_q6_dai_tdm_probe,
8482 .remove = msm_dai_q6_dai_tdm_remove,
8483 },
8484 {
8485 .capture = {
8486 .stream_name = "Tertiary TDM0 Capture",
8487 .aif_name = "TERT_TDM_TX_0",
8488 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8489 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8490 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8491 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8492 SNDRV_PCM_FMTBIT_S24_LE |
8493 SNDRV_PCM_FMTBIT_S32_LE,
8494 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308495 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308496 .rate_min = 8000,
8497 .rate_max = 352800,
8498 },
8499 .ops = &msm_dai_q6_tdm_ops,
8500 .id = AFE_PORT_ID_TERTIARY_TDM_TX,
8501 .probe = msm_dai_q6_dai_tdm_probe,
8502 .remove = msm_dai_q6_dai_tdm_remove,
8503 },
8504 {
8505 .capture = {
8506 .stream_name = "Tertiary TDM1 Capture",
8507 .aif_name = "TERT_TDM_TX_1",
8508 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8509 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8510 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8511 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8512 SNDRV_PCM_FMTBIT_S24_LE |
8513 SNDRV_PCM_FMTBIT_S32_LE,
8514 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308515 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308516 .rate_min = 8000,
8517 .rate_max = 352800,
8518 },
8519 .ops = &msm_dai_q6_tdm_ops,
8520 .id = AFE_PORT_ID_TERTIARY_TDM_TX_1,
8521 .probe = msm_dai_q6_dai_tdm_probe,
8522 .remove = msm_dai_q6_dai_tdm_remove,
8523 },
8524 {
8525 .capture = {
8526 .stream_name = "Tertiary TDM2 Capture",
8527 .aif_name = "TERT_TDM_TX_2",
8528 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8529 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8530 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8531 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8532 SNDRV_PCM_FMTBIT_S24_LE |
8533 SNDRV_PCM_FMTBIT_S32_LE,
8534 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308535 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308536 .rate_min = 8000,
8537 .rate_max = 352800,
8538 },
8539 .ops = &msm_dai_q6_tdm_ops,
8540 .id = AFE_PORT_ID_TERTIARY_TDM_TX_2,
8541 .probe = msm_dai_q6_dai_tdm_probe,
8542 .remove = msm_dai_q6_dai_tdm_remove,
8543 },
8544 {
8545 .capture = {
8546 .stream_name = "Tertiary TDM3 Capture",
8547 .aif_name = "TERT_TDM_TX_3",
8548 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8549 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8550 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8551 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8552 SNDRV_PCM_FMTBIT_S24_LE |
8553 SNDRV_PCM_FMTBIT_S32_LE,
8554 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308555 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308556 .rate_min = 8000,
8557 .rate_max = 352800,
8558 },
8559 .ops = &msm_dai_q6_tdm_ops,
8560 .id = AFE_PORT_ID_TERTIARY_TDM_TX_3,
8561 .probe = msm_dai_q6_dai_tdm_probe,
8562 .remove = msm_dai_q6_dai_tdm_remove,
8563 },
8564 {
8565 .capture = {
8566 .stream_name = "Tertiary TDM4 Capture",
8567 .aif_name = "TERT_TDM_TX_4",
8568 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8569 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8570 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8571 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8572 SNDRV_PCM_FMTBIT_S24_LE |
8573 SNDRV_PCM_FMTBIT_S32_LE,
8574 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308575 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308576 .rate_min = 8000,
8577 .rate_max = 352800,
8578 },
8579 .ops = &msm_dai_q6_tdm_ops,
8580 .id = AFE_PORT_ID_TERTIARY_TDM_TX_4,
8581 .probe = msm_dai_q6_dai_tdm_probe,
8582 .remove = msm_dai_q6_dai_tdm_remove,
8583 },
8584 {
8585 .capture = {
8586 .stream_name = "Tertiary TDM5 Capture",
8587 .aif_name = "TERT_TDM_TX_5",
8588 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8589 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8590 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8591 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8592 SNDRV_PCM_FMTBIT_S24_LE |
8593 SNDRV_PCM_FMTBIT_S32_LE,
8594 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308595 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308596 .rate_min = 8000,
8597 .rate_max = 352800,
8598 },
8599 .ops = &msm_dai_q6_tdm_ops,
8600 .id = AFE_PORT_ID_TERTIARY_TDM_TX_5,
8601 .probe = msm_dai_q6_dai_tdm_probe,
8602 .remove = msm_dai_q6_dai_tdm_remove,
8603 },
8604 {
8605 .capture = {
8606 .stream_name = "Tertiary TDM6 Capture",
8607 .aif_name = "TERT_TDM_TX_6",
8608 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8609 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8610 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8611 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8612 SNDRV_PCM_FMTBIT_S24_LE |
8613 SNDRV_PCM_FMTBIT_S32_LE,
8614 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308615 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308616 .rate_min = 8000,
8617 .rate_max = 352800,
8618 },
8619 .ops = &msm_dai_q6_tdm_ops,
8620 .id = AFE_PORT_ID_TERTIARY_TDM_TX_6,
8621 .probe = msm_dai_q6_dai_tdm_probe,
8622 .remove = msm_dai_q6_dai_tdm_remove,
8623 },
8624 {
8625 .capture = {
8626 .stream_name = "Tertiary TDM7 Capture",
8627 .aif_name = "TERT_TDM_TX_7",
8628 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8629 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8630 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8631 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8632 SNDRV_PCM_FMTBIT_S24_LE |
8633 SNDRV_PCM_FMTBIT_S32_LE,
8634 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308635 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308636 .rate_min = 8000,
8637 .rate_max = 352800,
8638 },
8639 .ops = &msm_dai_q6_tdm_ops,
8640 .id = AFE_PORT_ID_TERTIARY_TDM_TX_7,
8641 .probe = msm_dai_q6_dai_tdm_probe,
8642 .remove = msm_dai_q6_dai_tdm_remove,
8643 },
8644 {
8645 .playback = {
8646 .stream_name = "Quaternary TDM0 Playback",
8647 .aif_name = "QUAT_TDM_RX_0",
8648 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
8649 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
8650 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8651 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8652 SNDRV_PCM_FMTBIT_S24_LE |
8653 SNDRV_PCM_FMTBIT_S32_LE,
8654 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308655 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308656 .rate_min = 8000,
8657 .rate_max = 352800,
8658 },
8659 .ops = &msm_dai_q6_tdm_ops,
8660 .id = AFE_PORT_ID_QUATERNARY_TDM_RX,
8661 .probe = msm_dai_q6_dai_tdm_probe,
8662 .remove = msm_dai_q6_dai_tdm_remove,
8663 },
8664 {
8665 .playback = {
8666 .stream_name = "Quaternary TDM1 Playback",
8667 .aif_name = "QUAT_TDM_RX_1",
8668 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8669 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8670 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8671 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8672 SNDRV_PCM_FMTBIT_S24_LE |
8673 SNDRV_PCM_FMTBIT_S32_LE,
8674 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308675 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308676 .rate_min = 8000,
8677 .rate_max = 352800,
8678 },
8679 .ops = &msm_dai_q6_tdm_ops,
8680 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_1,
8681 .probe = msm_dai_q6_dai_tdm_probe,
8682 .remove = msm_dai_q6_dai_tdm_remove,
8683 },
8684 {
8685 .playback = {
8686 .stream_name = "Quaternary TDM2 Playback",
8687 .aif_name = "QUAT_TDM_RX_2",
8688 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8689 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8690 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8691 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8692 SNDRV_PCM_FMTBIT_S24_LE |
8693 SNDRV_PCM_FMTBIT_S32_LE,
8694 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308695 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308696 .rate_min = 8000,
8697 .rate_max = 352800,
8698 },
8699 .ops = &msm_dai_q6_tdm_ops,
8700 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_2,
8701 .probe = msm_dai_q6_dai_tdm_probe,
8702 .remove = msm_dai_q6_dai_tdm_remove,
8703 },
8704 {
8705 .playback = {
8706 .stream_name = "Quaternary TDM3 Playback",
8707 .aif_name = "QUAT_TDM_RX_3",
8708 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8709 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8710 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8711 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8712 SNDRV_PCM_FMTBIT_S24_LE |
8713 SNDRV_PCM_FMTBIT_S32_LE,
8714 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308715 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308716 .rate_min = 8000,
8717 .rate_max = 352800,
8718 },
8719 .ops = &msm_dai_q6_tdm_ops,
8720 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_3,
8721 .probe = msm_dai_q6_dai_tdm_probe,
8722 .remove = msm_dai_q6_dai_tdm_remove,
8723 },
8724 {
8725 .playback = {
8726 .stream_name = "Quaternary TDM4 Playback",
8727 .aif_name = "QUAT_TDM_RX_4",
8728 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8729 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8730 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8731 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8732 SNDRV_PCM_FMTBIT_S24_LE |
8733 SNDRV_PCM_FMTBIT_S32_LE,
8734 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308735 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308736 .rate_min = 8000,
8737 .rate_max = 352800,
8738 },
8739 .ops = &msm_dai_q6_tdm_ops,
8740 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_4,
8741 .probe = msm_dai_q6_dai_tdm_probe,
8742 .remove = msm_dai_q6_dai_tdm_remove,
8743 },
8744 {
8745 .playback = {
8746 .stream_name = "Quaternary TDM5 Playback",
8747 .aif_name = "QUAT_TDM_RX_5",
8748 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8749 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8750 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8751 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8752 SNDRV_PCM_FMTBIT_S24_LE |
8753 SNDRV_PCM_FMTBIT_S32_LE,
8754 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308755 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308756 .rate_min = 8000,
8757 .rate_max = 352800,
8758 },
8759 .ops = &msm_dai_q6_tdm_ops,
8760 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_5,
8761 .probe = msm_dai_q6_dai_tdm_probe,
8762 .remove = msm_dai_q6_dai_tdm_remove,
8763 },
8764 {
8765 .playback = {
8766 .stream_name = "Quaternary TDM6 Playback",
8767 .aif_name = "QUAT_TDM_RX_6",
8768 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8769 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8770 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8771 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8772 SNDRV_PCM_FMTBIT_S24_LE |
8773 SNDRV_PCM_FMTBIT_S32_LE,
8774 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308775 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308776 .rate_min = 8000,
8777 .rate_max = 352800,
8778 },
8779 .ops = &msm_dai_q6_tdm_ops,
8780 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_6,
8781 .probe = msm_dai_q6_dai_tdm_probe,
8782 .remove = msm_dai_q6_dai_tdm_remove,
8783 },
8784 {
8785 .playback = {
8786 .stream_name = "Quaternary TDM7 Playback",
8787 .aif_name = "QUAT_TDM_RX_7",
8788 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8789 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8790 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8791 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8792 SNDRV_PCM_FMTBIT_S24_LE |
8793 SNDRV_PCM_FMTBIT_S32_LE,
8794 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308795 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308796 .rate_min = 8000,
8797 .rate_max = 352800,
8798 },
8799 .ops = &msm_dai_q6_tdm_ops,
8800 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_7,
8801 .probe = msm_dai_q6_dai_tdm_probe,
8802 .remove = msm_dai_q6_dai_tdm_remove,
8803 },
8804 {
8805 .capture = {
8806 .stream_name = "Quaternary TDM0 Capture",
8807 .aif_name = "QUAT_TDM_TX_0",
8808 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8809 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8810 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8811 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8812 SNDRV_PCM_FMTBIT_S24_LE |
8813 SNDRV_PCM_FMTBIT_S32_LE,
8814 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308815 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308816 .rate_min = 8000,
8817 .rate_max = 352800,
8818 },
8819 .ops = &msm_dai_q6_tdm_ops,
8820 .id = AFE_PORT_ID_QUATERNARY_TDM_TX,
8821 .probe = msm_dai_q6_dai_tdm_probe,
8822 .remove = msm_dai_q6_dai_tdm_remove,
8823 },
8824 {
8825 .capture = {
8826 .stream_name = "Quaternary TDM1 Capture",
8827 .aif_name = "QUAT_TDM_TX_1",
8828 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8829 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8830 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8831 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8832 SNDRV_PCM_FMTBIT_S24_LE |
8833 SNDRV_PCM_FMTBIT_S32_LE,
8834 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308835 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308836 .rate_min = 8000,
8837 .rate_max = 352800,
8838 },
8839 .ops = &msm_dai_q6_tdm_ops,
8840 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_1,
8841 .probe = msm_dai_q6_dai_tdm_probe,
8842 .remove = msm_dai_q6_dai_tdm_remove,
8843 },
8844 {
8845 .capture = {
8846 .stream_name = "Quaternary TDM2 Capture",
8847 .aif_name = "QUAT_TDM_TX_2",
8848 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8849 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8850 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8851 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8852 SNDRV_PCM_FMTBIT_S24_LE |
8853 SNDRV_PCM_FMTBIT_S32_LE,
8854 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308855 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308856 .rate_min = 8000,
8857 .rate_max = 352800,
8858 },
8859 .ops = &msm_dai_q6_tdm_ops,
8860 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_2,
8861 .probe = msm_dai_q6_dai_tdm_probe,
8862 .remove = msm_dai_q6_dai_tdm_remove,
8863 },
8864 {
8865 .capture = {
8866 .stream_name = "Quaternary TDM3 Capture",
8867 .aif_name = "QUAT_TDM_TX_3",
8868 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8869 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8870 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8871 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8872 SNDRV_PCM_FMTBIT_S24_LE |
8873 SNDRV_PCM_FMTBIT_S32_LE,
8874 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308875 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308876 .rate_min = 8000,
8877 .rate_max = 352800,
8878 },
8879 .ops = &msm_dai_q6_tdm_ops,
8880 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_3,
8881 .probe = msm_dai_q6_dai_tdm_probe,
8882 .remove = msm_dai_q6_dai_tdm_remove,
8883 },
8884 {
8885 .capture = {
8886 .stream_name = "Quaternary TDM4 Capture",
8887 .aif_name = "QUAT_TDM_TX_4",
8888 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8889 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8890 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8891 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8892 SNDRV_PCM_FMTBIT_S24_LE |
8893 SNDRV_PCM_FMTBIT_S32_LE,
8894 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308895 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308896 .rate_min = 8000,
8897 .rate_max = 352800,
8898 },
8899 .ops = &msm_dai_q6_tdm_ops,
8900 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_4,
8901 .probe = msm_dai_q6_dai_tdm_probe,
8902 .remove = msm_dai_q6_dai_tdm_remove,
8903 },
8904 {
8905 .capture = {
8906 .stream_name = "Quaternary TDM5 Capture",
8907 .aif_name = "QUAT_TDM_TX_5",
8908 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8909 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8910 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8911 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8912 SNDRV_PCM_FMTBIT_S24_LE |
8913 SNDRV_PCM_FMTBIT_S32_LE,
8914 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308915 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308916 .rate_min = 8000,
8917 .rate_max = 352800,
8918 },
8919 .ops = &msm_dai_q6_tdm_ops,
8920 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_5,
8921 .probe = msm_dai_q6_dai_tdm_probe,
8922 .remove = msm_dai_q6_dai_tdm_remove,
8923 },
8924 {
8925 .capture = {
8926 .stream_name = "Quaternary TDM6 Capture",
8927 .aif_name = "QUAT_TDM_TX_6",
8928 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8929 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8930 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8931 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8932 SNDRV_PCM_FMTBIT_S24_LE |
8933 SNDRV_PCM_FMTBIT_S32_LE,
8934 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308935 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308936 .rate_min = 8000,
8937 .rate_max = 352800,
8938 },
8939 .ops = &msm_dai_q6_tdm_ops,
8940 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_6,
8941 .probe = msm_dai_q6_dai_tdm_probe,
8942 .remove = msm_dai_q6_dai_tdm_remove,
8943 },
8944 {
8945 .capture = {
8946 .stream_name = "Quaternary TDM7 Capture",
8947 .aif_name = "QUAT_TDM_TX_7",
8948 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8949 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8950 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8951 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8952 SNDRV_PCM_FMTBIT_S24_LE |
8953 SNDRV_PCM_FMTBIT_S32_LE,
8954 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308955 .channels_max = 16,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308956 .rate_min = 8000,
8957 .rate_max = 352800,
8958 },
8959 .ops = &msm_dai_q6_tdm_ops,
8960 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_7,
8961 .probe = msm_dai_q6_dai_tdm_probe,
8962 .remove = msm_dai_q6_dai_tdm_remove,
8963 },
Rohit Kumara5077932017-09-10 22:05:05 +05308964 {
8965 .playback = {
8966 .stream_name = "Quinary TDM0 Playback",
8967 .aif_name = "QUIN_TDM_RX_0",
8968 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
8969 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
8970 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8971 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8972 SNDRV_PCM_FMTBIT_S24_LE |
8973 SNDRV_PCM_FMTBIT_S32_LE,
8974 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308975 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05308976 .rate_min = 8000,
8977 .rate_max = 352800,
8978 },
8979 .ops = &msm_dai_q6_tdm_ops,
8980 .id = AFE_PORT_ID_QUINARY_TDM_RX,
8981 .probe = msm_dai_q6_dai_tdm_probe,
8982 .remove = msm_dai_q6_dai_tdm_remove,
8983 },
8984 {
8985 .playback = {
8986 .stream_name = "Quinary TDM1 Playback",
8987 .aif_name = "QUIN_TDM_RX_1",
8988 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
8989 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
8990 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8991 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8992 SNDRV_PCM_FMTBIT_S24_LE |
8993 SNDRV_PCM_FMTBIT_S32_LE,
8994 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05308995 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05308996 .rate_min = 8000,
8997 .rate_max = 352800,
8998 },
8999 .ops = &msm_dai_q6_tdm_ops,
9000 .id = AFE_PORT_ID_QUINARY_TDM_RX_1,
9001 .probe = msm_dai_q6_dai_tdm_probe,
9002 .remove = msm_dai_q6_dai_tdm_remove,
9003 },
9004 {
9005 .playback = {
9006 .stream_name = "Quinary TDM2 Playback",
9007 .aif_name = "QUIN_TDM_RX_2",
9008 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
9009 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
9010 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
9011 .formats = SNDRV_PCM_FMTBIT_S16_LE |
9012 SNDRV_PCM_FMTBIT_S24_LE |
9013 SNDRV_PCM_FMTBIT_S32_LE,
9014 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05309015 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05309016 .rate_min = 8000,
9017 .rate_max = 352800,
9018 },
9019 .ops = &msm_dai_q6_tdm_ops,
9020 .id = AFE_PORT_ID_QUINARY_TDM_RX_2,
9021 .probe = msm_dai_q6_dai_tdm_probe,
9022 .remove = msm_dai_q6_dai_tdm_remove,
9023 },
9024 {
9025 .playback = {
9026 .stream_name = "Quinary TDM3 Playback",
9027 .aif_name = "QUIN_TDM_RX_3",
9028 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
9029 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
9030 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
9031 .formats = SNDRV_PCM_FMTBIT_S16_LE |
9032 SNDRV_PCM_FMTBIT_S24_LE |
9033 SNDRV_PCM_FMTBIT_S32_LE,
9034 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05309035 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05309036 .rate_min = 8000,
9037 .rate_max = 352800,
9038 },
9039 .ops = &msm_dai_q6_tdm_ops,
9040 .id = AFE_PORT_ID_QUINARY_TDM_RX_3,
9041 .probe = msm_dai_q6_dai_tdm_probe,
9042 .remove = msm_dai_q6_dai_tdm_remove,
9043 },
9044 {
9045 .playback = {
9046 .stream_name = "Quinary TDM4 Playback",
9047 .aif_name = "QUIN_TDM_RX_4",
9048 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
9049 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
9050 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
9051 .formats = SNDRV_PCM_FMTBIT_S16_LE |
9052 SNDRV_PCM_FMTBIT_S24_LE |
9053 SNDRV_PCM_FMTBIT_S32_LE,
9054 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05309055 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05309056 .rate_min = 8000,
9057 .rate_max = 352800,
9058 },
9059 .ops = &msm_dai_q6_tdm_ops,
9060 .id = AFE_PORT_ID_QUINARY_TDM_RX_4,
9061 .probe = msm_dai_q6_dai_tdm_probe,
9062 .remove = msm_dai_q6_dai_tdm_remove,
9063 },
9064 {
9065 .playback = {
9066 .stream_name = "Quinary TDM5 Playback",
9067 .aif_name = "QUIN_TDM_RX_5",
9068 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
9069 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
9070 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
9071 .formats = SNDRV_PCM_FMTBIT_S16_LE |
9072 SNDRV_PCM_FMTBIT_S24_LE |
9073 SNDRV_PCM_FMTBIT_S32_LE,
9074 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05309075 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05309076 .rate_min = 8000,
9077 .rate_max = 352800,
9078 },
9079 .ops = &msm_dai_q6_tdm_ops,
9080 .id = AFE_PORT_ID_QUINARY_TDM_RX_5,
9081 .probe = msm_dai_q6_dai_tdm_probe,
9082 .remove = msm_dai_q6_dai_tdm_remove,
9083 },
9084 {
9085 .playback = {
9086 .stream_name = "Quinary TDM6 Playback",
9087 .aif_name = "QUIN_TDM_RX_6",
9088 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
9089 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
9090 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
9091 .formats = SNDRV_PCM_FMTBIT_S16_LE |
9092 SNDRV_PCM_FMTBIT_S24_LE |
9093 SNDRV_PCM_FMTBIT_S32_LE,
9094 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05309095 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05309096 .rate_min = 8000,
9097 .rate_max = 352800,
9098 },
9099 .ops = &msm_dai_q6_tdm_ops,
9100 .id = AFE_PORT_ID_QUINARY_TDM_RX_6,
9101 .probe = msm_dai_q6_dai_tdm_probe,
9102 .remove = msm_dai_q6_dai_tdm_remove,
9103 },
9104 {
9105 .playback = {
9106 .stream_name = "Quinary TDM7 Playback",
9107 .aif_name = "QUIN_TDM_RX_7",
9108 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
9109 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
9110 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
9111 .formats = SNDRV_PCM_FMTBIT_S16_LE |
9112 SNDRV_PCM_FMTBIT_S24_LE |
9113 SNDRV_PCM_FMTBIT_S32_LE,
9114 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05309115 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05309116 .rate_min = 8000,
9117 .rate_max = 352800,
9118 },
9119 .ops = &msm_dai_q6_tdm_ops,
9120 .id = AFE_PORT_ID_QUINARY_TDM_RX_7,
9121 .probe = msm_dai_q6_dai_tdm_probe,
9122 .remove = msm_dai_q6_dai_tdm_remove,
9123 },
9124 {
9125 .capture = {
9126 .stream_name = "Quinary TDM0 Capture",
9127 .aif_name = "QUIN_TDM_TX_0",
9128 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
9129 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
9130 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
9131 .formats = SNDRV_PCM_FMTBIT_S16_LE |
9132 SNDRV_PCM_FMTBIT_S24_LE |
9133 SNDRV_PCM_FMTBIT_S32_LE,
9134 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05309135 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05309136 .rate_min = 8000,
9137 .rate_max = 352800,
9138 },
9139 .ops = &msm_dai_q6_tdm_ops,
9140 .id = AFE_PORT_ID_QUINARY_TDM_TX,
9141 .probe = msm_dai_q6_dai_tdm_probe,
9142 .remove = msm_dai_q6_dai_tdm_remove,
9143 },
9144 {
9145 .capture = {
9146 .stream_name = "Quinary TDM1 Capture",
9147 .aif_name = "QUIN_TDM_TX_1",
9148 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
9149 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
9150 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
9151 .formats = SNDRV_PCM_FMTBIT_S16_LE |
9152 SNDRV_PCM_FMTBIT_S24_LE |
9153 SNDRV_PCM_FMTBIT_S32_LE,
9154 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05309155 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05309156 .rate_min = 8000,
9157 .rate_max = 352800,
9158 },
9159 .ops = &msm_dai_q6_tdm_ops,
9160 .id = AFE_PORT_ID_QUINARY_TDM_TX_1,
9161 .probe = msm_dai_q6_dai_tdm_probe,
9162 .remove = msm_dai_q6_dai_tdm_remove,
9163 },
9164 {
9165 .capture = {
9166 .stream_name = "Quinary TDM2 Capture",
9167 .aif_name = "QUIN_TDM_TX_2",
9168 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
9169 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
9170 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
9171 .formats = SNDRV_PCM_FMTBIT_S16_LE |
9172 SNDRV_PCM_FMTBIT_S24_LE |
9173 SNDRV_PCM_FMTBIT_S32_LE,
9174 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05309175 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05309176 .rate_min = 8000,
9177 .rate_max = 352800,
9178 },
9179 .ops = &msm_dai_q6_tdm_ops,
9180 .id = AFE_PORT_ID_QUINARY_TDM_TX_2,
9181 .probe = msm_dai_q6_dai_tdm_probe,
9182 .remove = msm_dai_q6_dai_tdm_remove,
9183 },
9184 {
9185 .capture = {
9186 .stream_name = "Quinary TDM3 Capture",
9187 .aif_name = "QUIN_TDM_TX_3",
9188 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
9189 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
9190 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
9191 .formats = SNDRV_PCM_FMTBIT_S16_LE |
9192 SNDRV_PCM_FMTBIT_S24_LE |
9193 SNDRV_PCM_FMTBIT_S32_LE,
9194 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05309195 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05309196 .rate_min = 8000,
9197 .rate_max = 352800,
9198 },
9199 .ops = &msm_dai_q6_tdm_ops,
9200 .id = AFE_PORT_ID_QUINARY_TDM_TX_3,
9201 .probe = msm_dai_q6_dai_tdm_probe,
9202 .remove = msm_dai_q6_dai_tdm_remove,
9203 },
9204 {
9205 .capture = {
9206 .stream_name = "Quinary TDM4 Capture",
9207 .aif_name = "QUIN_TDM_TX_4",
9208 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
9209 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
9210 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
9211 .formats = SNDRV_PCM_FMTBIT_S16_LE |
9212 SNDRV_PCM_FMTBIT_S24_LE |
9213 SNDRV_PCM_FMTBIT_S32_LE,
9214 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05309215 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05309216 .rate_min = 8000,
9217 .rate_max = 352800,
9218 },
9219 .ops = &msm_dai_q6_tdm_ops,
9220 .id = AFE_PORT_ID_QUINARY_TDM_TX_4,
9221 .probe = msm_dai_q6_dai_tdm_probe,
9222 .remove = msm_dai_q6_dai_tdm_remove,
9223 },
9224 {
9225 .capture = {
9226 .stream_name = "Quinary TDM5 Capture",
9227 .aif_name = "QUIN_TDM_TX_5",
9228 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
9229 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
9230 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
9231 .formats = SNDRV_PCM_FMTBIT_S16_LE |
9232 SNDRV_PCM_FMTBIT_S24_LE |
9233 SNDRV_PCM_FMTBIT_S32_LE,
9234 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05309235 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05309236 .rate_min = 8000,
9237 .rate_max = 352800,
9238 },
9239 .ops = &msm_dai_q6_tdm_ops,
9240 .id = AFE_PORT_ID_QUINARY_TDM_TX_5,
9241 .probe = msm_dai_q6_dai_tdm_probe,
9242 .remove = msm_dai_q6_dai_tdm_remove,
9243 },
9244 {
9245 .capture = {
9246 .stream_name = "Quinary TDM6 Capture",
9247 .aif_name = "QUIN_TDM_TX_6",
9248 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
9249 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
9250 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
9251 .formats = SNDRV_PCM_FMTBIT_S16_LE |
9252 SNDRV_PCM_FMTBIT_S24_LE |
9253 SNDRV_PCM_FMTBIT_S32_LE,
9254 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05309255 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05309256 .rate_min = 8000,
9257 .rate_max = 352800,
9258 },
9259 .ops = &msm_dai_q6_tdm_ops,
9260 .id = AFE_PORT_ID_QUINARY_TDM_TX_6,
9261 .probe = msm_dai_q6_dai_tdm_probe,
9262 .remove = msm_dai_q6_dai_tdm_remove,
9263 },
9264 {
9265 .capture = {
9266 .stream_name = "Quinary TDM7 Capture",
9267 .aif_name = "QUIN_TDM_TX_7",
9268 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
9269 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
9270 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
9271 .formats = SNDRV_PCM_FMTBIT_S16_LE |
9272 SNDRV_PCM_FMTBIT_S24_LE |
9273 SNDRV_PCM_FMTBIT_S32_LE,
9274 .channels_min = 1,
Dhanalakshmi Siddani20a2fe12019-05-31 17:52:52 +05309275 .channels_max = 16,
Rohit Kumara5077932017-09-10 22:05:05 +05309276 .rate_min = 8000,
9277 .rate_max = 352800,
9278 },
9279 .ops = &msm_dai_q6_tdm_ops,
9280 .id = AFE_PORT_ID_QUINARY_TDM_TX_7,
9281 .probe = msm_dai_q6_dai_tdm_probe,
9282 .remove = msm_dai_q6_dai_tdm_remove,
9283 },
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309284};
9285
9286static const struct snd_soc_component_driver msm_q6_tdm_dai_component = {
9287 .name = "msm-dai-q6-tdm",
9288};
9289
9290static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev)
9291{
9292 struct msm_dai_q6_tdm_dai_data *dai_data = NULL;
9293 struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header = NULL;
9294 int rc = 0;
9295 u32 tdm_dev_id = 0;
9296 int port_idx = 0;
9297 struct device_node *tdm_parent_node = NULL;
9298
9299 /* retrieve device/afe id */
9300 rc = of_property_read_u32(pdev->dev.of_node,
9301 "qcom,msm-cpudai-tdm-dev-id",
9302 &tdm_dev_id);
9303 if (rc) {
9304 dev_err(&pdev->dev, "%s: Device ID missing in DT file\n",
9305 __func__);
9306 goto rtn;
9307 }
9308 if ((tdm_dev_id < AFE_PORT_ID_TDM_PORT_RANGE_START) ||
9309 (tdm_dev_id > AFE_PORT_ID_TDM_PORT_RANGE_END)) {
9310 dev_err(&pdev->dev, "%s: Invalid TDM Device ID 0x%x in DT file\n",
9311 __func__, tdm_dev_id);
9312 rc = -ENXIO;
9313 goto rtn;
9314 }
9315 pdev->id = tdm_dev_id;
9316
9317 dev_info(&pdev->dev, "%s: dev_name: %s dev_id: 0x%x\n",
9318 __func__, dev_name(&pdev->dev), tdm_dev_id);
9319
9320 dai_data = kzalloc(sizeof(struct msm_dai_q6_tdm_dai_data),
9321 GFP_KERNEL);
9322 if (!dai_data) {
9323 rc = -ENOMEM;
9324 dev_err(&pdev->dev,
9325 "%s Failed to allocate memory for tdm dai_data\n",
9326 __func__);
9327 goto rtn;
9328 }
9329 memset(dai_data, 0, sizeof(*dai_data));
9330
9331 /* TDM CFG */
9332 tdm_parent_node = of_get_parent(pdev->dev.of_node);
9333 rc = of_property_read_u32(tdm_parent_node,
9334 "qcom,msm-cpudai-tdm-sync-mode",
9335 (u32 *)&dai_data->port_cfg.tdm.sync_mode);
9336 if (rc) {
9337 dev_err(&pdev->dev, "%s: Sync Mode from DT file %s\n",
9338 __func__, "qcom,msm-cpudai-tdm-sync-mode");
9339 goto free_dai_data;
9340 }
9341 dev_dbg(&pdev->dev, "%s: Sync Mode from DT file 0x%x\n",
9342 __func__, dai_data->port_cfg.tdm.sync_mode);
9343
9344 rc = of_property_read_u32(tdm_parent_node,
9345 "qcom,msm-cpudai-tdm-sync-src",
9346 (u32 *)&dai_data->port_cfg.tdm.sync_src);
9347 if (rc) {
9348 dev_err(&pdev->dev, "%s: Sync Src from DT file %s\n",
9349 __func__, "qcom,msm-cpudai-tdm-sync-src");
9350 goto free_dai_data;
9351 }
9352 dev_dbg(&pdev->dev, "%s: Sync Src from DT file 0x%x\n",
9353 __func__, dai_data->port_cfg.tdm.sync_src);
9354
9355 rc = of_property_read_u32(tdm_parent_node,
9356 "qcom,msm-cpudai-tdm-data-out",
9357 (u32 *)&dai_data->port_cfg.tdm.ctrl_data_out_enable);
9358 if (rc) {
9359 dev_err(&pdev->dev, "%s: Data Out from DT file %s\n",
9360 __func__, "qcom,msm-cpudai-tdm-data-out");
9361 goto free_dai_data;
9362 }
9363 dev_dbg(&pdev->dev, "%s: Data Out from DT file 0x%x\n",
9364 __func__, dai_data->port_cfg.tdm.ctrl_data_out_enable);
9365
9366 rc = of_property_read_u32(tdm_parent_node,
9367 "qcom,msm-cpudai-tdm-invert-sync",
9368 (u32 *)&dai_data->port_cfg.tdm.ctrl_invert_sync_pulse);
9369 if (rc) {
9370 dev_err(&pdev->dev, "%s: Invert Sync from DT file %s\n",
9371 __func__, "qcom,msm-cpudai-tdm-invert-sync");
9372 goto free_dai_data;
9373 }
9374 dev_dbg(&pdev->dev, "%s: Invert Sync from DT file 0x%x\n",
9375 __func__, dai_data->port_cfg.tdm.ctrl_invert_sync_pulse);
9376
9377 rc = of_property_read_u32(tdm_parent_node,
9378 "qcom,msm-cpudai-tdm-data-delay",
9379 (u32 *)&dai_data->port_cfg.tdm.ctrl_sync_data_delay);
9380 if (rc) {
9381 dev_err(&pdev->dev, "%s: Data Delay from DT file %s\n",
9382 __func__, "qcom,msm-cpudai-tdm-data-delay");
9383 goto free_dai_data;
9384 }
9385 dev_dbg(&pdev->dev, "%s: Data Delay from DT file 0x%x\n",
9386 __func__, dai_data->port_cfg.tdm.ctrl_sync_data_delay);
9387
9388 /* TDM CFG -- set default */
9389 dai_data->port_cfg.tdm.data_format = AFE_LINEAR_PCM_DATA;
9390 dai_data->port_cfg.tdm.tdm_cfg_minor_version =
9391 AFE_API_VERSION_TDM_CONFIG;
9392
9393 /* TDM SLOT MAPPING CFG */
9394 rc = of_property_read_u32(pdev->dev.of_node,
9395 "qcom,msm-cpudai-tdm-data-align",
9396 &dai_data->port_cfg.slot_mapping.data_align_type);
9397 if (rc) {
9398 dev_err(&pdev->dev, "%s: Data Align from DT file %s\n",
9399 __func__,
9400 "qcom,msm-cpudai-tdm-data-align");
9401 goto free_dai_data;
9402 }
9403 dev_dbg(&pdev->dev, "%s: Data Align from DT file 0x%x\n",
9404 __func__, dai_data->port_cfg.slot_mapping.data_align_type);
9405
9406 /* TDM SLOT MAPPING CFG -- set default */
9407 dai_data->port_cfg.slot_mapping.minor_version =
9408 AFE_API_VERSION_SLOT_MAPPING_CONFIG;
Cong Tang76c7e642019-02-26 15:08:55 +08009409 dai_data->port_cfg.slot_mapping_v2.minor_version =
9410 AFE_API_VERSION_SLOT_MAPPING_CONFIG_V2;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309411
9412 /* CUSTOM TDM HEADER CFG */
9413 custom_tdm_header = &dai_data->port_cfg.custom_tdm_header;
9414 if (of_find_property(pdev->dev.of_node,
9415 "qcom,msm-cpudai-tdm-header-start-offset", NULL) &&
9416 of_find_property(pdev->dev.of_node,
9417 "qcom,msm-cpudai-tdm-header-width", NULL) &&
9418 of_find_property(pdev->dev.of_node,
9419 "qcom,msm-cpudai-tdm-header-num-frame-repeat", NULL)) {
9420 /* if the property exist */
9421 rc = of_property_read_u32(pdev->dev.of_node,
9422 "qcom,msm-cpudai-tdm-header-start-offset",
9423 (u32 *)&custom_tdm_header->start_offset);
9424 if (rc) {
9425 dev_err(&pdev->dev, "%s: Header Start Offset from DT file %s\n",
9426 __func__,
9427 "qcom,msm-cpudai-tdm-header-start-offset");
9428 goto free_dai_data;
9429 }
9430 dev_dbg(&pdev->dev, "%s: Header Start Offset from DT file 0x%x\n",
9431 __func__, custom_tdm_header->start_offset);
9432
9433 rc = of_property_read_u32(pdev->dev.of_node,
9434 "qcom,msm-cpudai-tdm-header-width",
9435 (u32 *)&custom_tdm_header->header_width);
9436 if (rc) {
9437 dev_err(&pdev->dev, "%s: Header Width from DT file %s\n",
9438 __func__, "qcom,msm-cpudai-tdm-header-width");
9439 goto free_dai_data;
9440 }
9441 dev_dbg(&pdev->dev, "%s: Header Width from DT file 0x%x\n",
9442 __func__, custom_tdm_header->header_width);
9443
9444 rc = of_property_read_u32(pdev->dev.of_node,
9445 "qcom,msm-cpudai-tdm-header-num-frame-repeat",
9446 (u32 *)&custom_tdm_header->num_frame_repeat);
9447 if (rc) {
9448 dev_err(&pdev->dev, "%s: Header Num Frame Repeat from DT file %s\n",
9449 __func__,
9450 "qcom,msm-cpudai-tdm-header-num-frame-repeat");
9451 goto free_dai_data;
9452 }
9453 dev_dbg(&pdev->dev, "%s: Header Num Frame Repeat from DT file 0x%x\n",
9454 __func__, custom_tdm_header->num_frame_repeat);
9455
9456 /* CUSTOM TDM HEADER CFG -- set default */
9457 custom_tdm_header->minor_version =
9458 AFE_API_VERSION_CUSTOM_TDM_HEADER_CONFIG;
9459 custom_tdm_header->header_type =
9460 AFE_CUSTOM_TDM_HEADER_TYPE_INVALID;
9461 } else {
9462 dev_info(&pdev->dev,
9463 "%s: Custom tdm header not supported\n", __func__);
9464 /* CUSTOM TDM HEADER CFG -- set default */
9465 custom_tdm_header->header_type =
9466 AFE_CUSTOM_TDM_HEADER_TYPE_INVALID;
9467 /* proceed with probe */
9468 }
9469
9470 /* copy static clk per parent node */
9471 dai_data->clk_set = tdm_clk_set;
9472 /* copy static group cfg per parent node */
9473 dai_data->group_cfg.tdm_cfg = tdm_group_cfg;
9474 /* copy static num group ports per parent node */
9475 dai_data->num_group_ports = num_tdm_group_ports;
9476
9477
Ashish Jain757e1452018-04-30 20:58:04 +05309478
9479
9480 dev_dbg(&pdev->dev, "TX group configuration tdm_dev_id 0x%x\n",
9481 tdm_dev_id);
9482
9483 dai_data->afe_ebit_unsupported = afe_ebit_unsupported;
Surendar karka23677262018-04-30 22:52:08 +05309484 dai_data->sec_port_enable = tdm_sec_port_enable;
Ashish Jain757e1452018-04-30 20:58:04 +05309485
9486 if (tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_TX ||
9487 tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_TX_1 ||
9488 tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_TX_2 ||
9489 tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_TX_3) {
Ashish Jain757e1452018-04-30 20:58:04 +05309490 memcpy(&group_cfg_tx.group_cfg,
9491 &dai_data->group_cfg.group_cfg,
9492 sizeof(dai_data->group_cfg.group_cfg));
9493 memcpy(&group_cfg_tx.group_enable,
9494 &dai_data->group_cfg.group_enable,
9495 sizeof(dai_data->group_cfg.group_enable));
9496 memcpy(&group_cfg_tx.tdm_cfg,
9497 &dai_data->group_cfg.tdm_cfg,
9498 sizeof(dai_data->group_cfg.tdm_cfg));
9499 dev_dbg(&pdev->dev,
9500 "Copy TX group configuration Successfully tdm_id %d\n",
9501 tdm_dev_id);
9502 }
9503
Bala Kishore Patia0575102018-05-01 12:37:51 +05309504 if (tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_RX ||
9505 tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_RX_1 ||
9506 tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_RX_2 ||
9507 tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_RX_3) {
9508 memcpy(&group_cfg_rx.group_cfg,
9509 &dai_data->group_cfg.group_cfg,
9510 sizeof(dai_data->group_cfg.group_cfg));
9511 memcpy(&group_cfg_rx.group_enable,
9512 &dai_data->group_cfg.group_enable,
9513 sizeof(dai_data->group_cfg.group_enable));
9514 memcpy(&group_cfg_rx.tdm_cfg,
9515 &dai_data->group_cfg.tdm_cfg,
9516 sizeof(dai_data->group_cfg.tdm_cfg));
9517 dev_dbg(&pdev->dev,
9518 "Copy RX group configuration Successfully tdm_id %d\n",
9519 tdm_dev_id);
9520 }
9521
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309522 dev_set_drvdata(&pdev->dev, dai_data);
9523
9524 port_idx = msm_dai_q6_get_port_idx(tdm_dev_id);
9525 if (port_idx < 0) {
9526 dev_err(&pdev->dev, "%s Port id 0x%x not supported\n",
9527 __func__, tdm_dev_id);
9528 rc = -EINVAL;
9529 goto free_dai_data;
9530 }
9531
9532 rc = snd_soc_register_component(&pdev->dev,
9533 &msm_q6_tdm_dai_component,
9534 &msm_dai_q6_tdm_dai[port_idx], 1);
9535
9536 if (rc) {
9537 dev_err(&pdev->dev, "%s: TDM dai 0x%x register failed, rc=%d\n",
9538 __func__, tdm_dev_id, rc);
9539 goto err_register;
9540 }
9541
9542 return 0;
9543
9544err_register:
9545free_dai_data:
9546 kfree(dai_data);
9547rtn:
9548 return rc;
9549}
9550
9551static int msm_dai_q6_tdm_dev_remove(struct platform_device *pdev)
9552{
9553 struct msm_dai_q6_tdm_dai_data *dai_data =
9554 dev_get_drvdata(&pdev->dev);
9555
9556 snd_soc_unregister_component(&pdev->dev);
9557
9558 kfree(dai_data);
9559
9560 return 0;
9561}
9562
9563static const struct of_device_id msm_dai_q6_tdm_dev_dt_match[] = {
9564 { .compatible = "qcom,msm-dai-q6-tdm", },
9565 {}
9566};
9567
9568MODULE_DEVICE_TABLE(of, msm_dai_q6_tdm_dev_dt_match);
9569
9570static struct platform_driver msm_dai_q6_tdm_driver = {
9571 .probe = msm_dai_q6_tdm_dev_probe,
9572 .remove = msm_dai_q6_tdm_dev_remove,
9573 .driver = {
9574 .name = "msm-dai-q6-tdm",
9575 .owner = THIS_MODULE,
9576 .of_match_table = msm_dai_q6_tdm_dev_dt_match,
9577 },
9578};
9579
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05309580int __init msm_dai_q6_init(void)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309581{
9582 int rc;
9583
9584 rc = platform_driver_register(&msm_auxpcm_dev_driver);
9585 if (rc) {
9586 pr_err("%s: fail to register auxpcm dev driver", __func__);
9587 goto fail;
9588 }
9589
9590 rc = platform_driver_register(&msm_dai_q6);
9591 if (rc) {
9592 pr_err("%s: fail to register dai q6 driver", __func__);
9593 goto dai_q6_fail;
9594 }
9595
9596 rc = platform_driver_register(&msm_dai_q6_dev);
9597 if (rc) {
9598 pr_err("%s: fail to register dai q6 dev driver", __func__);
9599 goto dai_q6_dev_fail;
9600 }
9601
9602 rc = platform_driver_register(&msm_dai_q6_mi2s_driver);
9603 if (rc) {
9604 pr_err("%s: fail to register dai MI2S dev drv\n", __func__);
9605 goto dai_q6_mi2s_drv_fail;
9606 }
9607
9608 rc = platform_driver_register(&msm_dai_mi2s_q6);
9609 if (rc) {
9610 pr_err("%s: fail to register dai MI2S\n", __func__);
9611 goto dai_mi2s_q6_fail;
9612 }
9613
9614 rc = platform_driver_register(&msm_dai_q6_spdif_driver);
9615 if (rc) {
9616 pr_err("%s: fail to register dai SPDIF\n", __func__);
9617 goto dai_spdif_q6_fail;
9618 }
9619
9620 rc = platform_driver_register(&msm_dai_q6_tdm_driver);
9621 if (rc) {
9622 pr_err("%s: fail to register dai TDM dev drv\n", __func__);
9623 goto dai_q6_tdm_drv_fail;
9624 }
9625
9626 rc = platform_driver_register(&msm_dai_tdm_q6);
9627 if (rc) {
9628 pr_err("%s: fail to register dai TDM\n", __func__);
9629 goto dai_tdm_q6_fail;
9630 }
9631 return rc;
9632
9633dai_tdm_q6_fail:
9634 platform_driver_unregister(&msm_dai_q6_tdm_driver);
9635dai_q6_tdm_drv_fail:
9636 platform_driver_unregister(&msm_dai_q6_spdif_driver);
9637dai_spdif_q6_fail:
9638 platform_driver_unregister(&msm_dai_mi2s_q6);
9639dai_mi2s_q6_fail:
9640 platform_driver_unregister(&msm_dai_q6_mi2s_driver);
9641dai_q6_mi2s_drv_fail:
9642 platform_driver_unregister(&msm_dai_q6_dev);
9643dai_q6_dev_fail:
9644 platform_driver_unregister(&msm_dai_q6);
9645dai_q6_fail:
9646 platform_driver_unregister(&msm_auxpcm_dev_driver);
9647fail:
9648 return rc;
9649}
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309650
Asish Bhattacharya5faacb32017-12-04 17:23:15 +05309651void msm_dai_q6_exit(void)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309652{
Laxminath Kasam468ece32017-11-28 12:40:22 +05309653 platform_driver_unregister(&msm_dai_tdm_q6);
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05309654 platform_driver_unregister(&msm_dai_q6_tdm_driver);
9655 platform_driver_unregister(&msm_dai_q6_spdif_driver);
9656 platform_driver_unregister(&msm_dai_mi2s_q6);
9657 platform_driver_unregister(&msm_dai_q6_mi2s_driver);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309658 platform_driver_unregister(&msm_dai_q6_dev);
9659 platform_driver_unregister(&msm_dai_q6);
9660 platform_driver_unregister(&msm_auxpcm_dev_driver);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309661}
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309662
9663/* Module information */
9664MODULE_DESCRIPTION("MSM DSP DAI driver");
9665MODULE_LICENSE("GPL v2");