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