blob: 1d01026f1cf26014742ca9b0487e1ce0471df241 [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>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053017#include <linux/bitops.h>
18#include <linux/slab.h>
19#include <linux/clk.h>
20#include <linux/of_device.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053024#include <sound/pcm_params.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053025#include <dsp/apr_audio-v2.h>
26#include <dsp/q6afe-v2.h>
27#include "msm-dai-q6-v2.h"
28#include "codecs/core.h"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053029
30#define MSM_DAI_PRI_AUXPCM_DT_DEV_ID 1
31#define MSM_DAI_SEC_AUXPCM_DT_DEV_ID 2
32#define MSM_DAI_TERT_AUXPCM_DT_DEV_ID 3
33#define MSM_DAI_QUAT_AUXPCM_DT_DEV_ID 4
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 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303635 return 0;
3636}
3637
3638static int msm_dai_q6_mi2s_startup(struct snd_pcm_substream *substream,
3639 struct snd_soc_dai *dai)
3640{
3641
3642 return 0;
3643}
3644
3645
3646static int msm_mi2s_get_port_id(u32 mi2s_id, int stream, u16 *port_id)
3647{
3648 int ret = 0;
3649
3650 switch (stream) {
3651 case SNDRV_PCM_STREAM_PLAYBACK:
3652 switch (mi2s_id) {
3653 case MSM_PRIM_MI2S:
3654 *port_id = AFE_PORT_ID_PRIMARY_MI2S_RX;
3655 break;
3656 case MSM_SEC_MI2S:
3657 *port_id = AFE_PORT_ID_SECONDARY_MI2S_RX;
3658 break;
3659 case MSM_TERT_MI2S:
3660 *port_id = AFE_PORT_ID_TERTIARY_MI2S_RX;
3661 break;
3662 case MSM_QUAT_MI2S:
3663 *port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX;
3664 break;
3665 case MSM_SEC_MI2S_SD1:
3666 *port_id = AFE_PORT_ID_SECONDARY_MI2S_RX_SD1;
3667 break;
3668 case MSM_QUIN_MI2S:
3669 *port_id = AFE_PORT_ID_QUINARY_MI2S_RX;
3670 break;
3671 case MSM_INT0_MI2S:
3672 *port_id = AFE_PORT_ID_INT0_MI2S_RX;
3673 break;
3674 case MSM_INT1_MI2S:
3675 *port_id = AFE_PORT_ID_INT1_MI2S_RX;
3676 break;
3677 case MSM_INT2_MI2S:
3678 *port_id = AFE_PORT_ID_INT2_MI2S_RX;
3679 break;
3680 case MSM_INT3_MI2S:
3681 *port_id = AFE_PORT_ID_INT3_MI2S_RX;
3682 break;
3683 case MSM_INT4_MI2S:
3684 *port_id = AFE_PORT_ID_INT4_MI2S_RX;
3685 break;
3686 case MSM_INT5_MI2S:
3687 *port_id = AFE_PORT_ID_INT5_MI2S_RX;
3688 break;
3689 case MSM_INT6_MI2S:
3690 *port_id = AFE_PORT_ID_INT6_MI2S_RX;
3691 break;
3692 default:
3693 pr_err("%s: playback err id 0x%x\n",
3694 __func__, mi2s_id);
3695 ret = -1;
3696 break;
3697 }
3698 break;
3699 case SNDRV_PCM_STREAM_CAPTURE:
3700 switch (mi2s_id) {
3701 case MSM_PRIM_MI2S:
3702 *port_id = AFE_PORT_ID_PRIMARY_MI2S_TX;
3703 break;
3704 case MSM_SEC_MI2S:
3705 *port_id = AFE_PORT_ID_SECONDARY_MI2S_TX;
3706 break;
3707 case MSM_TERT_MI2S:
3708 *port_id = AFE_PORT_ID_TERTIARY_MI2S_TX;
3709 break;
3710 case MSM_QUAT_MI2S:
3711 *port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX;
3712 break;
3713 case MSM_QUIN_MI2S:
3714 *port_id = AFE_PORT_ID_QUINARY_MI2S_TX;
3715 break;
3716 case MSM_SENARY_MI2S:
3717 *port_id = AFE_PORT_ID_SENARY_MI2S_TX;
3718 break;
3719 case MSM_INT0_MI2S:
3720 *port_id = AFE_PORT_ID_INT0_MI2S_TX;
3721 break;
3722 case MSM_INT1_MI2S:
3723 *port_id = AFE_PORT_ID_INT1_MI2S_TX;
3724 break;
3725 case MSM_INT2_MI2S:
3726 *port_id = AFE_PORT_ID_INT2_MI2S_TX;
3727 break;
3728 case MSM_INT3_MI2S:
3729 *port_id = AFE_PORT_ID_INT3_MI2S_TX;
3730 break;
3731 case MSM_INT4_MI2S:
3732 *port_id = AFE_PORT_ID_INT4_MI2S_TX;
3733 break;
3734 case MSM_INT5_MI2S:
3735 *port_id = AFE_PORT_ID_INT5_MI2S_TX;
3736 break;
3737 case MSM_INT6_MI2S:
3738 *port_id = AFE_PORT_ID_INT6_MI2S_TX;
3739 break;
3740 default:
3741 pr_err("%s: capture err id 0x%x\n", __func__, mi2s_id);
3742 ret = -1;
3743 break;
3744 }
3745 break;
3746 default:
3747 pr_err("%s: default err %d\n", __func__, stream);
3748 ret = -1;
3749 break;
3750 }
3751 pr_debug("%s: port_id = 0x%x\n", __func__, *port_id);
3752 return ret;
3753}
3754
3755static int msm_dai_q6_mi2s_prepare(struct snd_pcm_substream *substream,
3756 struct snd_soc_dai *dai)
3757{
3758 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
3759 dev_get_drvdata(dai->dev);
3760 struct msm_dai_q6_dai_data *dai_data =
3761 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
3762 &mi2s_dai_data->rx_dai.mi2s_dai_data :
3763 &mi2s_dai_data->tx_dai.mi2s_dai_data);
3764 u16 port_id = 0;
3765 int rc = 0;
3766
3767 if (msm_mi2s_get_port_id(dai->id, substream->stream,
3768 &port_id) != 0) {
3769 dev_err(dai->dev, "%s: Invalid Port ID 0x%x\n",
3770 __func__, port_id);
3771 return -EINVAL;
3772 }
3773
3774 dev_dbg(dai->dev, "%s: dai id %d, afe port id = 0x%x\n"
3775 "dai_data->channels = %u sample_rate = %u\n", __func__,
3776 dai->id, port_id, dai_data->channels, dai_data->rate);
3777
3778 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
3779 /* PORT START should be set if prepare called
3780 * in active state.
3781 */
3782 rc = afe_port_start(port_id, &dai_data->port_config,
3783 dai_data->rate);
3784 if (rc < 0)
3785 dev_err(dai->dev, "fail to open AFE port 0x%x\n",
3786 dai->id);
3787 else
3788 set_bit(STATUS_PORT_STARTED,
3789 dai_data->status_mask);
3790 }
3791 if (!test_bit(STATUS_PORT_STARTED, dai_data->hwfree_status)) {
3792 set_bit(STATUS_PORT_STARTED, dai_data->hwfree_status);
3793 dev_dbg(dai->dev, "%s: set hwfree_status to started\n",
3794 __func__);
3795 }
3796 return rc;
3797}
3798
3799static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream,
3800 struct snd_pcm_hw_params *params,
3801 struct snd_soc_dai *dai)
3802{
3803 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
3804 dev_get_drvdata(dai->dev);
3805 struct msm_dai_q6_mi2s_dai_config *mi2s_dai_config =
3806 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
3807 &mi2s_dai_data->rx_dai : &mi2s_dai_data->tx_dai);
3808 struct msm_dai_q6_dai_data *dai_data = &mi2s_dai_config->mi2s_dai_data;
3809 struct afe_param_id_i2s_cfg *i2s = &dai_data->port_config.i2s;
3810
3811 dai_data->channels = params_channels(params);
3812 switch (dai_data->channels) {
3813 case 8:
3814 case 7:
3815 if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_8CHS)
3816 goto error_invalid_data;
3817 dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_8CHS;
3818 break;
3819 case 6:
3820 case 5:
3821 if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_6CHS)
3822 goto error_invalid_data;
3823 dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_6CHS;
3824 break;
3825 case 4:
3826 case 3:
3827 if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_QUAD01)
3828 goto error_invalid_data;
3829 if (mi2s_dai_config->pdata_mi2s_lines == AFE_PORT_I2S_QUAD23)
3830 dai_data->port_config.i2s.channel_mode =
3831 mi2s_dai_config->pdata_mi2s_lines;
3832 else
3833 dai_data->port_config.i2s.channel_mode =
3834 AFE_PORT_I2S_QUAD01;
3835 break;
3836 case 2:
3837 case 1:
3838 if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_SD0)
3839 goto error_invalid_data;
3840 switch (mi2s_dai_config->pdata_mi2s_lines) {
3841 case AFE_PORT_I2S_SD0:
3842 case AFE_PORT_I2S_SD1:
3843 case AFE_PORT_I2S_SD2:
3844 case AFE_PORT_I2S_SD3:
3845 dai_data->port_config.i2s.channel_mode =
3846 mi2s_dai_config->pdata_mi2s_lines;
3847 break;
3848 case AFE_PORT_I2S_QUAD01:
3849 case AFE_PORT_I2S_6CHS:
3850 case AFE_PORT_I2S_8CHS:
3851 if (dai_data->vi_feed_mono == SPKR_1)
3852 dai_data->port_config.i2s.channel_mode =
3853 AFE_PORT_I2S_SD0;
3854 else
3855 dai_data->port_config.i2s.channel_mode =
3856 AFE_PORT_I2S_SD1;
3857 break;
3858 case AFE_PORT_I2S_QUAD23:
3859 dai_data->port_config.i2s.channel_mode =
3860 AFE_PORT_I2S_SD2;
3861 break;
3862 }
3863 if (dai_data->channels == 2)
3864 dai_data->port_config.i2s.mono_stereo =
3865 MSM_AFE_CH_STEREO;
3866 else
3867 dai_data->port_config.i2s.mono_stereo = MSM_AFE_MONO;
3868 break;
3869 default:
3870 pr_err("%s: default err channels %d\n",
3871 __func__, dai_data->channels);
3872 goto error_invalid_data;
3873 }
3874 dai_data->rate = params_rate(params);
3875
3876 switch (params_format(params)) {
3877 case SNDRV_PCM_FORMAT_S16_LE:
3878 case SNDRV_PCM_FORMAT_SPECIAL:
3879 dai_data->port_config.i2s.bit_width = 16;
3880 dai_data->bitwidth = 16;
3881 break;
3882 case SNDRV_PCM_FORMAT_S24_LE:
3883 case SNDRV_PCM_FORMAT_S24_3LE:
3884 dai_data->port_config.i2s.bit_width = 24;
3885 dai_data->bitwidth = 24;
3886 break;
3887 default:
3888 pr_err("%s: format %d\n",
3889 __func__, params_format(params));
3890 return -EINVAL;
3891 }
3892
3893 dai_data->port_config.i2s.i2s_cfg_minor_version =
3894 AFE_API_VERSION_I2S_CONFIG;
3895 dai_data->port_config.i2s.sample_rate = dai_data->rate;
3896 if ((test_bit(STATUS_PORT_STARTED,
3897 mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask) &&
3898 test_bit(STATUS_PORT_STARTED,
3899 mi2s_dai_data->rx_dai.mi2s_dai_data.hwfree_status)) ||
3900 (test_bit(STATUS_PORT_STARTED,
3901 mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask) &&
3902 test_bit(STATUS_PORT_STARTED,
3903 mi2s_dai_data->tx_dai.mi2s_dai_data.hwfree_status))) {
3904 if ((mi2s_dai_data->tx_dai.mi2s_dai_data.rate !=
3905 mi2s_dai_data->rx_dai.mi2s_dai_data.rate) ||
3906 (mi2s_dai_data->rx_dai.mi2s_dai_data.bitwidth !=
3907 mi2s_dai_data->tx_dai.mi2s_dai_data.bitwidth)) {
3908 dev_err(dai->dev, "%s: Error mismatch in HW params\n"
3909 "Tx sample_rate = %u bit_width = %hu\n"
3910 "Rx sample_rate = %u bit_width = %hu\n"
3911 , __func__,
3912 mi2s_dai_data->tx_dai.mi2s_dai_data.rate,
3913 mi2s_dai_data->tx_dai.mi2s_dai_data.bitwidth,
3914 mi2s_dai_data->rx_dai.mi2s_dai_data.rate,
3915 mi2s_dai_data->rx_dai.mi2s_dai_data.bitwidth);
3916 return -EINVAL;
3917 }
3918 }
3919 dev_dbg(dai->dev, "%s: dai id %d dai_data->channels = %d\n"
3920 "sample_rate = %u i2s_cfg_minor_version = 0x%x\n"
3921 "bit_width = %hu channel_mode = 0x%x mono_stereo = %#x\n"
3922 "ws_src = 0x%x sample_rate = %u data_format = 0x%x\n"
3923 "reserved = %u\n", __func__, dai->id, dai_data->channels,
3924 dai_data->rate, i2s->i2s_cfg_minor_version, i2s->bit_width,
3925 i2s->channel_mode, i2s->mono_stereo, i2s->ws_src,
3926 i2s->sample_rate, i2s->data_format, i2s->reserved);
3927
3928 return 0;
3929
3930error_invalid_data:
3931 pr_err("%s: dai_data->channels = %d channel_mode = %d\n", __func__,
3932 dai_data->channels, dai_data->port_config.i2s.channel_mode);
3933 return -EINVAL;
3934}
3935
3936
3937static int msm_dai_q6_mi2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3938{
3939 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
3940 dev_get_drvdata(dai->dev);
3941
3942 if (test_bit(STATUS_PORT_STARTED,
3943 mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask) ||
3944 test_bit(STATUS_PORT_STARTED,
3945 mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask)) {
3946 dev_err(dai->dev, "%s: err chg i2s mode while dai running",
3947 __func__);
3948 return -EPERM;
3949 }
3950
3951 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
3952 case SND_SOC_DAIFMT_CBS_CFS:
3953 mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.i2s.ws_src = 1;
3954 mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.ws_src = 1;
3955 break;
3956 case SND_SOC_DAIFMT_CBM_CFM:
3957 mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.i2s.ws_src = 0;
3958 mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.ws_src = 0;
3959 break;
3960 default:
3961 pr_err("%s: fmt %d\n",
3962 __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
3963 return -EINVAL;
3964 }
3965
3966 return 0;
3967}
3968
3969static int msm_dai_q6_mi2s_hw_free(struct snd_pcm_substream *substream,
3970 struct snd_soc_dai *dai)
3971{
3972 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
3973 dev_get_drvdata(dai->dev);
3974 struct msm_dai_q6_dai_data *dai_data =
3975 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
3976 &mi2s_dai_data->rx_dai.mi2s_dai_data :
3977 &mi2s_dai_data->tx_dai.mi2s_dai_data);
3978
3979 if (test_bit(STATUS_PORT_STARTED, dai_data->hwfree_status)) {
3980 clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status);
3981 dev_dbg(dai->dev, "%s: clear hwfree_status\n", __func__);
3982 }
3983 return 0;
3984}
3985
3986static void msm_dai_q6_mi2s_shutdown(struct snd_pcm_substream *substream,
3987 struct snd_soc_dai *dai)
3988{
3989 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
3990 dev_get_drvdata(dai->dev);
3991 struct msm_dai_q6_dai_data *dai_data =
3992 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
3993 &mi2s_dai_data->rx_dai.mi2s_dai_data :
3994 &mi2s_dai_data->tx_dai.mi2s_dai_data);
3995 u16 port_id = 0;
3996 int rc = 0;
3997
3998 if (msm_mi2s_get_port_id(dai->id, substream->stream,
3999 &port_id) != 0) {
4000 dev_err(dai->dev, "%s: Invalid Port ID 0x%x\n",
4001 __func__, port_id);
4002 }
4003
4004 dev_dbg(dai->dev, "%s: closing afe port id = 0x%x\n",
4005 __func__, port_id);
4006
4007 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
4008 rc = afe_close(port_id);
4009 if (rc < 0)
4010 dev_err(dai->dev, "fail to close AFE port\n");
4011 clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
4012 }
4013 if (test_bit(STATUS_PORT_STARTED, dai_data->hwfree_status))
4014 clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status);
4015}
4016
4017static struct snd_soc_dai_ops msm_dai_q6_mi2s_ops = {
4018 .startup = msm_dai_q6_mi2s_startup,
4019 .prepare = msm_dai_q6_mi2s_prepare,
4020 .hw_params = msm_dai_q6_mi2s_hw_params,
4021 .hw_free = msm_dai_q6_mi2s_hw_free,
4022 .set_fmt = msm_dai_q6_mi2s_set_fmt,
4023 .shutdown = msm_dai_q6_mi2s_shutdown,
4024};
4025
4026/* Channel min and max are initialized base on platform data */
4027static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = {
4028 {
4029 .playback = {
4030 .stream_name = "Primary MI2S Playback",
4031 .aif_name = "PRI_MI2S_RX",
4032 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4033 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4034 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4035 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4036 SNDRV_PCM_RATE_192000,
4037 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4038 SNDRV_PCM_FMTBIT_S24_LE |
4039 SNDRV_PCM_FMTBIT_S24_3LE,
4040 .rate_min = 8000,
4041 .rate_max = 192000,
4042 },
4043 .capture = {
4044 .stream_name = "Primary MI2S Capture",
4045 .aif_name = "PRI_MI2S_TX",
4046 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4047 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4048 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4049 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4050 SNDRV_PCM_RATE_192000,
4051 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4052 .rate_min = 8000,
4053 .rate_max = 192000,
4054 },
4055 .ops = &msm_dai_q6_mi2s_ops,
4056 .id = MSM_PRIM_MI2S,
4057 .probe = msm_dai_q6_dai_mi2s_probe,
4058 .remove = msm_dai_q6_dai_mi2s_remove,
4059 },
4060 {
4061 .playback = {
4062 .stream_name = "Secondary MI2S Playback",
4063 .aif_name = "SEC_MI2S_RX",
4064 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4065 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4066 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4067 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4068 SNDRV_PCM_RATE_192000,
4069 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4070 .rate_min = 8000,
4071 .rate_max = 192000,
4072 },
4073 .capture = {
4074 .stream_name = "Secondary MI2S Capture",
4075 .aif_name = "SEC_MI2S_TX",
4076 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4077 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4078 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4079 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4080 SNDRV_PCM_RATE_192000,
4081 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4082 .rate_min = 8000,
4083 .rate_max = 192000,
4084 },
4085 .ops = &msm_dai_q6_mi2s_ops,
4086 .id = MSM_SEC_MI2S,
4087 .probe = msm_dai_q6_dai_mi2s_probe,
4088 .remove = msm_dai_q6_dai_mi2s_remove,
4089 },
4090 {
4091 .playback = {
4092 .stream_name = "Tertiary MI2S Playback",
4093 .aif_name = "TERT_MI2S_RX",
4094 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4095 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4096 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4097 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4098 SNDRV_PCM_RATE_192000,
4099 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4100 .rate_min = 8000,
4101 .rate_max = 192000,
4102 },
4103 .capture = {
4104 .stream_name = "Tertiary MI2S Capture",
4105 .aif_name = "TERT_MI2S_TX",
4106 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4107 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4108 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4109 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4110 SNDRV_PCM_RATE_192000,
4111 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4112 .rate_min = 8000,
4113 .rate_max = 192000,
4114 },
4115 .ops = &msm_dai_q6_mi2s_ops,
4116 .id = MSM_TERT_MI2S,
4117 .probe = msm_dai_q6_dai_mi2s_probe,
4118 .remove = msm_dai_q6_dai_mi2s_remove,
4119 },
4120 {
4121 .playback = {
4122 .stream_name = "Quaternary MI2S Playback",
4123 .aif_name = "QUAT_MI2S_RX",
4124 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4125 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4126 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4127 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4128 SNDRV_PCM_RATE_192000,
4129 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4130 .rate_min = 8000,
4131 .rate_max = 192000,
4132 },
4133 .capture = {
4134 .stream_name = "Quaternary MI2S Capture",
4135 .aif_name = "QUAT_MI2S_TX",
4136 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4137 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4138 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4139 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4140 SNDRV_PCM_RATE_192000,
4141 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4142 .rate_min = 8000,
4143 .rate_max = 192000,
4144 },
4145 .ops = &msm_dai_q6_mi2s_ops,
4146 .id = MSM_QUAT_MI2S,
4147 .probe = msm_dai_q6_dai_mi2s_probe,
4148 .remove = msm_dai_q6_dai_mi2s_remove,
4149 },
4150 {
4151 .playback = {
4152 .stream_name = "Secondary MI2S Playback SD1",
4153 .aif_name = "SEC_MI2S_RX_SD1",
4154 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4155 SNDRV_PCM_RATE_16000,
4156 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4157 .rate_min = 8000,
4158 .rate_max = 48000,
4159 },
4160 .id = MSM_SEC_MI2S_SD1,
4161 },
4162 {
4163 .playback = {
4164 .stream_name = "Quinary MI2S Playback",
4165 .aif_name = "QUIN_MI2S_RX",
4166 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4167 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
4168 SNDRV_PCM_RATE_192000,
4169 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4170 .rate_min = 8000,
4171 .rate_max = 192000,
4172 },
4173 .capture = {
4174 .stream_name = "Quinary MI2S Capture",
4175 .aif_name = "QUIN_MI2S_TX",
4176 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4177 SNDRV_PCM_RATE_16000,
4178 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4179 .rate_min = 8000,
4180 .rate_max = 48000,
4181 },
4182 .ops = &msm_dai_q6_mi2s_ops,
4183 .id = MSM_QUIN_MI2S,
4184 .probe = msm_dai_q6_dai_mi2s_probe,
4185 .remove = msm_dai_q6_dai_mi2s_remove,
4186 },
4187 {
4188 .capture = {
4189 .stream_name = "Senary_mi2s Capture",
4190 .aif_name = "SENARY_TX",
4191 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4192 SNDRV_PCM_RATE_16000,
4193 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4194 .rate_min = 8000,
4195 .rate_max = 48000,
4196 },
4197 .ops = &msm_dai_q6_mi2s_ops,
4198 .id = MSM_SENARY_MI2S,
4199 .probe = msm_dai_q6_dai_mi2s_probe,
4200 .remove = msm_dai_q6_dai_mi2s_remove,
4201 },
4202 {
4203 .playback = {
4204 .stream_name = "INT0 MI2S Playback",
4205 .aif_name = "INT0_MI2S_RX",
4206 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4207 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_44100 |
4208 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
4209 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4210 SNDRV_PCM_FMTBIT_S24_LE |
4211 SNDRV_PCM_FMTBIT_S24_3LE,
4212 .rate_min = 8000,
4213 .rate_max = 192000,
4214 },
4215 .capture = {
4216 .stream_name = "INT0 MI2S Capture",
4217 .aif_name = "INT0_MI2S_TX",
4218 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4219 SNDRV_PCM_RATE_16000,
4220 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4221 .rate_min = 8000,
4222 .rate_max = 48000,
4223 },
4224 .ops = &msm_dai_q6_mi2s_ops,
4225 .id = MSM_INT0_MI2S,
4226 .probe = msm_dai_q6_dai_mi2s_probe,
4227 .remove = msm_dai_q6_dai_mi2s_remove,
4228 },
4229 {
4230 .playback = {
4231 .stream_name = "INT1 MI2S Playback",
4232 .aif_name = "INT1_MI2S_RX",
4233 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4234 SNDRV_PCM_RATE_16000,
4235 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4236 SNDRV_PCM_FMTBIT_S24_LE |
4237 SNDRV_PCM_FMTBIT_S24_3LE,
4238 .rate_min = 8000,
4239 .rate_max = 48000,
4240 },
4241 .capture = {
4242 .stream_name = "INT1 MI2S Capture",
4243 .aif_name = "INT1_MI2S_TX",
4244 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4245 SNDRV_PCM_RATE_16000,
4246 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4247 .rate_min = 8000,
4248 .rate_max = 48000,
4249 },
4250 .ops = &msm_dai_q6_mi2s_ops,
4251 .id = MSM_INT1_MI2S,
4252 .probe = msm_dai_q6_dai_mi2s_probe,
4253 .remove = msm_dai_q6_dai_mi2s_remove,
4254 },
4255 {
4256 .playback = {
4257 .stream_name = "INT2 MI2S Playback",
4258 .aif_name = "INT2_MI2S_RX",
4259 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4260 SNDRV_PCM_RATE_16000,
4261 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4262 SNDRV_PCM_FMTBIT_S24_LE |
4263 SNDRV_PCM_FMTBIT_S24_3LE,
4264 .rate_min = 8000,
4265 .rate_max = 48000,
4266 },
4267 .capture = {
4268 .stream_name = "INT2 MI2S Capture",
4269 .aif_name = "INT2_MI2S_TX",
4270 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4271 SNDRV_PCM_RATE_16000,
4272 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4273 .rate_min = 8000,
4274 .rate_max = 48000,
4275 },
4276 .ops = &msm_dai_q6_mi2s_ops,
4277 .id = MSM_INT2_MI2S,
4278 .probe = msm_dai_q6_dai_mi2s_probe,
4279 .remove = msm_dai_q6_dai_mi2s_remove,
4280 },
4281 {
4282 .playback = {
4283 .stream_name = "INT3 MI2S Playback",
4284 .aif_name = "INT3_MI2S_RX",
4285 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4286 SNDRV_PCM_RATE_16000,
4287 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4288 SNDRV_PCM_FMTBIT_S24_LE |
4289 SNDRV_PCM_FMTBIT_S24_3LE,
4290 .rate_min = 8000,
4291 .rate_max = 48000,
4292 },
4293 .capture = {
4294 .stream_name = "INT3 MI2S Capture",
4295 .aif_name = "INT3_MI2S_TX",
4296 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4297 SNDRV_PCM_RATE_16000,
4298 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4299 .rate_min = 8000,
4300 .rate_max = 48000,
4301 },
4302 .ops = &msm_dai_q6_mi2s_ops,
4303 .id = MSM_INT3_MI2S,
4304 .probe = msm_dai_q6_dai_mi2s_probe,
4305 .remove = msm_dai_q6_dai_mi2s_remove,
4306 },
4307 {
4308 .playback = {
4309 .stream_name = "INT4 MI2S Playback",
4310 .aif_name = "INT4_MI2S_RX",
4311 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4312 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
4313 SNDRV_PCM_RATE_192000,
4314 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4315 SNDRV_PCM_FMTBIT_S24_LE |
4316 SNDRV_PCM_FMTBIT_S24_3LE,
4317 .rate_min = 8000,
4318 .rate_max = 192000,
4319 },
4320 .capture = {
4321 .stream_name = "INT4 MI2S Capture",
4322 .aif_name = "INT4_MI2S_TX",
4323 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4324 SNDRV_PCM_RATE_16000,
4325 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4326 .rate_min = 8000,
4327 .rate_max = 48000,
4328 },
4329 .ops = &msm_dai_q6_mi2s_ops,
4330 .id = MSM_INT4_MI2S,
4331 .probe = msm_dai_q6_dai_mi2s_probe,
4332 .remove = msm_dai_q6_dai_mi2s_remove,
4333 },
4334 {
4335 .playback = {
4336 .stream_name = "INT5 MI2S Playback",
4337 .aif_name = "INT5_MI2S_RX",
4338 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4339 SNDRV_PCM_RATE_16000,
4340 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4341 SNDRV_PCM_FMTBIT_S24_LE |
4342 SNDRV_PCM_FMTBIT_S24_3LE,
4343 .rate_min = 8000,
4344 .rate_max = 48000,
4345 },
4346 .capture = {
4347 .stream_name = "INT5 MI2S Capture",
4348 .aif_name = "INT5_MI2S_TX",
4349 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4350 SNDRV_PCM_RATE_16000,
4351 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4352 .rate_min = 8000,
4353 .rate_max = 48000,
4354 },
4355 .ops = &msm_dai_q6_mi2s_ops,
4356 .id = MSM_INT5_MI2S,
4357 .probe = msm_dai_q6_dai_mi2s_probe,
4358 .remove = msm_dai_q6_dai_mi2s_remove,
4359 },
4360 {
4361 .playback = {
4362 .stream_name = "INT6 MI2S Playback",
4363 .aif_name = "INT6_MI2S_RX",
4364 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4365 SNDRV_PCM_RATE_16000,
4366 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4367 SNDRV_PCM_FMTBIT_S24_LE |
4368 SNDRV_PCM_FMTBIT_S24_3LE,
4369 .rate_min = 8000,
4370 .rate_max = 48000,
4371 },
4372 .capture = {
4373 .stream_name = "INT6 MI2S Capture",
4374 .aif_name = "INT6_MI2S_TX",
4375 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4376 SNDRV_PCM_RATE_16000,
4377 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4378 .rate_min = 8000,
4379 .rate_max = 48000,
4380 },
4381 .ops = &msm_dai_q6_mi2s_ops,
4382 .id = MSM_INT6_MI2S,
4383 .probe = msm_dai_q6_dai_mi2s_probe,
4384 .remove = msm_dai_q6_dai_mi2s_remove,
4385 },
4386};
4387
4388
4389static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr,
4390 unsigned int *ch_cnt)
4391{
4392 u8 num_of_sd_lines;
4393
4394 num_of_sd_lines = num_of_bits_set(sd_lines);
4395 switch (num_of_sd_lines) {
4396 case 0:
4397 pr_debug("%s: no line is assigned\n", __func__);
4398 break;
4399 case 1:
4400 switch (sd_lines) {
4401 case MSM_MI2S_SD0:
4402 *config_ptr = AFE_PORT_I2S_SD0;
4403 break;
4404 case MSM_MI2S_SD1:
4405 *config_ptr = AFE_PORT_I2S_SD1;
4406 break;
4407 case MSM_MI2S_SD2:
4408 *config_ptr = AFE_PORT_I2S_SD2;
4409 break;
4410 case MSM_MI2S_SD3:
4411 *config_ptr = AFE_PORT_I2S_SD3;
4412 break;
4413 default:
4414 pr_err("%s: invalid SD lines %d\n",
4415 __func__, sd_lines);
4416 goto error_invalid_data;
4417 }
4418 break;
4419 case 2:
4420 switch (sd_lines) {
4421 case MSM_MI2S_SD0 | MSM_MI2S_SD1:
4422 *config_ptr = AFE_PORT_I2S_QUAD01;
4423 break;
4424 case MSM_MI2S_SD2 | MSM_MI2S_SD3:
4425 *config_ptr = AFE_PORT_I2S_QUAD23;
4426 break;
4427 default:
4428 pr_err("%s: invalid SD lines %d\n",
4429 __func__, sd_lines);
4430 goto error_invalid_data;
4431 }
4432 break;
4433 case 3:
4434 switch (sd_lines) {
4435 case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2:
4436 *config_ptr = AFE_PORT_I2S_6CHS;
4437 break;
4438 default:
4439 pr_err("%s: invalid SD lines %d\n",
4440 __func__, sd_lines);
4441 goto error_invalid_data;
4442 }
4443 break;
4444 case 4:
4445 switch (sd_lines) {
4446 case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3:
4447 *config_ptr = AFE_PORT_I2S_8CHS;
4448 break;
4449 default:
4450 pr_err("%s: invalid SD lines %d\n",
4451 __func__, sd_lines);
4452 goto error_invalid_data;
4453 }
4454 break;
4455 default:
4456 pr_err("%s: invalid SD lines %d\n", __func__, num_of_sd_lines);
4457 goto error_invalid_data;
4458 }
4459 *ch_cnt = num_of_sd_lines;
4460 return 0;
4461
4462error_invalid_data:
4463 pr_err("%s: invalid data\n", __func__);
4464 return -EINVAL;
4465}
4466
4467static int msm_dai_q6_mi2s_platform_data_validation(
4468 struct platform_device *pdev, struct snd_soc_dai_driver *dai_driver)
4469{
4470 struct msm_dai_q6_mi2s_dai_data *dai_data = dev_get_drvdata(&pdev->dev);
4471 struct msm_mi2s_pdata *mi2s_pdata =
4472 (struct msm_mi2s_pdata *) pdev->dev.platform_data;
4473 unsigned int ch_cnt;
4474 int rc = 0;
4475 u16 sd_line;
4476
4477 if (mi2s_pdata == NULL) {
4478 pr_err("%s: mi2s_pdata NULL", __func__);
4479 return -EINVAL;
4480 }
4481
4482 rc = msm_dai_q6_mi2s_get_lineconfig(mi2s_pdata->rx_sd_lines,
4483 &sd_line, &ch_cnt);
4484 if (rc < 0) {
4485 dev_err(&pdev->dev, "invalid MI2S RX sd line config\n");
4486 goto rtn;
4487 }
4488
4489 if (ch_cnt) {
4490 dai_data->rx_dai.mi2s_dai_data.port_config.i2s.channel_mode =
4491 sd_line;
4492 dai_data->rx_dai.pdata_mi2s_lines = sd_line;
4493 dai_driver->playback.channels_min = 1;
4494 dai_driver->playback.channels_max = ch_cnt << 1;
4495 } else {
4496 dai_driver->playback.channels_min = 0;
4497 dai_driver->playback.channels_max = 0;
4498 }
4499 rc = msm_dai_q6_mi2s_get_lineconfig(mi2s_pdata->tx_sd_lines,
4500 &sd_line, &ch_cnt);
4501 if (rc < 0) {
4502 dev_err(&pdev->dev, "invalid MI2S TX sd line config\n");
4503 goto rtn;
4504 }
4505
4506 if (ch_cnt) {
4507 dai_data->tx_dai.mi2s_dai_data.port_config.i2s.channel_mode =
4508 sd_line;
4509 dai_data->tx_dai.pdata_mi2s_lines = sd_line;
4510 dai_driver->capture.channels_min = 1;
4511 dai_driver->capture.channels_max = ch_cnt << 1;
4512 } else {
4513 dai_driver->capture.channels_min = 0;
4514 dai_driver->capture.channels_max = 0;
4515 }
4516
4517 dev_dbg(&pdev->dev, "%s: playback sdline 0x%x capture sdline 0x%x\n",
4518 __func__, dai_data->rx_dai.pdata_mi2s_lines,
4519 dai_data->tx_dai.pdata_mi2s_lines);
4520 dev_dbg(&pdev->dev, "%s: playback ch_max %d capture ch_mx %d\n",
4521 __func__, dai_driver->playback.channels_max,
4522 dai_driver->capture.channels_max);
4523rtn:
4524 return rc;
4525}
4526
4527static const struct snd_soc_component_driver msm_q6_mi2s_dai_component = {
4528 .name = "msm-dai-q6-mi2s",
4529};
4530static int msm_dai_q6_mi2s_dev_probe(struct platform_device *pdev)
4531{
4532 struct msm_dai_q6_mi2s_dai_data *dai_data;
4533 const char *q6_mi2s_dev_id = "qcom,msm-dai-q6-mi2s-dev-id";
4534 u32 tx_line = 0;
4535 u32 rx_line = 0;
4536 u32 mi2s_intf = 0;
4537 struct msm_mi2s_pdata *mi2s_pdata;
4538 int rc;
4539
4540 rc = of_property_read_u32(pdev->dev.of_node, q6_mi2s_dev_id,
4541 &mi2s_intf);
4542 if (rc) {
4543 dev_err(&pdev->dev,
4544 "%s: missing 0x%x in dt node\n", __func__, mi2s_intf);
4545 goto rtn;
4546 }
4547
4548 dev_dbg(&pdev->dev, "dev name %s dev id 0x%x\n", dev_name(&pdev->dev),
4549 mi2s_intf);
4550
4551 if ((mi2s_intf < MSM_MI2S_MIN || mi2s_intf > MSM_MI2S_MAX)
4552 || (mi2s_intf >= ARRAY_SIZE(msm_dai_q6_mi2s_dai))) {
4553 dev_err(&pdev->dev,
4554 "%s: Invalid MI2S ID %u from Device Tree\n",
4555 __func__, mi2s_intf);
4556 rc = -ENXIO;
4557 goto rtn;
4558 }
4559
4560 pdev->id = mi2s_intf;
4561
4562 mi2s_pdata = kzalloc(sizeof(struct msm_mi2s_pdata), GFP_KERNEL);
4563 if (!mi2s_pdata) {
4564 rc = -ENOMEM;
4565 goto rtn;
4566 }
4567
4568 rc = of_property_read_u32(pdev->dev.of_node, "qcom,msm-mi2s-rx-lines",
4569 &rx_line);
4570 if (rc) {
4571 dev_err(&pdev->dev, "%s: Rx line from DT file %s\n", __func__,
4572 "qcom,msm-mi2s-rx-lines");
4573 goto free_pdata;
4574 }
4575
4576 rc = of_property_read_u32(pdev->dev.of_node, "qcom,msm-mi2s-tx-lines",
4577 &tx_line);
4578 if (rc) {
4579 dev_err(&pdev->dev, "%s: Tx line from DT file %s\n", __func__,
4580 "qcom,msm-mi2s-tx-lines");
4581 goto free_pdata;
4582 }
4583 dev_dbg(&pdev->dev, "dev name %s Rx line 0x%x , Tx ine 0x%x\n",
4584 dev_name(&pdev->dev), rx_line, tx_line);
4585 mi2s_pdata->rx_sd_lines = rx_line;
4586 mi2s_pdata->tx_sd_lines = tx_line;
4587 mi2s_pdata->intf_id = mi2s_intf;
4588
4589 dai_data = kzalloc(sizeof(struct msm_dai_q6_mi2s_dai_data),
4590 GFP_KERNEL);
4591 if (!dai_data) {
4592 rc = -ENOMEM;
4593 goto free_pdata;
4594 } else
4595 dev_set_drvdata(&pdev->dev, dai_data);
4596
4597 pdev->dev.platform_data = mi2s_pdata;
4598
4599 rc = msm_dai_q6_mi2s_platform_data_validation(pdev,
4600 &msm_dai_q6_mi2s_dai[mi2s_intf]);
4601 if (rc < 0)
4602 goto free_dai_data;
4603
4604 rc = snd_soc_register_component(&pdev->dev, &msm_q6_mi2s_dai_component,
4605 &msm_dai_q6_mi2s_dai[mi2s_intf], 1);
4606 if (rc < 0)
4607 goto err_register;
4608 return 0;
4609
4610err_register:
4611 dev_err(&pdev->dev, "fail to msm_dai_q6_mi2s_dev_probe\n");
4612free_dai_data:
4613 kfree(dai_data);
4614free_pdata:
4615 kfree(mi2s_pdata);
4616rtn:
4617 return rc;
4618}
4619
4620static int msm_dai_q6_mi2s_dev_remove(struct platform_device *pdev)
4621{
4622 snd_soc_unregister_component(&pdev->dev);
4623 return 0;
4624}
4625
4626static const struct snd_soc_component_driver msm_dai_q6_component = {
4627 .name = "msm-dai-q6-dev",
4628};
4629
4630static int msm_dai_q6_dev_probe(struct platform_device *pdev)
4631{
4632 int rc, id, i, len;
4633 const char *q6_dev_id = "qcom,msm-dai-q6-dev-id";
4634 char stream_name[80];
4635
4636 rc = of_property_read_u32(pdev->dev.of_node, q6_dev_id, &id);
4637 if (rc) {
4638 dev_err(&pdev->dev,
4639 "%s: missing %s in dt node\n", __func__, q6_dev_id);
4640 return rc;
4641 }
4642
4643 pdev->id = id;
4644
4645 pr_debug("%s: dev name %s, id:%d\n", __func__,
4646 dev_name(&pdev->dev), pdev->id);
4647
4648 switch (id) {
4649 case SLIMBUS_0_RX:
4650 strlcpy(stream_name, "Slimbus Playback", 80);
4651 goto register_slim_playback;
4652 case SLIMBUS_2_RX:
4653 strlcpy(stream_name, "Slimbus2 Playback", 80);
4654 goto register_slim_playback;
4655 case SLIMBUS_1_RX:
4656 strlcpy(stream_name, "Slimbus1 Playback", 80);
4657 goto register_slim_playback;
4658 case SLIMBUS_3_RX:
4659 strlcpy(stream_name, "Slimbus3 Playback", 80);
4660 goto register_slim_playback;
4661 case SLIMBUS_4_RX:
4662 strlcpy(stream_name, "Slimbus4 Playback", 80);
4663 goto register_slim_playback;
4664 case SLIMBUS_5_RX:
4665 strlcpy(stream_name, "Slimbus5 Playback", 80);
4666 goto register_slim_playback;
4667 case SLIMBUS_6_RX:
4668 strlcpy(stream_name, "Slimbus6 Playback", 80);
4669 goto register_slim_playback;
4670 case SLIMBUS_7_RX:
4671 strlcpy(stream_name, "Slimbus7 Playback", sizeof(stream_name));
4672 goto register_slim_playback;
4673 case SLIMBUS_8_RX:
4674 strlcpy(stream_name, "Slimbus8 Playback", sizeof(stream_name));
4675 goto register_slim_playback;
4676register_slim_playback:
4677 rc = -ENODEV;
4678 len = strnlen(stream_name, 80);
4679 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_slimbus_rx_dai); i++) {
4680 if (msm_dai_q6_slimbus_rx_dai[i].playback.stream_name &&
4681 !strcmp(stream_name,
4682 msm_dai_q6_slimbus_rx_dai[i]
4683 .playback.stream_name)) {
4684 rc = snd_soc_register_component(&pdev->dev,
4685 &msm_dai_q6_component,
4686 &msm_dai_q6_slimbus_rx_dai[i], 1);
4687 break;
4688 }
4689 }
4690 if (rc)
4691 pr_err("%s: Device not found stream name %s\n",
4692 __func__, stream_name);
4693 break;
4694 case SLIMBUS_0_TX:
4695 strlcpy(stream_name, "Slimbus Capture", 80);
4696 goto register_slim_capture;
4697 case SLIMBUS_1_TX:
4698 strlcpy(stream_name, "Slimbus1 Capture", 80);
4699 goto register_slim_capture;
4700 case SLIMBUS_2_TX:
4701 strlcpy(stream_name, "Slimbus2 Capture", 80);
4702 goto register_slim_capture;
4703 case SLIMBUS_3_TX:
4704 strlcpy(stream_name, "Slimbus3 Capture", 80);
4705 goto register_slim_capture;
4706 case SLIMBUS_4_TX:
4707 strlcpy(stream_name, "Slimbus4 Capture", 80);
4708 goto register_slim_capture;
4709 case SLIMBUS_5_TX:
4710 strlcpy(stream_name, "Slimbus5 Capture", 80);
4711 goto register_slim_capture;
4712 case SLIMBUS_6_TX:
4713 strlcpy(stream_name, "Slimbus6 Capture", 80);
4714 goto register_slim_capture;
4715 case SLIMBUS_7_TX:
4716 strlcpy(stream_name, "Slimbus7 Capture", sizeof(stream_name));
4717 goto register_slim_capture;
4718 case SLIMBUS_8_TX:
4719 strlcpy(stream_name, "Slimbus8 Capture", sizeof(stream_name));
4720 goto register_slim_capture;
4721register_slim_capture:
4722 rc = -ENODEV;
4723 len = strnlen(stream_name, 80);
4724 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_slimbus_tx_dai); i++) {
4725 if (msm_dai_q6_slimbus_tx_dai[i].capture.stream_name &&
4726 !strcmp(stream_name,
4727 msm_dai_q6_slimbus_tx_dai[i]
4728 .capture.stream_name)) {
4729 rc = snd_soc_register_component(&pdev->dev,
4730 &msm_dai_q6_component,
4731 &msm_dai_q6_slimbus_tx_dai[i], 1);
4732 break;
4733 }
4734 }
4735 if (rc)
4736 pr_err("%s: Device not found stream name %s\n",
4737 __func__, stream_name);
4738 break;
4739 case INT_BT_SCO_RX:
4740 rc = snd_soc_register_component(&pdev->dev,
4741 &msm_dai_q6_component, &msm_dai_q6_bt_sco_rx_dai, 1);
4742 break;
4743 case INT_BT_SCO_TX:
4744 rc = snd_soc_register_component(&pdev->dev,
4745 &msm_dai_q6_component, &msm_dai_q6_bt_sco_tx_dai, 1);
4746 break;
4747 case INT_BT_A2DP_RX:
4748 rc = snd_soc_register_component(&pdev->dev,
4749 &msm_dai_q6_component, &msm_dai_q6_bt_a2dp_rx_dai, 1);
4750 break;
4751 case INT_FM_RX:
4752 rc = snd_soc_register_component(&pdev->dev,
4753 &msm_dai_q6_component, &msm_dai_q6_fm_rx_dai, 1);
4754 break;
4755 case INT_FM_TX:
4756 rc = snd_soc_register_component(&pdev->dev,
4757 &msm_dai_q6_component, &msm_dai_q6_fm_tx_dai, 1);
4758 break;
4759 case AFE_PORT_ID_USB_RX:
4760 rc = snd_soc_register_component(&pdev->dev,
4761 &msm_dai_q6_component, &msm_dai_q6_usb_rx_dai, 1);
4762 break;
4763 case AFE_PORT_ID_USB_TX:
4764 rc = snd_soc_register_component(&pdev->dev,
4765 &msm_dai_q6_component, &msm_dai_q6_usb_tx_dai, 1);
4766 break;
4767 case RT_PROXY_DAI_001_RX:
4768 strlcpy(stream_name, "AFE Playback", 80);
4769 goto register_afe_playback;
4770 case RT_PROXY_DAI_002_RX:
4771 strlcpy(stream_name, "AFE-PROXY RX", 80);
4772register_afe_playback:
4773 rc = -ENODEV;
4774 len = strnlen(stream_name, 80);
4775 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_afe_rx_dai); i++) {
4776 if (msm_dai_q6_afe_rx_dai[i].playback.stream_name &&
4777 !strcmp(stream_name,
4778 msm_dai_q6_afe_rx_dai[i].playback.stream_name)) {
4779 rc = snd_soc_register_component(&pdev->dev,
4780 &msm_dai_q6_component,
4781 &msm_dai_q6_afe_rx_dai[i], 1);
4782 break;
4783 }
4784 }
4785 if (rc)
4786 pr_err("%s: Device not found stream name %s\n",
4787 __func__, stream_name);
4788 break;
4789 case RT_PROXY_DAI_001_TX:
4790 strlcpy(stream_name, "AFE-PROXY TX", 80);
4791 goto register_afe_capture;
4792 case RT_PROXY_DAI_002_TX:
4793 strlcpy(stream_name, "AFE Capture", 80);
4794register_afe_capture:
4795 rc = -ENODEV;
4796 len = strnlen(stream_name, 80);
4797 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_afe_tx_dai); i++) {
4798 if (msm_dai_q6_afe_tx_dai[i].capture.stream_name &&
4799 !strcmp(stream_name,
4800 msm_dai_q6_afe_tx_dai[i].capture.stream_name)) {
4801 rc = snd_soc_register_component(&pdev->dev,
4802 &msm_dai_q6_component,
4803 &msm_dai_q6_afe_tx_dai[i], 1);
4804 break;
4805 }
4806 }
4807 if (rc)
4808 pr_err("%s: Device not found stream name %s\n",
4809 __func__, stream_name);
4810 break;
4811 case VOICE_PLAYBACK_TX:
4812 strlcpy(stream_name, "Voice Farend Playback", 80);
4813 goto register_voice_playback;
4814 case VOICE2_PLAYBACK_TX:
4815 strlcpy(stream_name, "Voice2 Farend Playback", 80);
4816register_voice_playback:
4817 rc = -ENODEV;
4818 len = strnlen(stream_name, 80);
4819 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_voc_playback_dai); i++) {
4820 if (msm_dai_q6_voc_playback_dai[i].playback.stream_name
4821 && !strcmp(stream_name,
4822 msm_dai_q6_voc_playback_dai[i].playback.stream_name)) {
4823 rc = snd_soc_register_component(&pdev->dev,
4824 &msm_dai_q6_component,
4825 &msm_dai_q6_voc_playback_dai[i], 1);
4826 break;
4827 }
4828 }
4829 if (rc)
4830 pr_err("%s Device not found stream name %s\n",
4831 __func__, stream_name);
4832 break;
4833 case VOICE_RECORD_RX:
4834 strlcpy(stream_name, "Voice Downlink Capture", 80);
4835 goto register_uplink_capture;
4836 case VOICE_RECORD_TX:
4837 strlcpy(stream_name, "Voice Uplink Capture", 80);
4838register_uplink_capture:
4839 rc = -ENODEV;
4840 len = strnlen(stream_name, 80);
4841 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_incall_record_dai); i++) {
4842 if (msm_dai_q6_incall_record_dai[i].capture.stream_name
4843 && !strcmp(stream_name,
4844 msm_dai_q6_incall_record_dai[i].
4845 capture.stream_name)) {
4846 rc = snd_soc_register_component(&pdev->dev,
4847 &msm_dai_q6_component,
4848 &msm_dai_q6_incall_record_dai[i], 1);
4849 break;
4850 }
4851 }
4852 if (rc)
4853 pr_err("%s: Device not found stream name %s\n",
4854 __func__, stream_name);
4855 break;
4856
4857 default:
4858 rc = -ENODEV;
4859 break;
4860 }
4861
4862 return rc;
4863}
4864
4865static int msm_dai_q6_dev_remove(struct platform_device *pdev)
4866{
4867 snd_soc_unregister_component(&pdev->dev);
4868 return 0;
4869}
4870
4871static const struct of_device_id msm_dai_q6_dev_dt_match[] = {
4872 { .compatible = "qcom,msm-dai-q6-dev", },
4873 { }
4874};
4875MODULE_DEVICE_TABLE(of, msm_dai_q6_dev_dt_match);
4876
4877static struct platform_driver msm_dai_q6_dev = {
4878 .probe = msm_dai_q6_dev_probe,
4879 .remove = msm_dai_q6_dev_remove,
4880 .driver = {
4881 .name = "msm-dai-q6-dev",
4882 .owner = THIS_MODULE,
4883 .of_match_table = msm_dai_q6_dev_dt_match,
4884 },
4885};
4886
4887static int msm_dai_q6_probe(struct platform_device *pdev)
4888{
4889 int rc;
4890
4891 pr_debug("%s: dev name %s, id:%d\n", __func__,
4892 dev_name(&pdev->dev), pdev->id);
4893 rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
4894 if (rc) {
4895 dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n",
4896 __func__, rc);
4897 } else
4898 dev_dbg(&pdev->dev, "%s: added child node\n", __func__);
4899
4900 return rc;
4901}
4902
4903static int msm_dai_q6_remove(struct platform_device *pdev)
4904{
4905 return 0;
4906}
4907
4908static const struct of_device_id msm_dai_q6_dt_match[] = {
4909 { .compatible = "qcom,msm-dai-q6", },
4910 { }
4911};
4912MODULE_DEVICE_TABLE(of, msm_dai_q6_dt_match);
4913static struct platform_driver msm_dai_q6 = {
4914 .probe = msm_dai_q6_probe,
4915 .remove = msm_dai_q6_remove,
4916 .driver = {
4917 .name = "msm-dai-q6",
4918 .owner = THIS_MODULE,
4919 .of_match_table = msm_dai_q6_dt_match,
4920 },
4921};
4922
4923static int msm_dai_mi2s_q6_probe(struct platform_device *pdev)
4924{
4925 int rc;
4926
4927 rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
4928 if (rc) {
4929 dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n",
4930 __func__, rc);
4931 } else
4932 dev_dbg(&pdev->dev, "%s: added child node\n", __func__);
4933 return rc;
4934}
4935
4936static int msm_dai_mi2s_q6_remove(struct platform_device *pdev)
4937{
4938 return 0;
4939}
4940
4941static const struct of_device_id msm_dai_mi2s_dt_match[] = {
4942 { .compatible = "qcom,msm-dai-mi2s", },
4943 { }
4944};
4945
4946MODULE_DEVICE_TABLE(of, msm_dai_mi2s_dt_match);
4947
4948static struct platform_driver msm_dai_mi2s_q6 = {
4949 .probe = msm_dai_mi2s_q6_probe,
4950 .remove = msm_dai_mi2s_q6_remove,
4951 .driver = {
4952 .name = "msm-dai-mi2s",
4953 .owner = THIS_MODULE,
4954 .of_match_table = msm_dai_mi2s_dt_match,
4955 },
4956};
4957
4958static const struct of_device_id msm_dai_q6_mi2s_dev_dt_match[] = {
4959 { .compatible = "qcom,msm-dai-q6-mi2s", },
4960 { }
4961};
4962
4963MODULE_DEVICE_TABLE(of, msm_dai_q6_mi2s_dev_dt_match);
4964
4965static struct platform_driver msm_dai_q6_mi2s_driver = {
4966 .probe = msm_dai_q6_mi2s_dev_probe,
4967 .remove = msm_dai_q6_mi2s_dev_remove,
4968 .driver = {
4969 .name = "msm-dai-q6-mi2s",
4970 .owner = THIS_MODULE,
4971 .of_match_table = msm_dai_q6_mi2s_dev_dt_match,
4972 },
4973};
4974
4975static int msm_dai_q6_spdif_dev_probe(struct platform_device *pdev)
4976{
4977 int rc;
4978
4979 pdev->id = AFE_PORT_ID_SPDIF_RX;
4980
4981 pr_debug("%s: dev name %s, id:%d\n", __func__,
4982 dev_name(&pdev->dev), pdev->id);
4983
4984 rc = snd_soc_register_component(&pdev->dev,
4985 &msm_dai_spdif_q6_component,
4986 &msm_dai_q6_spdif_spdif_rx_dai, 1);
4987 return rc;
4988}
4989
4990static int msm_dai_q6_spdif_dev_remove(struct platform_device *pdev)
4991{
4992 snd_soc_unregister_component(&pdev->dev);
4993 return 0;
4994}
4995
4996static const struct of_device_id msm_dai_q6_spdif_dt_match[] = {
4997 {.compatible = "qcom,msm-dai-q6-spdif"},
4998 {}
4999};
5000MODULE_DEVICE_TABLE(of, msm_dai_q6_spdif_dt_match);
5001
5002static struct platform_driver msm_dai_q6_spdif_driver = {
5003 .probe = msm_dai_q6_spdif_dev_probe,
5004 .remove = msm_dai_q6_spdif_dev_remove,
5005 .driver = {
5006 .name = "msm-dai-q6-spdif",
5007 .owner = THIS_MODULE,
5008 .of_match_table = msm_dai_q6_spdif_dt_match,
5009 },
5010};
5011
5012static int msm_dai_q6_tdm_set_clk_param(u32 group_id,
5013 struct afe_clk_set *clk_set, u32 mode)
5014{
5015 switch (group_id) {
5016 case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX:
5017 case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX:
5018 if (mode)
5019 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT;
5020 else
5021 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_PRI_TDM_EBIT;
5022 break;
5023 case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_RX:
5024 case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_TX:
5025 if (mode)
5026 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT;
5027 else
5028 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_SEC_TDM_EBIT;
5029 break;
5030 case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_RX:
5031 case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_TX:
5032 if (mode)
5033 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT;
5034 else
5035 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_TER_TDM_EBIT;
5036 break;
5037 case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_RX:
5038 case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_TX:
5039 if (mode)
5040 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT;
5041 else
5042 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUAD_TDM_EBIT;
5043 break;
5044 default:
5045 return -EINVAL;
5046 }
5047 return 0;
5048}
5049
5050static int msm_dai_tdm_q6_probe(struct platform_device *pdev)
5051{
5052 int rc = 0;
5053 const uint32_t *port_id_array = NULL;
5054 uint32_t array_length = 0;
5055 int i = 0;
5056 int group_idx = 0;
5057 u32 clk_mode = 0;
5058
5059 /* extract tdm group info into static */
5060 rc = of_property_read_u32(pdev->dev.of_node,
5061 "qcom,msm-cpudai-tdm-group-id",
5062 (u32 *)&tdm_group_cfg.group_id);
5063 if (rc) {
5064 dev_err(&pdev->dev, "%s: Group ID from DT file %s\n",
5065 __func__, "qcom,msm-cpudai-tdm-group-id");
5066 goto rtn;
5067 }
5068 dev_dbg(&pdev->dev, "%s: Group ID from DT file 0x%x\n",
5069 __func__, tdm_group_cfg.group_id);
5070
5071 dev_info(&pdev->dev, "%s: dev_name: %s group_id: 0x%x\n",
5072 __func__, dev_name(&pdev->dev), tdm_group_cfg.group_id);
5073
5074 rc = of_property_read_u32(pdev->dev.of_node,
5075 "qcom,msm-cpudai-tdm-group-num-ports",
5076 &num_tdm_group_ports);
5077 if (rc) {
5078 dev_err(&pdev->dev, "%s: Group Num Ports from DT file %s\n",
5079 __func__, "qcom,msm-cpudai-tdm-group-num-ports");
5080 goto rtn;
5081 }
5082 dev_dbg(&pdev->dev, "%s: Group Num Ports from DT file 0x%x\n",
5083 __func__, num_tdm_group_ports);
5084
5085 if (num_tdm_group_ports > AFE_GROUP_DEVICE_NUM_PORTS) {
5086 dev_err(&pdev->dev, "%s Group Num Ports %d greater than Max %d\n",
5087 __func__, num_tdm_group_ports,
5088 AFE_GROUP_DEVICE_NUM_PORTS);
5089 rc = -EINVAL;
5090 goto rtn;
5091 }
5092
5093 port_id_array = of_get_property(pdev->dev.of_node,
5094 "qcom,msm-cpudai-tdm-group-port-id",
5095 &array_length);
5096 if (port_id_array == NULL) {
5097 dev_err(&pdev->dev, "%s port_id_array is not valid\n",
5098 __func__);
5099 rc = -EINVAL;
5100 goto rtn;
5101 }
5102 if (array_length != sizeof(uint32_t) * num_tdm_group_ports) {
5103 dev_err(&pdev->dev, "%s array_length is %d, expected is %zd\n",
5104 __func__, array_length,
5105 sizeof(uint32_t) * num_tdm_group_ports);
5106 rc = -EINVAL;
5107 goto rtn;
5108 }
5109
5110 for (i = 0; i < num_tdm_group_ports; i++)
5111 tdm_group_cfg.port_id[i] =
5112 (u16)be32_to_cpu(port_id_array[i]);
5113 /* Unused index should be filled with 0 or AFE_PORT_INVALID */
5114 for (i = num_tdm_group_ports; i < AFE_GROUP_DEVICE_NUM_PORTS; i++)
5115 tdm_group_cfg.port_id[i] =
5116 AFE_PORT_INVALID;
5117
5118 /* extract tdm clk info into static */
5119 rc = of_property_read_u32(pdev->dev.of_node,
5120 "qcom,msm-cpudai-tdm-clk-rate",
5121 &tdm_clk_set.clk_freq_in_hz);
5122 if (rc) {
5123 dev_err(&pdev->dev, "%s: Clk Rate from DT file %s\n",
5124 __func__, "qcom,msm-cpudai-tdm-clk-rate");
5125 goto rtn;
5126 }
5127 dev_dbg(&pdev->dev, "%s: Clk Rate from DT file %d\n",
5128 __func__, tdm_clk_set.clk_freq_in_hz);
5129
5130 /* extract tdm clk src master/slave info into static */
5131 rc = of_property_read_u32(pdev->dev.of_node,
5132 "qcom,msm-cpudai-tdm-clk-internal",
5133 &clk_mode);
5134 if (rc) {
5135 dev_err(&pdev->dev, "%s: Clk id from DT file %s\n",
5136 __func__, "qcom,msm-cpudai-tdm-clk-internal");
5137 goto rtn;
5138 }
5139 dev_dbg(&pdev->dev, "%s: Clk id from DT file %d\n",
5140 __func__, clk_mode);
5141
5142 rc = msm_dai_q6_tdm_set_clk_param(tdm_group_cfg.group_id,
5143 &tdm_clk_set, clk_mode);
5144 if (rc) {
5145 dev_err(&pdev->dev, "%s: group id not supported 0x%x\n",
5146 __func__, tdm_group_cfg.group_id);
5147 goto rtn;
5148 }
5149
5150 /* other initializations within device group */
5151 group_idx = msm_dai_q6_get_group_idx(tdm_group_cfg.group_id);
5152 if (group_idx < 0) {
5153 dev_err(&pdev->dev, "%s: group id 0x%x not supported\n",
5154 __func__, tdm_group_cfg.group_id);
5155 rc = -EINVAL;
5156 goto rtn;
5157 }
5158 atomic_set(&tdm_group_ref[group_idx], 0);
5159
5160 /* probe child node info */
5161 rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
5162 if (rc) {
5163 dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n",
5164 __func__, rc);
5165 goto rtn;
5166 } else
5167 dev_dbg(&pdev->dev, "%s: added child node\n", __func__);
5168
5169rtn:
5170 return rc;
5171}
5172
5173static int msm_dai_tdm_q6_remove(struct platform_device *pdev)
5174{
5175 return 0;
5176}
5177
5178static const struct of_device_id msm_dai_tdm_dt_match[] = {
5179 { .compatible = "qcom,msm-dai-tdm", },
5180 {}
5181};
5182
5183MODULE_DEVICE_TABLE(of, msm_dai_tdm_dt_match);
5184
5185static struct platform_driver msm_dai_tdm_q6 = {
5186 .probe = msm_dai_tdm_q6_probe,
5187 .remove = msm_dai_tdm_q6_remove,
5188 .driver = {
5189 .name = "msm-dai-tdm",
5190 .owner = THIS_MODULE,
5191 .of_match_table = msm_dai_tdm_dt_match,
5192 },
5193};
5194
5195static int msm_dai_q6_tdm_data_format_put(struct snd_kcontrol *kcontrol,
5196 struct snd_ctl_elem_value *ucontrol)
5197{
5198 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5199 int value = ucontrol->value.integer.value[0];
5200
5201 switch (value) {
5202 case 0:
5203 dai_data->port_cfg.tdm.data_format = AFE_LINEAR_PCM_DATA;
5204 break;
5205 case 1:
5206 dai_data->port_cfg.tdm.data_format = AFE_NON_LINEAR_DATA;
5207 break;
5208 case 2:
5209 dai_data->port_cfg.tdm.data_format = AFE_GENERIC_COMPRESSED;
5210 break;
5211 default:
5212 pr_err("%s: data_format invalid\n", __func__);
5213 break;
5214 }
5215 pr_debug("%s: data_format = %d\n",
5216 __func__, dai_data->port_cfg.tdm.data_format);
5217 return 0;
5218}
5219
5220static int msm_dai_q6_tdm_data_format_get(struct snd_kcontrol *kcontrol,
5221 struct snd_ctl_elem_value *ucontrol)
5222{
5223 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5224
5225 ucontrol->value.integer.value[0] =
5226 dai_data->port_cfg.tdm.data_format;
5227 pr_debug("%s: data_format = %d\n",
5228 __func__, dai_data->port_cfg.tdm.data_format);
5229 return 0;
5230}
5231
5232static int msm_dai_q6_tdm_header_type_put(struct snd_kcontrol *kcontrol,
5233 struct snd_ctl_elem_value *ucontrol)
5234{
5235 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5236 int value = ucontrol->value.integer.value[0];
5237
5238 dai_data->port_cfg.custom_tdm_header.header_type = value;
5239 pr_debug("%s: header_type = %d\n",
5240 __func__,
5241 dai_data->port_cfg.custom_tdm_header.header_type);
5242 return 0;
5243}
5244
5245static int msm_dai_q6_tdm_header_type_get(struct snd_kcontrol *kcontrol,
5246 struct snd_ctl_elem_value *ucontrol)
5247{
5248 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5249
5250 ucontrol->value.integer.value[0] =
5251 dai_data->port_cfg.custom_tdm_header.header_type;
5252 pr_debug("%s: header_type = %d\n",
5253 __func__,
5254 dai_data->port_cfg.custom_tdm_header.header_type);
5255 return 0;
5256}
5257
5258static int msm_dai_q6_tdm_header_put(struct snd_kcontrol *kcontrol,
5259 struct snd_ctl_elem_value *ucontrol)
5260{
5261 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5262 int i = 0;
5263
5264 for (i = 0; i < AFE_CUSTOM_TDM_HEADER_MAX_CNT; i++) {
5265 dai_data->port_cfg.custom_tdm_header.header[i] =
5266 (u16)ucontrol->value.integer.value[i];
5267 pr_debug("%s: header #%d = 0x%x\n",
5268 __func__, i,
5269 dai_data->port_cfg.custom_tdm_header.header[i]);
5270 }
5271 return 0;
5272}
5273
5274static int msm_dai_q6_tdm_header_get(struct snd_kcontrol *kcontrol,
5275 struct snd_ctl_elem_value *ucontrol)
5276{
5277 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5278 int i = 0;
5279
5280 for (i = 0; i < AFE_CUSTOM_TDM_HEADER_MAX_CNT; i++) {
5281 ucontrol->value.integer.value[i] =
5282 dai_data->port_cfg.custom_tdm_header.header[i];
5283 pr_debug("%s: header #%d = 0x%x\n",
5284 __func__, i,
5285 dai_data->port_cfg.custom_tdm_header.header[i]);
5286 }
5287 return 0;
5288}
5289
5290static const struct snd_kcontrol_new tdm_config_controls_data_format[] = {
5291 SOC_ENUM_EXT("PRI_TDM_RX_0 Data Format", tdm_config_enum[0],
5292 msm_dai_q6_tdm_data_format_get,
5293 msm_dai_q6_tdm_data_format_put),
5294 SOC_ENUM_EXT("PRI_TDM_RX_1 Data Format", tdm_config_enum[0],
5295 msm_dai_q6_tdm_data_format_get,
5296 msm_dai_q6_tdm_data_format_put),
5297 SOC_ENUM_EXT("PRI_TDM_RX_2 Data Format", tdm_config_enum[0],
5298 msm_dai_q6_tdm_data_format_get,
5299 msm_dai_q6_tdm_data_format_put),
5300 SOC_ENUM_EXT("PRI_TDM_RX_3 Data Format", tdm_config_enum[0],
5301 msm_dai_q6_tdm_data_format_get,
5302 msm_dai_q6_tdm_data_format_put),
5303 SOC_ENUM_EXT("PRI_TDM_RX_4 Data Format", tdm_config_enum[0],
5304 msm_dai_q6_tdm_data_format_get,
5305 msm_dai_q6_tdm_data_format_put),
5306 SOC_ENUM_EXT("PRI_TDM_RX_5 Data Format", tdm_config_enum[0],
5307 msm_dai_q6_tdm_data_format_get,
5308 msm_dai_q6_tdm_data_format_put),
5309 SOC_ENUM_EXT("PRI_TDM_RX_6 Data Format", tdm_config_enum[0],
5310 msm_dai_q6_tdm_data_format_get,
5311 msm_dai_q6_tdm_data_format_put),
5312 SOC_ENUM_EXT("PRI_TDM_RX_7 Data Format", tdm_config_enum[0],
5313 msm_dai_q6_tdm_data_format_get,
5314 msm_dai_q6_tdm_data_format_put),
5315 SOC_ENUM_EXT("PRI_TDM_TX_0 Data Format", tdm_config_enum[0],
5316 msm_dai_q6_tdm_data_format_get,
5317 msm_dai_q6_tdm_data_format_put),
5318 SOC_ENUM_EXT("PRI_TDM_TX_1 Data Format", tdm_config_enum[0],
5319 msm_dai_q6_tdm_data_format_get,
5320 msm_dai_q6_tdm_data_format_put),
5321 SOC_ENUM_EXT("PRI_TDM_TX_2 Data Format", tdm_config_enum[0],
5322 msm_dai_q6_tdm_data_format_get,
5323 msm_dai_q6_tdm_data_format_put),
5324 SOC_ENUM_EXT("PRI_TDM_TX_3 Data Format", tdm_config_enum[0],
5325 msm_dai_q6_tdm_data_format_get,
5326 msm_dai_q6_tdm_data_format_put),
5327 SOC_ENUM_EXT("PRI_TDM_TX_4 Data Format", tdm_config_enum[0],
5328 msm_dai_q6_tdm_data_format_get,
5329 msm_dai_q6_tdm_data_format_put),
5330 SOC_ENUM_EXT("PRI_TDM_TX_5 Data Format", tdm_config_enum[0],
5331 msm_dai_q6_tdm_data_format_get,
5332 msm_dai_q6_tdm_data_format_put),
5333 SOC_ENUM_EXT("PRI_TDM_TX_6 Data Format", tdm_config_enum[0],
5334 msm_dai_q6_tdm_data_format_get,
5335 msm_dai_q6_tdm_data_format_put),
5336 SOC_ENUM_EXT("PRI_TDM_TX_7 Data Format", tdm_config_enum[0],
5337 msm_dai_q6_tdm_data_format_get,
5338 msm_dai_q6_tdm_data_format_put),
5339 SOC_ENUM_EXT("SEC_TDM_RX_0 Data Format", tdm_config_enum[0],
5340 msm_dai_q6_tdm_data_format_get,
5341 msm_dai_q6_tdm_data_format_put),
5342 SOC_ENUM_EXT("SEC_TDM_RX_1 Data Format", tdm_config_enum[0],
5343 msm_dai_q6_tdm_data_format_get,
5344 msm_dai_q6_tdm_data_format_put),
5345 SOC_ENUM_EXT("SEC_TDM_RX_2 Data Format", tdm_config_enum[0],
5346 msm_dai_q6_tdm_data_format_get,
5347 msm_dai_q6_tdm_data_format_put),
5348 SOC_ENUM_EXT("SEC_TDM_RX_3 Data Format", tdm_config_enum[0],
5349 msm_dai_q6_tdm_data_format_get,
5350 msm_dai_q6_tdm_data_format_put),
5351 SOC_ENUM_EXT("SEC_TDM_RX_4 Data Format", tdm_config_enum[0],
5352 msm_dai_q6_tdm_data_format_get,
5353 msm_dai_q6_tdm_data_format_put),
5354 SOC_ENUM_EXT("SEC_TDM_RX_5 Data Format", tdm_config_enum[0],
5355 msm_dai_q6_tdm_data_format_get,
5356 msm_dai_q6_tdm_data_format_put),
5357 SOC_ENUM_EXT("SEC_TDM_RX_6 Data Format", tdm_config_enum[0],
5358 msm_dai_q6_tdm_data_format_get,
5359 msm_dai_q6_tdm_data_format_put),
5360 SOC_ENUM_EXT("SEC_TDM_RX_7 Data Format", tdm_config_enum[0],
5361 msm_dai_q6_tdm_data_format_get,
5362 msm_dai_q6_tdm_data_format_put),
5363 SOC_ENUM_EXT("SEC_TDM_TX_0 Data Format", tdm_config_enum[0],
5364 msm_dai_q6_tdm_data_format_get,
5365 msm_dai_q6_tdm_data_format_put),
5366 SOC_ENUM_EXT("SEC_TDM_TX_1 Data Format", tdm_config_enum[0],
5367 msm_dai_q6_tdm_data_format_get,
5368 msm_dai_q6_tdm_data_format_put),
5369 SOC_ENUM_EXT("SEC_TDM_TX_2 Data Format", tdm_config_enum[0],
5370 msm_dai_q6_tdm_data_format_get,
5371 msm_dai_q6_tdm_data_format_put),
5372 SOC_ENUM_EXT("SEC_TDM_TX_3 Data Format", tdm_config_enum[0],
5373 msm_dai_q6_tdm_data_format_get,
5374 msm_dai_q6_tdm_data_format_put),
5375 SOC_ENUM_EXT("SEC_TDM_TX_4 Data Format", tdm_config_enum[0],
5376 msm_dai_q6_tdm_data_format_get,
5377 msm_dai_q6_tdm_data_format_put),
5378 SOC_ENUM_EXT("SEC_TDM_TX_5 Data Format", tdm_config_enum[0],
5379 msm_dai_q6_tdm_data_format_get,
5380 msm_dai_q6_tdm_data_format_put),
5381 SOC_ENUM_EXT("SEC_TDM_TX_6 Data Format", tdm_config_enum[0],
5382 msm_dai_q6_tdm_data_format_get,
5383 msm_dai_q6_tdm_data_format_put),
5384 SOC_ENUM_EXT("SEC_TDM_TX_7 Data Format", tdm_config_enum[0],
5385 msm_dai_q6_tdm_data_format_get,
5386 msm_dai_q6_tdm_data_format_put),
5387 SOC_ENUM_EXT("TERT_TDM_RX_0 Data Format", tdm_config_enum[0],
5388 msm_dai_q6_tdm_data_format_get,
5389 msm_dai_q6_tdm_data_format_put),
5390 SOC_ENUM_EXT("TERT_TDM_RX_1 Data Format", tdm_config_enum[0],
5391 msm_dai_q6_tdm_data_format_get,
5392 msm_dai_q6_tdm_data_format_put),
5393 SOC_ENUM_EXT("TERT_TDM_RX_2 Data Format", tdm_config_enum[0],
5394 msm_dai_q6_tdm_data_format_get,
5395 msm_dai_q6_tdm_data_format_put),
5396 SOC_ENUM_EXT("TERT_TDM_RX_3 Data Format", tdm_config_enum[0],
5397 msm_dai_q6_tdm_data_format_get,
5398 msm_dai_q6_tdm_data_format_put),
5399 SOC_ENUM_EXT("TERT_TDM_RX_4 Data Format", tdm_config_enum[0],
5400 msm_dai_q6_tdm_data_format_get,
5401 msm_dai_q6_tdm_data_format_put),
5402 SOC_ENUM_EXT("TERT_TDM_RX_5 Data Format", tdm_config_enum[0],
5403 msm_dai_q6_tdm_data_format_get,
5404 msm_dai_q6_tdm_data_format_put),
5405 SOC_ENUM_EXT("TERT_TDM_RX_6 Data Format", tdm_config_enum[0],
5406 msm_dai_q6_tdm_data_format_get,
5407 msm_dai_q6_tdm_data_format_put),
5408 SOC_ENUM_EXT("TERT_TDM_RX_7 Data Format", tdm_config_enum[0],
5409 msm_dai_q6_tdm_data_format_get,
5410 msm_dai_q6_tdm_data_format_put),
5411 SOC_ENUM_EXT("TERT_TDM_TX_0 Data Format", tdm_config_enum[0],
5412 msm_dai_q6_tdm_data_format_get,
5413 msm_dai_q6_tdm_data_format_put),
5414 SOC_ENUM_EXT("TERT_TDM_TX_1 Data Format", tdm_config_enum[0],
5415 msm_dai_q6_tdm_data_format_get,
5416 msm_dai_q6_tdm_data_format_put),
5417 SOC_ENUM_EXT("TERT_TDM_TX_2 Data Format", tdm_config_enum[0],
5418 msm_dai_q6_tdm_data_format_get,
5419 msm_dai_q6_tdm_data_format_put),
5420 SOC_ENUM_EXT("TERT_TDM_TX_3 Data Format", tdm_config_enum[0],
5421 msm_dai_q6_tdm_data_format_get,
5422 msm_dai_q6_tdm_data_format_put),
5423 SOC_ENUM_EXT("TERT_TDM_TX_4 Data Format", tdm_config_enum[0],
5424 msm_dai_q6_tdm_data_format_get,
5425 msm_dai_q6_tdm_data_format_put),
5426 SOC_ENUM_EXT("TERT_TDM_TX_5 Data Format", tdm_config_enum[0],
5427 msm_dai_q6_tdm_data_format_get,
5428 msm_dai_q6_tdm_data_format_put),
5429 SOC_ENUM_EXT("TERT_TDM_TX_6 Data Format", tdm_config_enum[0],
5430 msm_dai_q6_tdm_data_format_get,
5431 msm_dai_q6_tdm_data_format_put),
5432 SOC_ENUM_EXT("TERT_TDM_TX_7 Data Format", tdm_config_enum[0],
5433 msm_dai_q6_tdm_data_format_get,
5434 msm_dai_q6_tdm_data_format_put),
5435 SOC_ENUM_EXT("QUAT_TDM_RX_0 Data Format", tdm_config_enum[0],
5436 msm_dai_q6_tdm_data_format_get,
5437 msm_dai_q6_tdm_data_format_put),
5438 SOC_ENUM_EXT("QUAT_TDM_RX_1 Data Format", tdm_config_enum[0],
5439 msm_dai_q6_tdm_data_format_get,
5440 msm_dai_q6_tdm_data_format_put),
5441 SOC_ENUM_EXT("QUAT_TDM_RX_2 Data Format", tdm_config_enum[0],
5442 msm_dai_q6_tdm_data_format_get,
5443 msm_dai_q6_tdm_data_format_put),
5444 SOC_ENUM_EXT("QUAT_TDM_RX_3 Data Format", tdm_config_enum[0],
5445 msm_dai_q6_tdm_data_format_get,
5446 msm_dai_q6_tdm_data_format_put),
5447 SOC_ENUM_EXT("QUAT_TDM_RX_4 Data Format", tdm_config_enum[0],
5448 msm_dai_q6_tdm_data_format_get,
5449 msm_dai_q6_tdm_data_format_put),
5450 SOC_ENUM_EXT("QUAT_TDM_RX_5 Data Format", tdm_config_enum[0],
5451 msm_dai_q6_tdm_data_format_get,
5452 msm_dai_q6_tdm_data_format_put),
5453 SOC_ENUM_EXT("QUAT_TDM_RX_6 Data Format", tdm_config_enum[0],
5454 msm_dai_q6_tdm_data_format_get,
5455 msm_dai_q6_tdm_data_format_put),
5456 SOC_ENUM_EXT("QUAT_TDM_RX_7 Data Format", tdm_config_enum[0],
5457 msm_dai_q6_tdm_data_format_get,
5458 msm_dai_q6_tdm_data_format_put),
5459 SOC_ENUM_EXT("QUAT_TDM_TX_0 Data Format", tdm_config_enum[0],
5460 msm_dai_q6_tdm_data_format_get,
5461 msm_dai_q6_tdm_data_format_put),
5462 SOC_ENUM_EXT("QUAT_TDM_TX_1 Data Format", tdm_config_enum[0],
5463 msm_dai_q6_tdm_data_format_get,
5464 msm_dai_q6_tdm_data_format_put),
5465 SOC_ENUM_EXT("QUAT_TDM_TX_2 Data Format", tdm_config_enum[0],
5466 msm_dai_q6_tdm_data_format_get,
5467 msm_dai_q6_tdm_data_format_put),
5468 SOC_ENUM_EXT("QUAT_TDM_TX_3 Data Format", tdm_config_enum[0],
5469 msm_dai_q6_tdm_data_format_get,
5470 msm_dai_q6_tdm_data_format_put),
5471 SOC_ENUM_EXT("QUAT_TDM_TX_4 Data Format", tdm_config_enum[0],
5472 msm_dai_q6_tdm_data_format_get,
5473 msm_dai_q6_tdm_data_format_put),
5474 SOC_ENUM_EXT("QUAT_TDM_TX_5 Data Format", tdm_config_enum[0],
5475 msm_dai_q6_tdm_data_format_get,
5476 msm_dai_q6_tdm_data_format_put),
5477 SOC_ENUM_EXT("QUAT_TDM_TX_6 Data Format", tdm_config_enum[0],
5478 msm_dai_q6_tdm_data_format_get,
5479 msm_dai_q6_tdm_data_format_put),
5480 SOC_ENUM_EXT("QUAT_TDM_TX_7 Data Format", tdm_config_enum[0],
5481 msm_dai_q6_tdm_data_format_get,
5482 msm_dai_q6_tdm_data_format_put),
5483};
5484
5485static const struct snd_kcontrol_new tdm_config_controls_header_type[] = {
5486 SOC_ENUM_EXT("PRI_TDM_RX_0 Header Type", tdm_config_enum[1],
5487 msm_dai_q6_tdm_header_type_get,
5488 msm_dai_q6_tdm_header_type_put),
5489 SOC_ENUM_EXT("PRI_TDM_RX_1 Header Type", tdm_config_enum[1],
5490 msm_dai_q6_tdm_header_type_get,
5491 msm_dai_q6_tdm_header_type_put),
5492 SOC_ENUM_EXT("PRI_TDM_RX_2 Header Type", tdm_config_enum[1],
5493 msm_dai_q6_tdm_header_type_get,
5494 msm_dai_q6_tdm_header_type_put),
5495 SOC_ENUM_EXT("PRI_TDM_RX_3 Header Type", tdm_config_enum[1],
5496 msm_dai_q6_tdm_header_type_get,
5497 msm_dai_q6_tdm_header_type_put),
5498 SOC_ENUM_EXT("PRI_TDM_RX_4 Header Type", tdm_config_enum[1],
5499 msm_dai_q6_tdm_header_type_get,
5500 msm_dai_q6_tdm_header_type_put),
5501 SOC_ENUM_EXT("PRI_TDM_RX_5 Header Type", tdm_config_enum[1],
5502 msm_dai_q6_tdm_header_type_get,
5503 msm_dai_q6_tdm_header_type_put),
5504 SOC_ENUM_EXT("PRI_TDM_RX_6 Header Type", tdm_config_enum[1],
5505 msm_dai_q6_tdm_header_type_get,
5506 msm_dai_q6_tdm_header_type_put),
5507 SOC_ENUM_EXT("PRI_TDM_RX_7 Header Type", tdm_config_enum[1],
5508 msm_dai_q6_tdm_header_type_get,
5509 msm_dai_q6_tdm_header_type_put),
5510 SOC_ENUM_EXT("PRI_TDM_TX_0 Header Type", tdm_config_enum[1],
5511 msm_dai_q6_tdm_header_type_get,
5512 msm_dai_q6_tdm_header_type_put),
5513 SOC_ENUM_EXT("PRI_TDM_TX_1 Header Type", tdm_config_enum[1],
5514 msm_dai_q6_tdm_header_type_get,
5515 msm_dai_q6_tdm_header_type_put),
5516 SOC_ENUM_EXT("PRI_TDM_TX_2 Header Type", tdm_config_enum[1],
5517 msm_dai_q6_tdm_header_type_get,
5518 msm_dai_q6_tdm_header_type_put),
5519 SOC_ENUM_EXT("PRI_TDM_TX_3 Header Type", tdm_config_enum[1],
5520 msm_dai_q6_tdm_header_type_get,
5521 msm_dai_q6_tdm_header_type_put),
5522 SOC_ENUM_EXT("PRI_TDM_TX_4 Header Type", tdm_config_enum[1],
5523 msm_dai_q6_tdm_header_type_get,
5524 msm_dai_q6_tdm_header_type_put),
5525 SOC_ENUM_EXT("PRI_TDM_TX_5 Header Type", tdm_config_enum[1],
5526 msm_dai_q6_tdm_header_type_get,
5527 msm_dai_q6_tdm_header_type_put),
5528 SOC_ENUM_EXT("PRI_TDM_TX_6 Header Type", tdm_config_enum[1],
5529 msm_dai_q6_tdm_header_type_get,
5530 msm_dai_q6_tdm_header_type_put),
5531 SOC_ENUM_EXT("PRI_TDM_TX_7 Header Type", tdm_config_enum[1],
5532 msm_dai_q6_tdm_header_type_get,
5533 msm_dai_q6_tdm_header_type_put),
5534 SOC_ENUM_EXT("SEC_TDM_RX_0 Header Type", tdm_config_enum[1],
5535 msm_dai_q6_tdm_header_type_get,
5536 msm_dai_q6_tdm_header_type_put),
5537 SOC_ENUM_EXT("SEC_TDM_RX_1 Header Type", tdm_config_enum[1],
5538 msm_dai_q6_tdm_header_type_get,
5539 msm_dai_q6_tdm_header_type_put),
5540 SOC_ENUM_EXT("SEC_TDM_RX_2 Header Type", tdm_config_enum[1],
5541 msm_dai_q6_tdm_header_type_get,
5542 msm_dai_q6_tdm_header_type_put),
5543 SOC_ENUM_EXT("SEC_TDM_RX_3 Header Type", tdm_config_enum[1],
5544 msm_dai_q6_tdm_header_type_get,
5545 msm_dai_q6_tdm_header_type_put),
5546 SOC_ENUM_EXT("SEC_TDM_RX_4 Header Type", tdm_config_enum[1],
5547 msm_dai_q6_tdm_header_type_get,
5548 msm_dai_q6_tdm_header_type_put),
5549 SOC_ENUM_EXT("SEC_TDM_RX_5 Header Type", tdm_config_enum[1],
5550 msm_dai_q6_tdm_header_type_get,
5551 msm_dai_q6_tdm_header_type_put),
5552 SOC_ENUM_EXT("SEC_TDM_RX_6 Header Type", tdm_config_enum[1],
5553 msm_dai_q6_tdm_header_type_get,
5554 msm_dai_q6_tdm_header_type_put),
5555 SOC_ENUM_EXT("SEC_TDM_RX_7 Header Type", tdm_config_enum[1],
5556 msm_dai_q6_tdm_header_type_get,
5557 msm_dai_q6_tdm_header_type_put),
5558 SOC_ENUM_EXT("SEC_TDM_TX_0 Header Type", tdm_config_enum[1],
5559 msm_dai_q6_tdm_header_type_get,
5560 msm_dai_q6_tdm_header_type_put),
5561 SOC_ENUM_EXT("SEC_TDM_TX_1 Header Type", tdm_config_enum[1],
5562 msm_dai_q6_tdm_header_type_get,
5563 msm_dai_q6_tdm_header_type_put),
5564 SOC_ENUM_EXT("SEC_TDM_TX_2 Header Type", tdm_config_enum[1],
5565 msm_dai_q6_tdm_header_type_get,
5566 msm_dai_q6_tdm_header_type_put),
5567 SOC_ENUM_EXT("SEC_TDM_TX_3 Header Type", tdm_config_enum[1],
5568 msm_dai_q6_tdm_header_type_get,
5569 msm_dai_q6_tdm_header_type_put),
5570 SOC_ENUM_EXT("SEC_TDM_TX_4 Header Type", tdm_config_enum[1],
5571 msm_dai_q6_tdm_header_type_get,
5572 msm_dai_q6_tdm_header_type_put),
5573 SOC_ENUM_EXT("SEC_TDM_TX_5 Header Type", tdm_config_enum[1],
5574 msm_dai_q6_tdm_header_type_get,
5575 msm_dai_q6_tdm_header_type_put),
5576 SOC_ENUM_EXT("SEC_TDM_TX_6 Header Type", tdm_config_enum[1],
5577 msm_dai_q6_tdm_header_type_get,
5578 msm_dai_q6_tdm_header_type_put),
5579 SOC_ENUM_EXT("SEC_TDM_TX_7 Header Type", tdm_config_enum[1],
5580 msm_dai_q6_tdm_header_type_get,
5581 msm_dai_q6_tdm_header_type_put),
5582 SOC_ENUM_EXT("TERT_TDM_RX_0 Header Type", tdm_config_enum[1],
5583 msm_dai_q6_tdm_header_type_get,
5584 msm_dai_q6_tdm_header_type_put),
5585 SOC_ENUM_EXT("TERT_TDM_RX_1 Header Type", tdm_config_enum[1],
5586 msm_dai_q6_tdm_header_type_get,
5587 msm_dai_q6_tdm_header_type_put),
5588 SOC_ENUM_EXT("TERT_TDM_RX_2 Header Type", tdm_config_enum[1],
5589 msm_dai_q6_tdm_header_type_get,
5590 msm_dai_q6_tdm_header_type_put),
5591 SOC_ENUM_EXT("TERT_TDM_RX_3 Header Type", tdm_config_enum[1],
5592 msm_dai_q6_tdm_header_type_get,
5593 msm_dai_q6_tdm_header_type_put),
5594 SOC_ENUM_EXT("TERT_TDM_RX_4 Header Type", tdm_config_enum[1],
5595 msm_dai_q6_tdm_header_type_get,
5596 msm_dai_q6_tdm_header_type_put),
5597 SOC_ENUM_EXT("TERT_TDM_RX_5 Header Type", tdm_config_enum[1],
5598 msm_dai_q6_tdm_header_type_get,
5599 msm_dai_q6_tdm_header_type_put),
5600 SOC_ENUM_EXT("TERT_TDM_RX_6 Header Type", tdm_config_enum[1],
5601 msm_dai_q6_tdm_header_type_get,
5602 msm_dai_q6_tdm_header_type_put),
5603 SOC_ENUM_EXT("TERT_TDM_RX_7 Header Type", tdm_config_enum[1],
5604 msm_dai_q6_tdm_header_type_get,
5605 msm_dai_q6_tdm_header_type_put),
5606 SOC_ENUM_EXT("TERT_TDM_TX_0 Header Type", tdm_config_enum[1],
5607 msm_dai_q6_tdm_header_type_get,
5608 msm_dai_q6_tdm_header_type_put),
5609 SOC_ENUM_EXT("TERT_TDM_TX_1 Header Type", tdm_config_enum[1],
5610 msm_dai_q6_tdm_header_type_get,
5611 msm_dai_q6_tdm_header_type_put),
5612 SOC_ENUM_EXT("TERT_TDM_TX_2 Header Type", tdm_config_enum[1],
5613 msm_dai_q6_tdm_header_type_get,
5614 msm_dai_q6_tdm_header_type_put),
5615 SOC_ENUM_EXT("TERT_TDM_TX_3 Header Type", tdm_config_enum[1],
5616 msm_dai_q6_tdm_header_type_get,
5617 msm_dai_q6_tdm_header_type_put),
5618 SOC_ENUM_EXT("TERT_TDM_TX_4 Header Type", tdm_config_enum[1],
5619 msm_dai_q6_tdm_header_type_get,
5620 msm_dai_q6_tdm_header_type_put),
5621 SOC_ENUM_EXT("TERT_TDM_TX_5 Header Type", tdm_config_enum[1],
5622 msm_dai_q6_tdm_header_type_get,
5623 msm_dai_q6_tdm_header_type_put),
5624 SOC_ENUM_EXT("TERT_TDM_TX_6 Header Type", tdm_config_enum[1],
5625 msm_dai_q6_tdm_header_type_get,
5626 msm_dai_q6_tdm_header_type_put),
5627 SOC_ENUM_EXT("TERT_TDM_TX_7 Header Type", tdm_config_enum[1],
5628 msm_dai_q6_tdm_header_type_get,
5629 msm_dai_q6_tdm_header_type_put),
5630 SOC_ENUM_EXT("QUAT_TDM_RX_0 Header Type", tdm_config_enum[1],
5631 msm_dai_q6_tdm_header_type_get,
5632 msm_dai_q6_tdm_header_type_put),
5633 SOC_ENUM_EXT("QUAT_TDM_RX_1 Header Type", tdm_config_enum[1],
5634 msm_dai_q6_tdm_header_type_get,
5635 msm_dai_q6_tdm_header_type_put),
5636 SOC_ENUM_EXT("QUAT_TDM_RX_2 Header Type", tdm_config_enum[1],
5637 msm_dai_q6_tdm_header_type_get,
5638 msm_dai_q6_tdm_header_type_put),
5639 SOC_ENUM_EXT("QUAT_TDM_RX_3 Header Type", tdm_config_enum[1],
5640 msm_dai_q6_tdm_header_type_get,
5641 msm_dai_q6_tdm_header_type_put),
5642 SOC_ENUM_EXT("QUAT_TDM_RX_4 Header Type", tdm_config_enum[1],
5643 msm_dai_q6_tdm_header_type_get,
5644 msm_dai_q6_tdm_header_type_put),
5645 SOC_ENUM_EXT("QUAT_TDM_RX_5 Header Type", tdm_config_enum[1],
5646 msm_dai_q6_tdm_header_type_get,
5647 msm_dai_q6_tdm_header_type_put),
5648 SOC_ENUM_EXT("QUAT_TDM_RX_6 Header Type", tdm_config_enum[1],
5649 msm_dai_q6_tdm_header_type_get,
5650 msm_dai_q6_tdm_header_type_put),
5651 SOC_ENUM_EXT("QUAT_TDM_RX_7 Header Type", tdm_config_enum[1],
5652 msm_dai_q6_tdm_header_type_get,
5653 msm_dai_q6_tdm_header_type_put),
5654 SOC_ENUM_EXT("QUAT_TDM_TX_0 Header Type", tdm_config_enum[1],
5655 msm_dai_q6_tdm_header_type_get,
5656 msm_dai_q6_tdm_header_type_put),
5657 SOC_ENUM_EXT("QUAT_TDM_TX_1 Header Type", tdm_config_enum[1],
5658 msm_dai_q6_tdm_header_type_get,
5659 msm_dai_q6_tdm_header_type_put),
5660 SOC_ENUM_EXT("QUAT_TDM_TX_2 Header Type", tdm_config_enum[1],
5661 msm_dai_q6_tdm_header_type_get,
5662 msm_dai_q6_tdm_header_type_put),
5663 SOC_ENUM_EXT("QUAT_TDM_TX_3 Header Type", tdm_config_enum[1],
5664 msm_dai_q6_tdm_header_type_get,
5665 msm_dai_q6_tdm_header_type_put),
5666 SOC_ENUM_EXT("QUAT_TDM_TX_4 Header Type", tdm_config_enum[1],
5667 msm_dai_q6_tdm_header_type_get,
5668 msm_dai_q6_tdm_header_type_put),
5669 SOC_ENUM_EXT("QUAT_TDM_TX_5 Header Type", tdm_config_enum[1],
5670 msm_dai_q6_tdm_header_type_get,
5671 msm_dai_q6_tdm_header_type_put),
5672 SOC_ENUM_EXT("QUAT_TDM_TX_6 Header Type", tdm_config_enum[1],
5673 msm_dai_q6_tdm_header_type_get,
5674 msm_dai_q6_tdm_header_type_put),
5675 SOC_ENUM_EXT("QUAT_TDM_TX_7 Header Type", tdm_config_enum[1],
5676 msm_dai_q6_tdm_header_type_get,
5677 msm_dai_q6_tdm_header_type_put),
5678};
5679
5680static const struct snd_kcontrol_new tdm_config_controls_header[] = {
5681 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_0 Header",
5682 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5683 msm_dai_q6_tdm_header_get,
5684 msm_dai_q6_tdm_header_put),
5685 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_1 Header",
5686 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5687 msm_dai_q6_tdm_header_get,
5688 msm_dai_q6_tdm_header_put),
5689 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_2 Header",
5690 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5691 msm_dai_q6_tdm_header_get,
5692 msm_dai_q6_tdm_header_put),
5693 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_3 Header",
5694 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5695 msm_dai_q6_tdm_header_get,
5696 msm_dai_q6_tdm_header_put),
5697 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_4 Header",
5698 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5699 msm_dai_q6_tdm_header_get,
5700 msm_dai_q6_tdm_header_put),
5701 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_5 Header",
5702 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5703 msm_dai_q6_tdm_header_get,
5704 msm_dai_q6_tdm_header_put),
5705 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_6 Header",
5706 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5707 msm_dai_q6_tdm_header_get,
5708 msm_dai_q6_tdm_header_put),
5709 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_7 Header",
5710 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5711 msm_dai_q6_tdm_header_get,
5712 msm_dai_q6_tdm_header_put),
5713 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_0 Header",
5714 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5715 msm_dai_q6_tdm_header_get,
5716 msm_dai_q6_tdm_header_put),
5717 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_1 Header",
5718 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5719 msm_dai_q6_tdm_header_get,
5720 msm_dai_q6_tdm_header_put),
5721 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_2 Header",
5722 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5723 msm_dai_q6_tdm_header_get,
5724 msm_dai_q6_tdm_header_put),
5725 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_3 Header",
5726 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5727 msm_dai_q6_tdm_header_get,
5728 msm_dai_q6_tdm_header_put),
5729 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_4 Header",
5730 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5731 msm_dai_q6_tdm_header_get,
5732 msm_dai_q6_tdm_header_put),
5733 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_5 Header",
5734 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5735 msm_dai_q6_tdm_header_get,
5736 msm_dai_q6_tdm_header_put),
5737 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_6 Header",
5738 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5739 msm_dai_q6_tdm_header_get,
5740 msm_dai_q6_tdm_header_put),
5741 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_7 Header",
5742 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5743 msm_dai_q6_tdm_header_get,
5744 msm_dai_q6_tdm_header_put),
5745 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_0 Header",
5746 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5747 msm_dai_q6_tdm_header_get,
5748 msm_dai_q6_tdm_header_put),
5749 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_1 Header",
5750 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5751 msm_dai_q6_tdm_header_get,
5752 msm_dai_q6_tdm_header_put),
5753 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_2 Header",
5754 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5755 msm_dai_q6_tdm_header_get,
5756 msm_dai_q6_tdm_header_put),
5757 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_3 Header",
5758 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5759 msm_dai_q6_tdm_header_get,
5760 msm_dai_q6_tdm_header_put),
5761 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_4 Header",
5762 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5763 msm_dai_q6_tdm_header_get,
5764 msm_dai_q6_tdm_header_put),
5765 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_5 Header",
5766 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5767 msm_dai_q6_tdm_header_get,
5768 msm_dai_q6_tdm_header_put),
5769 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_6 Header",
5770 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5771 msm_dai_q6_tdm_header_get,
5772 msm_dai_q6_tdm_header_put),
5773 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_7 Header",
5774 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5775 msm_dai_q6_tdm_header_get,
5776 msm_dai_q6_tdm_header_put),
5777 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_0 Header",
5778 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5779 msm_dai_q6_tdm_header_get,
5780 msm_dai_q6_tdm_header_put),
5781 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_1 Header",
5782 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5783 msm_dai_q6_tdm_header_get,
5784 msm_dai_q6_tdm_header_put),
5785 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_2 Header",
5786 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5787 msm_dai_q6_tdm_header_get,
5788 msm_dai_q6_tdm_header_put),
5789 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_3 Header",
5790 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5791 msm_dai_q6_tdm_header_get,
5792 msm_dai_q6_tdm_header_put),
5793 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_4 Header",
5794 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5795 msm_dai_q6_tdm_header_get,
5796 msm_dai_q6_tdm_header_put),
5797 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_5 Header",
5798 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5799 msm_dai_q6_tdm_header_get,
5800 msm_dai_q6_tdm_header_put),
5801 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_6 Header",
5802 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5803 msm_dai_q6_tdm_header_get,
5804 msm_dai_q6_tdm_header_put),
5805 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_7 Header",
5806 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5807 msm_dai_q6_tdm_header_get,
5808 msm_dai_q6_tdm_header_put),
5809 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_0 Header",
5810 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5811 msm_dai_q6_tdm_header_get,
5812 msm_dai_q6_tdm_header_put),
5813 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_1 Header",
5814 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5815 msm_dai_q6_tdm_header_get,
5816 msm_dai_q6_tdm_header_put),
5817 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_2 Header",
5818 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5819 msm_dai_q6_tdm_header_get,
5820 msm_dai_q6_tdm_header_put),
5821 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_3 Header",
5822 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5823 msm_dai_q6_tdm_header_get,
5824 msm_dai_q6_tdm_header_put),
5825 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_4 Header",
5826 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5827 msm_dai_q6_tdm_header_get,
5828 msm_dai_q6_tdm_header_put),
5829 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_5 Header",
5830 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5831 msm_dai_q6_tdm_header_get,
5832 msm_dai_q6_tdm_header_put),
5833 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_6 Header",
5834 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5835 msm_dai_q6_tdm_header_get,
5836 msm_dai_q6_tdm_header_put),
5837 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_7 Header",
5838 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5839 msm_dai_q6_tdm_header_get,
5840 msm_dai_q6_tdm_header_put),
5841 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_0 Header",
5842 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5843 msm_dai_q6_tdm_header_get,
5844 msm_dai_q6_tdm_header_put),
5845 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_1 Header",
5846 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5847 msm_dai_q6_tdm_header_get,
5848 msm_dai_q6_tdm_header_put),
5849 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_2 Header",
5850 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5851 msm_dai_q6_tdm_header_get,
5852 msm_dai_q6_tdm_header_put),
5853 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_3 Header",
5854 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5855 msm_dai_q6_tdm_header_get,
5856 msm_dai_q6_tdm_header_put),
5857 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_4 Header",
5858 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5859 msm_dai_q6_tdm_header_get,
5860 msm_dai_q6_tdm_header_put),
5861 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_5 Header",
5862 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5863 msm_dai_q6_tdm_header_get,
5864 msm_dai_q6_tdm_header_put),
5865 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_6 Header",
5866 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5867 msm_dai_q6_tdm_header_get,
5868 msm_dai_q6_tdm_header_put),
5869 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_7 Header",
5870 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5871 msm_dai_q6_tdm_header_get,
5872 msm_dai_q6_tdm_header_put),
5873 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_0 Header",
5874 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5875 msm_dai_q6_tdm_header_get,
5876 msm_dai_q6_tdm_header_put),
5877 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_1 Header",
5878 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5879 msm_dai_q6_tdm_header_get,
5880 msm_dai_q6_tdm_header_put),
5881 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_2 Header",
5882 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5883 msm_dai_q6_tdm_header_get,
5884 msm_dai_q6_tdm_header_put),
5885 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_3 Header",
5886 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5887 msm_dai_q6_tdm_header_get,
5888 msm_dai_q6_tdm_header_put),
5889 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_4 Header",
5890 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5891 msm_dai_q6_tdm_header_get,
5892 msm_dai_q6_tdm_header_put),
5893 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_5 Header",
5894 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5895 msm_dai_q6_tdm_header_get,
5896 msm_dai_q6_tdm_header_put),
5897 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_6 Header",
5898 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5899 msm_dai_q6_tdm_header_get,
5900 msm_dai_q6_tdm_header_put),
5901 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_7 Header",
5902 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5903 msm_dai_q6_tdm_header_get,
5904 msm_dai_q6_tdm_header_put),
5905 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_0 Header",
5906 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5907 msm_dai_q6_tdm_header_get,
5908 msm_dai_q6_tdm_header_put),
5909 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_1 Header",
5910 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5911 msm_dai_q6_tdm_header_get,
5912 msm_dai_q6_tdm_header_put),
5913 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_2 Header",
5914 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5915 msm_dai_q6_tdm_header_get,
5916 msm_dai_q6_tdm_header_put),
5917 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_3 Header",
5918 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5919 msm_dai_q6_tdm_header_get,
5920 msm_dai_q6_tdm_header_put),
5921 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_4 Header",
5922 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5923 msm_dai_q6_tdm_header_get,
5924 msm_dai_q6_tdm_header_put),
5925 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_5 Header",
5926 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5927 msm_dai_q6_tdm_header_get,
5928 msm_dai_q6_tdm_header_put),
5929 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_6 Header",
5930 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5931 msm_dai_q6_tdm_header_get,
5932 msm_dai_q6_tdm_header_put),
5933 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_7 Header",
5934 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5935 msm_dai_q6_tdm_header_get,
5936 msm_dai_q6_tdm_header_put),
5937};
5938
5939static int msm_dai_q6_tdm_set_clk(
5940 struct msm_dai_q6_tdm_dai_data *dai_data,
5941 u16 port_id, bool enable)
5942{
5943 int rc = 0;
5944
5945 dai_data->clk_set.enable = enable;
5946
5947 rc = afe_set_lpass_clock_v2(port_id,
5948 &dai_data->clk_set);
5949 if (rc < 0)
5950 pr_err("%s: afe lpass clock failed, err:%d\n",
5951 __func__, rc);
5952
5953 return rc;
5954}
5955
5956static int msm_dai_q6_dai_tdm_probe(struct snd_soc_dai *dai)
5957{
5958 int rc = 0;
5959 struct msm_dai_q6_tdm_dai_data *tdm_dai_data =
5960 dev_get_drvdata(dai->dev);
5961 struct snd_kcontrol *data_format_kcontrol = NULL;
5962 struct snd_kcontrol *header_type_kcontrol = NULL;
5963 struct snd_kcontrol *header_kcontrol = NULL;
5964 int port_idx = 0;
5965 const struct snd_kcontrol_new *data_format_ctrl = NULL;
5966 const struct snd_kcontrol_new *header_type_ctrl = NULL;
5967 const struct snd_kcontrol_new *header_ctrl = NULL;
5968
5969 msm_dai_q6_set_dai_id(dai);
5970
5971 port_idx = msm_dai_q6_get_port_idx(dai->id);
5972 if (port_idx < 0) {
5973 dev_err(dai->dev, "%s port id 0x%x not supported\n",
5974 __func__, dai->id);
5975 rc = -EINVAL;
5976 goto rtn;
5977 }
5978
5979 data_format_ctrl =
5980 &tdm_config_controls_data_format[port_idx];
5981 header_type_ctrl =
5982 &tdm_config_controls_header_type[port_idx];
5983 header_ctrl =
5984 &tdm_config_controls_header[port_idx];
5985
5986 if (data_format_ctrl) {
5987 data_format_kcontrol = snd_ctl_new1(data_format_ctrl,
5988 tdm_dai_data);
5989 rc = snd_ctl_add(dai->component->card->snd_card,
5990 data_format_kcontrol);
5991 if (rc < 0) {
5992 dev_err(dai->dev, "%s: err add data format ctrl DAI = %s\n",
5993 __func__, dai->name);
5994 goto rtn;
5995 }
5996 }
5997
5998 if (header_type_ctrl) {
5999 header_type_kcontrol = snd_ctl_new1(header_type_ctrl,
6000 tdm_dai_data);
6001 rc = snd_ctl_add(dai->component->card->snd_card,
6002 header_type_kcontrol);
6003 if (rc < 0) {
6004 if (data_format_kcontrol)
6005 snd_ctl_remove(dai->component->card->snd_card,
6006 data_format_kcontrol);
6007 dev_err(dai->dev, "%s: err add header type ctrl DAI = %s\n",
6008 __func__, dai->name);
6009 goto rtn;
6010 }
6011 }
6012
6013 if (header_ctrl) {
6014 header_kcontrol = snd_ctl_new1(header_ctrl,
6015 tdm_dai_data);
6016 rc = snd_ctl_add(dai->component->card->snd_card,
6017 header_kcontrol);
6018 if (rc < 0) {
6019 if (header_type_kcontrol)
6020 snd_ctl_remove(dai->component->card->snd_card,
6021 header_type_kcontrol);
6022 if (data_format_kcontrol)
6023 snd_ctl_remove(dai->component->card->snd_card,
6024 data_format_kcontrol);
6025 dev_err(dai->dev, "%s: err add header ctrl DAI = %s\n",
6026 __func__, dai->name);
6027 goto rtn;
6028 }
6029 }
6030
6031 rc = msm_dai_q6_dai_add_route(dai);
6032
6033rtn:
6034 return rc;
6035}
6036
6037
6038static int msm_dai_q6_dai_tdm_remove(struct snd_soc_dai *dai)
6039{
6040 int rc = 0;
6041 struct msm_dai_q6_tdm_dai_data *tdm_dai_data =
6042 dev_get_drvdata(dai->dev);
6043 u16 group_id = tdm_dai_data->group_cfg.tdm_cfg.group_id;
6044 int group_idx = 0;
6045 atomic_t *group_ref = NULL;
6046
6047 group_idx = msm_dai_q6_get_group_idx(dai->id);
6048 if (group_idx < 0) {
6049 dev_err(dai->dev, "%s port id 0x%x not supported\n",
6050 __func__, dai->id);
6051 return -EINVAL;
6052 }
6053
6054 group_ref = &tdm_group_ref[group_idx];
6055
6056 /* If AFE port is still up, close it */
6057 if (test_bit(STATUS_PORT_STARTED, tdm_dai_data->status_mask)) {
6058 rc = afe_close(dai->id); /* can block */
6059 if (rc < 0) {
6060 dev_err(dai->dev, "%s: fail to close AFE port 0x%x\n",
6061 __func__, dai->id);
6062 }
6063 atomic_dec(group_ref);
6064 clear_bit(STATUS_PORT_STARTED,
6065 tdm_dai_data->status_mask);
6066
6067 if (atomic_read(group_ref) == 0) {
6068 rc = afe_port_group_enable(group_id,
6069 NULL, false);
6070 if (rc < 0) {
6071 dev_err(dai->dev, "fail to disable AFE group 0x%x\n",
6072 group_id);
6073 }
6074 rc = msm_dai_q6_tdm_set_clk(tdm_dai_data,
6075 dai->id, false);
6076 if (rc < 0) {
6077 dev_err(dai->dev, "%s: fail to disable AFE clk 0x%x\n",
6078 __func__, dai->id);
6079 }
6080 }
6081 }
6082
6083 return 0;
6084}
6085
6086static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai,
6087 unsigned int tx_mask,
6088 unsigned int rx_mask,
6089 int slots, int slot_width)
6090{
6091 int rc = 0;
6092 struct msm_dai_q6_tdm_dai_data *dai_data =
6093 dev_get_drvdata(dai->dev);
6094 struct afe_param_id_group_device_tdm_cfg *tdm_group =
6095 &dai_data->group_cfg.tdm_cfg;
6096 unsigned int cap_mask;
6097
6098 dev_dbg(dai->dev, "%s: dai id = 0x%x\n", __func__, dai->id);
6099
6100 /* HW only supports 16 and 32 bit slot width configuration */
6101 if ((slot_width != 16) && (slot_width != 32)) {
6102 dev_err(dai->dev, "%s: invalid slot_width %d\n",
6103 __func__, slot_width);
6104 return -EINVAL;
6105 }
6106
Xiaoyu Ye1cb5ce02017-09-12 18:19:08 -07006107 /* HW supports 1-32 slots configuration. Typical: 1, 2, 4, 8, 16, 32 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306108 switch (slots) {
6109 case 2:
6110 cap_mask = 0x03;
6111 break;
Xiaoyu Ye1cb5ce02017-09-12 18:19:08 -07006112 case 4:
6113 cap_mask = 0x0F;
6114 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306115 case 8:
6116 cap_mask = 0xFF;
6117 break;
6118 case 16:
6119 cap_mask = 0xFFFF;
6120 break;
6121 default:
6122 dev_err(dai->dev, "%s: invalid slots %d\n",
6123 __func__, slots);
6124 return -EINVAL;
6125 }
6126
6127 switch (dai->id) {
6128 case AFE_PORT_ID_PRIMARY_TDM_RX:
6129 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
6130 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
6131 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
6132 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
6133 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
6134 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
6135 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
6136 case AFE_PORT_ID_SECONDARY_TDM_RX:
6137 case AFE_PORT_ID_SECONDARY_TDM_RX_1:
6138 case AFE_PORT_ID_SECONDARY_TDM_RX_2:
6139 case AFE_PORT_ID_SECONDARY_TDM_RX_3:
6140 case AFE_PORT_ID_SECONDARY_TDM_RX_4:
6141 case AFE_PORT_ID_SECONDARY_TDM_RX_5:
6142 case AFE_PORT_ID_SECONDARY_TDM_RX_6:
6143 case AFE_PORT_ID_SECONDARY_TDM_RX_7:
6144 case AFE_PORT_ID_TERTIARY_TDM_RX:
6145 case AFE_PORT_ID_TERTIARY_TDM_RX_1:
6146 case AFE_PORT_ID_TERTIARY_TDM_RX_2:
6147 case AFE_PORT_ID_TERTIARY_TDM_RX_3:
6148 case AFE_PORT_ID_TERTIARY_TDM_RX_4:
6149 case AFE_PORT_ID_TERTIARY_TDM_RX_5:
6150 case AFE_PORT_ID_TERTIARY_TDM_RX_6:
6151 case AFE_PORT_ID_TERTIARY_TDM_RX_7:
6152 case AFE_PORT_ID_QUATERNARY_TDM_RX:
6153 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
6154 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
6155 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
6156 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
6157 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
6158 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
6159 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
6160 tdm_group->nslots_per_frame = slots;
6161 tdm_group->slot_width = slot_width;
6162 tdm_group->slot_mask = rx_mask & cap_mask;
6163 break;
6164 case AFE_PORT_ID_PRIMARY_TDM_TX:
6165 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
6166 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
6167 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
6168 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
6169 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
6170 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
6171 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
6172 case AFE_PORT_ID_SECONDARY_TDM_TX:
6173 case AFE_PORT_ID_SECONDARY_TDM_TX_1:
6174 case AFE_PORT_ID_SECONDARY_TDM_TX_2:
6175 case AFE_PORT_ID_SECONDARY_TDM_TX_3:
6176 case AFE_PORT_ID_SECONDARY_TDM_TX_4:
6177 case AFE_PORT_ID_SECONDARY_TDM_TX_5:
6178 case AFE_PORT_ID_SECONDARY_TDM_TX_6:
6179 case AFE_PORT_ID_SECONDARY_TDM_TX_7:
6180 case AFE_PORT_ID_TERTIARY_TDM_TX:
6181 case AFE_PORT_ID_TERTIARY_TDM_TX_1:
6182 case AFE_PORT_ID_TERTIARY_TDM_TX_2:
6183 case AFE_PORT_ID_TERTIARY_TDM_TX_3:
6184 case AFE_PORT_ID_TERTIARY_TDM_TX_4:
6185 case AFE_PORT_ID_TERTIARY_TDM_TX_5:
6186 case AFE_PORT_ID_TERTIARY_TDM_TX_6:
6187 case AFE_PORT_ID_TERTIARY_TDM_TX_7:
6188 case AFE_PORT_ID_QUATERNARY_TDM_TX:
6189 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
6190 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
6191 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
6192 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
6193 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
6194 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
6195 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
6196 tdm_group->nslots_per_frame = slots;
6197 tdm_group->slot_width = slot_width;
6198 tdm_group->slot_mask = tx_mask & cap_mask;
6199 break;
6200 default:
6201 dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
6202 __func__, dai->id);
6203 return -EINVAL;
6204 }
6205
6206 return rc;
6207}
6208
6209static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai,
6210 unsigned int tx_num, unsigned int *tx_slot,
6211 unsigned int rx_num, unsigned int *rx_slot)
6212{
6213 int rc = 0;
6214 struct msm_dai_q6_tdm_dai_data *dai_data =
6215 dev_get_drvdata(dai->dev);
6216 struct afe_param_id_slot_mapping_cfg *slot_mapping =
6217 &dai_data->port_cfg.slot_mapping;
6218 int i = 0;
6219
6220 dev_dbg(dai->dev, "%s: dai id = 0x%x\n", __func__, dai->id);
6221
6222 switch (dai->id) {
6223 case AFE_PORT_ID_PRIMARY_TDM_RX:
6224 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
6225 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
6226 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
6227 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
6228 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
6229 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
6230 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
6231 case AFE_PORT_ID_SECONDARY_TDM_RX:
6232 case AFE_PORT_ID_SECONDARY_TDM_RX_1:
6233 case AFE_PORT_ID_SECONDARY_TDM_RX_2:
6234 case AFE_PORT_ID_SECONDARY_TDM_RX_3:
6235 case AFE_PORT_ID_SECONDARY_TDM_RX_4:
6236 case AFE_PORT_ID_SECONDARY_TDM_RX_5:
6237 case AFE_PORT_ID_SECONDARY_TDM_RX_6:
6238 case AFE_PORT_ID_SECONDARY_TDM_RX_7:
6239 case AFE_PORT_ID_TERTIARY_TDM_RX:
6240 case AFE_PORT_ID_TERTIARY_TDM_RX_1:
6241 case AFE_PORT_ID_TERTIARY_TDM_RX_2:
6242 case AFE_PORT_ID_TERTIARY_TDM_RX_3:
6243 case AFE_PORT_ID_TERTIARY_TDM_RX_4:
6244 case AFE_PORT_ID_TERTIARY_TDM_RX_5:
6245 case AFE_PORT_ID_TERTIARY_TDM_RX_6:
6246 case AFE_PORT_ID_TERTIARY_TDM_RX_7:
6247 case AFE_PORT_ID_QUATERNARY_TDM_RX:
6248 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
6249 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
6250 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
6251 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
6252 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
6253 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
6254 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
6255 if (!rx_slot) {
6256 dev_err(dai->dev, "%s: rx slot not found\n", __func__);
6257 return -EINVAL;
6258 }
6259 if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
6260 dev_err(dai->dev, "%s: invalid rx num %d\n", __func__,
6261 rx_num);
6262 return -EINVAL;
6263 }
6264
6265 for (i = 0; i < rx_num; i++)
6266 slot_mapping->offset[i] = rx_slot[i];
6267 for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
6268 slot_mapping->offset[i] =
6269 AFE_SLOT_MAPPING_OFFSET_INVALID;
6270
6271 slot_mapping->num_channel = rx_num;
6272 break;
6273 case AFE_PORT_ID_PRIMARY_TDM_TX:
6274 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
6275 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
6276 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
6277 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
6278 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
6279 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
6280 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
6281 case AFE_PORT_ID_SECONDARY_TDM_TX:
6282 case AFE_PORT_ID_SECONDARY_TDM_TX_1:
6283 case AFE_PORT_ID_SECONDARY_TDM_TX_2:
6284 case AFE_PORT_ID_SECONDARY_TDM_TX_3:
6285 case AFE_PORT_ID_SECONDARY_TDM_TX_4:
6286 case AFE_PORT_ID_SECONDARY_TDM_TX_5:
6287 case AFE_PORT_ID_SECONDARY_TDM_TX_6:
6288 case AFE_PORT_ID_SECONDARY_TDM_TX_7:
6289 case AFE_PORT_ID_TERTIARY_TDM_TX:
6290 case AFE_PORT_ID_TERTIARY_TDM_TX_1:
6291 case AFE_PORT_ID_TERTIARY_TDM_TX_2:
6292 case AFE_PORT_ID_TERTIARY_TDM_TX_3:
6293 case AFE_PORT_ID_TERTIARY_TDM_TX_4:
6294 case AFE_PORT_ID_TERTIARY_TDM_TX_5:
6295 case AFE_PORT_ID_TERTIARY_TDM_TX_6:
6296 case AFE_PORT_ID_TERTIARY_TDM_TX_7:
6297 case AFE_PORT_ID_QUATERNARY_TDM_TX:
6298 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
6299 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
6300 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
6301 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
6302 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
6303 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
6304 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
6305 if (!tx_slot) {
6306 dev_err(dai->dev, "%s: tx slot not found\n", __func__);
6307 return -EINVAL;
6308 }
6309 if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
6310 dev_err(dai->dev, "%s: invalid tx num %d\n", __func__,
6311 tx_num);
6312 return -EINVAL;
6313 }
6314
6315 for (i = 0; i < tx_num; i++)
6316 slot_mapping->offset[i] = tx_slot[i];
6317 for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
6318 slot_mapping->offset[i] =
6319 AFE_SLOT_MAPPING_OFFSET_INVALID;
6320
6321 slot_mapping->num_channel = tx_num;
6322 break;
6323 default:
6324 dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
6325 __func__, dai->id);
6326 return -EINVAL;
6327 }
6328
6329 return rc;
6330}
6331
6332static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream,
6333 struct snd_pcm_hw_params *params,
6334 struct snd_soc_dai *dai)
6335{
6336 struct msm_dai_q6_tdm_dai_data *dai_data =
6337 dev_get_drvdata(dai->dev);
6338
6339 struct afe_param_id_group_device_tdm_cfg *tdm_group =
6340 &dai_data->group_cfg.tdm_cfg;
6341 struct afe_param_id_tdm_cfg *tdm =
6342 &dai_data->port_cfg.tdm;
6343 struct afe_param_id_slot_mapping_cfg *slot_mapping =
6344 &dai_data->port_cfg.slot_mapping;
6345 struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header =
6346 &dai_data->port_cfg.custom_tdm_header;
6347
6348 pr_debug("%s: dev_name: %s\n",
6349 __func__, dev_name(dai->dev));
6350
6351 if ((params_channels(params) == 0) ||
6352 (params_channels(params) > 8)) {
6353 dev_err(dai->dev, "%s: invalid param channels %d\n",
6354 __func__, params_channels(params));
6355 return -EINVAL;
6356 }
6357 switch (params_format(params)) {
6358 case SNDRV_PCM_FORMAT_S16_LE:
6359 dai_data->bitwidth = 16;
6360 break;
6361 case SNDRV_PCM_FORMAT_S24_LE:
6362 case SNDRV_PCM_FORMAT_S24_3LE:
6363 dai_data->bitwidth = 24;
6364 break;
6365 case SNDRV_PCM_FORMAT_S32_LE:
6366 dai_data->bitwidth = 32;
6367 break;
6368 default:
6369 dev_err(dai->dev, "%s: invalid param format 0x%x\n",
6370 __func__, params_format(params));
6371 return -EINVAL;
6372 }
6373 dai_data->channels = params_channels(params);
6374 dai_data->rate = params_rate(params);
6375
6376 /*
6377 * update tdm group config param
6378 * NOTE: group config is set to the same as slot config.
6379 */
6380 tdm_group->bit_width = tdm_group->slot_width;
6381 tdm_group->num_channels = tdm_group->nslots_per_frame;
6382 tdm_group->sample_rate = dai_data->rate;
6383
6384 pr_debug("%s: TDM GROUP:\n"
6385 "num_channels=%d sample_rate=%d bit_width=%d\n"
6386 "nslots_per_frame=%d slot_width=%d slot_mask=0x%x\n",
6387 __func__,
6388 tdm_group->num_channels,
6389 tdm_group->sample_rate,
6390 tdm_group->bit_width,
6391 tdm_group->nslots_per_frame,
6392 tdm_group->slot_width,
6393 tdm_group->slot_mask);
6394 pr_debug("%s: TDM GROUP:\n"
6395 "port_id[0]=0x%x port_id[1]=0x%x port_id[2]=0x%x port_id[3]=0x%x\n"
6396 "port_id[4]=0x%x port_id[5]=0x%x port_id[6]=0x%x port_id[7]=0x%x\n",
6397 __func__,
6398 tdm_group->port_id[0],
6399 tdm_group->port_id[1],
6400 tdm_group->port_id[2],
6401 tdm_group->port_id[3],
6402 tdm_group->port_id[4],
6403 tdm_group->port_id[5],
6404 tdm_group->port_id[6],
6405 tdm_group->port_id[7]);
6406
6407 /*
6408 * update tdm config param
6409 * NOTE: channels/rate/bitwidth are per stream property
6410 */
6411 tdm->num_channels = dai_data->channels;
6412 tdm->sample_rate = dai_data->rate;
6413 tdm->bit_width = dai_data->bitwidth;
6414 /*
6415 * port slot config is the same as group slot config
6416 * port slot mask should be set according to offset
6417 */
6418 tdm->nslots_per_frame = tdm_group->nslots_per_frame;
6419 tdm->slot_width = tdm_group->slot_width;
6420 tdm->slot_mask = tdm_group->slot_mask;
6421
6422 pr_debug("%s: TDM:\n"
6423 "num_channels=%d sample_rate=%d bit_width=%d\n"
6424 "nslots_per_frame=%d slot_width=%d slot_mask=0x%x\n"
6425 "data_format=0x%x sync_mode=0x%x sync_src=0x%x\n"
6426 "data_out=0x%x invert_sync=0x%x data_delay=0x%x\n",
6427 __func__,
6428 tdm->num_channels,
6429 tdm->sample_rate,
6430 tdm->bit_width,
6431 tdm->nslots_per_frame,
6432 tdm->slot_width,
6433 tdm->slot_mask,
6434 tdm->data_format,
6435 tdm->sync_mode,
6436 tdm->sync_src,
6437 tdm->ctrl_data_out_enable,
6438 tdm->ctrl_invert_sync_pulse,
6439 tdm->ctrl_sync_data_delay);
6440
6441 /*
6442 * update slot mapping config param
6443 * NOTE: channels/rate/bitwidth are per stream property
6444 */
6445 slot_mapping->bitwidth = dai_data->bitwidth;
6446
6447 pr_debug("%s: SLOT MAPPING:\n"
6448 "num_channel=%d bitwidth=%d data_align=0x%x\n",
6449 __func__,
6450 slot_mapping->num_channel,
6451 slot_mapping->bitwidth,
6452 slot_mapping->data_align_type);
6453 pr_debug("%s: SLOT MAPPING:\n"
6454 "offset[0]=0x%x offset[1]=0x%x offset[2]=0x%x offset[3]=0x%x\n"
6455 "offset[4]=0x%x offset[5]=0x%x offset[6]=0x%x offset[7]=0x%x\n",
6456 __func__,
6457 slot_mapping->offset[0],
6458 slot_mapping->offset[1],
6459 slot_mapping->offset[2],
6460 slot_mapping->offset[3],
6461 slot_mapping->offset[4],
6462 slot_mapping->offset[5],
6463 slot_mapping->offset[6],
6464 slot_mapping->offset[7]);
6465
6466 /*
6467 * update custom header config param
6468 * NOTE: channels/rate/bitwidth are per playback stream property.
6469 * custom tdm header only applicable to playback stream.
6470 */
6471 if (custom_tdm_header->header_type !=
6472 AFE_CUSTOM_TDM_HEADER_TYPE_INVALID) {
6473 pr_debug("%s: CUSTOM TDM HEADER:\n"
6474 "start_offset=0x%x header_width=%d\n"
6475 "num_frame_repeat=%d header_type=0x%x\n",
6476 __func__,
6477 custom_tdm_header->start_offset,
6478 custom_tdm_header->header_width,
6479 custom_tdm_header->num_frame_repeat,
6480 custom_tdm_header->header_type);
6481 pr_debug("%s: CUSTOM TDM HEADER:\n"
6482 "header[0]=0x%x header[1]=0x%x header[2]=0x%x header[3]=0x%x\n"
6483 "header[4]=0x%x header[5]=0x%x header[6]=0x%x header[7]=0x%x\n",
6484 __func__,
6485 custom_tdm_header->header[0],
6486 custom_tdm_header->header[1],
6487 custom_tdm_header->header[2],
6488 custom_tdm_header->header[3],
6489 custom_tdm_header->header[4],
6490 custom_tdm_header->header[5],
6491 custom_tdm_header->header[6],
6492 custom_tdm_header->header[7]);
6493 }
6494
6495 return 0;
6496}
6497
6498static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream,
6499 struct snd_soc_dai *dai)
6500{
6501 int rc = 0;
6502 struct msm_dai_q6_tdm_dai_data *dai_data =
6503 dev_get_drvdata(dai->dev);
6504 u16 group_id = dai_data->group_cfg.tdm_cfg.group_id;
6505 int group_idx = 0;
6506 atomic_t *group_ref = NULL;
6507
6508 group_idx = msm_dai_q6_get_group_idx(dai->id);
6509 if (group_idx < 0) {
6510 dev_err(dai->dev, "%s port id 0x%x not supported\n",
6511 __func__, dai->id);
6512 return -EINVAL;
6513 }
6514
6515 mutex_lock(&tdm_mutex);
6516
6517 group_ref = &tdm_group_ref[group_idx];
6518
6519 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
6520 /* PORT START should be set if prepare called
6521 * in active state.
6522 */
6523 if (atomic_read(group_ref) == 0) {
6524 /* TX and RX share the same clk.
6525 * AFE clk is enabled per group to simplify the logic.
6526 * DSP will monitor the clk count.
6527 */
6528 rc = msm_dai_q6_tdm_set_clk(dai_data,
6529 dai->id, true);
6530 if (rc < 0) {
6531 dev_err(dai->dev, "%s: fail to enable AFE clk 0x%x\n",
6532 __func__, dai->id);
6533 goto rtn;
6534 }
6535
6536 /*
6537 * if only one port, don't do group enable as there
6538 * is no group need for only one port
6539 */
6540 if (dai_data->num_group_ports > 1) {
6541 rc = afe_port_group_enable(group_id,
6542 &dai_data->group_cfg, true);
6543 if (rc < 0) {
6544 dev_err(dai->dev,
6545 "%s: fail to enable AFE group 0x%x\n",
6546 __func__, group_id);
6547 goto rtn;
6548 }
6549 }
6550 }
6551
6552 rc = afe_tdm_port_start(dai->id, &dai_data->port_cfg,
6553 dai_data->rate, dai_data->num_group_ports);
6554 if (rc < 0) {
6555 if (atomic_read(group_ref) == 0) {
6556 afe_port_group_enable(group_id,
6557 NULL, false);
6558 msm_dai_q6_tdm_set_clk(dai_data,
6559 dai->id, false);
6560 }
6561 dev_err(dai->dev, "%s: fail to open AFE port 0x%x\n",
6562 __func__, dai->id);
6563 } else {
6564 set_bit(STATUS_PORT_STARTED,
6565 dai_data->status_mask);
6566 atomic_inc(group_ref);
6567 }
6568
6569 /* TODO: need to monitor PCM/MI2S/TDM HW status */
6570 /* NOTE: AFE should error out if HW resource contention */
6571
6572 }
6573
6574rtn:
6575 mutex_unlock(&tdm_mutex);
6576 return rc;
6577}
6578
6579static void msm_dai_q6_tdm_shutdown(struct snd_pcm_substream *substream,
6580 struct snd_soc_dai *dai)
6581{
6582 int rc = 0;
6583 struct msm_dai_q6_tdm_dai_data *dai_data =
6584 dev_get_drvdata(dai->dev);
6585 u16 group_id = dai_data->group_cfg.tdm_cfg.group_id;
6586 int group_idx = 0;
6587 atomic_t *group_ref = NULL;
6588
6589 group_idx = msm_dai_q6_get_group_idx(dai->id);
6590 if (group_idx < 0) {
6591 dev_err(dai->dev, "%s port id 0x%x not supported\n",
6592 __func__, dai->id);
6593 return;
6594 }
6595
6596 mutex_lock(&tdm_mutex);
6597
6598 group_ref = &tdm_group_ref[group_idx];
6599
6600 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
6601 rc = afe_close(dai->id);
6602 if (rc < 0) {
6603 dev_err(dai->dev, "%s: fail to close AFE port 0x%x\n",
6604 __func__, dai->id);
6605 }
6606 atomic_dec(group_ref);
6607 clear_bit(STATUS_PORT_STARTED,
6608 dai_data->status_mask);
6609
6610 if (atomic_read(group_ref) == 0) {
6611 rc = afe_port_group_enable(group_id,
6612 NULL, false);
6613 if (rc < 0) {
6614 dev_err(dai->dev, "%s: fail to disable AFE group 0x%x\n",
6615 __func__, group_id);
6616 }
6617 rc = msm_dai_q6_tdm_set_clk(dai_data,
6618 dai->id, false);
6619 if (rc < 0) {
6620 dev_err(dai->dev, "%s: fail to disable AFE clk 0x%x\n",
6621 __func__, dai->id);
6622 }
6623 }
6624
6625 /* TODO: need to monitor PCM/MI2S/TDM HW status */
6626 /* NOTE: AFE should error out if HW resource contention */
6627
6628 }
6629
6630 mutex_unlock(&tdm_mutex);
6631}
6632
6633static struct snd_soc_dai_ops msm_dai_q6_tdm_ops = {
6634 .prepare = msm_dai_q6_tdm_prepare,
6635 .hw_params = msm_dai_q6_tdm_hw_params,
6636 .set_tdm_slot = msm_dai_q6_tdm_set_tdm_slot,
6637 .set_channel_map = msm_dai_q6_tdm_set_channel_map,
6638 .shutdown = msm_dai_q6_tdm_shutdown,
6639};
6640
6641static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
6642 {
6643 .playback = {
6644 .stream_name = "Primary TDM0 Playback",
6645 .aif_name = "PRI_TDM_RX_0",
6646 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6647 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6648 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6649 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6650 SNDRV_PCM_FMTBIT_S24_LE |
6651 SNDRV_PCM_FMTBIT_S32_LE,
6652 .channels_min = 1,
6653 .channels_max = 8,
6654 .rate_min = 8000,
6655 .rate_max = 352800,
6656 },
6657 .ops = &msm_dai_q6_tdm_ops,
6658 .id = AFE_PORT_ID_PRIMARY_TDM_RX,
6659 .probe = msm_dai_q6_dai_tdm_probe,
6660 .remove = msm_dai_q6_dai_tdm_remove,
6661 },
6662 {
6663 .playback = {
6664 .stream_name = "Primary TDM1 Playback",
6665 .aif_name = "PRI_TDM_RX_1",
6666 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6667 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6668 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6669 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6670 SNDRV_PCM_FMTBIT_S24_LE |
6671 SNDRV_PCM_FMTBIT_S32_LE,
6672 .channels_min = 1,
6673 .channels_max = 8,
6674 .rate_min = 8000,
6675 .rate_max = 352800,
6676 },
6677 .ops = &msm_dai_q6_tdm_ops,
6678 .id = AFE_PORT_ID_PRIMARY_TDM_RX_1,
6679 .probe = msm_dai_q6_dai_tdm_probe,
6680 .remove = msm_dai_q6_dai_tdm_remove,
6681 },
6682 {
6683 .playback = {
6684 .stream_name = "Primary TDM2 Playback",
6685 .aif_name = "PRI_TDM_RX_2",
6686 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6687 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6688 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6689 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6690 SNDRV_PCM_FMTBIT_S24_LE |
6691 SNDRV_PCM_FMTBIT_S32_LE,
6692 .channels_min = 1,
6693 .channels_max = 8,
6694 .rate_min = 8000,
6695 .rate_max = 352800,
6696 },
6697 .ops = &msm_dai_q6_tdm_ops,
6698 .id = AFE_PORT_ID_PRIMARY_TDM_RX_2,
6699 .probe = msm_dai_q6_dai_tdm_probe,
6700 .remove = msm_dai_q6_dai_tdm_remove,
6701 },
6702 {
6703 .playback = {
6704 .stream_name = "Primary TDM3 Playback",
6705 .aif_name = "PRI_TDM_RX_3",
6706 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6707 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6708 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6709 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6710 SNDRV_PCM_FMTBIT_S24_LE |
6711 SNDRV_PCM_FMTBIT_S32_LE,
6712 .channels_min = 1,
6713 .channels_max = 8,
6714 .rate_min = 8000,
6715 .rate_max = 352800,
6716 },
6717 .ops = &msm_dai_q6_tdm_ops,
6718 .id = AFE_PORT_ID_PRIMARY_TDM_RX_3,
6719 .probe = msm_dai_q6_dai_tdm_probe,
6720 .remove = msm_dai_q6_dai_tdm_remove,
6721 },
6722 {
6723 .playback = {
6724 .stream_name = "Primary TDM4 Playback",
6725 .aif_name = "PRI_TDM_RX_4",
6726 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6727 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6728 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6729 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6730 SNDRV_PCM_FMTBIT_S24_LE |
6731 SNDRV_PCM_FMTBIT_S32_LE,
6732 .channels_min = 1,
6733 .channels_max = 8,
6734 .rate_min = 8000,
6735 .rate_max = 352800,
6736 },
6737 .ops = &msm_dai_q6_tdm_ops,
6738 .id = AFE_PORT_ID_PRIMARY_TDM_RX_4,
6739 .probe = msm_dai_q6_dai_tdm_probe,
6740 .remove = msm_dai_q6_dai_tdm_remove,
6741 },
6742 {
6743 .playback = {
6744 .stream_name = "Primary TDM5 Playback",
6745 .aif_name = "PRI_TDM_RX_5",
6746 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6747 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6748 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6749 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6750 SNDRV_PCM_FMTBIT_S24_LE |
6751 SNDRV_PCM_FMTBIT_S32_LE,
6752 .channels_min = 1,
6753 .channels_max = 8,
6754 .rate_min = 8000,
6755 .rate_max = 352800,
6756 },
6757 .ops = &msm_dai_q6_tdm_ops,
6758 .id = AFE_PORT_ID_PRIMARY_TDM_RX_5,
6759 .probe = msm_dai_q6_dai_tdm_probe,
6760 .remove = msm_dai_q6_dai_tdm_remove,
6761 },
6762 {
6763 .playback = {
6764 .stream_name = "Primary TDM6 Playback",
6765 .aif_name = "PRI_TDM_RX_6",
6766 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6767 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6768 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6769 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6770 SNDRV_PCM_FMTBIT_S24_LE |
6771 SNDRV_PCM_FMTBIT_S32_LE,
6772 .channels_min = 1,
6773 .channels_max = 8,
6774 .rate_min = 8000,
6775 .rate_max = 352800,
6776 },
6777 .ops = &msm_dai_q6_tdm_ops,
6778 .id = AFE_PORT_ID_PRIMARY_TDM_RX_6,
6779 .probe = msm_dai_q6_dai_tdm_probe,
6780 .remove = msm_dai_q6_dai_tdm_remove,
6781 },
6782 {
6783 .playback = {
6784 .stream_name = "Primary TDM7 Playback",
6785 .aif_name = "PRI_TDM_RX_7",
6786 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6787 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6788 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6789 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6790 SNDRV_PCM_FMTBIT_S24_LE |
6791 SNDRV_PCM_FMTBIT_S32_LE,
6792 .channels_min = 1,
6793 .channels_max = 8,
6794 .rate_min = 8000,
6795 .rate_max = 352800,
6796 },
6797 .ops = &msm_dai_q6_tdm_ops,
6798 .id = AFE_PORT_ID_PRIMARY_TDM_RX_7,
6799 .probe = msm_dai_q6_dai_tdm_probe,
6800 .remove = msm_dai_q6_dai_tdm_remove,
6801 },
6802 {
6803 .capture = {
6804 .stream_name = "Primary TDM0 Capture",
6805 .aif_name = "PRI_TDM_TX_0",
6806 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6807 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6808 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6809 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6810 SNDRV_PCM_FMTBIT_S24_LE |
6811 SNDRV_PCM_FMTBIT_S32_LE,
6812 .channels_min = 1,
6813 .channels_max = 8,
6814 .rate_min = 8000,
6815 .rate_max = 352800,
6816 },
6817 .ops = &msm_dai_q6_tdm_ops,
6818 .id = AFE_PORT_ID_PRIMARY_TDM_TX,
6819 .probe = msm_dai_q6_dai_tdm_probe,
6820 .remove = msm_dai_q6_dai_tdm_remove,
6821 },
6822 {
6823 .capture = {
6824 .stream_name = "Primary TDM1 Capture",
6825 .aif_name = "PRI_TDM_TX_1",
6826 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6827 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6828 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6829 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6830 SNDRV_PCM_FMTBIT_S24_LE |
6831 SNDRV_PCM_FMTBIT_S32_LE,
6832 .channels_min = 1,
6833 .channels_max = 8,
6834 .rate_min = 8000,
6835 .rate_max = 352800,
6836 },
6837 .ops = &msm_dai_q6_tdm_ops,
6838 .id = AFE_PORT_ID_PRIMARY_TDM_TX_1,
6839 .probe = msm_dai_q6_dai_tdm_probe,
6840 .remove = msm_dai_q6_dai_tdm_remove,
6841 },
6842 {
6843 .capture = {
6844 .stream_name = "Primary TDM2 Capture",
6845 .aif_name = "PRI_TDM_TX_2",
6846 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6847 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6848 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6849 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6850 SNDRV_PCM_FMTBIT_S24_LE |
6851 SNDRV_PCM_FMTBIT_S32_LE,
6852 .channels_min = 1,
6853 .channels_max = 8,
6854 .rate_min = 8000,
6855 .rate_max = 352800,
6856 },
6857 .ops = &msm_dai_q6_tdm_ops,
6858 .id = AFE_PORT_ID_PRIMARY_TDM_TX_2,
6859 .probe = msm_dai_q6_dai_tdm_probe,
6860 .remove = msm_dai_q6_dai_tdm_remove,
6861 },
6862 {
6863 .capture = {
6864 .stream_name = "Primary TDM3 Capture",
6865 .aif_name = "PRI_TDM_TX_3",
6866 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6867 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6868 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6869 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6870 SNDRV_PCM_FMTBIT_S24_LE |
6871 SNDRV_PCM_FMTBIT_S32_LE,
6872 .channels_min = 1,
6873 .channels_max = 8,
6874 .rate_min = 8000,
6875 .rate_max = 352800,
6876 },
6877 .ops = &msm_dai_q6_tdm_ops,
6878 .id = AFE_PORT_ID_PRIMARY_TDM_TX_3,
6879 .probe = msm_dai_q6_dai_tdm_probe,
6880 .remove = msm_dai_q6_dai_tdm_remove,
6881 },
6882 {
6883 .capture = {
6884 .stream_name = "Primary TDM4 Capture",
6885 .aif_name = "PRI_TDM_TX_4",
6886 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6887 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6888 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6889 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6890 SNDRV_PCM_FMTBIT_S24_LE |
6891 SNDRV_PCM_FMTBIT_S32_LE,
6892 .channels_min = 1,
6893 .channels_max = 8,
6894 .rate_min = 8000,
6895 .rate_max = 352800,
6896 },
6897 .ops = &msm_dai_q6_tdm_ops,
6898 .id = AFE_PORT_ID_PRIMARY_TDM_TX_4,
6899 .probe = msm_dai_q6_dai_tdm_probe,
6900 .remove = msm_dai_q6_dai_tdm_remove,
6901 },
6902 {
6903 .capture = {
6904 .stream_name = "Primary TDM5 Capture",
6905 .aif_name = "PRI_TDM_TX_5",
6906 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6907 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6908 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6909 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6910 SNDRV_PCM_FMTBIT_S24_LE |
6911 SNDRV_PCM_FMTBIT_S32_LE,
6912 .channels_min = 1,
6913 .channels_max = 8,
6914 .rate_min = 8000,
6915 .rate_max = 352800,
6916 },
6917 .ops = &msm_dai_q6_tdm_ops,
6918 .id = AFE_PORT_ID_PRIMARY_TDM_TX_5,
6919 .probe = msm_dai_q6_dai_tdm_probe,
6920 .remove = msm_dai_q6_dai_tdm_remove,
6921 },
6922 {
6923 .capture = {
6924 .stream_name = "Primary TDM6 Capture",
6925 .aif_name = "PRI_TDM_TX_6",
6926 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6927 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6928 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6929 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6930 SNDRV_PCM_FMTBIT_S24_LE |
6931 SNDRV_PCM_FMTBIT_S32_LE,
6932 .channels_min = 1,
6933 .channels_max = 8,
6934 .rate_min = 8000,
6935 .rate_max = 352800,
6936 },
6937 .ops = &msm_dai_q6_tdm_ops,
6938 .id = AFE_PORT_ID_PRIMARY_TDM_TX_6,
6939 .probe = msm_dai_q6_dai_tdm_probe,
6940 .remove = msm_dai_q6_dai_tdm_remove,
6941 },
6942 {
6943 .capture = {
6944 .stream_name = "Primary TDM7 Capture",
6945 .aif_name = "PRI_TDM_TX_7",
6946 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6947 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6948 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6949 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6950 SNDRV_PCM_FMTBIT_S24_LE |
6951 SNDRV_PCM_FMTBIT_S32_LE,
6952 .channels_min = 1,
6953 .channels_max = 8,
6954 .rate_min = 8000,
6955 .rate_max = 352800,
6956 },
6957 .ops = &msm_dai_q6_tdm_ops,
6958 .id = AFE_PORT_ID_PRIMARY_TDM_TX_7,
6959 .probe = msm_dai_q6_dai_tdm_probe,
6960 .remove = msm_dai_q6_dai_tdm_remove,
6961 },
6962 {
6963 .playback = {
6964 .stream_name = "Secondary TDM0 Playback",
6965 .aif_name = "SEC_TDM_RX_0",
6966 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6967 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6968 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6969 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6970 SNDRV_PCM_FMTBIT_S24_LE |
6971 SNDRV_PCM_FMTBIT_S32_LE,
6972 .channels_min = 1,
6973 .channels_max = 8,
6974 .rate_min = 8000,
6975 .rate_max = 352800,
6976 },
6977 .ops = &msm_dai_q6_tdm_ops,
6978 .id = AFE_PORT_ID_SECONDARY_TDM_RX,
6979 .probe = msm_dai_q6_dai_tdm_probe,
6980 .remove = msm_dai_q6_dai_tdm_remove,
6981 },
6982 {
6983 .playback = {
6984 .stream_name = "Secondary TDM1 Playback",
6985 .aif_name = "SEC_TDM_RX_1",
6986 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
6987 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
6988 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
6989 .formats = SNDRV_PCM_FMTBIT_S16_LE |
6990 SNDRV_PCM_FMTBIT_S24_LE |
6991 SNDRV_PCM_FMTBIT_S32_LE,
6992 .channels_min = 1,
6993 .channels_max = 8,
6994 .rate_min = 8000,
6995 .rate_max = 352800,
6996 },
6997 .ops = &msm_dai_q6_tdm_ops,
6998 .id = AFE_PORT_ID_SECONDARY_TDM_RX_1,
6999 .probe = msm_dai_q6_dai_tdm_probe,
7000 .remove = msm_dai_q6_dai_tdm_remove,
7001 },
7002 {
7003 .playback = {
7004 .stream_name = "Secondary TDM2 Playback",
7005 .aif_name = "SEC_TDM_RX_2",
7006 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7007 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7008 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7009 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7010 SNDRV_PCM_FMTBIT_S24_LE |
7011 SNDRV_PCM_FMTBIT_S32_LE,
7012 .channels_min = 1,
7013 .channels_max = 8,
7014 .rate_min = 8000,
7015 .rate_max = 352800,
7016 },
7017 .ops = &msm_dai_q6_tdm_ops,
7018 .id = AFE_PORT_ID_SECONDARY_TDM_RX_2,
7019 .probe = msm_dai_q6_dai_tdm_probe,
7020 .remove = msm_dai_q6_dai_tdm_remove,
7021 },
7022 {
7023 .playback = {
7024 .stream_name = "Secondary TDM3 Playback",
7025 .aif_name = "SEC_TDM_RX_3",
7026 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7027 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7028 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7029 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7030 SNDRV_PCM_FMTBIT_S24_LE |
7031 SNDRV_PCM_FMTBIT_S32_LE,
7032 .channels_min = 1,
7033 .channels_max = 8,
7034 .rate_min = 8000,
7035 .rate_max = 352800,
7036 },
7037 .ops = &msm_dai_q6_tdm_ops,
7038 .id = AFE_PORT_ID_SECONDARY_TDM_RX_3,
7039 .probe = msm_dai_q6_dai_tdm_probe,
7040 .remove = msm_dai_q6_dai_tdm_remove,
7041 },
7042 {
7043 .playback = {
7044 .stream_name = "Secondary TDM4 Playback",
7045 .aif_name = "SEC_TDM_RX_4",
7046 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7047 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7048 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7049 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7050 SNDRV_PCM_FMTBIT_S24_LE |
7051 SNDRV_PCM_FMTBIT_S32_LE,
7052 .channels_min = 1,
7053 .channels_max = 8,
7054 .rate_min = 8000,
7055 .rate_max = 352800,
7056 },
7057 .ops = &msm_dai_q6_tdm_ops,
7058 .id = AFE_PORT_ID_SECONDARY_TDM_RX_4,
7059 .probe = msm_dai_q6_dai_tdm_probe,
7060 .remove = msm_dai_q6_dai_tdm_remove,
7061 },
7062 {
7063 .playback = {
7064 .stream_name = "Secondary TDM5 Playback",
7065 .aif_name = "SEC_TDM_RX_5",
7066 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7067 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7068 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7069 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7070 SNDRV_PCM_FMTBIT_S24_LE |
7071 SNDRV_PCM_FMTBIT_S32_LE,
7072 .channels_min = 1,
7073 .channels_max = 8,
7074 .rate_min = 8000,
7075 .rate_max = 352800,
7076 },
7077 .ops = &msm_dai_q6_tdm_ops,
7078 .id = AFE_PORT_ID_SECONDARY_TDM_RX_5,
7079 .probe = msm_dai_q6_dai_tdm_probe,
7080 .remove = msm_dai_q6_dai_tdm_remove,
7081 },
7082 {
7083 .playback = {
7084 .stream_name = "Secondary TDM6 Playback",
7085 .aif_name = "SEC_TDM_RX_6",
7086 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7087 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7088 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7089 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7090 SNDRV_PCM_FMTBIT_S24_LE |
7091 SNDRV_PCM_FMTBIT_S32_LE,
7092 .channels_min = 1,
7093 .channels_max = 8,
7094 .rate_min = 8000,
7095 .rate_max = 352800,
7096 },
7097 .ops = &msm_dai_q6_tdm_ops,
7098 .id = AFE_PORT_ID_SECONDARY_TDM_RX_6,
7099 .probe = msm_dai_q6_dai_tdm_probe,
7100 .remove = msm_dai_q6_dai_tdm_remove,
7101 },
7102 {
7103 .playback = {
7104 .stream_name = "Secondary TDM7 Playback",
7105 .aif_name = "SEC_TDM_RX_7",
7106 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7107 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7108 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7109 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7110 SNDRV_PCM_FMTBIT_S24_LE |
7111 SNDRV_PCM_FMTBIT_S32_LE,
7112 .channels_min = 1,
7113 .channels_max = 8,
7114 .rate_min = 8000,
7115 .rate_max = 352800,
7116 },
7117 .ops = &msm_dai_q6_tdm_ops,
7118 .id = AFE_PORT_ID_SECONDARY_TDM_RX_7,
7119 .probe = msm_dai_q6_dai_tdm_probe,
7120 .remove = msm_dai_q6_dai_tdm_remove,
7121 },
7122 {
7123 .capture = {
7124 .stream_name = "Secondary TDM0 Capture",
7125 .aif_name = "SEC_TDM_TX_0",
7126 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7127 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7128 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7129 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7130 SNDRV_PCM_FMTBIT_S24_LE |
7131 SNDRV_PCM_FMTBIT_S32_LE,
7132 .channels_min = 1,
7133 .channels_max = 8,
7134 .rate_min = 8000,
7135 .rate_max = 352800,
7136 },
7137 .ops = &msm_dai_q6_tdm_ops,
7138 .id = AFE_PORT_ID_SECONDARY_TDM_TX,
7139 .probe = msm_dai_q6_dai_tdm_probe,
7140 .remove = msm_dai_q6_dai_tdm_remove,
7141 },
7142 {
7143 .capture = {
7144 .stream_name = "Secondary TDM1 Capture",
7145 .aif_name = "SEC_TDM_TX_1",
7146 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7147 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7148 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7149 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7150 SNDRV_PCM_FMTBIT_S24_LE |
7151 SNDRV_PCM_FMTBIT_S32_LE,
7152 .channels_min = 1,
7153 .channels_max = 8,
7154 .rate_min = 8000,
7155 .rate_max = 352800,
7156 },
7157 .ops = &msm_dai_q6_tdm_ops,
7158 .id = AFE_PORT_ID_SECONDARY_TDM_TX_1,
7159 .probe = msm_dai_q6_dai_tdm_probe,
7160 .remove = msm_dai_q6_dai_tdm_remove,
7161 },
7162 {
7163 .capture = {
7164 .stream_name = "Secondary TDM2 Capture",
7165 .aif_name = "SEC_TDM_TX_2",
7166 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7167 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7168 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7169 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7170 SNDRV_PCM_FMTBIT_S24_LE |
7171 SNDRV_PCM_FMTBIT_S32_LE,
7172 .channels_min = 1,
7173 .channels_max = 8,
7174 .rate_min = 8000,
7175 .rate_max = 352800,
7176 },
7177 .ops = &msm_dai_q6_tdm_ops,
7178 .id = AFE_PORT_ID_SECONDARY_TDM_TX_2,
7179 .probe = msm_dai_q6_dai_tdm_probe,
7180 .remove = msm_dai_q6_dai_tdm_remove,
7181 },
7182 {
7183 .capture = {
7184 .stream_name = "Secondary TDM3 Capture",
7185 .aif_name = "SEC_TDM_TX_3",
7186 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7187 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7188 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7189 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7190 SNDRV_PCM_FMTBIT_S24_LE |
7191 SNDRV_PCM_FMTBIT_S32_LE,
7192 .channels_min = 1,
7193 .channels_max = 8,
7194 .rate_min = 8000,
7195 .rate_max = 352800,
7196 },
7197 .ops = &msm_dai_q6_tdm_ops,
7198 .id = AFE_PORT_ID_SECONDARY_TDM_TX_3,
7199 .probe = msm_dai_q6_dai_tdm_probe,
7200 .remove = msm_dai_q6_dai_tdm_remove,
7201 },
7202 {
7203 .capture = {
7204 .stream_name = "Secondary TDM4 Capture",
7205 .aif_name = "SEC_TDM_TX_4",
7206 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7207 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7208 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7209 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7210 SNDRV_PCM_FMTBIT_S24_LE |
7211 SNDRV_PCM_FMTBIT_S32_LE,
7212 .channels_min = 1,
7213 .channels_max = 8,
7214 .rate_min = 8000,
7215 .rate_max = 352800,
7216 },
7217 .ops = &msm_dai_q6_tdm_ops,
7218 .id = AFE_PORT_ID_SECONDARY_TDM_TX_4,
7219 .probe = msm_dai_q6_dai_tdm_probe,
7220 .remove = msm_dai_q6_dai_tdm_remove,
7221 },
7222 {
7223 .capture = {
7224 .stream_name = "Secondary TDM5 Capture",
7225 .aif_name = "SEC_TDM_TX_5",
7226 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7227 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7228 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7229 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7230 SNDRV_PCM_FMTBIT_S24_LE |
7231 SNDRV_PCM_FMTBIT_S32_LE,
7232 .channels_min = 1,
7233 .channels_max = 8,
7234 .rate_min = 8000,
7235 .rate_max = 352800,
7236 },
7237 .ops = &msm_dai_q6_tdm_ops,
7238 .id = AFE_PORT_ID_SECONDARY_TDM_TX_5,
7239 .probe = msm_dai_q6_dai_tdm_probe,
7240 .remove = msm_dai_q6_dai_tdm_remove,
7241 },
7242 {
7243 .capture = {
7244 .stream_name = "Secondary TDM6 Capture",
7245 .aif_name = "SEC_TDM_TX_6",
7246 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7247 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7248 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7249 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7250 SNDRV_PCM_FMTBIT_S24_LE |
7251 SNDRV_PCM_FMTBIT_S32_LE,
7252 .channels_min = 1,
7253 .channels_max = 8,
7254 .rate_min = 8000,
7255 .rate_max = 352800,
7256 },
7257 .ops = &msm_dai_q6_tdm_ops,
7258 .id = AFE_PORT_ID_SECONDARY_TDM_TX_6,
7259 .probe = msm_dai_q6_dai_tdm_probe,
7260 .remove = msm_dai_q6_dai_tdm_remove,
7261 },
7262 {
7263 .capture = {
7264 .stream_name = "Secondary TDM7 Capture",
7265 .aif_name = "SEC_TDM_TX_7",
7266 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7267 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7268 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7269 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7270 SNDRV_PCM_FMTBIT_S24_LE |
7271 SNDRV_PCM_FMTBIT_S32_LE,
7272 .channels_min = 1,
7273 .channels_max = 8,
7274 .rate_min = 8000,
7275 .rate_max = 352800,
7276 },
7277 .ops = &msm_dai_q6_tdm_ops,
7278 .id = AFE_PORT_ID_SECONDARY_TDM_TX_7,
7279 .probe = msm_dai_q6_dai_tdm_probe,
7280 .remove = msm_dai_q6_dai_tdm_remove,
7281 },
7282 {
7283 .playback = {
7284 .stream_name = "Tertiary TDM0 Playback",
7285 .aif_name = "TERT_TDM_RX_0",
7286 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7287 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7288 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7289 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7290 SNDRV_PCM_FMTBIT_S24_LE |
7291 SNDRV_PCM_FMTBIT_S32_LE,
7292 .channels_min = 1,
7293 .channels_max = 8,
7294 .rate_min = 8000,
7295 .rate_max = 352800,
7296 },
7297 .ops = &msm_dai_q6_tdm_ops,
7298 .id = AFE_PORT_ID_TERTIARY_TDM_RX,
7299 .probe = msm_dai_q6_dai_tdm_probe,
7300 .remove = msm_dai_q6_dai_tdm_remove,
7301 },
7302 {
7303 .playback = {
7304 .stream_name = "Tertiary TDM1 Playback",
7305 .aif_name = "TERT_TDM_RX_1",
7306 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7307 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7308 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7309 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7310 SNDRV_PCM_FMTBIT_S24_LE |
7311 SNDRV_PCM_FMTBIT_S32_LE,
7312 .channels_min = 1,
7313 .channels_max = 8,
7314 .rate_min = 8000,
7315 .rate_max = 352800,
7316 },
7317 .ops = &msm_dai_q6_tdm_ops,
7318 .id = AFE_PORT_ID_TERTIARY_TDM_RX_1,
7319 .probe = msm_dai_q6_dai_tdm_probe,
7320 .remove = msm_dai_q6_dai_tdm_remove,
7321 },
7322 {
7323 .playback = {
7324 .stream_name = "Tertiary TDM2 Playback",
7325 .aif_name = "TERT_TDM_RX_2",
7326 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7327 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7328 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7329 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7330 SNDRV_PCM_FMTBIT_S24_LE |
7331 SNDRV_PCM_FMTBIT_S32_LE,
7332 .channels_min = 1,
7333 .channels_max = 8,
7334 .rate_min = 8000,
7335 .rate_max = 352800,
7336 },
7337 .ops = &msm_dai_q6_tdm_ops,
7338 .id = AFE_PORT_ID_TERTIARY_TDM_RX_2,
7339 .probe = msm_dai_q6_dai_tdm_probe,
7340 .remove = msm_dai_q6_dai_tdm_remove,
7341 },
7342 {
7343 .playback = {
7344 .stream_name = "Tertiary TDM3 Playback",
7345 .aif_name = "TERT_TDM_RX_3",
7346 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7347 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7348 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7349 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7350 SNDRV_PCM_FMTBIT_S24_LE |
7351 SNDRV_PCM_FMTBIT_S32_LE,
7352 .channels_min = 1,
7353 .channels_max = 8,
7354 .rate_min = 8000,
7355 .rate_max = 352800,
7356 },
7357 .ops = &msm_dai_q6_tdm_ops,
7358 .id = AFE_PORT_ID_TERTIARY_TDM_RX_3,
7359 .probe = msm_dai_q6_dai_tdm_probe,
7360 .remove = msm_dai_q6_dai_tdm_remove,
7361 },
7362 {
7363 .playback = {
7364 .stream_name = "Tertiary TDM4 Playback",
7365 .aif_name = "TERT_TDM_RX_4",
7366 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7367 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7368 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7369 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7370 SNDRV_PCM_FMTBIT_S24_LE |
7371 SNDRV_PCM_FMTBIT_S32_LE,
7372 .channels_min = 1,
7373 .channels_max = 8,
7374 .rate_min = 8000,
7375 .rate_max = 352800,
7376 },
7377 .ops = &msm_dai_q6_tdm_ops,
7378 .id = AFE_PORT_ID_TERTIARY_TDM_RX_4,
7379 .probe = msm_dai_q6_dai_tdm_probe,
7380 .remove = msm_dai_q6_dai_tdm_remove,
7381 },
7382 {
7383 .playback = {
7384 .stream_name = "Tertiary TDM5 Playback",
7385 .aif_name = "TERT_TDM_RX_5",
7386 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7387 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7388 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7389 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7390 SNDRV_PCM_FMTBIT_S24_LE |
7391 SNDRV_PCM_FMTBIT_S32_LE,
7392 .channels_min = 1,
7393 .channels_max = 8,
7394 .rate_min = 8000,
7395 .rate_max = 352800,
7396 },
7397 .ops = &msm_dai_q6_tdm_ops,
7398 .id = AFE_PORT_ID_TERTIARY_TDM_RX_5,
7399 .probe = msm_dai_q6_dai_tdm_probe,
7400 .remove = msm_dai_q6_dai_tdm_remove,
7401 },
7402 {
7403 .playback = {
7404 .stream_name = "Tertiary TDM6 Playback",
7405 .aif_name = "TERT_TDM_RX_6",
7406 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7407 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7408 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7409 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7410 SNDRV_PCM_FMTBIT_S24_LE |
7411 SNDRV_PCM_FMTBIT_S32_LE,
7412 .channels_min = 1,
7413 .channels_max = 8,
7414 .rate_min = 8000,
7415 .rate_max = 352800,
7416 },
7417 .ops = &msm_dai_q6_tdm_ops,
7418 .id = AFE_PORT_ID_TERTIARY_TDM_RX_6,
7419 .probe = msm_dai_q6_dai_tdm_probe,
7420 .remove = msm_dai_q6_dai_tdm_remove,
7421 },
7422 {
7423 .playback = {
7424 .stream_name = "Tertiary TDM7 Playback",
7425 .aif_name = "TERT_TDM_RX_7",
7426 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7427 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7428 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7429 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7430 SNDRV_PCM_FMTBIT_S24_LE |
7431 SNDRV_PCM_FMTBIT_S32_LE,
7432 .channels_min = 1,
7433 .channels_max = 8,
7434 .rate_min = 8000,
7435 .rate_max = 352800,
7436 },
7437 .ops = &msm_dai_q6_tdm_ops,
7438 .id = AFE_PORT_ID_TERTIARY_TDM_RX_7,
7439 .probe = msm_dai_q6_dai_tdm_probe,
7440 .remove = msm_dai_q6_dai_tdm_remove,
7441 },
7442 {
7443 .capture = {
7444 .stream_name = "Tertiary TDM0 Capture",
7445 .aif_name = "TERT_TDM_TX_0",
7446 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7447 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7448 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7449 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7450 SNDRV_PCM_FMTBIT_S24_LE |
7451 SNDRV_PCM_FMTBIT_S32_LE,
7452 .channels_min = 1,
7453 .channels_max = 8,
7454 .rate_min = 8000,
7455 .rate_max = 352800,
7456 },
7457 .ops = &msm_dai_q6_tdm_ops,
7458 .id = AFE_PORT_ID_TERTIARY_TDM_TX,
7459 .probe = msm_dai_q6_dai_tdm_probe,
7460 .remove = msm_dai_q6_dai_tdm_remove,
7461 },
7462 {
7463 .capture = {
7464 .stream_name = "Tertiary TDM1 Capture",
7465 .aif_name = "TERT_TDM_TX_1",
7466 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7467 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7468 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7469 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7470 SNDRV_PCM_FMTBIT_S24_LE |
7471 SNDRV_PCM_FMTBIT_S32_LE,
7472 .channels_min = 1,
7473 .channels_max = 8,
7474 .rate_min = 8000,
7475 .rate_max = 352800,
7476 },
7477 .ops = &msm_dai_q6_tdm_ops,
7478 .id = AFE_PORT_ID_TERTIARY_TDM_TX_1,
7479 .probe = msm_dai_q6_dai_tdm_probe,
7480 .remove = msm_dai_q6_dai_tdm_remove,
7481 },
7482 {
7483 .capture = {
7484 .stream_name = "Tertiary TDM2 Capture",
7485 .aif_name = "TERT_TDM_TX_2",
7486 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7487 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7488 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7489 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7490 SNDRV_PCM_FMTBIT_S24_LE |
7491 SNDRV_PCM_FMTBIT_S32_LE,
7492 .channels_min = 1,
7493 .channels_max = 8,
7494 .rate_min = 8000,
7495 .rate_max = 352800,
7496 },
7497 .ops = &msm_dai_q6_tdm_ops,
7498 .id = AFE_PORT_ID_TERTIARY_TDM_TX_2,
7499 .probe = msm_dai_q6_dai_tdm_probe,
7500 .remove = msm_dai_q6_dai_tdm_remove,
7501 },
7502 {
7503 .capture = {
7504 .stream_name = "Tertiary TDM3 Capture",
7505 .aif_name = "TERT_TDM_TX_3",
7506 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7507 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7508 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7509 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7510 SNDRV_PCM_FMTBIT_S24_LE |
7511 SNDRV_PCM_FMTBIT_S32_LE,
7512 .channels_min = 1,
7513 .channels_max = 8,
7514 .rate_min = 8000,
7515 .rate_max = 352800,
7516 },
7517 .ops = &msm_dai_q6_tdm_ops,
7518 .id = AFE_PORT_ID_TERTIARY_TDM_TX_3,
7519 .probe = msm_dai_q6_dai_tdm_probe,
7520 .remove = msm_dai_q6_dai_tdm_remove,
7521 },
7522 {
7523 .capture = {
7524 .stream_name = "Tertiary TDM4 Capture",
7525 .aif_name = "TERT_TDM_TX_4",
7526 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7527 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7528 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7529 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7530 SNDRV_PCM_FMTBIT_S24_LE |
7531 SNDRV_PCM_FMTBIT_S32_LE,
7532 .channels_min = 1,
7533 .channels_max = 8,
7534 .rate_min = 8000,
7535 .rate_max = 352800,
7536 },
7537 .ops = &msm_dai_q6_tdm_ops,
7538 .id = AFE_PORT_ID_TERTIARY_TDM_TX_4,
7539 .probe = msm_dai_q6_dai_tdm_probe,
7540 .remove = msm_dai_q6_dai_tdm_remove,
7541 },
7542 {
7543 .capture = {
7544 .stream_name = "Tertiary TDM5 Capture",
7545 .aif_name = "TERT_TDM_TX_5",
7546 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7547 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7548 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7549 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7550 SNDRV_PCM_FMTBIT_S24_LE |
7551 SNDRV_PCM_FMTBIT_S32_LE,
7552 .channels_min = 1,
7553 .channels_max = 8,
7554 .rate_min = 8000,
7555 .rate_max = 352800,
7556 },
7557 .ops = &msm_dai_q6_tdm_ops,
7558 .id = AFE_PORT_ID_TERTIARY_TDM_TX_5,
7559 .probe = msm_dai_q6_dai_tdm_probe,
7560 .remove = msm_dai_q6_dai_tdm_remove,
7561 },
7562 {
7563 .capture = {
7564 .stream_name = "Tertiary TDM6 Capture",
7565 .aif_name = "TERT_TDM_TX_6",
7566 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7567 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7568 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7569 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7570 SNDRV_PCM_FMTBIT_S24_LE |
7571 SNDRV_PCM_FMTBIT_S32_LE,
7572 .channels_min = 1,
7573 .channels_max = 8,
7574 .rate_min = 8000,
7575 .rate_max = 352800,
7576 },
7577 .ops = &msm_dai_q6_tdm_ops,
7578 .id = AFE_PORT_ID_TERTIARY_TDM_TX_6,
7579 .probe = msm_dai_q6_dai_tdm_probe,
7580 .remove = msm_dai_q6_dai_tdm_remove,
7581 },
7582 {
7583 .capture = {
7584 .stream_name = "Tertiary TDM7 Capture",
7585 .aif_name = "TERT_TDM_TX_7",
7586 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7587 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7588 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7589 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7590 SNDRV_PCM_FMTBIT_S24_LE |
7591 SNDRV_PCM_FMTBIT_S32_LE,
7592 .channels_min = 1,
7593 .channels_max = 8,
7594 .rate_min = 8000,
7595 .rate_max = 352800,
7596 },
7597 .ops = &msm_dai_q6_tdm_ops,
7598 .id = AFE_PORT_ID_TERTIARY_TDM_TX_7,
7599 .probe = msm_dai_q6_dai_tdm_probe,
7600 .remove = msm_dai_q6_dai_tdm_remove,
7601 },
7602 {
7603 .playback = {
7604 .stream_name = "Quaternary TDM0 Playback",
7605 .aif_name = "QUAT_TDM_RX_0",
7606 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
7607 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
7608 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7609 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7610 SNDRV_PCM_FMTBIT_S24_LE |
7611 SNDRV_PCM_FMTBIT_S32_LE,
7612 .channels_min = 1,
7613 .channels_max = 8,
7614 .rate_min = 8000,
7615 .rate_max = 352800,
7616 },
7617 .ops = &msm_dai_q6_tdm_ops,
7618 .id = AFE_PORT_ID_QUATERNARY_TDM_RX,
7619 .probe = msm_dai_q6_dai_tdm_probe,
7620 .remove = msm_dai_q6_dai_tdm_remove,
7621 },
7622 {
7623 .playback = {
7624 .stream_name = "Quaternary TDM1 Playback",
7625 .aif_name = "QUAT_TDM_RX_1",
7626 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7627 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7628 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7629 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7630 SNDRV_PCM_FMTBIT_S24_LE |
7631 SNDRV_PCM_FMTBIT_S32_LE,
7632 .channels_min = 1,
7633 .channels_max = 8,
7634 .rate_min = 8000,
7635 .rate_max = 352800,
7636 },
7637 .ops = &msm_dai_q6_tdm_ops,
7638 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_1,
7639 .probe = msm_dai_q6_dai_tdm_probe,
7640 .remove = msm_dai_q6_dai_tdm_remove,
7641 },
7642 {
7643 .playback = {
7644 .stream_name = "Quaternary TDM2 Playback",
7645 .aif_name = "QUAT_TDM_RX_2",
7646 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7647 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7648 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7649 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7650 SNDRV_PCM_FMTBIT_S24_LE |
7651 SNDRV_PCM_FMTBIT_S32_LE,
7652 .channels_min = 1,
7653 .channels_max = 8,
7654 .rate_min = 8000,
7655 .rate_max = 352800,
7656 },
7657 .ops = &msm_dai_q6_tdm_ops,
7658 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_2,
7659 .probe = msm_dai_q6_dai_tdm_probe,
7660 .remove = msm_dai_q6_dai_tdm_remove,
7661 },
7662 {
7663 .playback = {
7664 .stream_name = "Quaternary TDM3 Playback",
7665 .aif_name = "QUAT_TDM_RX_3",
7666 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7667 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7668 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7669 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7670 SNDRV_PCM_FMTBIT_S24_LE |
7671 SNDRV_PCM_FMTBIT_S32_LE,
7672 .channels_min = 1,
7673 .channels_max = 8,
7674 .rate_min = 8000,
7675 .rate_max = 352800,
7676 },
7677 .ops = &msm_dai_q6_tdm_ops,
7678 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_3,
7679 .probe = msm_dai_q6_dai_tdm_probe,
7680 .remove = msm_dai_q6_dai_tdm_remove,
7681 },
7682 {
7683 .playback = {
7684 .stream_name = "Quaternary TDM4 Playback",
7685 .aif_name = "QUAT_TDM_RX_4",
7686 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7687 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7688 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7689 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7690 SNDRV_PCM_FMTBIT_S24_LE |
7691 SNDRV_PCM_FMTBIT_S32_LE,
7692 .channels_min = 1,
7693 .channels_max = 8,
7694 .rate_min = 8000,
7695 .rate_max = 352800,
7696 },
7697 .ops = &msm_dai_q6_tdm_ops,
7698 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_4,
7699 .probe = msm_dai_q6_dai_tdm_probe,
7700 .remove = msm_dai_q6_dai_tdm_remove,
7701 },
7702 {
7703 .playback = {
7704 .stream_name = "Quaternary TDM5 Playback",
7705 .aif_name = "QUAT_TDM_RX_5",
7706 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7707 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7708 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7709 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7710 SNDRV_PCM_FMTBIT_S24_LE |
7711 SNDRV_PCM_FMTBIT_S32_LE,
7712 .channels_min = 1,
7713 .channels_max = 8,
7714 .rate_min = 8000,
7715 .rate_max = 352800,
7716 },
7717 .ops = &msm_dai_q6_tdm_ops,
7718 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_5,
7719 .probe = msm_dai_q6_dai_tdm_probe,
7720 .remove = msm_dai_q6_dai_tdm_remove,
7721 },
7722 {
7723 .playback = {
7724 .stream_name = "Quaternary TDM6 Playback",
7725 .aif_name = "QUAT_TDM_RX_6",
7726 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7727 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7728 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7729 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7730 SNDRV_PCM_FMTBIT_S24_LE |
7731 SNDRV_PCM_FMTBIT_S32_LE,
7732 .channels_min = 1,
7733 .channels_max = 8,
7734 .rate_min = 8000,
7735 .rate_max = 352800,
7736 },
7737 .ops = &msm_dai_q6_tdm_ops,
7738 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_6,
7739 .probe = msm_dai_q6_dai_tdm_probe,
7740 .remove = msm_dai_q6_dai_tdm_remove,
7741 },
7742 {
7743 .playback = {
7744 .stream_name = "Quaternary TDM7 Playback",
7745 .aif_name = "QUAT_TDM_RX_7",
7746 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7747 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7748 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7749 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7750 SNDRV_PCM_FMTBIT_S24_LE |
7751 SNDRV_PCM_FMTBIT_S32_LE,
7752 .channels_min = 1,
7753 .channels_max = 8,
7754 .rate_min = 8000,
7755 .rate_max = 352800,
7756 },
7757 .ops = &msm_dai_q6_tdm_ops,
7758 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_7,
7759 .probe = msm_dai_q6_dai_tdm_probe,
7760 .remove = msm_dai_q6_dai_tdm_remove,
7761 },
7762 {
7763 .capture = {
7764 .stream_name = "Quaternary TDM0 Capture",
7765 .aif_name = "QUAT_TDM_TX_0",
7766 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7767 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7768 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7769 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7770 SNDRV_PCM_FMTBIT_S24_LE |
7771 SNDRV_PCM_FMTBIT_S32_LE,
7772 .channels_min = 1,
7773 .channels_max = 8,
7774 .rate_min = 8000,
7775 .rate_max = 352800,
7776 },
7777 .ops = &msm_dai_q6_tdm_ops,
7778 .id = AFE_PORT_ID_QUATERNARY_TDM_TX,
7779 .probe = msm_dai_q6_dai_tdm_probe,
7780 .remove = msm_dai_q6_dai_tdm_remove,
7781 },
7782 {
7783 .capture = {
7784 .stream_name = "Quaternary TDM1 Capture",
7785 .aif_name = "QUAT_TDM_TX_1",
7786 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7787 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7788 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7789 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7790 SNDRV_PCM_FMTBIT_S24_LE |
7791 SNDRV_PCM_FMTBIT_S32_LE,
7792 .channels_min = 1,
7793 .channels_max = 8,
7794 .rate_min = 8000,
7795 .rate_max = 352800,
7796 },
7797 .ops = &msm_dai_q6_tdm_ops,
7798 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_1,
7799 .probe = msm_dai_q6_dai_tdm_probe,
7800 .remove = msm_dai_q6_dai_tdm_remove,
7801 },
7802 {
7803 .capture = {
7804 .stream_name = "Quaternary TDM2 Capture",
7805 .aif_name = "QUAT_TDM_TX_2",
7806 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7807 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7808 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7809 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7810 SNDRV_PCM_FMTBIT_S24_LE |
7811 SNDRV_PCM_FMTBIT_S32_LE,
7812 .channels_min = 1,
7813 .channels_max = 8,
7814 .rate_min = 8000,
7815 .rate_max = 352800,
7816 },
7817 .ops = &msm_dai_q6_tdm_ops,
7818 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_2,
7819 .probe = msm_dai_q6_dai_tdm_probe,
7820 .remove = msm_dai_q6_dai_tdm_remove,
7821 },
7822 {
7823 .capture = {
7824 .stream_name = "Quaternary TDM3 Capture",
7825 .aif_name = "QUAT_TDM_TX_3",
7826 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7827 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7828 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7829 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7830 SNDRV_PCM_FMTBIT_S24_LE |
7831 SNDRV_PCM_FMTBIT_S32_LE,
7832 .channels_min = 1,
7833 .channels_max = 8,
7834 .rate_min = 8000,
7835 .rate_max = 352800,
7836 },
7837 .ops = &msm_dai_q6_tdm_ops,
7838 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_3,
7839 .probe = msm_dai_q6_dai_tdm_probe,
7840 .remove = msm_dai_q6_dai_tdm_remove,
7841 },
7842 {
7843 .capture = {
7844 .stream_name = "Quaternary TDM4 Capture",
7845 .aif_name = "QUAT_TDM_TX_4",
7846 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7847 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7848 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7849 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7850 SNDRV_PCM_FMTBIT_S24_LE |
7851 SNDRV_PCM_FMTBIT_S32_LE,
7852 .channels_min = 1,
7853 .channels_max = 8,
7854 .rate_min = 8000,
7855 .rate_max = 352800,
7856 },
7857 .ops = &msm_dai_q6_tdm_ops,
7858 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_4,
7859 .probe = msm_dai_q6_dai_tdm_probe,
7860 .remove = msm_dai_q6_dai_tdm_remove,
7861 },
7862 {
7863 .capture = {
7864 .stream_name = "Quaternary TDM5 Capture",
7865 .aif_name = "QUAT_TDM_TX_5",
7866 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7867 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7868 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7869 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7870 SNDRV_PCM_FMTBIT_S24_LE |
7871 SNDRV_PCM_FMTBIT_S32_LE,
7872 .channels_min = 1,
7873 .channels_max = 8,
7874 .rate_min = 8000,
7875 .rate_max = 352800,
7876 },
7877 .ops = &msm_dai_q6_tdm_ops,
7878 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_5,
7879 .probe = msm_dai_q6_dai_tdm_probe,
7880 .remove = msm_dai_q6_dai_tdm_remove,
7881 },
7882 {
7883 .capture = {
7884 .stream_name = "Quaternary TDM6 Capture",
7885 .aif_name = "QUAT_TDM_TX_6",
7886 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7887 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7888 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7889 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7890 SNDRV_PCM_FMTBIT_S24_LE |
7891 SNDRV_PCM_FMTBIT_S32_LE,
7892 .channels_min = 1,
7893 .channels_max = 8,
7894 .rate_min = 8000,
7895 .rate_max = 352800,
7896 },
7897 .ops = &msm_dai_q6_tdm_ops,
7898 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_6,
7899 .probe = msm_dai_q6_dai_tdm_probe,
7900 .remove = msm_dai_q6_dai_tdm_remove,
7901 },
7902 {
7903 .capture = {
7904 .stream_name = "Quaternary TDM7 Capture",
7905 .aif_name = "QUAT_TDM_TX_7",
7906 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7907 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7908 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7909 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7910 SNDRV_PCM_FMTBIT_S24_LE |
7911 SNDRV_PCM_FMTBIT_S32_LE,
7912 .channels_min = 1,
7913 .channels_max = 8,
7914 .rate_min = 8000,
7915 .rate_max = 352800,
7916 },
7917 .ops = &msm_dai_q6_tdm_ops,
7918 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_7,
7919 .probe = msm_dai_q6_dai_tdm_probe,
7920 .remove = msm_dai_q6_dai_tdm_remove,
7921 },
7922};
7923
7924static const struct snd_soc_component_driver msm_q6_tdm_dai_component = {
7925 .name = "msm-dai-q6-tdm",
7926};
7927
7928static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev)
7929{
7930 struct msm_dai_q6_tdm_dai_data *dai_data = NULL;
7931 struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header = NULL;
7932 int rc = 0;
7933 u32 tdm_dev_id = 0;
7934 int port_idx = 0;
7935 struct device_node *tdm_parent_node = NULL;
7936
7937 /* retrieve device/afe id */
7938 rc = of_property_read_u32(pdev->dev.of_node,
7939 "qcom,msm-cpudai-tdm-dev-id",
7940 &tdm_dev_id);
7941 if (rc) {
7942 dev_err(&pdev->dev, "%s: Device ID missing in DT file\n",
7943 __func__);
7944 goto rtn;
7945 }
7946 if ((tdm_dev_id < AFE_PORT_ID_TDM_PORT_RANGE_START) ||
7947 (tdm_dev_id > AFE_PORT_ID_TDM_PORT_RANGE_END)) {
7948 dev_err(&pdev->dev, "%s: Invalid TDM Device ID 0x%x in DT file\n",
7949 __func__, tdm_dev_id);
7950 rc = -ENXIO;
7951 goto rtn;
7952 }
7953 pdev->id = tdm_dev_id;
7954
7955 dev_info(&pdev->dev, "%s: dev_name: %s dev_id: 0x%x\n",
7956 __func__, dev_name(&pdev->dev), tdm_dev_id);
7957
7958 dai_data = kzalloc(sizeof(struct msm_dai_q6_tdm_dai_data),
7959 GFP_KERNEL);
7960 if (!dai_data) {
7961 rc = -ENOMEM;
7962 dev_err(&pdev->dev,
7963 "%s Failed to allocate memory for tdm dai_data\n",
7964 __func__);
7965 goto rtn;
7966 }
7967 memset(dai_data, 0, sizeof(*dai_data));
7968
7969 /* TDM CFG */
7970 tdm_parent_node = of_get_parent(pdev->dev.of_node);
7971 rc = of_property_read_u32(tdm_parent_node,
7972 "qcom,msm-cpudai-tdm-sync-mode",
7973 (u32 *)&dai_data->port_cfg.tdm.sync_mode);
7974 if (rc) {
7975 dev_err(&pdev->dev, "%s: Sync Mode from DT file %s\n",
7976 __func__, "qcom,msm-cpudai-tdm-sync-mode");
7977 goto free_dai_data;
7978 }
7979 dev_dbg(&pdev->dev, "%s: Sync Mode from DT file 0x%x\n",
7980 __func__, dai_data->port_cfg.tdm.sync_mode);
7981
7982 rc = of_property_read_u32(tdm_parent_node,
7983 "qcom,msm-cpudai-tdm-sync-src",
7984 (u32 *)&dai_data->port_cfg.tdm.sync_src);
7985 if (rc) {
7986 dev_err(&pdev->dev, "%s: Sync Src from DT file %s\n",
7987 __func__, "qcom,msm-cpudai-tdm-sync-src");
7988 goto free_dai_data;
7989 }
7990 dev_dbg(&pdev->dev, "%s: Sync Src from DT file 0x%x\n",
7991 __func__, dai_data->port_cfg.tdm.sync_src);
7992
7993 rc = of_property_read_u32(tdm_parent_node,
7994 "qcom,msm-cpudai-tdm-data-out",
7995 (u32 *)&dai_data->port_cfg.tdm.ctrl_data_out_enable);
7996 if (rc) {
7997 dev_err(&pdev->dev, "%s: Data Out from DT file %s\n",
7998 __func__, "qcom,msm-cpudai-tdm-data-out");
7999 goto free_dai_data;
8000 }
8001 dev_dbg(&pdev->dev, "%s: Data Out from DT file 0x%x\n",
8002 __func__, dai_data->port_cfg.tdm.ctrl_data_out_enable);
8003
8004 rc = of_property_read_u32(tdm_parent_node,
8005 "qcom,msm-cpudai-tdm-invert-sync",
8006 (u32 *)&dai_data->port_cfg.tdm.ctrl_invert_sync_pulse);
8007 if (rc) {
8008 dev_err(&pdev->dev, "%s: Invert Sync from DT file %s\n",
8009 __func__, "qcom,msm-cpudai-tdm-invert-sync");
8010 goto free_dai_data;
8011 }
8012 dev_dbg(&pdev->dev, "%s: Invert Sync from DT file 0x%x\n",
8013 __func__, dai_data->port_cfg.tdm.ctrl_invert_sync_pulse);
8014
8015 rc = of_property_read_u32(tdm_parent_node,
8016 "qcom,msm-cpudai-tdm-data-delay",
8017 (u32 *)&dai_data->port_cfg.tdm.ctrl_sync_data_delay);
8018 if (rc) {
8019 dev_err(&pdev->dev, "%s: Data Delay from DT file %s\n",
8020 __func__, "qcom,msm-cpudai-tdm-data-delay");
8021 goto free_dai_data;
8022 }
8023 dev_dbg(&pdev->dev, "%s: Data Delay from DT file 0x%x\n",
8024 __func__, dai_data->port_cfg.tdm.ctrl_sync_data_delay);
8025
8026 /* TDM CFG -- set default */
8027 dai_data->port_cfg.tdm.data_format = AFE_LINEAR_PCM_DATA;
8028 dai_data->port_cfg.tdm.tdm_cfg_minor_version =
8029 AFE_API_VERSION_TDM_CONFIG;
8030
8031 /* TDM SLOT MAPPING CFG */
8032 rc = of_property_read_u32(pdev->dev.of_node,
8033 "qcom,msm-cpudai-tdm-data-align",
8034 &dai_data->port_cfg.slot_mapping.data_align_type);
8035 if (rc) {
8036 dev_err(&pdev->dev, "%s: Data Align from DT file %s\n",
8037 __func__,
8038 "qcom,msm-cpudai-tdm-data-align");
8039 goto free_dai_data;
8040 }
8041 dev_dbg(&pdev->dev, "%s: Data Align from DT file 0x%x\n",
8042 __func__, dai_data->port_cfg.slot_mapping.data_align_type);
8043
8044 /* TDM SLOT MAPPING CFG -- set default */
8045 dai_data->port_cfg.slot_mapping.minor_version =
8046 AFE_API_VERSION_SLOT_MAPPING_CONFIG;
8047
8048 /* CUSTOM TDM HEADER CFG */
8049 custom_tdm_header = &dai_data->port_cfg.custom_tdm_header;
8050 if (of_find_property(pdev->dev.of_node,
8051 "qcom,msm-cpudai-tdm-header-start-offset", NULL) &&
8052 of_find_property(pdev->dev.of_node,
8053 "qcom,msm-cpudai-tdm-header-width", NULL) &&
8054 of_find_property(pdev->dev.of_node,
8055 "qcom,msm-cpudai-tdm-header-num-frame-repeat", NULL)) {
8056 /* if the property exist */
8057 rc = of_property_read_u32(pdev->dev.of_node,
8058 "qcom,msm-cpudai-tdm-header-start-offset",
8059 (u32 *)&custom_tdm_header->start_offset);
8060 if (rc) {
8061 dev_err(&pdev->dev, "%s: Header Start Offset from DT file %s\n",
8062 __func__,
8063 "qcom,msm-cpudai-tdm-header-start-offset");
8064 goto free_dai_data;
8065 }
8066 dev_dbg(&pdev->dev, "%s: Header Start Offset from DT file 0x%x\n",
8067 __func__, custom_tdm_header->start_offset);
8068
8069 rc = of_property_read_u32(pdev->dev.of_node,
8070 "qcom,msm-cpudai-tdm-header-width",
8071 (u32 *)&custom_tdm_header->header_width);
8072 if (rc) {
8073 dev_err(&pdev->dev, "%s: Header Width from DT file %s\n",
8074 __func__, "qcom,msm-cpudai-tdm-header-width");
8075 goto free_dai_data;
8076 }
8077 dev_dbg(&pdev->dev, "%s: Header Width from DT file 0x%x\n",
8078 __func__, custom_tdm_header->header_width);
8079
8080 rc = of_property_read_u32(pdev->dev.of_node,
8081 "qcom,msm-cpudai-tdm-header-num-frame-repeat",
8082 (u32 *)&custom_tdm_header->num_frame_repeat);
8083 if (rc) {
8084 dev_err(&pdev->dev, "%s: Header Num Frame Repeat from DT file %s\n",
8085 __func__,
8086 "qcom,msm-cpudai-tdm-header-num-frame-repeat");
8087 goto free_dai_data;
8088 }
8089 dev_dbg(&pdev->dev, "%s: Header Num Frame Repeat from DT file 0x%x\n",
8090 __func__, custom_tdm_header->num_frame_repeat);
8091
8092 /* CUSTOM TDM HEADER CFG -- set default */
8093 custom_tdm_header->minor_version =
8094 AFE_API_VERSION_CUSTOM_TDM_HEADER_CONFIG;
8095 custom_tdm_header->header_type =
8096 AFE_CUSTOM_TDM_HEADER_TYPE_INVALID;
8097 } else {
8098 dev_info(&pdev->dev,
8099 "%s: Custom tdm header not supported\n", __func__);
8100 /* CUSTOM TDM HEADER CFG -- set default */
8101 custom_tdm_header->header_type =
8102 AFE_CUSTOM_TDM_HEADER_TYPE_INVALID;
8103 /* proceed with probe */
8104 }
8105
8106 /* copy static clk per parent node */
8107 dai_data->clk_set = tdm_clk_set;
8108 /* copy static group cfg per parent node */
8109 dai_data->group_cfg.tdm_cfg = tdm_group_cfg;
8110 /* copy static num group ports per parent node */
8111 dai_data->num_group_ports = num_tdm_group_ports;
8112
8113
8114 dev_set_drvdata(&pdev->dev, dai_data);
8115
8116 port_idx = msm_dai_q6_get_port_idx(tdm_dev_id);
8117 if (port_idx < 0) {
8118 dev_err(&pdev->dev, "%s Port id 0x%x not supported\n",
8119 __func__, tdm_dev_id);
8120 rc = -EINVAL;
8121 goto free_dai_data;
8122 }
8123
8124 rc = snd_soc_register_component(&pdev->dev,
8125 &msm_q6_tdm_dai_component,
8126 &msm_dai_q6_tdm_dai[port_idx], 1);
8127
8128 if (rc) {
8129 dev_err(&pdev->dev, "%s: TDM dai 0x%x register failed, rc=%d\n",
8130 __func__, tdm_dev_id, rc);
8131 goto err_register;
8132 }
8133
8134 return 0;
8135
8136err_register:
8137free_dai_data:
8138 kfree(dai_data);
8139rtn:
8140 return rc;
8141}
8142
8143static int msm_dai_q6_tdm_dev_remove(struct platform_device *pdev)
8144{
8145 struct msm_dai_q6_tdm_dai_data *dai_data =
8146 dev_get_drvdata(&pdev->dev);
8147
8148 snd_soc_unregister_component(&pdev->dev);
8149
8150 kfree(dai_data);
8151
8152 return 0;
8153}
8154
8155static const struct of_device_id msm_dai_q6_tdm_dev_dt_match[] = {
8156 { .compatible = "qcom,msm-dai-q6-tdm", },
8157 {}
8158};
8159
8160MODULE_DEVICE_TABLE(of, msm_dai_q6_tdm_dev_dt_match);
8161
8162static struct platform_driver msm_dai_q6_tdm_driver = {
8163 .probe = msm_dai_q6_tdm_dev_probe,
8164 .remove = msm_dai_q6_tdm_dev_remove,
8165 .driver = {
8166 .name = "msm-dai-q6-tdm",
8167 .owner = THIS_MODULE,
8168 .of_match_table = msm_dai_q6_tdm_dev_dt_match,
8169 },
8170};
8171
8172static int __init msm_dai_q6_init(void)
8173{
8174 int rc;
8175
8176 rc = platform_driver_register(&msm_auxpcm_dev_driver);
8177 if (rc) {
8178 pr_err("%s: fail to register auxpcm dev driver", __func__);
8179 goto fail;
8180 }
8181
8182 rc = platform_driver_register(&msm_dai_q6);
8183 if (rc) {
8184 pr_err("%s: fail to register dai q6 driver", __func__);
8185 goto dai_q6_fail;
8186 }
8187
8188 rc = platform_driver_register(&msm_dai_q6_dev);
8189 if (rc) {
8190 pr_err("%s: fail to register dai q6 dev driver", __func__);
8191 goto dai_q6_dev_fail;
8192 }
8193
8194 rc = platform_driver_register(&msm_dai_q6_mi2s_driver);
8195 if (rc) {
8196 pr_err("%s: fail to register dai MI2S dev drv\n", __func__);
8197 goto dai_q6_mi2s_drv_fail;
8198 }
8199
8200 rc = platform_driver_register(&msm_dai_mi2s_q6);
8201 if (rc) {
8202 pr_err("%s: fail to register dai MI2S\n", __func__);
8203 goto dai_mi2s_q6_fail;
8204 }
8205
8206 rc = platform_driver_register(&msm_dai_q6_spdif_driver);
8207 if (rc) {
8208 pr_err("%s: fail to register dai SPDIF\n", __func__);
8209 goto dai_spdif_q6_fail;
8210 }
8211
8212 rc = platform_driver_register(&msm_dai_q6_tdm_driver);
8213 if (rc) {
8214 pr_err("%s: fail to register dai TDM dev drv\n", __func__);
8215 goto dai_q6_tdm_drv_fail;
8216 }
8217
8218 rc = platform_driver_register(&msm_dai_tdm_q6);
8219 if (rc) {
8220 pr_err("%s: fail to register dai TDM\n", __func__);
8221 goto dai_tdm_q6_fail;
8222 }
8223 return rc;
8224
8225dai_tdm_q6_fail:
8226 platform_driver_unregister(&msm_dai_q6_tdm_driver);
8227dai_q6_tdm_drv_fail:
8228 platform_driver_unregister(&msm_dai_q6_spdif_driver);
8229dai_spdif_q6_fail:
8230 platform_driver_unregister(&msm_dai_mi2s_q6);
8231dai_mi2s_q6_fail:
8232 platform_driver_unregister(&msm_dai_q6_mi2s_driver);
8233dai_q6_mi2s_drv_fail:
8234 platform_driver_unregister(&msm_dai_q6_dev);
8235dai_q6_dev_fail:
8236 platform_driver_unregister(&msm_dai_q6);
8237dai_q6_fail:
8238 platform_driver_unregister(&msm_auxpcm_dev_driver);
8239fail:
8240 return rc;
8241}
8242module_init(msm_dai_q6_init);
8243
8244static void __exit msm_dai_q6_exit(void)
8245{
8246 platform_driver_unregister(&msm_dai_q6_dev);
8247 platform_driver_unregister(&msm_dai_q6);
8248 platform_driver_unregister(&msm_auxpcm_dev_driver);
8249 platform_driver_unregister(&msm_dai_q6_spdif_driver);
8250}
8251module_exit(msm_dai_q6_exit);
8252
8253/* Module information */
8254MODULE_DESCRIPTION("MSM DSP DAI driver");
8255MODULE_LICENSE("GPL v2");