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