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