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