blob: 53622e0854650fde295266b3322f838fd9505a8d [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
2422
2423static const struct snd_kcontrol_new afe_enc_config_controls[] = {
2424 {
2425 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
2426 SNDRV_CTL_ELEM_ACCESS_INACTIVE),
2427 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2428 .name = "SLIM_7_RX Encoder Config",
2429 .info = msm_dai_q6_afe_enc_cfg_info,
2430 .get = msm_dai_q6_afe_enc_cfg_get,
2431 .put = msm_dai_q6_afe_enc_cfg_put,
2432 },
2433 SOC_ENUM_EXT("AFE Input Channels", afe_input_chs_enum[0],
2434 msm_dai_q6_afe_input_channel_get,
2435 msm_dai_q6_afe_input_channel_put),
2436 SOC_ENUM_EXT("AFE Input Bit Format", afe_input_bit_format_enum[0],
2437 msm_dai_q6_afe_input_bit_format_get,
2438 msm_dai_q6_afe_input_bit_format_put),
2439};
2440
2441static int msm_dai_q6_slim_rx_drift_info(struct snd_kcontrol *kcontrol,
2442 struct snd_ctl_elem_info *uinfo)
2443{
2444 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
2445 uinfo->count = sizeof(struct afe_param_id_dev_timing_stats);
2446
2447 return 0;
2448}
2449
2450static int msm_dai_q6_slim_rx_drift_get(struct snd_kcontrol *kcontrol,
2451 struct snd_ctl_elem_value *ucontrol)
2452{
2453 int ret = -EINVAL;
2454 struct afe_param_id_dev_timing_stats timing_stats;
2455 struct snd_soc_dai *dai = kcontrol->private_data;
2456 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
2457
2458 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
2459 pr_err("%s: afe port not started. dai_data->status_mask = %ld\n",
2460 __func__, *dai_data->status_mask);
2461 goto done;
2462 }
2463
2464 memset(&timing_stats, 0, sizeof(struct afe_param_id_dev_timing_stats));
2465 ret = afe_get_av_dev_drift(&timing_stats, dai->id);
2466 if (ret) {
2467 pr_err("%s: Error getting AFE Drift for port %d, err=%d\n",
2468 __func__, dai->id, ret);
2469
2470 goto done;
2471 }
2472
2473 memcpy(ucontrol->value.bytes.data, (void *)&timing_stats,
2474 sizeof(struct afe_param_id_dev_timing_stats));
2475done:
2476 return ret;
2477}
2478
2479static const char * const afe_cal_mode_text[] = {
2480 "CAL_MODE_DEFAULT", "CAL_MODE_NONE"
2481};
2482
2483static const struct soc_enum slim_2_rx_enum =
2484 SOC_ENUM_SINGLE(SLIMBUS_2_RX, 0, ARRAY_SIZE(afe_cal_mode_text),
2485 afe_cal_mode_text);
2486
2487static const struct soc_enum rt_proxy_1_rx_enum =
2488 SOC_ENUM_SINGLE(RT_PROXY_PORT_001_RX, 0, ARRAY_SIZE(afe_cal_mode_text),
2489 afe_cal_mode_text);
2490
2491static const struct soc_enum rt_proxy_1_tx_enum =
2492 SOC_ENUM_SINGLE(RT_PROXY_PORT_001_TX, 0, ARRAY_SIZE(afe_cal_mode_text),
2493 afe_cal_mode_text);
2494
2495static const struct snd_kcontrol_new sb_config_controls[] = {
2496 SOC_ENUM_EXT("SLIM_4_TX Format", sb_config_enum[0],
2497 msm_dai_q6_sb_format_get,
2498 msm_dai_q6_sb_format_put),
2499 SOC_ENUM_EXT("SLIM_2_RX SetCalMode", slim_2_rx_enum,
2500 msm_dai_q6_cal_info_get,
2501 msm_dai_q6_cal_info_put),
2502 SOC_ENUM_EXT("SLIM_2_RX Format", sb_config_enum[0],
2503 msm_dai_q6_sb_format_get,
2504 msm_dai_q6_sb_format_put)
2505};
2506
2507static const struct snd_kcontrol_new rt_proxy_config_controls[] = {
2508 SOC_ENUM_EXT("RT_PROXY_1_RX SetCalMode", rt_proxy_1_rx_enum,
2509 msm_dai_q6_cal_info_get,
2510 msm_dai_q6_cal_info_put),
2511 SOC_ENUM_EXT("RT_PROXY_1_TX SetCalMode", rt_proxy_1_tx_enum,
2512 msm_dai_q6_cal_info_get,
2513 msm_dai_q6_cal_info_put),
2514};
2515
2516static const struct snd_kcontrol_new usb_audio_cfg_controls[] = {
2517 SOC_SINGLE_EXT("USB_AUDIO_RX dev_token", 0, 0, UINT_MAX, 0,
2518 msm_dai_q6_usb_audio_cfg_get,
2519 msm_dai_q6_usb_audio_cfg_put),
2520 SOC_SINGLE_EXT("USB_AUDIO_RX endian", 0, 0, 1, 0,
2521 msm_dai_q6_usb_audio_endian_cfg_get,
2522 msm_dai_q6_usb_audio_endian_cfg_put),
2523 SOC_SINGLE_EXT("USB_AUDIO_TX dev_token", 0, 0, UINT_MAX, 0,
2524 msm_dai_q6_usb_audio_cfg_get,
2525 msm_dai_q6_usb_audio_cfg_put),
2526 SOC_SINGLE_EXT("USB_AUDIO_TX endian", 0, 0, 1, 0,
2527 msm_dai_q6_usb_audio_endian_cfg_get,
2528 msm_dai_q6_usb_audio_endian_cfg_put),
2529};
2530
2531static const struct snd_kcontrol_new avd_drift_config_controls[] = {
2532 {
2533 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2534 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2535 .name = "SLIMBUS_0_RX DRIFT",
2536 .info = msm_dai_q6_slim_rx_drift_info,
2537 .get = msm_dai_q6_slim_rx_drift_get,
2538 },
2539 {
2540 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2541 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2542 .name = "SLIMBUS_6_RX DRIFT",
2543 .info = msm_dai_q6_slim_rx_drift_info,
2544 .get = msm_dai_q6_slim_rx_drift_get,
2545 },
2546 {
2547 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2548 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2549 .name = "SLIMBUS_7_RX DRIFT",
2550 .info = msm_dai_q6_slim_rx_drift_info,
2551 .get = msm_dai_q6_slim_rx_drift_get,
2552 },
2553};
2554static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai)
2555{
2556 struct msm_dai_q6_dai_data *dai_data;
2557 int rc = 0;
2558
2559 if (!dai) {
2560 pr_err("%s: Invalid params dai\n", __func__);
2561 return -EINVAL;
2562 }
2563 if (!dai->dev) {
2564 pr_err("%s: Invalid params dai dev\n", __func__);
2565 return -EINVAL;
2566 }
2567
2568 dai_data = kzalloc(sizeof(struct msm_dai_q6_dai_data), GFP_KERNEL);
2569
2570 if (!dai_data)
2571 rc = -ENOMEM;
2572 else
2573 dev_set_drvdata(dai->dev, dai_data);
2574
2575 msm_dai_q6_set_dai_id(dai);
2576
2577 switch (dai->id) {
2578 case SLIMBUS_4_TX:
2579 rc = snd_ctl_add(dai->component->card->snd_card,
2580 snd_ctl_new1(&sb_config_controls[0],
2581 dai_data));
2582 break;
2583 case SLIMBUS_2_RX:
2584 rc = snd_ctl_add(dai->component->card->snd_card,
2585 snd_ctl_new1(&sb_config_controls[1],
2586 dai_data));
2587 rc = snd_ctl_add(dai->component->card->snd_card,
2588 snd_ctl_new1(&sb_config_controls[2],
2589 dai_data));
2590 break;
2591 case SLIMBUS_7_RX:
2592 rc = snd_ctl_add(dai->component->card->snd_card,
2593 snd_ctl_new1(&afe_enc_config_controls[0],
2594 dai_data));
2595 rc = snd_ctl_add(dai->component->card->snd_card,
2596 snd_ctl_new1(&afe_enc_config_controls[1],
2597 dai_data));
2598 rc = snd_ctl_add(dai->component->card->snd_card,
2599 snd_ctl_new1(&afe_enc_config_controls[2],
2600 dai_data));
2601 rc = snd_ctl_add(dai->component->card->snd_card,
2602 snd_ctl_new1(&avd_drift_config_controls[2],
2603 dai));
2604 break;
2605 case RT_PROXY_DAI_001_RX:
2606 rc = snd_ctl_add(dai->component->card->snd_card,
2607 snd_ctl_new1(&rt_proxy_config_controls[0],
2608 dai_data));
2609 break;
2610 case RT_PROXY_DAI_001_TX:
2611 rc = snd_ctl_add(dai->component->card->snd_card,
2612 snd_ctl_new1(&rt_proxy_config_controls[1],
2613 dai_data));
2614 break;
2615 case AFE_PORT_ID_USB_RX:
2616 rc = snd_ctl_add(dai->component->card->snd_card,
2617 snd_ctl_new1(&usb_audio_cfg_controls[0],
2618 dai_data));
2619 rc = snd_ctl_add(dai->component->card->snd_card,
2620 snd_ctl_new1(&usb_audio_cfg_controls[1],
2621 dai_data));
2622 break;
2623 case AFE_PORT_ID_USB_TX:
2624 rc = snd_ctl_add(dai->component->card->snd_card,
2625 snd_ctl_new1(&usb_audio_cfg_controls[2],
2626 dai_data));
2627 rc = snd_ctl_add(dai->component->card->snd_card,
2628 snd_ctl_new1(&usb_audio_cfg_controls[3],
2629 dai_data));
2630 break;
2631 case SLIMBUS_0_RX:
2632 rc = snd_ctl_add(dai->component->card->snd_card,
2633 snd_ctl_new1(&avd_drift_config_controls[0],
2634 dai));
2635 break;
2636 case SLIMBUS_6_RX:
2637 rc = snd_ctl_add(dai->component->card->snd_card,
2638 snd_ctl_new1(&avd_drift_config_controls[1],
2639 dai));
2640 break;
2641 }
2642 if (rc < 0)
2643 dev_err(dai->dev, "%s: err add config ctl, DAI = %s\n",
2644 __func__, dai->name);
2645
2646 rc = msm_dai_q6_dai_add_route(dai);
2647 return rc;
2648}
2649
2650static int msm_dai_q6_dai_remove(struct snd_soc_dai *dai)
2651{
2652 struct msm_dai_q6_dai_data *dai_data;
2653 int rc;
2654
2655 dai_data = dev_get_drvdata(dai->dev);
2656
2657 /* If AFE port is still up, close it */
2658 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
2659 pr_debug("%s: stop pseudo port:%d\n", __func__, dai->id);
2660 rc = afe_close(dai->id); /* can block */
2661 if (rc < 0)
2662 dev_err(dai->dev, "fail to close AFE port\n");
2663 clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
2664 }
2665 kfree(dai_data);
2666
2667 return 0;
2668}
2669
2670static struct snd_soc_dai_driver msm_dai_q6_afe_rx_dai[] = {
2671 {
2672 .playback = {
2673 .stream_name = "AFE Playback",
2674 .aif_name = "PCM_RX",
2675 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
2676 SNDRV_PCM_RATE_16000,
2677 .formats = SNDRV_PCM_FMTBIT_S16_LE |
2678 SNDRV_PCM_FMTBIT_S24_LE,
2679 .channels_min = 1,
2680 .channels_max = 2,
2681 .rate_min = 8000,
2682 .rate_max = 48000,
2683 },
2684 .ops = &msm_dai_q6_ops,
2685 .id = RT_PROXY_DAI_001_RX,
2686 .probe = msm_dai_q6_dai_probe,
2687 .remove = msm_dai_q6_dai_remove,
2688 },
2689 {
2690 .playback = {
2691 .stream_name = "AFE-PROXY RX",
2692 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
2693 SNDRV_PCM_RATE_16000,
2694 .formats = SNDRV_PCM_FMTBIT_S16_LE |
2695 SNDRV_PCM_FMTBIT_S24_LE,
2696 .channels_min = 1,
2697 .channels_max = 2,
2698 .rate_min = 8000,
2699 .rate_max = 48000,
2700 },
2701 .ops = &msm_dai_q6_ops,
2702 .id = RT_PROXY_DAI_002_RX,
2703 .probe = msm_dai_q6_dai_probe,
2704 .remove = msm_dai_q6_dai_remove,
2705 },
2706};
2707
2708static struct snd_soc_dai_driver msm_dai_q6_afe_tx_dai[] = {
2709 {
2710 .capture = {
2711 .stream_name = "AFE Capture",
2712 .aif_name = "PCM_TX",
2713 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
2714 SNDRV_PCM_RATE_16000,
2715 .formats = SNDRV_PCM_FMTBIT_S16_LE,
2716 .channels_min = 1,
2717 .channels_max = 8,
2718 .rate_min = 8000,
2719 .rate_max = 48000,
2720 },
2721 .ops = &msm_dai_q6_ops,
2722 .id = RT_PROXY_DAI_002_TX,
2723 .probe = msm_dai_q6_dai_probe,
2724 .remove = msm_dai_q6_dai_remove,
2725 },
2726 {
2727 .capture = {
2728 .stream_name = "AFE-PROXY TX",
2729 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
2730 SNDRV_PCM_RATE_16000,
2731 .formats = SNDRV_PCM_FMTBIT_S16_LE,
2732 .channels_min = 1,
2733 .channels_max = 8,
2734 .rate_min = 8000,
2735 .rate_max = 48000,
2736 },
2737 .ops = &msm_dai_q6_ops,
2738 .id = RT_PROXY_DAI_001_TX,
2739 .probe = msm_dai_q6_dai_probe,
2740 .remove = msm_dai_q6_dai_remove,
2741 },
2742};
2743
2744static struct snd_soc_dai_driver msm_dai_q6_bt_sco_rx_dai = {
2745 .playback = {
2746 .stream_name = "Internal BT-SCO Playback",
2747 .aif_name = "INT_BT_SCO_RX",
2748 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
2749 .formats = SNDRV_PCM_FMTBIT_S16_LE,
2750 .channels_min = 1,
2751 .channels_max = 1,
2752 .rate_max = 16000,
2753 .rate_min = 8000,
2754 },
2755 .ops = &msm_dai_q6_ops,
2756 .id = INT_BT_SCO_RX,
2757 .probe = msm_dai_q6_dai_probe,
2758 .remove = msm_dai_q6_dai_remove,
2759};
2760
2761static struct snd_soc_dai_driver msm_dai_q6_bt_a2dp_rx_dai = {
2762 .playback = {
2763 .stream_name = "Internal BT-A2DP Playback",
2764 .aif_name = "INT_BT_A2DP_RX",
2765 .rates = SNDRV_PCM_RATE_48000,
2766 .formats = SNDRV_PCM_FMTBIT_S16_LE,
2767 .channels_min = 1,
2768 .channels_max = 2,
2769 .rate_max = 48000,
2770 .rate_min = 48000,
2771 },
2772 .ops = &msm_dai_q6_ops,
2773 .id = INT_BT_A2DP_RX,
2774 .probe = msm_dai_q6_dai_probe,
2775 .remove = msm_dai_q6_dai_remove,
2776};
2777
2778static struct snd_soc_dai_driver msm_dai_q6_bt_sco_tx_dai = {
2779 .capture = {
2780 .stream_name = "Internal BT-SCO Capture",
2781 .aif_name = "INT_BT_SCO_TX",
2782 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
2783 .formats = SNDRV_PCM_FMTBIT_S16_LE,
2784 .channels_min = 1,
2785 .channels_max = 1,
2786 .rate_max = 16000,
2787 .rate_min = 8000,
2788 },
2789 .ops = &msm_dai_q6_ops,
2790 .id = INT_BT_SCO_TX,
2791 .probe = msm_dai_q6_dai_probe,
2792 .remove = msm_dai_q6_dai_remove,
2793};
2794
2795static struct snd_soc_dai_driver msm_dai_q6_fm_rx_dai = {
2796 .playback = {
2797 .stream_name = "Internal FM Playback",
2798 .aif_name = "INT_FM_RX",
2799 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
2800 SNDRV_PCM_RATE_16000,
2801 .formats = SNDRV_PCM_FMTBIT_S16_LE,
2802 .channels_min = 2,
2803 .channels_max = 2,
2804 .rate_max = 48000,
2805 .rate_min = 8000,
2806 },
2807 .ops = &msm_dai_q6_ops,
2808 .id = INT_FM_RX,
2809 .probe = msm_dai_q6_dai_probe,
2810 .remove = msm_dai_q6_dai_remove,
2811};
2812
2813static struct snd_soc_dai_driver msm_dai_q6_fm_tx_dai = {
2814 .capture = {
2815 .stream_name = "Internal FM Capture",
2816 .aif_name = "INT_FM_TX",
2817 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
2818 SNDRV_PCM_RATE_16000,
2819 .formats = SNDRV_PCM_FMTBIT_S16_LE,
2820 .channels_min = 2,
2821 .channels_max = 2,
2822 .rate_max = 48000,
2823 .rate_min = 8000,
2824 },
2825 .ops = &msm_dai_q6_ops,
2826 .id = INT_FM_TX,
2827 .probe = msm_dai_q6_dai_probe,
2828 .remove = msm_dai_q6_dai_remove,
2829};
2830
2831static struct snd_soc_dai_driver msm_dai_q6_voc_playback_dai[] = {
2832 {
2833 .playback = {
2834 .stream_name = "Voice Farend Playback",
2835 .aif_name = "VOICE_PLAYBACK_TX",
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 = 1,
2840 .channels_max = 2,
2841 .rate_min = 8000,
2842 .rate_max = 48000,
2843 },
2844 .ops = &msm_dai_q6_ops,
2845 .id = VOICE_PLAYBACK_TX,
2846 .probe = msm_dai_q6_dai_probe,
2847 .remove = msm_dai_q6_dai_remove,
2848 },
2849 {
2850 .playback = {
2851 .stream_name = "Voice2 Farend Playback",
2852 .aif_name = "VOICE2_PLAYBACK_TX",
2853 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
2854 SNDRV_PCM_RATE_16000,
2855 .formats = SNDRV_PCM_FMTBIT_S16_LE,
2856 .channels_min = 1,
2857 .channels_max = 2,
2858 .rate_min = 8000,
2859 .rate_max = 48000,
2860 },
2861 .ops = &msm_dai_q6_ops,
2862 .id = VOICE2_PLAYBACK_TX,
2863 .probe = msm_dai_q6_dai_probe,
2864 .remove = msm_dai_q6_dai_remove,
2865 },
2866};
2867
2868static struct snd_soc_dai_driver msm_dai_q6_incall_record_dai[] = {
2869 {
2870 .capture = {
2871 .stream_name = "Voice Uplink Capture",
2872 .aif_name = "INCALL_RECORD_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_RECORD_TX,
2883 .probe = msm_dai_q6_dai_probe,
2884 .remove = msm_dai_q6_dai_remove,
2885 },
2886 {
2887 .capture = {
2888 .stream_name = "Voice Downlink Capture",
2889 .aif_name = "INCALL_RECORD_RX",
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 = VOICE_RECORD_RX,
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_usb_rx_dai = {
2906 .playback = {
2907 .stream_name = "USB Audio Playback",
2908 .aif_name = "USB_AUDIO_RX",
2909 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
2910 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
2911 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
2912 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
2913 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
2914 SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 |
2915 SNDRV_PCM_RATE_384000,
2916 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
2917 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE,
2918 .channels_min = 1,
2919 .channels_max = 8,
2920 .rate_max = 384000,
2921 .rate_min = 8000,
2922 },
2923 .ops = &msm_dai_q6_ops,
2924 .id = AFE_PORT_ID_USB_RX,
2925 .probe = msm_dai_q6_dai_probe,
2926 .remove = msm_dai_q6_dai_remove,
2927};
2928
2929static struct snd_soc_dai_driver msm_dai_q6_usb_tx_dai = {
2930 .capture = {
2931 .stream_name = "USB Audio Capture",
2932 .aif_name = "USB_AUDIO_TX",
2933 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
2934 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
2935 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
2936 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
2937 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
2938 SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 |
2939 SNDRV_PCM_RATE_384000,
2940 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
2941 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE,
2942 .channels_min = 1,
2943 .channels_max = 8,
2944 .rate_max = 384000,
2945 .rate_min = 8000,
2946 },
2947 .ops = &msm_dai_q6_ops,
2948 .id = AFE_PORT_ID_USB_TX,
2949 .probe = msm_dai_q6_dai_probe,
2950 .remove = msm_dai_q6_dai_remove,
2951};
2952
2953static int msm_auxpcm_dev_probe(struct platform_device *pdev)
2954{
2955 struct msm_dai_q6_auxpcm_dai_data *dai_data;
2956 struct msm_dai_auxpcm_pdata *auxpcm_pdata;
2957 uint32_t val_array[RATE_MAX_NUM_OF_AUX_PCM_RATES];
2958 uint32_t val = 0;
2959 const char *intf_name;
2960 int rc = 0, i = 0, len = 0;
2961 const uint32_t *slot_mapping_array = NULL;
2962 u32 array_length = 0;
2963
2964 dai_data = kzalloc(sizeof(struct msm_dai_q6_auxpcm_dai_data),
2965 GFP_KERNEL);
2966 if (!dai_data)
2967 return -ENOMEM;
2968
2969 auxpcm_pdata = kzalloc(sizeof(struct msm_dai_auxpcm_pdata),
2970 GFP_KERNEL);
2971
2972 if (!auxpcm_pdata) {
2973 dev_err(&pdev->dev, "Failed to allocate memory for platform data\n");
2974 goto fail_pdata_nomem;
2975 }
2976
2977 dev_dbg(&pdev->dev, "%s: dev %pK, dai_data %pK, auxpcm_pdata %pK\n",
2978 __func__, &pdev->dev, dai_data, auxpcm_pdata);
2979
2980 rc = of_property_read_u32_array(pdev->dev.of_node,
2981 "qcom,msm-cpudai-auxpcm-mode",
2982 val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
2983 if (rc) {
2984 dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-mode missing in DT node\n",
2985 __func__);
2986 goto fail_invalid_dt;
2987 }
2988 auxpcm_pdata->mode_8k.mode = (u16)val_array[RATE_8KHZ];
2989 auxpcm_pdata->mode_16k.mode = (u16)val_array[RATE_16KHZ];
2990
2991 rc = of_property_read_u32_array(pdev->dev.of_node,
2992 "qcom,msm-cpudai-auxpcm-sync",
2993 val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
2994 if (rc) {
2995 dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-sync missing in DT node\n",
2996 __func__);
2997 goto fail_invalid_dt;
2998 }
2999 auxpcm_pdata->mode_8k.sync = (u16)val_array[RATE_8KHZ];
3000 auxpcm_pdata->mode_16k.sync = (u16)val_array[RATE_16KHZ];
3001
3002 rc = of_property_read_u32_array(pdev->dev.of_node,
3003 "qcom,msm-cpudai-auxpcm-frame",
3004 val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
3005
3006 if (rc) {
3007 dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-frame missing in DT node\n",
3008 __func__);
3009 goto fail_invalid_dt;
3010 }
3011 auxpcm_pdata->mode_8k.frame = (u16)val_array[RATE_8KHZ];
3012 auxpcm_pdata->mode_16k.frame = (u16)val_array[RATE_16KHZ];
3013
3014 rc = of_property_read_u32_array(pdev->dev.of_node,
3015 "qcom,msm-cpudai-auxpcm-quant",
3016 val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
3017 if (rc) {
3018 dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-quant missing in DT node\n",
3019 __func__);
3020 goto fail_invalid_dt;
3021 }
3022 auxpcm_pdata->mode_8k.quant = (u16)val_array[RATE_8KHZ];
3023 auxpcm_pdata->mode_16k.quant = (u16)val_array[RATE_16KHZ];
3024
3025 rc = of_property_read_u32_array(pdev->dev.of_node,
3026 "qcom,msm-cpudai-auxpcm-num-slots",
3027 val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
3028 if (rc) {
3029 dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-num-slots missing in DT node\n",
3030 __func__);
3031 goto fail_invalid_dt;
3032 }
3033 auxpcm_pdata->mode_8k.num_slots = (u16)val_array[RATE_8KHZ];
3034
3035 if (auxpcm_pdata->mode_8k.num_slots >
3036 msm_dai_q6_max_num_slot(auxpcm_pdata->mode_8k.frame)) {
3037 dev_err(&pdev->dev, "%s Max slots %d greater than DT node %d\n",
3038 __func__,
3039 msm_dai_q6_max_num_slot(auxpcm_pdata->mode_8k.frame),
3040 auxpcm_pdata->mode_8k.num_slots);
3041 rc = -EINVAL;
3042 goto fail_invalid_dt;
3043 }
3044 auxpcm_pdata->mode_16k.num_slots = (u16)val_array[RATE_16KHZ];
3045
3046 if (auxpcm_pdata->mode_16k.num_slots >
3047 msm_dai_q6_max_num_slot(auxpcm_pdata->mode_16k.frame)) {
3048 dev_err(&pdev->dev, "%s Max slots %d greater than DT node %d\n",
3049 __func__,
3050 msm_dai_q6_max_num_slot(auxpcm_pdata->mode_16k.frame),
3051 auxpcm_pdata->mode_16k.num_slots);
3052 rc = -EINVAL;
3053 goto fail_invalid_dt;
3054 }
3055
3056 slot_mapping_array = of_get_property(pdev->dev.of_node,
3057 "qcom,msm-cpudai-auxpcm-slot-mapping", &len);
3058
3059 if (slot_mapping_array == NULL) {
3060 dev_err(&pdev->dev, "%s slot_mapping_array is not valid\n",
3061 __func__);
3062 rc = -EINVAL;
3063 goto fail_invalid_dt;
3064 }
3065
3066 array_length = auxpcm_pdata->mode_8k.num_slots +
3067 auxpcm_pdata->mode_16k.num_slots;
3068
3069 if (len != sizeof(uint32_t) * array_length) {
3070 dev_err(&pdev->dev, "%s Length is %d and expected is %zd\n",
3071 __func__, len, sizeof(uint32_t) * array_length);
3072 rc = -EINVAL;
3073 goto fail_invalid_dt;
3074 }
3075
3076 auxpcm_pdata->mode_8k.slot_mapping =
3077 kzalloc(sizeof(uint16_t) *
3078 auxpcm_pdata->mode_8k.num_slots,
3079 GFP_KERNEL);
3080 if (!auxpcm_pdata->mode_8k.slot_mapping) {
3081 dev_err(&pdev->dev, "%s No mem for mode_8k slot mapping\n",
3082 __func__);
3083 rc = -ENOMEM;
3084 goto fail_invalid_dt;
3085 }
3086
3087 for (i = 0; i < auxpcm_pdata->mode_8k.num_slots; i++)
3088 auxpcm_pdata->mode_8k.slot_mapping[i] =
3089 (u16)be32_to_cpu(slot_mapping_array[i]);
3090
3091 auxpcm_pdata->mode_16k.slot_mapping =
3092 kzalloc(sizeof(uint16_t) *
3093 auxpcm_pdata->mode_16k.num_slots,
3094 GFP_KERNEL);
3095
3096 if (!auxpcm_pdata->mode_16k.slot_mapping) {
3097 dev_err(&pdev->dev, "%s No mem for mode_16k slot mapping\n",
3098 __func__);
3099 rc = -ENOMEM;
3100 goto fail_invalid_16k_slot_mapping;
3101 }
3102
3103 for (i = 0; i < auxpcm_pdata->mode_16k.num_slots; i++)
3104 auxpcm_pdata->mode_16k.slot_mapping[i] =
3105 (u16)be32_to_cpu(slot_mapping_array[i +
3106 auxpcm_pdata->mode_8k.num_slots]);
3107
3108 rc = of_property_read_u32_array(pdev->dev.of_node,
3109 "qcom,msm-cpudai-auxpcm-data",
3110 val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
3111 if (rc) {
3112 dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-data missing in DT node\n",
3113 __func__);
3114 goto fail_invalid_dt1;
3115 }
3116 auxpcm_pdata->mode_8k.data = (u16)val_array[RATE_8KHZ];
3117 auxpcm_pdata->mode_16k.data = (u16)val_array[RATE_16KHZ];
3118
3119 rc = of_property_read_u32_array(pdev->dev.of_node,
3120 "qcom,msm-cpudai-auxpcm-pcm-clk-rate",
3121 val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
3122 if (rc) {
3123 dev_err(&pdev->dev,
3124 "%s: qcom,msm-cpudai-auxpcm-pcm-clk-rate missing in DT\n",
3125 __func__);
3126 goto fail_invalid_dt1;
3127 }
3128 auxpcm_pdata->mode_8k.pcm_clk_rate = (int)val_array[RATE_8KHZ];
3129 auxpcm_pdata->mode_16k.pcm_clk_rate = (int)val_array[RATE_16KHZ];
3130
3131 rc = of_property_read_string(pdev->dev.of_node,
3132 "qcom,msm-auxpcm-interface", &intf_name);
3133 if (rc) {
3134 dev_err(&pdev->dev,
3135 "%s: qcom,msm-auxpcm-interface missing in DT node\n",
3136 __func__);
3137 goto fail_nodev_intf;
3138 }
3139
3140 if (!strcmp(intf_name, "primary")) {
3141 dai_data->rx_pid = AFE_PORT_ID_PRIMARY_PCM_RX;
3142 dai_data->tx_pid = AFE_PORT_ID_PRIMARY_PCM_TX;
3143 pdev->id = MSM_DAI_PRI_AUXPCM_DT_DEV_ID;
3144 i = 0;
3145 } else if (!strcmp(intf_name, "secondary")) {
3146 dai_data->rx_pid = AFE_PORT_ID_SECONDARY_PCM_RX;
3147 dai_data->tx_pid = AFE_PORT_ID_SECONDARY_PCM_TX;
3148 pdev->id = MSM_DAI_SEC_AUXPCM_DT_DEV_ID;
3149 i = 1;
3150 } else if (!strcmp(intf_name, "tertiary")) {
3151 dai_data->rx_pid = AFE_PORT_ID_TERTIARY_PCM_RX;
3152 dai_data->tx_pid = AFE_PORT_ID_TERTIARY_PCM_TX;
3153 pdev->id = MSM_DAI_TERT_AUXPCM_DT_DEV_ID;
3154 i = 2;
3155 } else if (!strcmp(intf_name, "quaternary")) {
3156 dai_data->rx_pid = AFE_PORT_ID_QUATERNARY_PCM_RX;
3157 dai_data->tx_pid = AFE_PORT_ID_QUATERNARY_PCM_TX;
3158 pdev->id = MSM_DAI_QUAT_AUXPCM_DT_DEV_ID;
3159 i = 3;
Rohit Kumara5077932017-09-10 22:05:05 +05303160 } else if (!strcmp(intf_name, "quinary")) {
3161 dai_data->rx_pid = AFE_PORT_ID_QUINARY_PCM_RX;
3162 dai_data->tx_pid = AFE_PORT_ID_QUINARY_PCM_TX;
3163 pdev->id = MSM_DAI_QUIN_AUXPCM_DT_DEV_ID;
3164 i = 4;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303165 } else {
3166 dev_err(&pdev->dev, "%s: invalid DT intf name %s\n",
3167 __func__, intf_name);
3168 goto fail_invalid_intf;
3169 }
3170 rc = of_property_read_u32(pdev->dev.of_node,
3171 "qcom,msm-cpudai-afe-clk-ver", &val);
3172 if (rc)
3173 dai_data->afe_clk_ver = AFE_CLK_VERSION_V1;
3174 else
3175 dai_data->afe_clk_ver = val;
3176
3177 mutex_init(&dai_data->rlock);
3178 dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));
3179
3180 dev_set_drvdata(&pdev->dev, dai_data);
3181 pdev->dev.platform_data = (void *) auxpcm_pdata;
3182
3183 rc = snd_soc_register_component(&pdev->dev,
3184 &msm_dai_q6_aux_pcm_dai_component,
3185 &msm_dai_q6_aux_pcm_dai[i], 1);
3186 if (rc) {
3187 dev_err(&pdev->dev, "%s: auxpcm dai reg failed, rc=%d\n",
3188 __func__, rc);
3189 goto fail_reg_dai;
3190 }
3191
3192 return rc;
3193
3194fail_reg_dai:
3195fail_invalid_intf:
3196fail_nodev_intf:
3197fail_invalid_dt1:
3198 kfree(auxpcm_pdata->mode_16k.slot_mapping);
3199fail_invalid_16k_slot_mapping:
3200 kfree(auxpcm_pdata->mode_8k.slot_mapping);
3201fail_invalid_dt:
3202 kfree(auxpcm_pdata);
3203fail_pdata_nomem:
3204 kfree(dai_data);
3205 return rc;
3206}
3207
3208static int msm_auxpcm_dev_remove(struct platform_device *pdev)
3209{
3210 struct msm_dai_q6_auxpcm_dai_data *dai_data;
3211
3212 dai_data = dev_get_drvdata(&pdev->dev);
3213
3214 snd_soc_unregister_component(&pdev->dev);
3215
3216 mutex_destroy(&dai_data->rlock);
3217 kfree(dai_data);
3218 kfree(pdev->dev.platform_data);
3219
3220 return 0;
3221}
3222
3223static const struct of_device_id msm_auxpcm_dev_dt_match[] = {
3224 { .compatible = "qcom,msm-auxpcm-dev", },
3225 {}
3226};
3227
3228
3229static struct platform_driver msm_auxpcm_dev_driver = {
3230 .probe = msm_auxpcm_dev_probe,
3231 .remove = msm_auxpcm_dev_remove,
3232 .driver = {
3233 .name = "msm-auxpcm-dev",
3234 .owner = THIS_MODULE,
3235 .of_match_table = msm_auxpcm_dev_dt_match,
3236 },
3237};
3238
3239static struct snd_soc_dai_driver msm_dai_q6_slimbus_rx_dai[] = {
3240 {
3241 .playback = {
3242 .stream_name = "Slimbus Playback",
3243 .aif_name = "SLIMBUS_0_RX",
3244 .rates = SNDRV_PCM_RATE_8000_384000,
3245 .formats = DAI_FORMATS_S16_S24_S32_LE,
3246 .channels_min = 1,
3247 .channels_max = 8,
3248 .rate_min = 8000,
3249 .rate_max = 384000,
3250 },
3251 .ops = &msm_dai_q6_ops,
3252 .id = SLIMBUS_0_RX,
3253 .probe = msm_dai_q6_dai_probe,
3254 .remove = msm_dai_q6_dai_remove,
3255 },
3256 {
3257 .playback = {
3258 .stream_name = "Slimbus1 Playback",
3259 .aif_name = "SLIMBUS_1_RX",
3260 .rates = SNDRV_PCM_RATE_8000_384000,
3261 .formats = DAI_FORMATS_S16_S24_S32_LE,
3262 .channels_min = 1,
3263 .channels_max = 2,
3264 .rate_min = 8000,
3265 .rate_max = 384000,
3266 },
3267 .ops = &msm_dai_q6_ops,
3268 .id = SLIMBUS_1_RX,
3269 .probe = msm_dai_q6_dai_probe,
3270 .remove = msm_dai_q6_dai_remove,
3271 },
3272 {
3273 .playback = {
3274 .stream_name = "Slimbus2 Playback",
3275 .aif_name = "SLIMBUS_2_RX",
3276 .rates = SNDRV_PCM_RATE_8000_384000,
3277 .formats = DAI_FORMATS_S16_S24_S32_LE,
3278 .channels_min = 1,
3279 .channels_max = 8,
3280 .rate_min = 8000,
3281 .rate_max = 384000,
3282 },
3283 .ops = &msm_dai_q6_ops,
3284 .id = SLIMBUS_2_RX,
3285 .probe = msm_dai_q6_dai_probe,
3286 .remove = msm_dai_q6_dai_remove,
3287 },
3288 {
3289 .playback = {
3290 .stream_name = "Slimbus3 Playback",
3291 .aif_name = "SLIMBUS_3_RX",
3292 .rates = SNDRV_PCM_RATE_8000_384000,
3293 .formats = DAI_FORMATS_S16_S24_S32_LE,
3294 .channels_min = 1,
3295 .channels_max = 2,
3296 .rate_min = 8000,
3297 .rate_max = 384000,
3298 },
3299 .ops = &msm_dai_q6_ops,
3300 .id = SLIMBUS_3_RX,
3301 .probe = msm_dai_q6_dai_probe,
3302 .remove = msm_dai_q6_dai_remove,
3303 },
3304 {
3305 .playback = {
3306 .stream_name = "Slimbus4 Playback",
3307 .aif_name = "SLIMBUS_4_RX",
3308 .rates = SNDRV_PCM_RATE_8000_384000,
3309 .formats = DAI_FORMATS_S16_S24_S32_LE,
3310 .channels_min = 1,
3311 .channels_max = 2,
3312 .rate_min = 8000,
3313 .rate_max = 384000,
3314 },
3315 .ops = &msm_dai_q6_ops,
3316 .id = SLIMBUS_4_RX,
3317 .probe = msm_dai_q6_dai_probe,
3318 .remove = msm_dai_q6_dai_remove,
3319 },
3320 {
3321 .playback = {
3322 .stream_name = "Slimbus6 Playback",
3323 .aif_name = "SLIMBUS_6_RX",
3324 .rates = SNDRV_PCM_RATE_8000_384000,
3325 .formats = DAI_FORMATS_S16_S24_S32_LE,
3326 .channels_min = 1,
3327 .channels_max = 2,
3328 .rate_min = 8000,
3329 .rate_max = 384000,
3330 },
3331 .ops = &msm_dai_q6_ops,
3332 .id = SLIMBUS_6_RX,
3333 .probe = msm_dai_q6_dai_probe,
3334 .remove = msm_dai_q6_dai_remove,
3335 },
3336 {
3337 .playback = {
3338 .stream_name = "Slimbus5 Playback",
3339 .aif_name = "SLIMBUS_5_RX",
3340 .rates = SNDRV_PCM_RATE_8000_384000,
3341 .formats = DAI_FORMATS_S16_S24_S32_LE,
3342 .channels_min = 1,
3343 .channels_max = 2,
3344 .rate_min = 8000,
3345 .rate_max = 384000,
3346 },
3347 .ops = &msm_dai_q6_ops,
3348 .id = SLIMBUS_5_RX,
3349 .probe = msm_dai_q6_dai_probe,
3350 .remove = msm_dai_q6_dai_remove,
3351 },
3352 {
3353 .playback = {
3354 .stream_name = "Slimbus7 Playback",
3355 .aif_name = "SLIMBUS_7_RX",
3356 .rates = SNDRV_PCM_RATE_8000_384000,
3357 .formats = DAI_FORMATS_S16_S24_S32_LE,
3358 .channels_min = 1,
3359 .channels_max = 8,
3360 .rate_min = 8000,
3361 .rate_max = 384000,
3362 },
3363 .ops = &msm_dai_q6_ops,
3364 .id = SLIMBUS_7_RX,
3365 .probe = msm_dai_q6_dai_probe,
3366 .remove = msm_dai_q6_dai_remove,
3367 },
3368 {
3369 .playback = {
3370 .stream_name = "Slimbus8 Playback",
3371 .aif_name = "SLIMBUS_8_RX",
3372 .rates = SNDRV_PCM_RATE_8000_384000,
3373 .formats = DAI_FORMATS_S16_S24_S32_LE,
3374 .channels_min = 1,
3375 .channels_max = 8,
3376 .rate_min = 8000,
3377 .rate_max = 384000,
3378 },
3379 .ops = &msm_dai_q6_ops,
3380 .id = SLIMBUS_8_RX,
3381 .probe = msm_dai_q6_dai_probe,
3382 .remove = msm_dai_q6_dai_remove,
3383 },
3384};
3385
3386static struct snd_soc_dai_driver msm_dai_q6_slimbus_tx_dai[] = {
3387 {
3388 .capture = {
3389 .stream_name = "Slimbus Capture",
3390 .aif_name = "SLIMBUS_0_TX",
3391 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
3392 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
3393 SNDRV_PCM_RATE_192000,
3394 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3395 SNDRV_PCM_FMTBIT_S24_LE |
3396 SNDRV_PCM_FMTBIT_S24_3LE,
3397 .channels_min = 1,
3398 .channels_max = 8,
3399 .rate_min = 8000,
3400 .rate_max = 192000,
3401 },
3402 .ops = &msm_dai_q6_ops,
3403 .id = SLIMBUS_0_TX,
3404 .probe = msm_dai_q6_dai_probe,
3405 .remove = msm_dai_q6_dai_remove,
3406 },
3407 {
3408 .capture = {
3409 .stream_name = "Slimbus1 Capture",
3410 .aif_name = "SLIMBUS_1_TX",
3411 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
3412 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
3413 SNDRV_PCM_RATE_192000,
3414 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3415 SNDRV_PCM_FMTBIT_S24_LE |
3416 SNDRV_PCM_FMTBIT_S24_3LE,
3417 .channels_min = 1,
3418 .channels_max = 2,
3419 .rate_min = 8000,
3420 .rate_max = 192000,
3421 },
3422 .ops = &msm_dai_q6_ops,
3423 .id = SLIMBUS_1_TX,
3424 .probe = msm_dai_q6_dai_probe,
3425 .remove = msm_dai_q6_dai_remove,
3426 },
3427 {
3428 .capture = {
3429 .stream_name = "Slimbus2 Capture",
3430 .aif_name = "SLIMBUS_2_TX",
3431 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
3432 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
3433 SNDRV_PCM_RATE_192000,
3434 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3435 SNDRV_PCM_FMTBIT_S24_LE,
3436 .channels_min = 1,
3437 .channels_max = 8,
3438 .rate_min = 8000,
3439 .rate_max = 192000,
3440 },
3441 .ops = &msm_dai_q6_ops,
3442 .id = SLIMBUS_2_TX,
3443 .probe = msm_dai_q6_dai_probe,
3444 .remove = msm_dai_q6_dai_remove,
3445 },
3446 {
3447 .capture = {
3448 .stream_name = "Slimbus3 Capture",
3449 .aif_name = "SLIMBUS_3_TX",
3450 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
3451 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
3452 SNDRV_PCM_RATE_192000,
3453 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3454 SNDRV_PCM_FMTBIT_S24_LE,
3455 .channels_min = 2,
3456 .channels_max = 4,
3457 .rate_min = 8000,
3458 .rate_max = 192000,
3459 },
3460 .ops = &msm_dai_q6_ops,
3461 .id = SLIMBUS_3_TX,
3462 .probe = msm_dai_q6_dai_probe,
3463 .remove = msm_dai_q6_dai_remove,
3464 },
3465 {
3466 .capture = {
3467 .stream_name = "Slimbus4 Capture",
3468 .aif_name = "SLIMBUS_4_TX",
3469 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
3470 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
3471 SNDRV_PCM_RATE_192000,
3472 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3473 SNDRV_PCM_FMTBIT_S24_LE |
3474 SNDRV_PCM_FMTBIT_S32_LE,
3475 .channels_min = 2,
3476 .channels_max = 4,
3477 .rate_min = 8000,
3478 .rate_max = 192000,
3479 },
3480 .ops = &msm_dai_q6_ops,
3481 .id = SLIMBUS_4_TX,
3482 .probe = msm_dai_q6_dai_probe,
3483 .remove = msm_dai_q6_dai_remove,
3484 },
3485 {
3486 .capture = {
3487 .stream_name = "Slimbus5 Capture",
3488 .aif_name = "SLIMBUS_5_TX",
3489 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
3490 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
3491 SNDRV_PCM_RATE_192000,
3492 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3493 SNDRV_PCM_FMTBIT_S24_LE,
3494 .channels_min = 1,
3495 .channels_max = 8,
3496 .rate_min = 8000,
3497 .rate_max = 192000,
3498 },
3499 .ops = &msm_dai_q6_ops,
3500 .id = SLIMBUS_5_TX,
3501 .probe = msm_dai_q6_dai_probe,
3502 .remove = msm_dai_q6_dai_remove,
3503 },
3504 {
3505 .capture = {
3506 .stream_name = "Slimbus6 Capture",
3507 .aif_name = "SLIMBUS_6_TX",
3508 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
3509 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
3510 SNDRV_PCM_RATE_192000,
3511 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3512 SNDRV_PCM_FMTBIT_S24_LE,
3513 .channels_min = 1,
3514 .channels_max = 2,
3515 .rate_min = 8000,
3516 .rate_max = 192000,
3517 },
3518 .ops = &msm_dai_q6_ops,
3519 .id = SLIMBUS_6_TX,
3520 .probe = msm_dai_q6_dai_probe,
3521 .remove = msm_dai_q6_dai_remove,
3522 },
3523 {
3524 .capture = {
3525 .stream_name = "Slimbus7 Capture",
3526 .aif_name = "SLIMBUS_7_TX",
3527 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
3528 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
3529 SNDRV_PCM_RATE_192000,
3530 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3531 SNDRV_PCM_FMTBIT_S24_LE |
3532 SNDRV_PCM_FMTBIT_S32_LE,
3533 .channels_min = 1,
3534 .channels_max = 8,
3535 .rate_min = 8000,
3536 .rate_max = 192000,
3537 },
3538 .ops = &msm_dai_q6_ops,
3539 .id = SLIMBUS_7_TX,
3540 .probe = msm_dai_q6_dai_probe,
3541 .remove = msm_dai_q6_dai_remove,
3542 },
3543 {
3544 .capture = {
3545 .stream_name = "Slimbus8 Capture",
3546 .aif_name = "SLIMBUS_8_TX",
3547 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
3548 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
3549 SNDRV_PCM_RATE_192000,
3550 .formats = SNDRV_PCM_FMTBIT_S16_LE |
3551 SNDRV_PCM_FMTBIT_S24_LE |
3552 SNDRV_PCM_FMTBIT_S32_LE,
3553 .channels_min = 1,
3554 .channels_max = 8,
3555 .rate_min = 8000,
3556 .rate_max = 192000,
3557 },
3558 .ops = &msm_dai_q6_ops,
3559 .id = SLIMBUS_8_TX,
3560 .probe = msm_dai_q6_dai_probe,
3561 .remove = msm_dai_q6_dai_remove,
3562 },
3563};
3564
3565static int msm_dai_q6_mi2s_format_put(struct snd_kcontrol *kcontrol,
3566 struct snd_ctl_elem_value *ucontrol)
3567{
3568 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
3569 int value = ucontrol->value.integer.value[0];
3570
3571 dai_data->port_config.i2s.data_format = value;
3572 pr_debug("%s: value = %d, channel = %d, line = %d\n",
3573 __func__, value, dai_data->port_config.i2s.mono_stereo,
3574 dai_data->port_config.i2s.channel_mode);
3575 return 0;
3576}
3577
3578static int msm_dai_q6_mi2s_format_get(struct snd_kcontrol *kcontrol,
3579 struct snd_ctl_elem_value *ucontrol)
3580{
3581 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
3582
3583 ucontrol->value.integer.value[0] =
3584 dai_data->port_config.i2s.data_format;
3585 return 0;
3586}
3587
3588static int msm_dai_q6_mi2s_vi_feed_mono_put(struct snd_kcontrol *kcontrol,
3589 struct snd_ctl_elem_value *ucontrol)
3590{
3591 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
3592 int value = ucontrol->value.integer.value[0];
3593
3594 dai_data->vi_feed_mono = value;
3595 pr_debug("%s: value = %d\n", __func__, value);
3596 return 0;
3597}
3598
3599static int msm_dai_q6_mi2s_vi_feed_mono_get(struct snd_kcontrol *kcontrol,
3600 struct snd_ctl_elem_value *ucontrol)
3601{
3602 struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
3603
3604 ucontrol->value.integer.value[0] = dai_data->vi_feed_mono;
3605 return 0;
3606}
3607
3608static const struct snd_kcontrol_new mi2s_config_controls[] = {
3609 SOC_ENUM_EXT("PRI MI2S RX Format", mi2s_config_enum[0],
3610 msm_dai_q6_mi2s_format_get,
3611 msm_dai_q6_mi2s_format_put),
3612 SOC_ENUM_EXT("SEC MI2S RX Format", mi2s_config_enum[0],
3613 msm_dai_q6_mi2s_format_get,
3614 msm_dai_q6_mi2s_format_put),
3615 SOC_ENUM_EXT("TERT MI2S RX Format", mi2s_config_enum[0],
3616 msm_dai_q6_mi2s_format_get,
3617 msm_dai_q6_mi2s_format_put),
3618 SOC_ENUM_EXT("QUAT MI2S RX Format", mi2s_config_enum[0],
3619 msm_dai_q6_mi2s_format_get,
3620 msm_dai_q6_mi2s_format_put),
3621 SOC_ENUM_EXT("QUIN MI2S RX Format", mi2s_config_enum[0],
3622 msm_dai_q6_mi2s_format_get,
3623 msm_dai_q6_mi2s_format_put),
3624 SOC_ENUM_EXT("PRI MI2S TX Format", mi2s_config_enum[0],
3625 msm_dai_q6_mi2s_format_get,
3626 msm_dai_q6_mi2s_format_put),
3627 SOC_ENUM_EXT("SEC MI2S TX Format", mi2s_config_enum[0],
3628 msm_dai_q6_mi2s_format_get,
3629 msm_dai_q6_mi2s_format_put),
3630 SOC_ENUM_EXT("TERT MI2S TX Format", mi2s_config_enum[0],
3631 msm_dai_q6_mi2s_format_get,
3632 msm_dai_q6_mi2s_format_put),
3633 SOC_ENUM_EXT("QUAT MI2S TX Format", mi2s_config_enum[0],
3634 msm_dai_q6_mi2s_format_get,
3635 msm_dai_q6_mi2s_format_put),
3636 SOC_ENUM_EXT("QUIN MI2S TX Format", mi2s_config_enum[0],
3637 msm_dai_q6_mi2s_format_get,
3638 msm_dai_q6_mi2s_format_put),
3639 SOC_ENUM_EXT("SENARY MI2S TX Format", mi2s_config_enum[0],
3640 msm_dai_q6_mi2s_format_get,
3641 msm_dai_q6_mi2s_format_put),
3642 SOC_ENUM_EXT("INT5 MI2S TX Format", mi2s_config_enum[0],
3643 msm_dai_q6_mi2s_format_get,
3644 msm_dai_q6_mi2s_format_put),
3645};
3646
3647static const struct snd_kcontrol_new mi2s_vi_feed_controls[] = {
3648 SOC_ENUM_EXT("INT5 MI2S VI MONO", mi2s_config_enum[1],
3649 msm_dai_q6_mi2s_vi_feed_mono_get,
3650 msm_dai_q6_mi2s_vi_feed_mono_put),
3651};
3652
3653static int msm_dai_q6_dai_mi2s_probe(struct snd_soc_dai *dai)
3654{
3655 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
3656 dev_get_drvdata(dai->dev);
3657 struct msm_mi2s_pdata *mi2s_pdata =
3658 (struct msm_mi2s_pdata *) dai->dev->platform_data;
3659 struct snd_kcontrol *kcontrol = NULL;
3660 int rc = 0;
3661 const struct snd_kcontrol_new *ctrl = NULL;
3662 const struct snd_kcontrol_new *vi_feed_ctrl = NULL;
3663
3664 dai->id = mi2s_pdata->intf_id;
3665
3666 if (mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.i2s.channel_mode) {
3667 if (dai->id == MSM_PRIM_MI2S)
3668 ctrl = &mi2s_config_controls[0];
3669 if (dai->id == MSM_SEC_MI2S)
3670 ctrl = &mi2s_config_controls[1];
3671 if (dai->id == MSM_TERT_MI2S)
3672 ctrl = &mi2s_config_controls[2];
3673 if (dai->id == MSM_QUAT_MI2S)
3674 ctrl = &mi2s_config_controls[3];
3675 if (dai->id == MSM_QUIN_MI2S)
3676 ctrl = &mi2s_config_controls[4];
3677 }
3678
3679 if (ctrl) {
3680 kcontrol = snd_ctl_new1(ctrl,
3681 &mi2s_dai_data->rx_dai.mi2s_dai_data);
3682 rc = snd_ctl_add(dai->component->card->snd_card, kcontrol);
3683 if (rc < 0) {
3684 dev_err(dai->dev, "%s: err add RX fmt ctl DAI = %s\n",
3685 __func__, dai->name);
3686 goto rtn;
3687 }
3688 }
3689
3690 ctrl = NULL;
3691 if (mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.channel_mode) {
3692 if (dai->id == MSM_PRIM_MI2S)
3693 ctrl = &mi2s_config_controls[4];
3694 if (dai->id == MSM_SEC_MI2S)
3695 ctrl = &mi2s_config_controls[5];
3696 if (dai->id == MSM_TERT_MI2S)
3697 ctrl = &mi2s_config_controls[6];
3698 if (dai->id == MSM_QUAT_MI2S)
3699 ctrl = &mi2s_config_controls[7];
3700 if (dai->id == MSM_QUIN_MI2S)
3701 ctrl = &mi2s_config_controls[9];
3702 if (dai->id == MSM_SENARY_MI2S)
3703 ctrl = &mi2s_config_controls[10];
3704 if (dai->id == MSM_INT5_MI2S)
3705 ctrl = &mi2s_config_controls[11];
3706 }
3707
3708 if (ctrl) {
3709 rc = snd_ctl_add(dai->component->card->snd_card,
3710 snd_ctl_new1(ctrl,
3711 &mi2s_dai_data->tx_dai.mi2s_dai_data));
3712 if (rc < 0) {
3713 if (kcontrol)
3714 snd_ctl_remove(dai->component->card->snd_card,
3715 kcontrol);
3716 dev_err(dai->dev, "%s: err add TX fmt ctl DAI = %s\n",
3717 __func__, dai->name);
3718 }
3719 }
3720
3721 if (dai->id == MSM_INT5_MI2S)
3722 vi_feed_ctrl = &mi2s_vi_feed_controls[0];
3723
3724 if (vi_feed_ctrl) {
3725 rc = snd_ctl_add(dai->component->card->snd_card,
3726 snd_ctl_new1(vi_feed_ctrl,
3727 &mi2s_dai_data->tx_dai.mi2s_dai_data));
3728
3729 if (rc < 0) {
3730 dev_err(dai->dev, "%s: err add TX vi feed channel ctl DAI = %s\n",
3731 __func__, dai->name);
3732 }
3733 }
3734
3735 rc = msm_dai_q6_dai_add_route(dai);
3736rtn:
3737 return rc;
3738}
3739
3740
3741static int msm_dai_q6_dai_mi2s_remove(struct snd_soc_dai *dai)
3742{
3743 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
3744 dev_get_drvdata(dai->dev);
3745 int rc;
3746
3747 /* If AFE port is still up, close it */
3748 if (test_bit(STATUS_PORT_STARTED,
3749 mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask)) {
3750 rc = afe_close(MI2S_RX); /* can block */
3751 if (rc < 0)
3752 dev_err(dai->dev, "fail to close MI2S_RX port\n");
3753 clear_bit(STATUS_PORT_STARTED,
3754 mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask);
3755 }
3756 if (test_bit(STATUS_PORT_STARTED,
3757 mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask)) {
3758 rc = afe_close(MI2S_TX); /* can block */
3759 if (rc < 0)
3760 dev_err(dai->dev, "fail to close MI2S_TX port\n");
3761 clear_bit(STATUS_PORT_STARTED,
3762 mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask);
3763 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303764 return 0;
3765}
3766
3767static int msm_dai_q6_mi2s_startup(struct snd_pcm_substream *substream,
3768 struct snd_soc_dai *dai)
3769{
3770
3771 return 0;
3772}
3773
3774
3775static int msm_mi2s_get_port_id(u32 mi2s_id, int stream, u16 *port_id)
3776{
3777 int ret = 0;
3778
3779 switch (stream) {
3780 case SNDRV_PCM_STREAM_PLAYBACK:
3781 switch (mi2s_id) {
3782 case MSM_PRIM_MI2S:
3783 *port_id = AFE_PORT_ID_PRIMARY_MI2S_RX;
3784 break;
3785 case MSM_SEC_MI2S:
3786 *port_id = AFE_PORT_ID_SECONDARY_MI2S_RX;
3787 break;
3788 case MSM_TERT_MI2S:
3789 *port_id = AFE_PORT_ID_TERTIARY_MI2S_RX;
3790 break;
3791 case MSM_QUAT_MI2S:
3792 *port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX;
3793 break;
3794 case MSM_SEC_MI2S_SD1:
3795 *port_id = AFE_PORT_ID_SECONDARY_MI2S_RX_SD1;
3796 break;
3797 case MSM_QUIN_MI2S:
3798 *port_id = AFE_PORT_ID_QUINARY_MI2S_RX;
3799 break;
3800 case MSM_INT0_MI2S:
3801 *port_id = AFE_PORT_ID_INT0_MI2S_RX;
3802 break;
3803 case MSM_INT1_MI2S:
3804 *port_id = AFE_PORT_ID_INT1_MI2S_RX;
3805 break;
3806 case MSM_INT2_MI2S:
3807 *port_id = AFE_PORT_ID_INT2_MI2S_RX;
3808 break;
3809 case MSM_INT3_MI2S:
3810 *port_id = AFE_PORT_ID_INT3_MI2S_RX;
3811 break;
3812 case MSM_INT4_MI2S:
3813 *port_id = AFE_PORT_ID_INT4_MI2S_RX;
3814 break;
3815 case MSM_INT5_MI2S:
3816 *port_id = AFE_PORT_ID_INT5_MI2S_RX;
3817 break;
3818 case MSM_INT6_MI2S:
3819 *port_id = AFE_PORT_ID_INT6_MI2S_RX;
3820 break;
3821 default:
3822 pr_err("%s: playback err id 0x%x\n",
3823 __func__, mi2s_id);
3824 ret = -1;
3825 break;
3826 }
3827 break;
3828 case SNDRV_PCM_STREAM_CAPTURE:
3829 switch (mi2s_id) {
3830 case MSM_PRIM_MI2S:
3831 *port_id = AFE_PORT_ID_PRIMARY_MI2S_TX;
3832 break;
3833 case MSM_SEC_MI2S:
3834 *port_id = AFE_PORT_ID_SECONDARY_MI2S_TX;
3835 break;
3836 case MSM_TERT_MI2S:
3837 *port_id = AFE_PORT_ID_TERTIARY_MI2S_TX;
3838 break;
3839 case MSM_QUAT_MI2S:
3840 *port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX;
3841 break;
3842 case MSM_QUIN_MI2S:
3843 *port_id = AFE_PORT_ID_QUINARY_MI2S_TX;
3844 break;
3845 case MSM_SENARY_MI2S:
3846 *port_id = AFE_PORT_ID_SENARY_MI2S_TX;
3847 break;
3848 case MSM_INT0_MI2S:
3849 *port_id = AFE_PORT_ID_INT0_MI2S_TX;
3850 break;
3851 case MSM_INT1_MI2S:
3852 *port_id = AFE_PORT_ID_INT1_MI2S_TX;
3853 break;
3854 case MSM_INT2_MI2S:
3855 *port_id = AFE_PORT_ID_INT2_MI2S_TX;
3856 break;
3857 case MSM_INT3_MI2S:
3858 *port_id = AFE_PORT_ID_INT3_MI2S_TX;
3859 break;
3860 case MSM_INT4_MI2S:
3861 *port_id = AFE_PORT_ID_INT4_MI2S_TX;
3862 break;
3863 case MSM_INT5_MI2S:
3864 *port_id = AFE_PORT_ID_INT5_MI2S_TX;
3865 break;
3866 case MSM_INT6_MI2S:
3867 *port_id = AFE_PORT_ID_INT6_MI2S_TX;
3868 break;
3869 default:
3870 pr_err("%s: capture err id 0x%x\n", __func__, mi2s_id);
3871 ret = -1;
3872 break;
3873 }
3874 break;
3875 default:
3876 pr_err("%s: default err %d\n", __func__, stream);
3877 ret = -1;
3878 break;
3879 }
3880 pr_debug("%s: port_id = 0x%x\n", __func__, *port_id);
3881 return ret;
3882}
3883
3884static int msm_dai_q6_mi2s_prepare(struct snd_pcm_substream *substream,
3885 struct snd_soc_dai *dai)
3886{
3887 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
3888 dev_get_drvdata(dai->dev);
3889 struct msm_dai_q6_dai_data *dai_data =
3890 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
3891 &mi2s_dai_data->rx_dai.mi2s_dai_data :
3892 &mi2s_dai_data->tx_dai.mi2s_dai_data);
3893 u16 port_id = 0;
3894 int rc = 0;
3895
3896 if (msm_mi2s_get_port_id(dai->id, substream->stream,
3897 &port_id) != 0) {
3898 dev_err(dai->dev, "%s: Invalid Port ID 0x%x\n",
3899 __func__, port_id);
3900 return -EINVAL;
3901 }
3902
3903 dev_dbg(dai->dev, "%s: dai id %d, afe port id = 0x%x\n"
3904 "dai_data->channels = %u sample_rate = %u\n", __func__,
3905 dai->id, port_id, dai_data->channels, dai_data->rate);
3906
3907 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
3908 /* PORT START should be set if prepare called
3909 * in active state.
3910 */
3911 rc = afe_port_start(port_id, &dai_data->port_config,
3912 dai_data->rate);
3913 if (rc < 0)
3914 dev_err(dai->dev, "fail to open AFE port 0x%x\n",
3915 dai->id);
3916 else
3917 set_bit(STATUS_PORT_STARTED,
3918 dai_data->status_mask);
3919 }
3920 if (!test_bit(STATUS_PORT_STARTED, dai_data->hwfree_status)) {
3921 set_bit(STATUS_PORT_STARTED, dai_data->hwfree_status);
3922 dev_dbg(dai->dev, "%s: set hwfree_status to started\n",
3923 __func__);
3924 }
3925 return rc;
3926}
3927
3928static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream,
3929 struct snd_pcm_hw_params *params,
3930 struct snd_soc_dai *dai)
3931{
3932 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
3933 dev_get_drvdata(dai->dev);
3934 struct msm_dai_q6_mi2s_dai_config *mi2s_dai_config =
3935 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
3936 &mi2s_dai_data->rx_dai : &mi2s_dai_data->tx_dai);
3937 struct msm_dai_q6_dai_data *dai_data = &mi2s_dai_config->mi2s_dai_data;
3938 struct afe_param_id_i2s_cfg *i2s = &dai_data->port_config.i2s;
3939
3940 dai_data->channels = params_channels(params);
3941 switch (dai_data->channels) {
3942 case 8:
3943 case 7:
3944 if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_8CHS)
3945 goto error_invalid_data;
3946 dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_8CHS;
3947 break;
3948 case 6:
3949 case 5:
3950 if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_6CHS)
3951 goto error_invalid_data;
3952 dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_6CHS;
3953 break;
3954 case 4:
3955 case 3:
3956 if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_QUAD01)
3957 goto error_invalid_data;
3958 if (mi2s_dai_config->pdata_mi2s_lines == AFE_PORT_I2S_QUAD23)
3959 dai_data->port_config.i2s.channel_mode =
3960 mi2s_dai_config->pdata_mi2s_lines;
3961 else
3962 dai_data->port_config.i2s.channel_mode =
3963 AFE_PORT_I2S_QUAD01;
3964 break;
3965 case 2:
3966 case 1:
3967 if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_SD0)
3968 goto error_invalid_data;
3969 switch (mi2s_dai_config->pdata_mi2s_lines) {
3970 case AFE_PORT_I2S_SD0:
3971 case AFE_PORT_I2S_SD1:
3972 case AFE_PORT_I2S_SD2:
3973 case AFE_PORT_I2S_SD3:
3974 dai_data->port_config.i2s.channel_mode =
3975 mi2s_dai_config->pdata_mi2s_lines;
3976 break;
3977 case AFE_PORT_I2S_QUAD01:
3978 case AFE_PORT_I2S_6CHS:
3979 case AFE_PORT_I2S_8CHS:
3980 if (dai_data->vi_feed_mono == SPKR_1)
3981 dai_data->port_config.i2s.channel_mode =
3982 AFE_PORT_I2S_SD0;
3983 else
3984 dai_data->port_config.i2s.channel_mode =
3985 AFE_PORT_I2S_SD1;
3986 break;
3987 case AFE_PORT_I2S_QUAD23:
3988 dai_data->port_config.i2s.channel_mode =
3989 AFE_PORT_I2S_SD2;
3990 break;
3991 }
3992 if (dai_data->channels == 2)
3993 dai_data->port_config.i2s.mono_stereo =
3994 MSM_AFE_CH_STEREO;
3995 else
3996 dai_data->port_config.i2s.mono_stereo = MSM_AFE_MONO;
3997 break;
3998 default:
3999 pr_err("%s: default err channels %d\n",
4000 __func__, dai_data->channels);
4001 goto error_invalid_data;
4002 }
4003 dai_data->rate = params_rate(params);
4004
4005 switch (params_format(params)) {
4006 case SNDRV_PCM_FORMAT_S16_LE:
4007 case SNDRV_PCM_FORMAT_SPECIAL:
4008 dai_data->port_config.i2s.bit_width = 16;
4009 dai_data->bitwidth = 16;
4010 break;
4011 case SNDRV_PCM_FORMAT_S24_LE:
4012 case SNDRV_PCM_FORMAT_S24_3LE:
4013 dai_data->port_config.i2s.bit_width = 24;
4014 dai_data->bitwidth = 24;
4015 break;
4016 default:
4017 pr_err("%s: format %d\n",
4018 __func__, params_format(params));
4019 return -EINVAL;
4020 }
4021
4022 dai_data->port_config.i2s.i2s_cfg_minor_version =
4023 AFE_API_VERSION_I2S_CONFIG;
4024 dai_data->port_config.i2s.sample_rate = dai_data->rate;
4025 if ((test_bit(STATUS_PORT_STARTED,
4026 mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask) &&
4027 test_bit(STATUS_PORT_STARTED,
4028 mi2s_dai_data->rx_dai.mi2s_dai_data.hwfree_status)) ||
4029 (test_bit(STATUS_PORT_STARTED,
4030 mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask) &&
4031 test_bit(STATUS_PORT_STARTED,
4032 mi2s_dai_data->tx_dai.mi2s_dai_data.hwfree_status))) {
4033 if ((mi2s_dai_data->tx_dai.mi2s_dai_data.rate !=
4034 mi2s_dai_data->rx_dai.mi2s_dai_data.rate) ||
4035 (mi2s_dai_data->rx_dai.mi2s_dai_data.bitwidth !=
4036 mi2s_dai_data->tx_dai.mi2s_dai_data.bitwidth)) {
4037 dev_err(dai->dev, "%s: Error mismatch in HW params\n"
4038 "Tx sample_rate = %u bit_width = %hu\n"
4039 "Rx sample_rate = %u bit_width = %hu\n"
4040 , __func__,
4041 mi2s_dai_data->tx_dai.mi2s_dai_data.rate,
4042 mi2s_dai_data->tx_dai.mi2s_dai_data.bitwidth,
4043 mi2s_dai_data->rx_dai.mi2s_dai_data.rate,
4044 mi2s_dai_data->rx_dai.mi2s_dai_data.bitwidth);
4045 return -EINVAL;
4046 }
4047 }
4048 dev_dbg(dai->dev, "%s: dai id %d dai_data->channels = %d\n"
4049 "sample_rate = %u i2s_cfg_minor_version = 0x%x\n"
4050 "bit_width = %hu channel_mode = 0x%x mono_stereo = %#x\n"
4051 "ws_src = 0x%x sample_rate = %u data_format = 0x%x\n"
4052 "reserved = %u\n", __func__, dai->id, dai_data->channels,
4053 dai_data->rate, i2s->i2s_cfg_minor_version, i2s->bit_width,
4054 i2s->channel_mode, i2s->mono_stereo, i2s->ws_src,
4055 i2s->sample_rate, i2s->data_format, i2s->reserved);
4056
4057 return 0;
4058
4059error_invalid_data:
4060 pr_err("%s: dai_data->channels = %d channel_mode = %d\n", __func__,
4061 dai_data->channels, dai_data->port_config.i2s.channel_mode);
4062 return -EINVAL;
4063}
4064
4065
4066static int msm_dai_q6_mi2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
4067{
4068 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
4069 dev_get_drvdata(dai->dev);
4070
4071 if (test_bit(STATUS_PORT_STARTED,
4072 mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask) ||
4073 test_bit(STATUS_PORT_STARTED,
4074 mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask)) {
4075 dev_err(dai->dev, "%s: err chg i2s mode while dai running",
4076 __func__);
4077 return -EPERM;
4078 }
4079
4080 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
4081 case SND_SOC_DAIFMT_CBS_CFS:
4082 mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.i2s.ws_src = 1;
4083 mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.ws_src = 1;
4084 break;
4085 case SND_SOC_DAIFMT_CBM_CFM:
4086 mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.i2s.ws_src = 0;
4087 mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.ws_src = 0;
4088 break;
4089 default:
4090 pr_err("%s: fmt %d\n",
4091 __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
4092 return -EINVAL;
4093 }
4094
4095 return 0;
4096}
4097
4098static int msm_dai_q6_mi2s_hw_free(struct snd_pcm_substream *substream,
4099 struct snd_soc_dai *dai)
4100{
4101 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
4102 dev_get_drvdata(dai->dev);
4103 struct msm_dai_q6_dai_data *dai_data =
4104 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
4105 &mi2s_dai_data->rx_dai.mi2s_dai_data :
4106 &mi2s_dai_data->tx_dai.mi2s_dai_data);
4107
4108 if (test_bit(STATUS_PORT_STARTED, dai_data->hwfree_status)) {
4109 clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status);
4110 dev_dbg(dai->dev, "%s: clear hwfree_status\n", __func__);
4111 }
4112 return 0;
4113}
4114
4115static void msm_dai_q6_mi2s_shutdown(struct snd_pcm_substream *substream,
4116 struct snd_soc_dai *dai)
4117{
4118 struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
4119 dev_get_drvdata(dai->dev);
4120 struct msm_dai_q6_dai_data *dai_data =
4121 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
4122 &mi2s_dai_data->rx_dai.mi2s_dai_data :
4123 &mi2s_dai_data->tx_dai.mi2s_dai_data);
4124 u16 port_id = 0;
4125 int rc = 0;
4126
4127 if (msm_mi2s_get_port_id(dai->id, substream->stream,
4128 &port_id) != 0) {
4129 dev_err(dai->dev, "%s: Invalid Port ID 0x%x\n",
4130 __func__, port_id);
4131 }
4132
4133 dev_dbg(dai->dev, "%s: closing afe port id = 0x%x\n",
4134 __func__, port_id);
4135
4136 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
4137 rc = afe_close(port_id);
4138 if (rc < 0)
4139 dev_err(dai->dev, "fail to close AFE port\n");
4140 clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
4141 }
4142 if (test_bit(STATUS_PORT_STARTED, dai_data->hwfree_status))
4143 clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status);
4144}
4145
4146static struct snd_soc_dai_ops msm_dai_q6_mi2s_ops = {
4147 .startup = msm_dai_q6_mi2s_startup,
4148 .prepare = msm_dai_q6_mi2s_prepare,
4149 .hw_params = msm_dai_q6_mi2s_hw_params,
4150 .hw_free = msm_dai_q6_mi2s_hw_free,
4151 .set_fmt = msm_dai_q6_mi2s_set_fmt,
4152 .shutdown = msm_dai_q6_mi2s_shutdown,
4153};
4154
4155/* Channel min and max are initialized base on platform data */
4156static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = {
4157 {
4158 .playback = {
4159 .stream_name = "Primary MI2S Playback",
4160 .aif_name = "PRI_MI2S_RX",
4161 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4162 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4163 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4164 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4165 SNDRV_PCM_RATE_192000,
4166 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4167 SNDRV_PCM_FMTBIT_S24_LE |
4168 SNDRV_PCM_FMTBIT_S24_3LE,
4169 .rate_min = 8000,
4170 .rate_max = 192000,
4171 },
4172 .capture = {
4173 .stream_name = "Primary MI2S Capture",
4174 .aif_name = "PRI_MI2S_TX",
4175 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4176 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4177 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4178 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4179 SNDRV_PCM_RATE_192000,
4180 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4181 .rate_min = 8000,
4182 .rate_max = 192000,
4183 },
4184 .ops = &msm_dai_q6_mi2s_ops,
4185 .id = MSM_PRIM_MI2S,
4186 .probe = msm_dai_q6_dai_mi2s_probe,
4187 .remove = msm_dai_q6_dai_mi2s_remove,
4188 },
4189 {
4190 .playback = {
4191 .stream_name = "Secondary MI2S Playback",
4192 .aif_name = "SEC_MI2S_RX",
4193 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4194 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4195 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4196 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4197 SNDRV_PCM_RATE_192000,
4198 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4199 .rate_min = 8000,
4200 .rate_max = 192000,
4201 },
4202 .capture = {
4203 .stream_name = "Secondary MI2S Capture",
4204 .aif_name = "SEC_MI2S_TX",
4205 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4206 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4207 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4208 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4209 SNDRV_PCM_RATE_192000,
4210 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4211 .rate_min = 8000,
4212 .rate_max = 192000,
4213 },
4214 .ops = &msm_dai_q6_mi2s_ops,
4215 .id = MSM_SEC_MI2S,
4216 .probe = msm_dai_q6_dai_mi2s_probe,
4217 .remove = msm_dai_q6_dai_mi2s_remove,
4218 },
4219 {
4220 .playback = {
4221 .stream_name = "Tertiary MI2S Playback",
4222 .aif_name = "TERT_MI2S_RX",
4223 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4224 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4225 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4226 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4227 SNDRV_PCM_RATE_192000,
4228 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4229 .rate_min = 8000,
4230 .rate_max = 192000,
4231 },
4232 .capture = {
4233 .stream_name = "Tertiary MI2S Capture",
4234 .aif_name = "TERT_MI2S_TX",
4235 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4236 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4237 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4238 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4239 SNDRV_PCM_RATE_192000,
4240 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4241 .rate_min = 8000,
4242 .rate_max = 192000,
4243 },
4244 .ops = &msm_dai_q6_mi2s_ops,
4245 .id = MSM_TERT_MI2S,
4246 .probe = msm_dai_q6_dai_mi2s_probe,
4247 .remove = msm_dai_q6_dai_mi2s_remove,
4248 },
4249 {
4250 .playback = {
4251 .stream_name = "Quaternary MI2S Playback",
4252 .aif_name = "QUAT_MI2S_RX",
4253 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4254 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4255 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4256 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4257 SNDRV_PCM_RATE_192000,
4258 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4259 .rate_min = 8000,
4260 .rate_max = 192000,
4261 },
4262 .capture = {
4263 .stream_name = "Quaternary MI2S Capture",
4264 .aif_name = "QUAT_MI2S_TX",
4265 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
4266 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
4267 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
4268 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
4269 SNDRV_PCM_RATE_192000,
4270 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4271 .rate_min = 8000,
4272 .rate_max = 192000,
4273 },
4274 .ops = &msm_dai_q6_mi2s_ops,
4275 .id = MSM_QUAT_MI2S,
4276 .probe = msm_dai_q6_dai_mi2s_probe,
4277 .remove = msm_dai_q6_dai_mi2s_remove,
4278 },
4279 {
4280 .playback = {
4281 .stream_name = "Secondary MI2S Playback SD1",
4282 .aif_name = "SEC_MI2S_RX_SD1",
4283 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4284 SNDRV_PCM_RATE_16000,
4285 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4286 .rate_min = 8000,
4287 .rate_max = 48000,
4288 },
4289 .id = MSM_SEC_MI2S_SD1,
4290 },
4291 {
4292 .playback = {
4293 .stream_name = "Quinary MI2S Playback",
4294 .aif_name = "QUIN_MI2S_RX",
4295 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4296 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
4297 SNDRV_PCM_RATE_192000,
4298 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4299 .rate_min = 8000,
4300 .rate_max = 192000,
4301 },
4302 .capture = {
4303 .stream_name = "Quinary MI2S Capture",
4304 .aif_name = "QUIN_MI2S_TX",
4305 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4306 SNDRV_PCM_RATE_16000,
4307 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4308 .rate_min = 8000,
4309 .rate_max = 48000,
4310 },
4311 .ops = &msm_dai_q6_mi2s_ops,
4312 .id = MSM_QUIN_MI2S,
4313 .probe = msm_dai_q6_dai_mi2s_probe,
4314 .remove = msm_dai_q6_dai_mi2s_remove,
4315 },
4316 {
4317 .capture = {
4318 .stream_name = "Senary_mi2s Capture",
4319 .aif_name = "SENARY_TX",
4320 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4321 SNDRV_PCM_RATE_16000,
4322 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4323 .rate_min = 8000,
4324 .rate_max = 48000,
4325 },
4326 .ops = &msm_dai_q6_mi2s_ops,
4327 .id = MSM_SENARY_MI2S,
4328 .probe = msm_dai_q6_dai_mi2s_probe,
4329 .remove = msm_dai_q6_dai_mi2s_remove,
4330 },
4331 {
4332 .playback = {
4333 .stream_name = "INT0 MI2S Playback",
4334 .aif_name = "INT0_MI2S_RX",
4335 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4336 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_44100 |
4337 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
4338 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4339 SNDRV_PCM_FMTBIT_S24_LE |
4340 SNDRV_PCM_FMTBIT_S24_3LE,
4341 .rate_min = 8000,
4342 .rate_max = 192000,
4343 },
4344 .capture = {
4345 .stream_name = "INT0 MI2S Capture",
4346 .aif_name = "INT0_MI2S_TX",
4347 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4348 SNDRV_PCM_RATE_16000,
4349 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4350 .rate_min = 8000,
4351 .rate_max = 48000,
4352 },
4353 .ops = &msm_dai_q6_mi2s_ops,
4354 .id = MSM_INT0_MI2S,
4355 .probe = msm_dai_q6_dai_mi2s_probe,
4356 .remove = msm_dai_q6_dai_mi2s_remove,
4357 },
4358 {
4359 .playback = {
4360 .stream_name = "INT1 MI2S Playback",
4361 .aif_name = "INT1_MI2S_RX",
4362 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4363 SNDRV_PCM_RATE_16000,
4364 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4365 SNDRV_PCM_FMTBIT_S24_LE |
4366 SNDRV_PCM_FMTBIT_S24_3LE,
4367 .rate_min = 8000,
4368 .rate_max = 48000,
4369 },
4370 .capture = {
4371 .stream_name = "INT1 MI2S Capture",
4372 .aif_name = "INT1_MI2S_TX",
4373 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4374 SNDRV_PCM_RATE_16000,
4375 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4376 .rate_min = 8000,
4377 .rate_max = 48000,
4378 },
4379 .ops = &msm_dai_q6_mi2s_ops,
4380 .id = MSM_INT1_MI2S,
4381 .probe = msm_dai_q6_dai_mi2s_probe,
4382 .remove = msm_dai_q6_dai_mi2s_remove,
4383 },
4384 {
4385 .playback = {
4386 .stream_name = "INT2 MI2S Playback",
4387 .aif_name = "INT2_MI2S_RX",
4388 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4389 SNDRV_PCM_RATE_16000,
4390 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4391 SNDRV_PCM_FMTBIT_S24_LE |
4392 SNDRV_PCM_FMTBIT_S24_3LE,
4393 .rate_min = 8000,
4394 .rate_max = 48000,
4395 },
4396 .capture = {
4397 .stream_name = "INT2 MI2S Capture",
4398 .aif_name = "INT2_MI2S_TX",
4399 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4400 SNDRV_PCM_RATE_16000,
4401 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4402 .rate_min = 8000,
4403 .rate_max = 48000,
4404 },
4405 .ops = &msm_dai_q6_mi2s_ops,
4406 .id = MSM_INT2_MI2S,
4407 .probe = msm_dai_q6_dai_mi2s_probe,
4408 .remove = msm_dai_q6_dai_mi2s_remove,
4409 },
4410 {
4411 .playback = {
4412 .stream_name = "INT3 MI2S Playback",
4413 .aif_name = "INT3_MI2S_RX",
4414 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4415 SNDRV_PCM_RATE_16000,
4416 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4417 SNDRV_PCM_FMTBIT_S24_LE |
4418 SNDRV_PCM_FMTBIT_S24_3LE,
4419 .rate_min = 8000,
4420 .rate_max = 48000,
4421 },
4422 .capture = {
4423 .stream_name = "INT3 MI2S Capture",
4424 .aif_name = "INT3_MI2S_TX",
4425 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4426 SNDRV_PCM_RATE_16000,
4427 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4428 .rate_min = 8000,
4429 .rate_max = 48000,
4430 },
4431 .ops = &msm_dai_q6_mi2s_ops,
4432 .id = MSM_INT3_MI2S,
4433 .probe = msm_dai_q6_dai_mi2s_probe,
4434 .remove = msm_dai_q6_dai_mi2s_remove,
4435 },
4436 {
4437 .playback = {
4438 .stream_name = "INT4 MI2S Playback",
4439 .aif_name = "INT4_MI2S_RX",
4440 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4441 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
4442 SNDRV_PCM_RATE_192000,
4443 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4444 SNDRV_PCM_FMTBIT_S24_LE |
4445 SNDRV_PCM_FMTBIT_S24_3LE,
4446 .rate_min = 8000,
4447 .rate_max = 192000,
4448 },
4449 .capture = {
4450 .stream_name = "INT4 MI2S Capture",
4451 .aif_name = "INT4_MI2S_TX",
4452 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4453 SNDRV_PCM_RATE_16000,
4454 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4455 .rate_min = 8000,
4456 .rate_max = 48000,
4457 },
4458 .ops = &msm_dai_q6_mi2s_ops,
4459 .id = MSM_INT4_MI2S,
4460 .probe = msm_dai_q6_dai_mi2s_probe,
4461 .remove = msm_dai_q6_dai_mi2s_remove,
4462 },
4463 {
4464 .playback = {
4465 .stream_name = "INT5 MI2S Playback",
4466 .aif_name = "INT5_MI2S_RX",
4467 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4468 SNDRV_PCM_RATE_16000,
4469 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4470 SNDRV_PCM_FMTBIT_S24_LE |
4471 SNDRV_PCM_FMTBIT_S24_3LE,
4472 .rate_min = 8000,
4473 .rate_max = 48000,
4474 },
4475 .capture = {
4476 .stream_name = "INT5 MI2S Capture",
4477 .aif_name = "INT5_MI2S_TX",
4478 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4479 SNDRV_PCM_RATE_16000,
4480 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4481 .rate_min = 8000,
4482 .rate_max = 48000,
4483 },
4484 .ops = &msm_dai_q6_mi2s_ops,
4485 .id = MSM_INT5_MI2S,
4486 .probe = msm_dai_q6_dai_mi2s_probe,
4487 .remove = msm_dai_q6_dai_mi2s_remove,
4488 },
4489 {
4490 .playback = {
4491 .stream_name = "INT6 MI2S Playback",
4492 .aif_name = "INT6_MI2S_RX",
4493 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4494 SNDRV_PCM_RATE_16000,
4495 .formats = SNDRV_PCM_FMTBIT_S16_LE |
4496 SNDRV_PCM_FMTBIT_S24_LE |
4497 SNDRV_PCM_FMTBIT_S24_3LE,
4498 .rate_min = 8000,
4499 .rate_max = 48000,
4500 },
4501 .capture = {
4502 .stream_name = "INT6 MI2S Capture",
4503 .aif_name = "INT6_MI2S_TX",
4504 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
4505 SNDRV_PCM_RATE_16000,
4506 .formats = SNDRV_PCM_FMTBIT_S16_LE,
4507 .rate_min = 8000,
4508 .rate_max = 48000,
4509 },
4510 .ops = &msm_dai_q6_mi2s_ops,
4511 .id = MSM_INT6_MI2S,
4512 .probe = msm_dai_q6_dai_mi2s_probe,
4513 .remove = msm_dai_q6_dai_mi2s_remove,
4514 },
4515};
4516
4517
4518static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr,
4519 unsigned int *ch_cnt)
4520{
4521 u8 num_of_sd_lines;
4522
4523 num_of_sd_lines = num_of_bits_set(sd_lines);
4524 switch (num_of_sd_lines) {
4525 case 0:
4526 pr_debug("%s: no line is assigned\n", __func__);
4527 break;
4528 case 1:
4529 switch (sd_lines) {
4530 case MSM_MI2S_SD0:
4531 *config_ptr = AFE_PORT_I2S_SD0;
4532 break;
4533 case MSM_MI2S_SD1:
4534 *config_ptr = AFE_PORT_I2S_SD1;
4535 break;
4536 case MSM_MI2S_SD2:
4537 *config_ptr = AFE_PORT_I2S_SD2;
4538 break;
4539 case MSM_MI2S_SD3:
4540 *config_ptr = AFE_PORT_I2S_SD3;
4541 break;
4542 default:
4543 pr_err("%s: invalid SD lines %d\n",
4544 __func__, sd_lines);
4545 goto error_invalid_data;
4546 }
4547 break;
4548 case 2:
4549 switch (sd_lines) {
4550 case MSM_MI2S_SD0 | MSM_MI2S_SD1:
4551 *config_ptr = AFE_PORT_I2S_QUAD01;
4552 break;
4553 case MSM_MI2S_SD2 | MSM_MI2S_SD3:
4554 *config_ptr = AFE_PORT_I2S_QUAD23;
4555 break;
4556 default:
4557 pr_err("%s: invalid SD lines %d\n",
4558 __func__, sd_lines);
4559 goto error_invalid_data;
4560 }
4561 break;
4562 case 3:
4563 switch (sd_lines) {
4564 case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2:
4565 *config_ptr = AFE_PORT_I2S_6CHS;
4566 break;
4567 default:
4568 pr_err("%s: invalid SD lines %d\n",
4569 __func__, sd_lines);
4570 goto error_invalid_data;
4571 }
4572 break;
4573 case 4:
4574 switch (sd_lines) {
4575 case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3:
4576 *config_ptr = AFE_PORT_I2S_8CHS;
4577 break;
4578 default:
4579 pr_err("%s: invalid SD lines %d\n",
4580 __func__, sd_lines);
4581 goto error_invalid_data;
4582 }
4583 break;
4584 default:
4585 pr_err("%s: invalid SD lines %d\n", __func__, num_of_sd_lines);
4586 goto error_invalid_data;
4587 }
4588 *ch_cnt = num_of_sd_lines;
4589 return 0;
4590
4591error_invalid_data:
4592 pr_err("%s: invalid data\n", __func__);
4593 return -EINVAL;
4594}
4595
4596static int msm_dai_q6_mi2s_platform_data_validation(
4597 struct platform_device *pdev, struct snd_soc_dai_driver *dai_driver)
4598{
4599 struct msm_dai_q6_mi2s_dai_data *dai_data = dev_get_drvdata(&pdev->dev);
4600 struct msm_mi2s_pdata *mi2s_pdata =
4601 (struct msm_mi2s_pdata *) pdev->dev.platform_data;
4602 unsigned int ch_cnt;
4603 int rc = 0;
4604 u16 sd_line;
4605
4606 if (mi2s_pdata == NULL) {
4607 pr_err("%s: mi2s_pdata NULL", __func__);
4608 return -EINVAL;
4609 }
4610
4611 rc = msm_dai_q6_mi2s_get_lineconfig(mi2s_pdata->rx_sd_lines,
4612 &sd_line, &ch_cnt);
4613 if (rc < 0) {
4614 dev_err(&pdev->dev, "invalid MI2S RX sd line config\n");
4615 goto rtn;
4616 }
4617
4618 if (ch_cnt) {
4619 dai_data->rx_dai.mi2s_dai_data.port_config.i2s.channel_mode =
4620 sd_line;
4621 dai_data->rx_dai.pdata_mi2s_lines = sd_line;
4622 dai_driver->playback.channels_min = 1;
4623 dai_driver->playback.channels_max = ch_cnt << 1;
4624 } else {
4625 dai_driver->playback.channels_min = 0;
4626 dai_driver->playback.channels_max = 0;
4627 }
4628 rc = msm_dai_q6_mi2s_get_lineconfig(mi2s_pdata->tx_sd_lines,
4629 &sd_line, &ch_cnt);
4630 if (rc < 0) {
4631 dev_err(&pdev->dev, "invalid MI2S TX sd line config\n");
4632 goto rtn;
4633 }
4634
4635 if (ch_cnt) {
4636 dai_data->tx_dai.mi2s_dai_data.port_config.i2s.channel_mode =
4637 sd_line;
4638 dai_data->tx_dai.pdata_mi2s_lines = sd_line;
4639 dai_driver->capture.channels_min = 1;
4640 dai_driver->capture.channels_max = ch_cnt << 1;
4641 } else {
4642 dai_driver->capture.channels_min = 0;
4643 dai_driver->capture.channels_max = 0;
4644 }
4645
4646 dev_dbg(&pdev->dev, "%s: playback sdline 0x%x capture sdline 0x%x\n",
4647 __func__, dai_data->rx_dai.pdata_mi2s_lines,
4648 dai_data->tx_dai.pdata_mi2s_lines);
4649 dev_dbg(&pdev->dev, "%s: playback ch_max %d capture ch_mx %d\n",
4650 __func__, dai_driver->playback.channels_max,
4651 dai_driver->capture.channels_max);
4652rtn:
4653 return rc;
4654}
4655
4656static const struct snd_soc_component_driver msm_q6_mi2s_dai_component = {
4657 .name = "msm-dai-q6-mi2s",
4658};
4659static int msm_dai_q6_mi2s_dev_probe(struct platform_device *pdev)
4660{
4661 struct msm_dai_q6_mi2s_dai_data *dai_data;
4662 const char *q6_mi2s_dev_id = "qcom,msm-dai-q6-mi2s-dev-id";
4663 u32 tx_line = 0;
4664 u32 rx_line = 0;
4665 u32 mi2s_intf = 0;
4666 struct msm_mi2s_pdata *mi2s_pdata;
4667 int rc;
4668
4669 rc = of_property_read_u32(pdev->dev.of_node, q6_mi2s_dev_id,
4670 &mi2s_intf);
4671 if (rc) {
4672 dev_err(&pdev->dev,
4673 "%s: missing 0x%x in dt node\n", __func__, mi2s_intf);
4674 goto rtn;
4675 }
4676
4677 dev_dbg(&pdev->dev, "dev name %s dev id 0x%x\n", dev_name(&pdev->dev),
4678 mi2s_intf);
4679
4680 if ((mi2s_intf < MSM_MI2S_MIN || mi2s_intf > MSM_MI2S_MAX)
4681 || (mi2s_intf >= ARRAY_SIZE(msm_dai_q6_mi2s_dai))) {
4682 dev_err(&pdev->dev,
4683 "%s: Invalid MI2S ID %u from Device Tree\n",
4684 __func__, mi2s_intf);
4685 rc = -ENXIO;
4686 goto rtn;
4687 }
4688
4689 pdev->id = mi2s_intf;
4690
4691 mi2s_pdata = kzalloc(sizeof(struct msm_mi2s_pdata), GFP_KERNEL);
4692 if (!mi2s_pdata) {
4693 rc = -ENOMEM;
4694 goto rtn;
4695 }
4696
4697 rc = of_property_read_u32(pdev->dev.of_node, "qcom,msm-mi2s-rx-lines",
4698 &rx_line);
4699 if (rc) {
4700 dev_err(&pdev->dev, "%s: Rx line from DT file %s\n", __func__,
4701 "qcom,msm-mi2s-rx-lines");
4702 goto free_pdata;
4703 }
4704
4705 rc = of_property_read_u32(pdev->dev.of_node, "qcom,msm-mi2s-tx-lines",
4706 &tx_line);
4707 if (rc) {
4708 dev_err(&pdev->dev, "%s: Tx line from DT file %s\n", __func__,
4709 "qcom,msm-mi2s-tx-lines");
4710 goto free_pdata;
4711 }
4712 dev_dbg(&pdev->dev, "dev name %s Rx line 0x%x , Tx ine 0x%x\n",
4713 dev_name(&pdev->dev), rx_line, tx_line);
4714 mi2s_pdata->rx_sd_lines = rx_line;
4715 mi2s_pdata->tx_sd_lines = tx_line;
4716 mi2s_pdata->intf_id = mi2s_intf;
4717
4718 dai_data = kzalloc(sizeof(struct msm_dai_q6_mi2s_dai_data),
4719 GFP_KERNEL);
4720 if (!dai_data) {
4721 rc = -ENOMEM;
4722 goto free_pdata;
4723 } else
4724 dev_set_drvdata(&pdev->dev, dai_data);
4725
4726 pdev->dev.platform_data = mi2s_pdata;
4727
4728 rc = msm_dai_q6_mi2s_platform_data_validation(pdev,
4729 &msm_dai_q6_mi2s_dai[mi2s_intf]);
4730 if (rc < 0)
4731 goto free_dai_data;
4732
4733 rc = snd_soc_register_component(&pdev->dev, &msm_q6_mi2s_dai_component,
4734 &msm_dai_q6_mi2s_dai[mi2s_intf], 1);
4735 if (rc < 0)
4736 goto err_register;
4737 return 0;
4738
4739err_register:
4740 dev_err(&pdev->dev, "fail to msm_dai_q6_mi2s_dev_probe\n");
4741free_dai_data:
4742 kfree(dai_data);
4743free_pdata:
4744 kfree(mi2s_pdata);
4745rtn:
4746 return rc;
4747}
4748
4749static int msm_dai_q6_mi2s_dev_remove(struct platform_device *pdev)
4750{
4751 snd_soc_unregister_component(&pdev->dev);
4752 return 0;
4753}
4754
4755static const struct snd_soc_component_driver msm_dai_q6_component = {
4756 .name = "msm-dai-q6-dev",
4757};
4758
4759static int msm_dai_q6_dev_probe(struct platform_device *pdev)
4760{
4761 int rc, id, i, len;
4762 const char *q6_dev_id = "qcom,msm-dai-q6-dev-id";
4763 char stream_name[80];
4764
4765 rc = of_property_read_u32(pdev->dev.of_node, q6_dev_id, &id);
4766 if (rc) {
4767 dev_err(&pdev->dev,
4768 "%s: missing %s in dt node\n", __func__, q6_dev_id);
4769 return rc;
4770 }
4771
4772 pdev->id = id;
4773
4774 pr_debug("%s: dev name %s, id:%d\n", __func__,
4775 dev_name(&pdev->dev), pdev->id);
4776
4777 switch (id) {
4778 case SLIMBUS_0_RX:
4779 strlcpy(stream_name, "Slimbus Playback", 80);
4780 goto register_slim_playback;
4781 case SLIMBUS_2_RX:
4782 strlcpy(stream_name, "Slimbus2 Playback", 80);
4783 goto register_slim_playback;
4784 case SLIMBUS_1_RX:
4785 strlcpy(stream_name, "Slimbus1 Playback", 80);
4786 goto register_slim_playback;
4787 case SLIMBUS_3_RX:
4788 strlcpy(stream_name, "Slimbus3 Playback", 80);
4789 goto register_slim_playback;
4790 case SLIMBUS_4_RX:
4791 strlcpy(stream_name, "Slimbus4 Playback", 80);
4792 goto register_slim_playback;
4793 case SLIMBUS_5_RX:
4794 strlcpy(stream_name, "Slimbus5 Playback", 80);
4795 goto register_slim_playback;
4796 case SLIMBUS_6_RX:
4797 strlcpy(stream_name, "Slimbus6 Playback", 80);
4798 goto register_slim_playback;
4799 case SLIMBUS_7_RX:
4800 strlcpy(stream_name, "Slimbus7 Playback", sizeof(stream_name));
4801 goto register_slim_playback;
4802 case SLIMBUS_8_RX:
4803 strlcpy(stream_name, "Slimbus8 Playback", sizeof(stream_name));
4804 goto register_slim_playback;
4805register_slim_playback:
4806 rc = -ENODEV;
4807 len = strnlen(stream_name, 80);
4808 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_slimbus_rx_dai); i++) {
4809 if (msm_dai_q6_slimbus_rx_dai[i].playback.stream_name &&
4810 !strcmp(stream_name,
4811 msm_dai_q6_slimbus_rx_dai[i]
4812 .playback.stream_name)) {
4813 rc = snd_soc_register_component(&pdev->dev,
4814 &msm_dai_q6_component,
4815 &msm_dai_q6_slimbus_rx_dai[i], 1);
4816 break;
4817 }
4818 }
4819 if (rc)
4820 pr_err("%s: Device not found stream name %s\n",
4821 __func__, stream_name);
4822 break;
4823 case SLIMBUS_0_TX:
4824 strlcpy(stream_name, "Slimbus Capture", 80);
4825 goto register_slim_capture;
4826 case SLIMBUS_1_TX:
4827 strlcpy(stream_name, "Slimbus1 Capture", 80);
4828 goto register_slim_capture;
4829 case SLIMBUS_2_TX:
4830 strlcpy(stream_name, "Slimbus2 Capture", 80);
4831 goto register_slim_capture;
4832 case SLIMBUS_3_TX:
4833 strlcpy(stream_name, "Slimbus3 Capture", 80);
4834 goto register_slim_capture;
4835 case SLIMBUS_4_TX:
4836 strlcpy(stream_name, "Slimbus4 Capture", 80);
4837 goto register_slim_capture;
4838 case SLIMBUS_5_TX:
4839 strlcpy(stream_name, "Slimbus5 Capture", 80);
4840 goto register_slim_capture;
4841 case SLIMBUS_6_TX:
4842 strlcpy(stream_name, "Slimbus6 Capture", 80);
4843 goto register_slim_capture;
4844 case SLIMBUS_7_TX:
4845 strlcpy(stream_name, "Slimbus7 Capture", sizeof(stream_name));
4846 goto register_slim_capture;
4847 case SLIMBUS_8_TX:
4848 strlcpy(stream_name, "Slimbus8 Capture", sizeof(stream_name));
4849 goto register_slim_capture;
4850register_slim_capture:
4851 rc = -ENODEV;
4852 len = strnlen(stream_name, 80);
4853 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_slimbus_tx_dai); i++) {
4854 if (msm_dai_q6_slimbus_tx_dai[i].capture.stream_name &&
4855 !strcmp(stream_name,
4856 msm_dai_q6_slimbus_tx_dai[i]
4857 .capture.stream_name)) {
4858 rc = snd_soc_register_component(&pdev->dev,
4859 &msm_dai_q6_component,
4860 &msm_dai_q6_slimbus_tx_dai[i], 1);
4861 break;
4862 }
4863 }
4864 if (rc)
4865 pr_err("%s: Device not found stream name %s\n",
4866 __func__, stream_name);
4867 break;
4868 case INT_BT_SCO_RX:
4869 rc = snd_soc_register_component(&pdev->dev,
4870 &msm_dai_q6_component, &msm_dai_q6_bt_sco_rx_dai, 1);
4871 break;
4872 case INT_BT_SCO_TX:
4873 rc = snd_soc_register_component(&pdev->dev,
4874 &msm_dai_q6_component, &msm_dai_q6_bt_sco_tx_dai, 1);
4875 break;
4876 case INT_BT_A2DP_RX:
4877 rc = snd_soc_register_component(&pdev->dev,
4878 &msm_dai_q6_component, &msm_dai_q6_bt_a2dp_rx_dai, 1);
4879 break;
4880 case INT_FM_RX:
4881 rc = snd_soc_register_component(&pdev->dev,
4882 &msm_dai_q6_component, &msm_dai_q6_fm_rx_dai, 1);
4883 break;
4884 case INT_FM_TX:
4885 rc = snd_soc_register_component(&pdev->dev,
4886 &msm_dai_q6_component, &msm_dai_q6_fm_tx_dai, 1);
4887 break;
4888 case AFE_PORT_ID_USB_RX:
4889 rc = snd_soc_register_component(&pdev->dev,
4890 &msm_dai_q6_component, &msm_dai_q6_usb_rx_dai, 1);
4891 break;
4892 case AFE_PORT_ID_USB_TX:
4893 rc = snd_soc_register_component(&pdev->dev,
4894 &msm_dai_q6_component, &msm_dai_q6_usb_tx_dai, 1);
4895 break;
4896 case RT_PROXY_DAI_001_RX:
4897 strlcpy(stream_name, "AFE Playback", 80);
4898 goto register_afe_playback;
4899 case RT_PROXY_DAI_002_RX:
4900 strlcpy(stream_name, "AFE-PROXY RX", 80);
4901register_afe_playback:
4902 rc = -ENODEV;
4903 len = strnlen(stream_name, 80);
4904 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_afe_rx_dai); i++) {
4905 if (msm_dai_q6_afe_rx_dai[i].playback.stream_name &&
4906 !strcmp(stream_name,
4907 msm_dai_q6_afe_rx_dai[i].playback.stream_name)) {
4908 rc = snd_soc_register_component(&pdev->dev,
4909 &msm_dai_q6_component,
4910 &msm_dai_q6_afe_rx_dai[i], 1);
4911 break;
4912 }
4913 }
4914 if (rc)
4915 pr_err("%s: Device not found stream name %s\n",
4916 __func__, stream_name);
4917 break;
4918 case RT_PROXY_DAI_001_TX:
4919 strlcpy(stream_name, "AFE-PROXY TX", 80);
4920 goto register_afe_capture;
4921 case RT_PROXY_DAI_002_TX:
4922 strlcpy(stream_name, "AFE Capture", 80);
4923register_afe_capture:
4924 rc = -ENODEV;
4925 len = strnlen(stream_name, 80);
4926 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_afe_tx_dai); i++) {
4927 if (msm_dai_q6_afe_tx_dai[i].capture.stream_name &&
4928 !strcmp(stream_name,
4929 msm_dai_q6_afe_tx_dai[i].capture.stream_name)) {
4930 rc = snd_soc_register_component(&pdev->dev,
4931 &msm_dai_q6_component,
4932 &msm_dai_q6_afe_tx_dai[i], 1);
4933 break;
4934 }
4935 }
4936 if (rc)
4937 pr_err("%s: Device not found stream name %s\n",
4938 __func__, stream_name);
4939 break;
4940 case VOICE_PLAYBACK_TX:
4941 strlcpy(stream_name, "Voice Farend Playback", 80);
4942 goto register_voice_playback;
4943 case VOICE2_PLAYBACK_TX:
4944 strlcpy(stream_name, "Voice2 Farend Playback", 80);
4945register_voice_playback:
4946 rc = -ENODEV;
4947 len = strnlen(stream_name, 80);
4948 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_voc_playback_dai); i++) {
4949 if (msm_dai_q6_voc_playback_dai[i].playback.stream_name
4950 && !strcmp(stream_name,
4951 msm_dai_q6_voc_playback_dai[i].playback.stream_name)) {
4952 rc = snd_soc_register_component(&pdev->dev,
4953 &msm_dai_q6_component,
4954 &msm_dai_q6_voc_playback_dai[i], 1);
4955 break;
4956 }
4957 }
4958 if (rc)
4959 pr_err("%s Device not found stream name %s\n",
4960 __func__, stream_name);
4961 break;
4962 case VOICE_RECORD_RX:
4963 strlcpy(stream_name, "Voice Downlink Capture", 80);
4964 goto register_uplink_capture;
4965 case VOICE_RECORD_TX:
4966 strlcpy(stream_name, "Voice Uplink Capture", 80);
4967register_uplink_capture:
4968 rc = -ENODEV;
4969 len = strnlen(stream_name, 80);
4970 for (i = 0; i < ARRAY_SIZE(msm_dai_q6_incall_record_dai); i++) {
4971 if (msm_dai_q6_incall_record_dai[i].capture.stream_name
4972 && !strcmp(stream_name,
4973 msm_dai_q6_incall_record_dai[i].
4974 capture.stream_name)) {
4975 rc = snd_soc_register_component(&pdev->dev,
4976 &msm_dai_q6_component,
4977 &msm_dai_q6_incall_record_dai[i], 1);
4978 break;
4979 }
4980 }
4981 if (rc)
4982 pr_err("%s: Device not found stream name %s\n",
4983 __func__, stream_name);
4984 break;
4985
4986 default:
4987 rc = -ENODEV;
4988 break;
4989 }
4990
4991 return rc;
4992}
4993
4994static int msm_dai_q6_dev_remove(struct platform_device *pdev)
4995{
4996 snd_soc_unregister_component(&pdev->dev);
4997 return 0;
4998}
4999
5000static const struct of_device_id msm_dai_q6_dev_dt_match[] = {
5001 { .compatible = "qcom,msm-dai-q6-dev", },
5002 { }
5003};
5004MODULE_DEVICE_TABLE(of, msm_dai_q6_dev_dt_match);
5005
5006static struct platform_driver msm_dai_q6_dev = {
5007 .probe = msm_dai_q6_dev_probe,
5008 .remove = msm_dai_q6_dev_remove,
5009 .driver = {
5010 .name = "msm-dai-q6-dev",
5011 .owner = THIS_MODULE,
5012 .of_match_table = msm_dai_q6_dev_dt_match,
5013 },
5014};
5015
5016static int msm_dai_q6_probe(struct platform_device *pdev)
5017{
5018 int rc;
5019
5020 pr_debug("%s: dev name %s, id:%d\n", __func__,
5021 dev_name(&pdev->dev), pdev->id);
5022 rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
5023 if (rc) {
5024 dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n",
5025 __func__, rc);
5026 } else
5027 dev_dbg(&pdev->dev, "%s: added child node\n", __func__);
5028
5029 return rc;
5030}
5031
5032static int msm_dai_q6_remove(struct platform_device *pdev)
5033{
5034 return 0;
5035}
5036
5037static const struct of_device_id msm_dai_q6_dt_match[] = {
5038 { .compatible = "qcom,msm-dai-q6", },
5039 { }
5040};
5041MODULE_DEVICE_TABLE(of, msm_dai_q6_dt_match);
5042static struct platform_driver msm_dai_q6 = {
5043 .probe = msm_dai_q6_probe,
5044 .remove = msm_dai_q6_remove,
5045 .driver = {
5046 .name = "msm-dai-q6",
5047 .owner = THIS_MODULE,
5048 .of_match_table = msm_dai_q6_dt_match,
5049 },
5050};
5051
5052static int msm_dai_mi2s_q6_probe(struct platform_device *pdev)
5053{
5054 int rc;
5055
5056 rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
5057 if (rc) {
5058 dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n",
5059 __func__, rc);
5060 } else
5061 dev_dbg(&pdev->dev, "%s: added child node\n", __func__);
5062 return rc;
5063}
5064
5065static int msm_dai_mi2s_q6_remove(struct platform_device *pdev)
5066{
5067 return 0;
5068}
5069
5070static const struct of_device_id msm_dai_mi2s_dt_match[] = {
5071 { .compatible = "qcom,msm-dai-mi2s", },
5072 { }
5073};
5074
5075MODULE_DEVICE_TABLE(of, msm_dai_mi2s_dt_match);
5076
5077static struct platform_driver msm_dai_mi2s_q6 = {
5078 .probe = msm_dai_mi2s_q6_probe,
5079 .remove = msm_dai_mi2s_q6_remove,
5080 .driver = {
5081 .name = "msm-dai-mi2s",
5082 .owner = THIS_MODULE,
5083 .of_match_table = msm_dai_mi2s_dt_match,
5084 },
5085};
5086
5087static const struct of_device_id msm_dai_q6_mi2s_dev_dt_match[] = {
5088 { .compatible = "qcom,msm-dai-q6-mi2s", },
5089 { }
5090};
5091
5092MODULE_DEVICE_TABLE(of, msm_dai_q6_mi2s_dev_dt_match);
5093
5094static struct platform_driver msm_dai_q6_mi2s_driver = {
5095 .probe = msm_dai_q6_mi2s_dev_probe,
5096 .remove = msm_dai_q6_mi2s_dev_remove,
5097 .driver = {
5098 .name = "msm-dai-q6-mi2s",
5099 .owner = THIS_MODULE,
5100 .of_match_table = msm_dai_q6_mi2s_dev_dt_match,
5101 },
5102};
5103
5104static int msm_dai_q6_spdif_dev_probe(struct platform_device *pdev)
5105{
5106 int rc;
5107
5108 pdev->id = AFE_PORT_ID_SPDIF_RX;
5109
5110 pr_debug("%s: dev name %s, id:%d\n", __func__,
5111 dev_name(&pdev->dev), pdev->id);
5112
5113 rc = snd_soc_register_component(&pdev->dev,
5114 &msm_dai_spdif_q6_component,
5115 &msm_dai_q6_spdif_spdif_rx_dai, 1);
5116 return rc;
5117}
5118
5119static int msm_dai_q6_spdif_dev_remove(struct platform_device *pdev)
5120{
5121 snd_soc_unregister_component(&pdev->dev);
5122 return 0;
5123}
5124
5125static const struct of_device_id msm_dai_q6_spdif_dt_match[] = {
5126 {.compatible = "qcom,msm-dai-q6-spdif"},
5127 {}
5128};
5129MODULE_DEVICE_TABLE(of, msm_dai_q6_spdif_dt_match);
5130
5131static struct platform_driver msm_dai_q6_spdif_driver = {
5132 .probe = msm_dai_q6_spdif_dev_probe,
5133 .remove = msm_dai_q6_spdif_dev_remove,
5134 .driver = {
5135 .name = "msm-dai-q6-spdif",
5136 .owner = THIS_MODULE,
5137 .of_match_table = msm_dai_q6_spdif_dt_match,
5138 },
5139};
5140
5141static int msm_dai_q6_tdm_set_clk_param(u32 group_id,
5142 struct afe_clk_set *clk_set, u32 mode)
5143{
5144 switch (group_id) {
5145 case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX:
5146 case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX:
5147 if (mode)
5148 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT;
5149 else
5150 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_PRI_TDM_EBIT;
5151 break;
5152 case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_RX:
5153 case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_TX:
5154 if (mode)
5155 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT;
5156 else
5157 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_SEC_TDM_EBIT;
5158 break;
5159 case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_RX:
5160 case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_TX:
5161 if (mode)
5162 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT;
5163 else
5164 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_TER_TDM_EBIT;
5165 break;
5166 case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_RX:
5167 case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_TX:
5168 if (mode)
5169 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT;
5170 else
5171 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUAD_TDM_EBIT;
5172 break;
Rohit Kumara5077932017-09-10 22:05:05 +05305173 case AFE_GROUP_DEVICE_ID_QUINARY_TDM_RX:
5174 case AFE_GROUP_DEVICE_ID_QUINARY_TDM_TX:
5175 if (mode)
5176 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUIN_TDM_IBIT;
5177 else
5178 clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT;
5179 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305180 default:
5181 return -EINVAL;
5182 }
5183 return 0;
5184}
5185
5186static int msm_dai_tdm_q6_probe(struct platform_device *pdev)
5187{
5188 int rc = 0;
5189 const uint32_t *port_id_array = NULL;
5190 uint32_t array_length = 0;
5191 int i = 0;
5192 int group_idx = 0;
5193 u32 clk_mode = 0;
5194
5195 /* extract tdm group info into static */
5196 rc = of_property_read_u32(pdev->dev.of_node,
5197 "qcom,msm-cpudai-tdm-group-id",
5198 (u32 *)&tdm_group_cfg.group_id);
5199 if (rc) {
5200 dev_err(&pdev->dev, "%s: Group ID from DT file %s\n",
5201 __func__, "qcom,msm-cpudai-tdm-group-id");
5202 goto rtn;
5203 }
5204 dev_dbg(&pdev->dev, "%s: Group ID from DT file 0x%x\n",
5205 __func__, tdm_group_cfg.group_id);
5206
5207 dev_info(&pdev->dev, "%s: dev_name: %s group_id: 0x%x\n",
5208 __func__, dev_name(&pdev->dev), tdm_group_cfg.group_id);
5209
5210 rc = of_property_read_u32(pdev->dev.of_node,
5211 "qcom,msm-cpudai-tdm-group-num-ports",
5212 &num_tdm_group_ports);
5213 if (rc) {
5214 dev_err(&pdev->dev, "%s: Group Num Ports from DT file %s\n",
5215 __func__, "qcom,msm-cpudai-tdm-group-num-ports");
5216 goto rtn;
5217 }
5218 dev_dbg(&pdev->dev, "%s: Group Num Ports from DT file 0x%x\n",
5219 __func__, num_tdm_group_ports);
5220
5221 if (num_tdm_group_ports > AFE_GROUP_DEVICE_NUM_PORTS) {
5222 dev_err(&pdev->dev, "%s Group Num Ports %d greater than Max %d\n",
5223 __func__, num_tdm_group_ports,
5224 AFE_GROUP_DEVICE_NUM_PORTS);
5225 rc = -EINVAL;
5226 goto rtn;
5227 }
5228
5229 port_id_array = of_get_property(pdev->dev.of_node,
5230 "qcom,msm-cpudai-tdm-group-port-id",
5231 &array_length);
5232 if (port_id_array == NULL) {
5233 dev_err(&pdev->dev, "%s port_id_array is not valid\n",
5234 __func__);
5235 rc = -EINVAL;
5236 goto rtn;
5237 }
5238 if (array_length != sizeof(uint32_t) * num_tdm_group_ports) {
5239 dev_err(&pdev->dev, "%s array_length is %d, expected is %zd\n",
5240 __func__, array_length,
5241 sizeof(uint32_t) * num_tdm_group_ports);
5242 rc = -EINVAL;
5243 goto rtn;
5244 }
5245
5246 for (i = 0; i < num_tdm_group_ports; i++)
5247 tdm_group_cfg.port_id[i] =
5248 (u16)be32_to_cpu(port_id_array[i]);
5249 /* Unused index should be filled with 0 or AFE_PORT_INVALID */
5250 for (i = num_tdm_group_ports; i < AFE_GROUP_DEVICE_NUM_PORTS; i++)
5251 tdm_group_cfg.port_id[i] =
5252 AFE_PORT_INVALID;
5253
5254 /* extract tdm clk info into static */
5255 rc = of_property_read_u32(pdev->dev.of_node,
5256 "qcom,msm-cpudai-tdm-clk-rate",
5257 &tdm_clk_set.clk_freq_in_hz);
5258 if (rc) {
5259 dev_err(&pdev->dev, "%s: Clk Rate from DT file %s\n",
5260 __func__, "qcom,msm-cpudai-tdm-clk-rate");
5261 goto rtn;
5262 }
5263 dev_dbg(&pdev->dev, "%s: Clk Rate from DT file %d\n",
5264 __func__, tdm_clk_set.clk_freq_in_hz);
5265
Cong Tang2b6adc82017-05-26 12:06:50 +08005266 /* initialize static tdm clk attribute to default value */
5267 tdm_clk_set.clk_attri = Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO;
5268
5269 /* extract tdm clk attribute into static */
5270 if (of_find_property(pdev->dev.of_node,
5271 "qcom,msm-cpudai-tdm-clk-attribute", NULL)) {
5272 rc = of_property_read_u16(pdev->dev.of_node,
5273 "qcom,msm-cpudai-tdm-clk-attribute",
5274 &tdm_clk_set.clk_attri);
5275 if (rc) {
5276 dev_err(&pdev->dev, "%s: value for clk attribute not found %s\n",
5277 __func__, "qcom,msm-cpudai-tdm-clk-attribute");
5278 goto rtn;
5279 }
5280 dev_dbg(&pdev->dev, "%s: clk attribute from DT file %d\n",
5281 __func__, tdm_clk_set.clk_attri);
5282 } else
5283 dev_dbg(&pdev->dev, "%s: clk attribute not found\n", __func__);
5284
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305285 /* extract tdm clk src master/slave info into static */
5286 rc = of_property_read_u32(pdev->dev.of_node,
5287 "qcom,msm-cpudai-tdm-clk-internal",
5288 &clk_mode);
5289 if (rc) {
5290 dev_err(&pdev->dev, "%s: Clk id from DT file %s\n",
5291 __func__, "qcom,msm-cpudai-tdm-clk-internal");
5292 goto rtn;
5293 }
5294 dev_dbg(&pdev->dev, "%s: Clk id from DT file %d\n",
5295 __func__, clk_mode);
5296
5297 rc = msm_dai_q6_tdm_set_clk_param(tdm_group_cfg.group_id,
5298 &tdm_clk_set, clk_mode);
5299 if (rc) {
5300 dev_err(&pdev->dev, "%s: group id not supported 0x%x\n",
5301 __func__, tdm_group_cfg.group_id);
5302 goto rtn;
5303 }
5304
5305 /* other initializations within device group */
5306 group_idx = msm_dai_q6_get_group_idx(tdm_group_cfg.group_id);
5307 if (group_idx < 0) {
5308 dev_err(&pdev->dev, "%s: group id 0x%x not supported\n",
5309 __func__, tdm_group_cfg.group_id);
5310 rc = -EINVAL;
5311 goto rtn;
5312 }
5313 atomic_set(&tdm_group_ref[group_idx], 0);
5314
5315 /* probe child node info */
5316 rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
5317 if (rc) {
5318 dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n",
5319 __func__, rc);
5320 goto rtn;
5321 } else
5322 dev_dbg(&pdev->dev, "%s: added child node\n", __func__);
5323
5324rtn:
5325 return rc;
5326}
5327
5328static int msm_dai_tdm_q6_remove(struct platform_device *pdev)
5329{
5330 return 0;
5331}
5332
5333static const struct of_device_id msm_dai_tdm_dt_match[] = {
5334 { .compatible = "qcom,msm-dai-tdm", },
5335 {}
5336};
5337
5338MODULE_DEVICE_TABLE(of, msm_dai_tdm_dt_match);
5339
5340static struct platform_driver msm_dai_tdm_q6 = {
5341 .probe = msm_dai_tdm_q6_probe,
5342 .remove = msm_dai_tdm_q6_remove,
5343 .driver = {
5344 .name = "msm-dai-tdm",
5345 .owner = THIS_MODULE,
5346 .of_match_table = msm_dai_tdm_dt_match,
5347 },
5348};
5349
5350static int msm_dai_q6_tdm_data_format_put(struct snd_kcontrol *kcontrol,
5351 struct snd_ctl_elem_value *ucontrol)
5352{
5353 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5354 int value = ucontrol->value.integer.value[0];
5355
5356 switch (value) {
5357 case 0:
5358 dai_data->port_cfg.tdm.data_format = AFE_LINEAR_PCM_DATA;
5359 break;
5360 case 1:
5361 dai_data->port_cfg.tdm.data_format = AFE_NON_LINEAR_DATA;
5362 break;
5363 case 2:
5364 dai_data->port_cfg.tdm.data_format = AFE_GENERIC_COMPRESSED;
5365 break;
5366 default:
5367 pr_err("%s: data_format invalid\n", __func__);
5368 break;
5369 }
5370 pr_debug("%s: data_format = %d\n",
5371 __func__, dai_data->port_cfg.tdm.data_format);
5372 return 0;
5373}
5374
5375static int msm_dai_q6_tdm_data_format_get(struct snd_kcontrol *kcontrol,
5376 struct snd_ctl_elem_value *ucontrol)
5377{
5378 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5379
5380 ucontrol->value.integer.value[0] =
5381 dai_data->port_cfg.tdm.data_format;
5382 pr_debug("%s: data_format = %d\n",
5383 __func__, dai_data->port_cfg.tdm.data_format);
5384 return 0;
5385}
5386
5387static int msm_dai_q6_tdm_header_type_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 dai_data->port_cfg.custom_tdm_header.header_type = value;
5394 pr_debug("%s: header_type = %d\n",
5395 __func__,
5396 dai_data->port_cfg.custom_tdm_header.header_type);
5397 return 0;
5398}
5399
5400static int msm_dai_q6_tdm_header_type_get(struct snd_kcontrol *kcontrol,
5401 struct snd_ctl_elem_value *ucontrol)
5402{
5403 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5404
5405 ucontrol->value.integer.value[0] =
5406 dai_data->port_cfg.custom_tdm_header.header_type;
5407 pr_debug("%s: header_type = %d\n",
5408 __func__,
5409 dai_data->port_cfg.custom_tdm_header.header_type);
5410 return 0;
5411}
5412
5413static int msm_dai_q6_tdm_header_put(struct snd_kcontrol *kcontrol,
5414 struct snd_ctl_elem_value *ucontrol)
5415{
5416 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5417 int i = 0;
5418
5419 for (i = 0; i < AFE_CUSTOM_TDM_HEADER_MAX_CNT; i++) {
5420 dai_data->port_cfg.custom_tdm_header.header[i] =
5421 (u16)ucontrol->value.integer.value[i];
5422 pr_debug("%s: header #%d = 0x%x\n",
5423 __func__, i,
5424 dai_data->port_cfg.custom_tdm_header.header[i]);
5425 }
5426 return 0;
5427}
5428
5429static int msm_dai_q6_tdm_header_get(struct snd_kcontrol *kcontrol,
5430 struct snd_ctl_elem_value *ucontrol)
5431{
5432 struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
5433 int i = 0;
5434
5435 for (i = 0; i < AFE_CUSTOM_TDM_HEADER_MAX_CNT; i++) {
5436 ucontrol->value.integer.value[i] =
5437 dai_data->port_cfg.custom_tdm_header.header[i];
5438 pr_debug("%s: header #%d = 0x%x\n",
5439 __func__, i,
5440 dai_data->port_cfg.custom_tdm_header.header[i]);
5441 }
5442 return 0;
5443}
5444
5445static const struct snd_kcontrol_new tdm_config_controls_data_format[] = {
5446 SOC_ENUM_EXT("PRI_TDM_RX_0 Data Format", tdm_config_enum[0],
5447 msm_dai_q6_tdm_data_format_get,
5448 msm_dai_q6_tdm_data_format_put),
5449 SOC_ENUM_EXT("PRI_TDM_RX_1 Data Format", tdm_config_enum[0],
5450 msm_dai_q6_tdm_data_format_get,
5451 msm_dai_q6_tdm_data_format_put),
5452 SOC_ENUM_EXT("PRI_TDM_RX_2 Data Format", tdm_config_enum[0],
5453 msm_dai_q6_tdm_data_format_get,
5454 msm_dai_q6_tdm_data_format_put),
5455 SOC_ENUM_EXT("PRI_TDM_RX_3 Data Format", tdm_config_enum[0],
5456 msm_dai_q6_tdm_data_format_get,
5457 msm_dai_q6_tdm_data_format_put),
5458 SOC_ENUM_EXT("PRI_TDM_RX_4 Data Format", tdm_config_enum[0],
5459 msm_dai_q6_tdm_data_format_get,
5460 msm_dai_q6_tdm_data_format_put),
5461 SOC_ENUM_EXT("PRI_TDM_RX_5 Data Format", tdm_config_enum[0],
5462 msm_dai_q6_tdm_data_format_get,
5463 msm_dai_q6_tdm_data_format_put),
5464 SOC_ENUM_EXT("PRI_TDM_RX_6 Data Format", tdm_config_enum[0],
5465 msm_dai_q6_tdm_data_format_get,
5466 msm_dai_q6_tdm_data_format_put),
5467 SOC_ENUM_EXT("PRI_TDM_RX_7 Data Format", tdm_config_enum[0],
5468 msm_dai_q6_tdm_data_format_get,
5469 msm_dai_q6_tdm_data_format_put),
5470 SOC_ENUM_EXT("PRI_TDM_TX_0 Data Format", tdm_config_enum[0],
5471 msm_dai_q6_tdm_data_format_get,
5472 msm_dai_q6_tdm_data_format_put),
5473 SOC_ENUM_EXT("PRI_TDM_TX_1 Data Format", tdm_config_enum[0],
5474 msm_dai_q6_tdm_data_format_get,
5475 msm_dai_q6_tdm_data_format_put),
5476 SOC_ENUM_EXT("PRI_TDM_TX_2 Data Format", tdm_config_enum[0],
5477 msm_dai_q6_tdm_data_format_get,
5478 msm_dai_q6_tdm_data_format_put),
5479 SOC_ENUM_EXT("PRI_TDM_TX_3 Data Format", tdm_config_enum[0],
5480 msm_dai_q6_tdm_data_format_get,
5481 msm_dai_q6_tdm_data_format_put),
5482 SOC_ENUM_EXT("PRI_TDM_TX_4 Data Format", tdm_config_enum[0],
5483 msm_dai_q6_tdm_data_format_get,
5484 msm_dai_q6_tdm_data_format_put),
5485 SOC_ENUM_EXT("PRI_TDM_TX_5 Data Format", tdm_config_enum[0],
5486 msm_dai_q6_tdm_data_format_get,
5487 msm_dai_q6_tdm_data_format_put),
5488 SOC_ENUM_EXT("PRI_TDM_TX_6 Data Format", tdm_config_enum[0],
5489 msm_dai_q6_tdm_data_format_get,
5490 msm_dai_q6_tdm_data_format_put),
5491 SOC_ENUM_EXT("PRI_TDM_TX_7 Data Format", tdm_config_enum[0],
5492 msm_dai_q6_tdm_data_format_get,
5493 msm_dai_q6_tdm_data_format_put),
5494 SOC_ENUM_EXT("SEC_TDM_RX_0 Data Format", tdm_config_enum[0],
5495 msm_dai_q6_tdm_data_format_get,
5496 msm_dai_q6_tdm_data_format_put),
5497 SOC_ENUM_EXT("SEC_TDM_RX_1 Data Format", tdm_config_enum[0],
5498 msm_dai_q6_tdm_data_format_get,
5499 msm_dai_q6_tdm_data_format_put),
5500 SOC_ENUM_EXT("SEC_TDM_RX_2 Data Format", tdm_config_enum[0],
5501 msm_dai_q6_tdm_data_format_get,
5502 msm_dai_q6_tdm_data_format_put),
5503 SOC_ENUM_EXT("SEC_TDM_RX_3 Data Format", tdm_config_enum[0],
5504 msm_dai_q6_tdm_data_format_get,
5505 msm_dai_q6_tdm_data_format_put),
5506 SOC_ENUM_EXT("SEC_TDM_RX_4 Data Format", tdm_config_enum[0],
5507 msm_dai_q6_tdm_data_format_get,
5508 msm_dai_q6_tdm_data_format_put),
5509 SOC_ENUM_EXT("SEC_TDM_RX_5 Data Format", tdm_config_enum[0],
5510 msm_dai_q6_tdm_data_format_get,
5511 msm_dai_q6_tdm_data_format_put),
5512 SOC_ENUM_EXT("SEC_TDM_RX_6 Data Format", tdm_config_enum[0],
5513 msm_dai_q6_tdm_data_format_get,
5514 msm_dai_q6_tdm_data_format_put),
5515 SOC_ENUM_EXT("SEC_TDM_RX_7 Data Format", tdm_config_enum[0],
5516 msm_dai_q6_tdm_data_format_get,
5517 msm_dai_q6_tdm_data_format_put),
5518 SOC_ENUM_EXT("SEC_TDM_TX_0 Data Format", tdm_config_enum[0],
5519 msm_dai_q6_tdm_data_format_get,
5520 msm_dai_q6_tdm_data_format_put),
5521 SOC_ENUM_EXT("SEC_TDM_TX_1 Data Format", tdm_config_enum[0],
5522 msm_dai_q6_tdm_data_format_get,
5523 msm_dai_q6_tdm_data_format_put),
5524 SOC_ENUM_EXT("SEC_TDM_TX_2 Data Format", tdm_config_enum[0],
5525 msm_dai_q6_tdm_data_format_get,
5526 msm_dai_q6_tdm_data_format_put),
5527 SOC_ENUM_EXT("SEC_TDM_TX_3 Data Format", tdm_config_enum[0],
5528 msm_dai_q6_tdm_data_format_get,
5529 msm_dai_q6_tdm_data_format_put),
5530 SOC_ENUM_EXT("SEC_TDM_TX_4 Data Format", tdm_config_enum[0],
5531 msm_dai_q6_tdm_data_format_get,
5532 msm_dai_q6_tdm_data_format_put),
5533 SOC_ENUM_EXT("SEC_TDM_TX_5 Data Format", tdm_config_enum[0],
5534 msm_dai_q6_tdm_data_format_get,
5535 msm_dai_q6_tdm_data_format_put),
5536 SOC_ENUM_EXT("SEC_TDM_TX_6 Data Format", tdm_config_enum[0],
5537 msm_dai_q6_tdm_data_format_get,
5538 msm_dai_q6_tdm_data_format_put),
5539 SOC_ENUM_EXT("SEC_TDM_TX_7 Data Format", tdm_config_enum[0],
5540 msm_dai_q6_tdm_data_format_get,
5541 msm_dai_q6_tdm_data_format_put),
5542 SOC_ENUM_EXT("TERT_TDM_RX_0 Data Format", tdm_config_enum[0],
5543 msm_dai_q6_tdm_data_format_get,
5544 msm_dai_q6_tdm_data_format_put),
5545 SOC_ENUM_EXT("TERT_TDM_RX_1 Data Format", tdm_config_enum[0],
5546 msm_dai_q6_tdm_data_format_get,
5547 msm_dai_q6_tdm_data_format_put),
5548 SOC_ENUM_EXT("TERT_TDM_RX_2 Data Format", tdm_config_enum[0],
5549 msm_dai_q6_tdm_data_format_get,
5550 msm_dai_q6_tdm_data_format_put),
5551 SOC_ENUM_EXT("TERT_TDM_RX_3 Data Format", tdm_config_enum[0],
5552 msm_dai_q6_tdm_data_format_get,
5553 msm_dai_q6_tdm_data_format_put),
5554 SOC_ENUM_EXT("TERT_TDM_RX_4 Data Format", tdm_config_enum[0],
5555 msm_dai_q6_tdm_data_format_get,
5556 msm_dai_q6_tdm_data_format_put),
5557 SOC_ENUM_EXT("TERT_TDM_RX_5 Data Format", tdm_config_enum[0],
5558 msm_dai_q6_tdm_data_format_get,
5559 msm_dai_q6_tdm_data_format_put),
5560 SOC_ENUM_EXT("TERT_TDM_RX_6 Data Format", tdm_config_enum[0],
5561 msm_dai_q6_tdm_data_format_get,
5562 msm_dai_q6_tdm_data_format_put),
5563 SOC_ENUM_EXT("TERT_TDM_RX_7 Data Format", tdm_config_enum[0],
5564 msm_dai_q6_tdm_data_format_get,
5565 msm_dai_q6_tdm_data_format_put),
5566 SOC_ENUM_EXT("TERT_TDM_TX_0 Data Format", tdm_config_enum[0],
5567 msm_dai_q6_tdm_data_format_get,
5568 msm_dai_q6_tdm_data_format_put),
5569 SOC_ENUM_EXT("TERT_TDM_TX_1 Data Format", tdm_config_enum[0],
5570 msm_dai_q6_tdm_data_format_get,
5571 msm_dai_q6_tdm_data_format_put),
5572 SOC_ENUM_EXT("TERT_TDM_TX_2 Data Format", tdm_config_enum[0],
5573 msm_dai_q6_tdm_data_format_get,
5574 msm_dai_q6_tdm_data_format_put),
5575 SOC_ENUM_EXT("TERT_TDM_TX_3 Data Format", tdm_config_enum[0],
5576 msm_dai_q6_tdm_data_format_get,
5577 msm_dai_q6_tdm_data_format_put),
5578 SOC_ENUM_EXT("TERT_TDM_TX_4 Data Format", tdm_config_enum[0],
5579 msm_dai_q6_tdm_data_format_get,
5580 msm_dai_q6_tdm_data_format_put),
5581 SOC_ENUM_EXT("TERT_TDM_TX_5 Data Format", tdm_config_enum[0],
5582 msm_dai_q6_tdm_data_format_get,
5583 msm_dai_q6_tdm_data_format_put),
5584 SOC_ENUM_EXT("TERT_TDM_TX_6 Data Format", tdm_config_enum[0],
5585 msm_dai_q6_tdm_data_format_get,
5586 msm_dai_q6_tdm_data_format_put),
5587 SOC_ENUM_EXT("TERT_TDM_TX_7 Data Format", tdm_config_enum[0],
5588 msm_dai_q6_tdm_data_format_get,
5589 msm_dai_q6_tdm_data_format_put),
5590 SOC_ENUM_EXT("QUAT_TDM_RX_0 Data Format", tdm_config_enum[0],
5591 msm_dai_q6_tdm_data_format_get,
5592 msm_dai_q6_tdm_data_format_put),
5593 SOC_ENUM_EXT("QUAT_TDM_RX_1 Data Format", tdm_config_enum[0],
5594 msm_dai_q6_tdm_data_format_get,
5595 msm_dai_q6_tdm_data_format_put),
5596 SOC_ENUM_EXT("QUAT_TDM_RX_2 Data Format", tdm_config_enum[0],
5597 msm_dai_q6_tdm_data_format_get,
5598 msm_dai_q6_tdm_data_format_put),
5599 SOC_ENUM_EXT("QUAT_TDM_RX_3 Data Format", tdm_config_enum[0],
5600 msm_dai_q6_tdm_data_format_get,
5601 msm_dai_q6_tdm_data_format_put),
5602 SOC_ENUM_EXT("QUAT_TDM_RX_4 Data Format", tdm_config_enum[0],
5603 msm_dai_q6_tdm_data_format_get,
5604 msm_dai_q6_tdm_data_format_put),
5605 SOC_ENUM_EXT("QUAT_TDM_RX_5 Data Format", tdm_config_enum[0],
5606 msm_dai_q6_tdm_data_format_get,
5607 msm_dai_q6_tdm_data_format_put),
5608 SOC_ENUM_EXT("QUAT_TDM_RX_6 Data Format", tdm_config_enum[0],
5609 msm_dai_q6_tdm_data_format_get,
5610 msm_dai_q6_tdm_data_format_put),
5611 SOC_ENUM_EXT("QUAT_TDM_RX_7 Data Format", tdm_config_enum[0],
5612 msm_dai_q6_tdm_data_format_get,
5613 msm_dai_q6_tdm_data_format_put),
5614 SOC_ENUM_EXT("QUAT_TDM_TX_0 Data Format", tdm_config_enum[0],
5615 msm_dai_q6_tdm_data_format_get,
5616 msm_dai_q6_tdm_data_format_put),
5617 SOC_ENUM_EXT("QUAT_TDM_TX_1 Data Format", tdm_config_enum[0],
5618 msm_dai_q6_tdm_data_format_get,
5619 msm_dai_q6_tdm_data_format_put),
5620 SOC_ENUM_EXT("QUAT_TDM_TX_2 Data Format", tdm_config_enum[0],
5621 msm_dai_q6_tdm_data_format_get,
5622 msm_dai_q6_tdm_data_format_put),
5623 SOC_ENUM_EXT("QUAT_TDM_TX_3 Data Format", tdm_config_enum[0],
5624 msm_dai_q6_tdm_data_format_get,
5625 msm_dai_q6_tdm_data_format_put),
5626 SOC_ENUM_EXT("QUAT_TDM_TX_4 Data Format", tdm_config_enum[0],
5627 msm_dai_q6_tdm_data_format_get,
5628 msm_dai_q6_tdm_data_format_put),
5629 SOC_ENUM_EXT("QUAT_TDM_TX_5 Data Format", tdm_config_enum[0],
5630 msm_dai_q6_tdm_data_format_get,
5631 msm_dai_q6_tdm_data_format_put),
5632 SOC_ENUM_EXT("QUAT_TDM_TX_6 Data Format", tdm_config_enum[0],
5633 msm_dai_q6_tdm_data_format_get,
5634 msm_dai_q6_tdm_data_format_put),
5635 SOC_ENUM_EXT("QUAT_TDM_TX_7 Data Format", tdm_config_enum[0],
5636 msm_dai_q6_tdm_data_format_get,
5637 msm_dai_q6_tdm_data_format_put),
Rohit Kumara5077932017-09-10 22:05:05 +05305638 SOC_ENUM_EXT("QUIN_TDM_RX_0 Data Format", tdm_config_enum[0],
5639 msm_dai_q6_tdm_data_format_get,
5640 msm_dai_q6_tdm_data_format_put),
5641 SOC_ENUM_EXT("QUIN_TDM_RX_1 Data Format", tdm_config_enum[0],
5642 msm_dai_q6_tdm_data_format_get,
5643 msm_dai_q6_tdm_data_format_put),
5644 SOC_ENUM_EXT("QUIN_TDM_RX_2 Data Format", tdm_config_enum[0],
5645 msm_dai_q6_tdm_data_format_get,
5646 msm_dai_q6_tdm_data_format_put),
5647 SOC_ENUM_EXT("QUIN_TDM_RX_3 Data Format", tdm_config_enum[0],
5648 msm_dai_q6_tdm_data_format_get,
5649 msm_dai_q6_tdm_data_format_put),
5650 SOC_ENUM_EXT("QUIN_TDM_RX_4 Data Format", tdm_config_enum[0],
5651 msm_dai_q6_tdm_data_format_get,
5652 msm_dai_q6_tdm_data_format_put),
5653 SOC_ENUM_EXT("QUIN_TDM_RX_5 Data Format", tdm_config_enum[0],
5654 msm_dai_q6_tdm_data_format_get,
5655 msm_dai_q6_tdm_data_format_put),
5656 SOC_ENUM_EXT("QUIN_TDM_RX_6 Data Format", tdm_config_enum[0],
5657 msm_dai_q6_tdm_data_format_get,
5658 msm_dai_q6_tdm_data_format_put),
5659 SOC_ENUM_EXT("QUIN_TDM_RX_7 Data Format", tdm_config_enum[0],
5660 msm_dai_q6_tdm_data_format_get,
5661 msm_dai_q6_tdm_data_format_put),
5662 SOC_ENUM_EXT("QUIN_TDM_TX_0 Data Format", tdm_config_enum[0],
5663 msm_dai_q6_tdm_data_format_get,
5664 msm_dai_q6_tdm_data_format_put),
5665 SOC_ENUM_EXT("QUIN_TDM_TX_1 Data Format", tdm_config_enum[0],
5666 msm_dai_q6_tdm_data_format_get,
5667 msm_dai_q6_tdm_data_format_put),
5668 SOC_ENUM_EXT("QUIN_TDM_TX_2 Data Format", tdm_config_enum[0],
5669 msm_dai_q6_tdm_data_format_get,
5670 msm_dai_q6_tdm_data_format_put),
5671 SOC_ENUM_EXT("QUIN_TDM_TX_3 Data Format", tdm_config_enum[0],
5672 msm_dai_q6_tdm_data_format_get,
5673 msm_dai_q6_tdm_data_format_put),
5674 SOC_ENUM_EXT("QUIN_TDM_TX_4 Data Format", tdm_config_enum[0],
5675 msm_dai_q6_tdm_data_format_get,
5676 msm_dai_q6_tdm_data_format_put),
5677 SOC_ENUM_EXT("QUIN_TDM_TX_5 Data Format", tdm_config_enum[0],
5678 msm_dai_q6_tdm_data_format_get,
5679 msm_dai_q6_tdm_data_format_put),
5680 SOC_ENUM_EXT("QUIN_TDM_TX_6 Data Format", tdm_config_enum[0],
5681 msm_dai_q6_tdm_data_format_get,
5682 msm_dai_q6_tdm_data_format_put),
5683 SOC_ENUM_EXT("QUIN_TDM_TX_7 Data Format", tdm_config_enum[0],
5684 msm_dai_q6_tdm_data_format_get,
5685 msm_dai_q6_tdm_data_format_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305686};
5687
5688static const struct snd_kcontrol_new tdm_config_controls_header_type[] = {
5689 SOC_ENUM_EXT("PRI_TDM_RX_0 Header Type", tdm_config_enum[1],
5690 msm_dai_q6_tdm_header_type_get,
5691 msm_dai_q6_tdm_header_type_put),
5692 SOC_ENUM_EXT("PRI_TDM_RX_1 Header Type", tdm_config_enum[1],
5693 msm_dai_q6_tdm_header_type_get,
5694 msm_dai_q6_tdm_header_type_put),
5695 SOC_ENUM_EXT("PRI_TDM_RX_2 Header Type", tdm_config_enum[1],
5696 msm_dai_q6_tdm_header_type_get,
5697 msm_dai_q6_tdm_header_type_put),
5698 SOC_ENUM_EXT("PRI_TDM_RX_3 Header Type", tdm_config_enum[1],
5699 msm_dai_q6_tdm_header_type_get,
5700 msm_dai_q6_tdm_header_type_put),
5701 SOC_ENUM_EXT("PRI_TDM_RX_4 Header Type", tdm_config_enum[1],
5702 msm_dai_q6_tdm_header_type_get,
5703 msm_dai_q6_tdm_header_type_put),
5704 SOC_ENUM_EXT("PRI_TDM_RX_5 Header Type", tdm_config_enum[1],
5705 msm_dai_q6_tdm_header_type_get,
5706 msm_dai_q6_tdm_header_type_put),
5707 SOC_ENUM_EXT("PRI_TDM_RX_6 Header Type", tdm_config_enum[1],
5708 msm_dai_q6_tdm_header_type_get,
5709 msm_dai_q6_tdm_header_type_put),
5710 SOC_ENUM_EXT("PRI_TDM_RX_7 Header Type", tdm_config_enum[1],
5711 msm_dai_q6_tdm_header_type_get,
5712 msm_dai_q6_tdm_header_type_put),
5713 SOC_ENUM_EXT("PRI_TDM_TX_0 Header Type", tdm_config_enum[1],
5714 msm_dai_q6_tdm_header_type_get,
5715 msm_dai_q6_tdm_header_type_put),
5716 SOC_ENUM_EXT("PRI_TDM_TX_1 Header Type", tdm_config_enum[1],
5717 msm_dai_q6_tdm_header_type_get,
5718 msm_dai_q6_tdm_header_type_put),
5719 SOC_ENUM_EXT("PRI_TDM_TX_2 Header Type", tdm_config_enum[1],
5720 msm_dai_q6_tdm_header_type_get,
5721 msm_dai_q6_tdm_header_type_put),
5722 SOC_ENUM_EXT("PRI_TDM_TX_3 Header Type", tdm_config_enum[1],
5723 msm_dai_q6_tdm_header_type_get,
5724 msm_dai_q6_tdm_header_type_put),
5725 SOC_ENUM_EXT("PRI_TDM_TX_4 Header Type", tdm_config_enum[1],
5726 msm_dai_q6_tdm_header_type_get,
5727 msm_dai_q6_tdm_header_type_put),
5728 SOC_ENUM_EXT("PRI_TDM_TX_5 Header Type", tdm_config_enum[1],
5729 msm_dai_q6_tdm_header_type_get,
5730 msm_dai_q6_tdm_header_type_put),
5731 SOC_ENUM_EXT("PRI_TDM_TX_6 Header Type", tdm_config_enum[1],
5732 msm_dai_q6_tdm_header_type_get,
5733 msm_dai_q6_tdm_header_type_put),
5734 SOC_ENUM_EXT("PRI_TDM_TX_7 Header Type", tdm_config_enum[1],
5735 msm_dai_q6_tdm_header_type_get,
5736 msm_dai_q6_tdm_header_type_put),
5737 SOC_ENUM_EXT("SEC_TDM_RX_0 Header Type", tdm_config_enum[1],
5738 msm_dai_q6_tdm_header_type_get,
5739 msm_dai_q6_tdm_header_type_put),
5740 SOC_ENUM_EXT("SEC_TDM_RX_1 Header Type", tdm_config_enum[1],
5741 msm_dai_q6_tdm_header_type_get,
5742 msm_dai_q6_tdm_header_type_put),
5743 SOC_ENUM_EXT("SEC_TDM_RX_2 Header Type", tdm_config_enum[1],
5744 msm_dai_q6_tdm_header_type_get,
5745 msm_dai_q6_tdm_header_type_put),
5746 SOC_ENUM_EXT("SEC_TDM_RX_3 Header Type", tdm_config_enum[1],
5747 msm_dai_q6_tdm_header_type_get,
5748 msm_dai_q6_tdm_header_type_put),
5749 SOC_ENUM_EXT("SEC_TDM_RX_4 Header Type", tdm_config_enum[1],
5750 msm_dai_q6_tdm_header_type_get,
5751 msm_dai_q6_tdm_header_type_put),
5752 SOC_ENUM_EXT("SEC_TDM_RX_5 Header Type", tdm_config_enum[1],
5753 msm_dai_q6_tdm_header_type_get,
5754 msm_dai_q6_tdm_header_type_put),
5755 SOC_ENUM_EXT("SEC_TDM_RX_6 Header Type", tdm_config_enum[1],
5756 msm_dai_q6_tdm_header_type_get,
5757 msm_dai_q6_tdm_header_type_put),
5758 SOC_ENUM_EXT("SEC_TDM_RX_7 Header Type", tdm_config_enum[1],
5759 msm_dai_q6_tdm_header_type_get,
5760 msm_dai_q6_tdm_header_type_put),
5761 SOC_ENUM_EXT("SEC_TDM_TX_0 Header Type", tdm_config_enum[1],
5762 msm_dai_q6_tdm_header_type_get,
5763 msm_dai_q6_tdm_header_type_put),
5764 SOC_ENUM_EXT("SEC_TDM_TX_1 Header Type", tdm_config_enum[1],
5765 msm_dai_q6_tdm_header_type_get,
5766 msm_dai_q6_tdm_header_type_put),
5767 SOC_ENUM_EXT("SEC_TDM_TX_2 Header Type", tdm_config_enum[1],
5768 msm_dai_q6_tdm_header_type_get,
5769 msm_dai_q6_tdm_header_type_put),
5770 SOC_ENUM_EXT("SEC_TDM_TX_3 Header Type", tdm_config_enum[1],
5771 msm_dai_q6_tdm_header_type_get,
5772 msm_dai_q6_tdm_header_type_put),
5773 SOC_ENUM_EXT("SEC_TDM_TX_4 Header Type", tdm_config_enum[1],
5774 msm_dai_q6_tdm_header_type_get,
5775 msm_dai_q6_tdm_header_type_put),
5776 SOC_ENUM_EXT("SEC_TDM_TX_5 Header Type", tdm_config_enum[1],
5777 msm_dai_q6_tdm_header_type_get,
5778 msm_dai_q6_tdm_header_type_put),
5779 SOC_ENUM_EXT("SEC_TDM_TX_6 Header Type", tdm_config_enum[1],
5780 msm_dai_q6_tdm_header_type_get,
5781 msm_dai_q6_tdm_header_type_put),
5782 SOC_ENUM_EXT("SEC_TDM_TX_7 Header Type", tdm_config_enum[1],
5783 msm_dai_q6_tdm_header_type_get,
5784 msm_dai_q6_tdm_header_type_put),
5785 SOC_ENUM_EXT("TERT_TDM_RX_0 Header Type", tdm_config_enum[1],
5786 msm_dai_q6_tdm_header_type_get,
5787 msm_dai_q6_tdm_header_type_put),
5788 SOC_ENUM_EXT("TERT_TDM_RX_1 Header Type", tdm_config_enum[1],
5789 msm_dai_q6_tdm_header_type_get,
5790 msm_dai_q6_tdm_header_type_put),
5791 SOC_ENUM_EXT("TERT_TDM_RX_2 Header Type", tdm_config_enum[1],
5792 msm_dai_q6_tdm_header_type_get,
5793 msm_dai_q6_tdm_header_type_put),
5794 SOC_ENUM_EXT("TERT_TDM_RX_3 Header Type", tdm_config_enum[1],
5795 msm_dai_q6_tdm_header_type_get,
5796 msm_dai_q6_tdm_header_type_put),
5797 SOC_ENUM_EXT("TERT_TDM_RX_4 Header Type", tdm_config_enum[1],
5798 msm_dai_q6_tdm_header_type_get,
5799 msm_dai_q6_tdm_header_type_put),
5800 SOC_ENUM_EXT("TERT_TDM_RX_5 Header Type", tdm_config_enum[1],
5801 msm_dai_q6_tdm_header_type_get,
5802 msm_dai_q6_tdm_header_type_put),
5803 SOC_ENUM_EXT("TERT_TDM_RX_6 Header Type", tdm_config_enum[1],
5804 msm_dai_q6_tdm_header_type_get,
5805 msm_dai_q6_tdm_header_type_put),
5806 SOC_ENUM_EXT("TERT_TDM_RX_7 Header Type", tdm_config_enum[1],
5807 msm_dai_q6_tdm_header_type_get,
5808 msm_dai_q6_tdm_header_type_put),
5809 SOC_ENUM_EXT("TERT_TDM_TX_0 Header Type", tdm_config_enum[1],
5810 msm_dai_q6_tdm_header_type_get,
5811 msm_dai_q6_tdm_header_type_put),
5812 SOC_ENUM_EXT("TERT_TDM_TX_1 Header Type", tdm_config_enum[1],
5813 msm_dai_q6_tdm_header_type_get,
5814 msm_dai_q6_tdm_header_type_put),
5815 SOC_ENUM_EXT("TERT_TDM_TX_2 Header Type", tdm_config_enum[1],
5816 msm_dai_q6_tdm_header_type_get,
5817 msm_dai_q6_tdm_header_type_put),
5818 SOC_ENUM_EXT("TERT_TDM_TX_3 Header Type", tdm_config_enum[1],
5819 msm_dai_q6_tdm_header_type_get,
5820 msm_dai_q6_tdm_header_type_put),
5821 SOC_ENUM_EXT("TERT_TDM_TX_4 Header Type", tdm_config_enum[1],
5822 msm_dai_q6_tdm_header_type_get,
5823 msm_dai_q6_tdm_header_type_put),
5824 SOC_ENUM_EXT("TERT_TDM_TX_5 Header Type", tdm_config_enum[1],
5825 msm_dai_q6_tdm_header_type_get,
5826 msm_dai_q6_tdm_header_type_put),
5827 SOC_ENUM_EXT("TERT_TDM_TX_6 Header Type", tdm_config_enum[1],
5828 msm_dai_q6_tdm_header_type_get,
5829 msm_dai_q6_tdm_header_type_put),
5830 SOC_ENUM_EXT("TERT_TDM_TX_7 Header Type", tdm_config_enum[1],
5831 msm_dai_q6_tdm_header_type_get,
5832 msm_dai_q6_tdm_header_type_put),
5833 SOC_ENUM_EXT("QUAT_TDM_RX_0 Header Type", tdm_config_enum[1],
5834 msm_dai_q6_tdm_header_type_get,
5835 msm_dai_q6_tdm_header_type_put),
5836 SOC_ENUM_EXT("QUAT_TDM_RX_1 Header Type", tdm_config_enum[1],
5837 msm_dai_q6_tdm_header_type_get,
5838 msm_dai_q6_tdm_header_type_put),
5839 SOC_ENUM_EXT("QUAT_TDM_RX_2 Header Type", tdm_config_enum[1],
5840 msm_dai_q6_tdm_header_type_get,
5841 msm_dai_q6_tdm_header_type_put),
5842 SOC_ENUM_EXT("QUAT_TDM_RX_3 Header Type", tdm_config_enum[1],
5843 msm_dai_q6_tdm_header_type_get,
5844 msm_dai_q6_tdm_header_type_put),
5845 SOC_ENUM_EXT("QUAT_TDM_RX_4 Header Type", tdm_config_enum[1],
5846 msm_dai_q6_tdm_header_type_get,
5847 msm_dai_q6_tdm_header_type_put),
5848 SOC_ENUM_EXT("QUAT_TDM_RX_5 Header Type", tdm_config_enum[1],
5849 msm_dai_q6_tdm_header_type_get,
5850 msm_dai_q6_tdm_header_type_put),
5851 SOC_ENUM_EXT("QUAT_TDM_RX_6 Header Type", tdm_config_enum[1],
5852 msm_dai_q6_tdm_header_type_get,
5853 msm_dai_q6_tdm_header_type_put),
5854 SOC_ENUM_EXT("QUAT_TDM_RX_7 Header Type", tdm_config_enum[1],
5855 msm_dai_q6_tdm_header_type_get,
5856 msm_dai_q6_tdm_header_type_put),
5857 SOC_ENUM_EXT("QUAT_TDM_TX_0 Header Type", tdm_config_enum[1],
5858 msm_dai_q6_tdm_header_type_get,
5859 msm_dai_q6_tdm_header_type_put),
5860 SOC_ENUM_EXT("QUAT_TDM_TX_1 Header Type", tdm_config_enum[1],
5861 msm_dai_q6_tdm_header_type_get,
5862 msm_dai_q6_tdm_header_type_put),
5863 SOC_ENUM_EXT("QUAT_TDM_TX_2 Header Type", tdm_config_enum[1],
5864 msm_dai_q6_tdm_header_type_get,
5865 msm_dai_q6_tdm_header_type_put),
5866 SOC_ENUM_EXT("QUAT_TDM_TX_3 Header Type", tdm_config_enum[1],
5867 msm_dai_q6_tdm_header_type_get,
5868 msm_dai_q6_tdm_header_type_put),
5869 SOC_ENUM_EXT("QUAT_TDM_TX_4 Header Type", tdm_config_enum[1],
5870 msm_dai_q6_tdm_header_type_get,
5871 msm_dai_q6_tdm_header_type_put),
5872 SOC_ENUM_EXT("QUAT_TDM_TX_5 Header Type", tdm_config_enum[1],
5873 msm_dai_q6_tdm_header_type_get,
5874 msm_dai_q6_tdm_header_type_put),
5875 SOC_ENUM_EXT("QUAT_TDM_TX_6 Header Type", tdm_config_enum[1],
5876 msm_dai_q6_tdm_header_type_get,
5877 msm_dai_q6_tdm_header_type_put),
5878 SOC_ENUM_EXT("QUAT_TDM_TX_7 Header Type", tdm_config_enum[1],
5879 msm_dai_q6_tdm_header_type_get,
5880 msm_dai_q6_tdm_header_type_put),
Rohit Kumara5077932017-09-10 22:05:05 +05305881 SOC_ENUM_EXT("QUIN_TDM_RX_0 Header Type", tdm_config_enum[1],
5882 msm_dai_q6_tdm_header_type_get,
5883 msm_dai_q6_tdm_header_type_put),
5884 SOC_ENUM_EXT("QUIN_TDM_RX_1 Header Type", tdm_config_enum[1],
5885 msm_dai_q6_tdm_header_type_get,
5886 msm_dai_q6_tdm_header_type_put),
5887 SOC_ENUM_EXT("QUIN_TDM_RX_2 Header Type", tdm_config_enum[1],
5888 msm_dai_q6_tdm_header_type_get,
5889 msm_dai_q6_tdm_header_type_put),
5890 SOC_ENUM_EXT("QUIN_TDM_RX_3 Header Type", tdm_config_enum[1],
5891 msm_dai_q6_tdm_header_type_get,
5892 msm_dai_q6_tdm_header_type_put),
5893 SOC_ENUM_EXT("QUIN_TDM_RX_4 Header Type", tdm_config_enum[1],
5894 msm_dai_q6_tdm_header_type_get,
5895 msm_dai_q6_tdm_header_type_put),
5896 SOC_ENUM_EXT("QUIN_TDM_RX_5 Header Type", tdm_config_enum[1],
5897 msm_dai_q6_tdm_header_type_get,
5898 msm_dai_q6_tdm_header_type_put),
5899 SOC_ENUM_EXT("QUIN_TDM_RX_6 Header Type", tdm_config_enum[1],
5900 msm_dai_q6_tdm_header_type_get,
5901 msm_dai_q6_tdm_header_type_put),
5902 SOC_ENUM_EXT("QUIN_TDM_RX_7 Header Type", tdm_config_enum[1],
5903 msm_dai_q6_tdm_header_type_get,
5904 msm_dai_q6_tdm_header_type_put),
5905 SOC_ENUM_EXT("QUIN_TDM_TX_0 Header Type", tdm_config_enum[1],
5906 msm_dai_q6_tdm_header_type_get,
5907 msm_dai_q6_tdm_header_type_put),
5908 SOC_ENUM_EXT("QUIN_TDM_TX_1 Header Type", tdm_config_enum[1],
5909 msm_dai_q6_tdm_header_type_get,
5910 msm_dai_q6_tdm_header_type_put),
5911 SOC_ENUM_EXT("QUIN_TDM_TX_2 Header Type", tdm_config_enum[1],
5912 msm_dai_q6_tdm_header_type_get,
5913 msm_dai_q6_tdm_header_type_put),
5914 SOC_ENUM_EXT("QUIN_TDM_TX_3 Header Type", tdm_config_enum[1],
5915 msm_dai_q6_tdm_header_type_get,
5916 msm_dai_q6_tdm_header_type_put),
5917 SOC_ENUM_EXT("QUIN_TDM_TX_4 Header Type", tdm_config_enum[1],
5918 msm_dai_q6_tdm_header_type_get,
5919 msm_dai_q6_tdm_header_type_put),
5920 SOC_ENUM_EXT("QUIN_TDM_TX_5 Header Type", tdm_config_enum[1],
5921 msm_dai_q6_tdm_header_type_get,
5922 msm_dai_q6_tdm_header_type_put),
5923 SOC_ENUM_EXT("QUIN_TDM_TX_6 Header Type", tdm_config_enum[1],
5924 msm_dai_q6_tdm_header_type_get,
5925 msm_dai_q6_tdm_header_type_put),
5926 SOC_ENUM_EXT("QUIN_TDM_TX_7 Header Type", tdm_config_enum[1],
5927 msm_dai_q6_tdm_header_type_get,
5928 msm_dai_q6_tdm_header_type_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305929};
5930
5931static const struct snd_kcontrol_new tdm_config_controls_header[] = {
5932 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_0 Header",
5933 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5934 msm_dai_q6_tdm_header_get,
5935 msm_dai_q6_tdm_header_put),
5936 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_1 Header",
5937 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5938 msm_dai_q6_tdm_header_get,
5939 msm_dai_q6_tdm_header_put),
5940 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_2 Header",
5941 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5942 msm_dai_q6_tdm_header_get,
5943 msm_dai_q6_tdm_header_put),
5944 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_3 Header",
5945 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5946 msm_dai_q6_tdm_header_get,
5947 msm_dai_q6_tdm_header_put),
5948 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_4 Header",
5949 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5950 msm_dai_q6_tdm_header_get,
5951 msm_dai_q6_tdm_header_put),
5952 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_5 Header",
5953 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5954 msm_dai_q6_tdm_header_get,
5955 msm_dai_q6_tdm_header_put),
5956 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_6 Header",
5957 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5958 msm_dai_q6_tdm_header_get,
5959 msm_dai_q6_tdm_header_put),
5960 SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_7 Header",
5961 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5962 msm_dai_q6_tdm_header_get,
5963 msm_dai_q6_tdm_header_put),
5964 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_0 Header",
5965 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5966 msm_dai_q6_tdm_header_get,
5967 msm_dai_q6_tdm_header_put),
5968 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_1 Header",
5969 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5970 msm_dai_q6_tdm_header_get,
5971 msm_dai_q6_tdm_header_put),
5972 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_2 Header",
5973 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5974 msm_dai_q6_tdm_header_get,
5975 msm_dai_q6_tdm_header_put),
5976 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_3 Header",
5977 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5978 msm_dai_q6_tdm_header_get,
5979 msm_dai_q6_tdm_header_put),
5980 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_4 Header",
5981 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5982 msm_dai_q6_tdm_header_get,
5983 msm_dai_q6_tdm_header_put),
5984 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_5 Header",
5985 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5986 msm_dai_q6_tdm_header_get,
5987 msm_dai_q6_tdm_header_put),
5988 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_6 Header",
5989 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5990 msm_dai_q6_tdm_header_get,
5991 msm_dai_q6_tdm_header_put),
5992 SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_7 Header",
5993 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5994 msm_dai_q6_tdm_header_get,
5995 msm_dai_q6_tdm_header_put),
5996 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_0 Header",
5997 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
5998 msm_dai_q6_tdm_header_get,
5999 msm_dai_q6_tdm_header_put),
6000 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_1 Header",
6001 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6002 msm_dai_q6_tdm_header_get,
6003 msm_dai_q6_tdm_header_put),
6004 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_2 Header",
6005 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6006 msm_dai_q6_tdm_header_get,
6007 msm_dai_q6_tdm_header_put),
6008 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_3 Header",
6009 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6010 msm_dai_q6_tdm_header_get,
6011 msm_dai_q6_tdm_header_put),
6012 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_4 Header",
6013 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6014 msm_dai_q6_tdm_header_get,
6015 msm_dai_q6_tdm_header_put),
6016 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_5 Header",
6017 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6018 msm_dai_q6_tdm_header_get,
6019 msm_dai_q6_tdm_header_put),
6020 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_6 Header",
6021 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6022 msm_dai_q6_tdm_header_get,
6023 msm_dai_q6_tdm_header_put),
6024 SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_7 Header",
6025 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6026 msm_dai_q6_tdm_header_get,
6027 msm_dai_q6_tdm_header_put),
6028 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_0 Header",
6029 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6030 msm_dai_q6_tdm_header_get,
6031 msm_dai_q6_tdm_header_put),
6032 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_1 Header",
6033 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6034 msm_dai_q6_tdm_header_get,
6035 msm_dai_q6_tdm_header_put),
6036 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_2 Header",
6037 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6038 msm_dai_q6_tdm_header_get,
6039 msm_dai_q6_tdm_header_put),
6040 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_3 Header",
6041 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6042 msm_dai_q6_tdm_header_get,
6043 msm_dai_q6_tdm_header_put),
6044 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_4 Header",
6045 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6046 msm_dai_q6_tdm_header_get,
6047 msm_dai_q6_tdm_header_put),
6048 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_5 Header",
6049 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6050 msm_dai_q6_tdm_header_get,
6051 msm_dai_q6_tdm_header_put),
6052 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_6 Header",
6053 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6054 msm_dai_q6_tdm_header_get,
6055 msm_dai_q6_tdm_header_put),
6056 SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_7 Header",
6057 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6058 msm_dai_q6_tdm_header_get,
6059 msm_dai_q6_tdm_header_put),
6060 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_0 Header",
6061 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6062 msm_dai_q6_tdm_header_get,
6063 msm_dai_q6_tdm_header_put),
6064 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_1 Header",
6065 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6066 msm_dai_q6_tdm_header_get,
6067 msm_dai_q6_tdm_header_put),
6068 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_2 Header",
6069 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6070 msm_dai_q6_tdm_header_get,
6071 msm_dai_q6_tdm_header_put),
6072 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_3 Header",
6073 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6074 msm_dai_q6_tdm_header_get,
6075 msm_dai_q6_tdm_header_put),
6076 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_4 Header",
6077 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6078 msm_dai_q6_tdm_header_get,
6079 msm_dai_q6_tdm_header_put),
6080 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_5 Header",
6081 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6082 msm_dai_q6_tdm_header_get,
6083 msm_dai_q6_tdm_header_put),
6084 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_6 Header",
6085 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6086 msm_dai_q6_tdm_header_get,
6087 msm_dai_q6_tdm_header_put),
6088 SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_7 Header",
6089 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6090 msm_dai_q6_tdm_header_get,
6091 msm_dai_q6_tdm_header_put),
6092 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_0 Header",
6093 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6094 msm_dai_q6_tdm_header_get,
6095 msm_dai_q6_tdm_header_put),
6096 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_1 Header",
6097 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6098 msm_dai_q6_tdm_header_get,
6099 msm_dai_q6_tdm_header_put),
6100 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_2 Header",
6101 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6102 msm_dai_q6_tdm_header_get,
6103 msm_dai_q6_tdm_header_put),
6104 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_3 Header",
6105 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6106 msm_dai_q6_tdm_header_get,
6107 msm_dai_q6_tdm_header_put),
6108 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_4 Header",
6109 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6110 msm_dai_q6_tdm_header_get,
6111 msm_dai_q6_tdm_header_put),
6112 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_5 Header",
6113 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6114 msm_dai_q6_tdm_header_get,
6115 msm_dai_q6_tdm_header_put),
6116 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_6 Header",
6117 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6118 msm_dai_q6_tdm_header_get,
6119 msm_dai_q6_tdm_header_put),
6120 SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_7 Header",
6121 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6122 msm_dai_q6_tdm_header_get,
6123 msm_dai_q6_tdm_header_put),
6124 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_0 Header",
6125 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6126 msm_dai_q6_tdm_header_get,
6127 msm_dai_q6_tdm_header_put),
6128 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_1 Header",
6129 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6130 msm_dai_q6_tdm_header_get,
6131 msm_dai_q6_tdm_header_put),
6132 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_2 Header",
6133 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6134 msm_dai_q6_tdm_header_get,
6135 msm_dai_q6_tdm_header_put),
6136 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_3 Header",
6137 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6138 msm_dai_q6_tdm_header_get,
6139 msm_dai_q6_tdm_header_put),
6140 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_4 Header",
6141 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6142 msm_dai_q6_tdm_header_get,
6143 msm_dai_q6_tdm_header_put),
6144 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_5 Header",
6145 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6146 msm_dai_q6_tdm_header_get,
6147 msm_dai_q6_tdm_header_put),
6148 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_6 Header",
6149 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6150 msm_dai_q6_tdm_header_get,
6151 msm_dai_q6_tdm_header_put),
6152 SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_7 Header",
6153 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6154 msm_dai_q6_tdm_header_get,
6155 msm_dai_q6_tdm_header_put),
6156 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_0 Header",
6157 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6158 msm_dai_q6_tdm_header_get,
6159 msm_dai_q6_tdm_header_put),
6160 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_1 Header",
6161 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6162 msm_dai_q6_tdm_header_get,
6163 msm_dai_q6_tdm_header_put),
6164 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_2 Header",
6165 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6166 msm_dai_q6_tdm_header_get,
6167 msm_dai_q6_tdm_header_put),
6168 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_3 Header",
6169 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6170 msm_dai_q6_tdm_header_get,
6171 msm_dai_q6_tdm_header_put),
6172 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_4 Header",
6173 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6174 msm_dai_q6_tdm_header_get,
6175 msm_dai_q6_tdm_header_put),
6176 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_5 Header",
6177 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6178 msm_dai_q6_tdm_header_get,
6179 msm_dai_q6_tdm_header_put),
6180 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_6 Header",
6181 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6182 msm_dai_q6_tdm_header_get,
6183 msm_dai_q6_tdm_header_put),
6184 SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_7 Header",
6185 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6186 msm_dai_q6_tdm_header_get,
6187 msm_dai_q6_tdm_header_put),
Rohit Kumara5077932017-09-10 22:05:05 +05306188 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_0 Header",
6189 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6190 msm_dai_q6_tdm_header_get,
6191 msm_dai_q6_tdm_header_put),
6192 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_1 Header",
6193 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6194 msm_dai_q6_tdm_header_get,
6195 msm_dai_q6_tdm_header_put),
6196 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_2 Header",
6197 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6198 msm_dai_q6_tdm_header_get,
6199 msm_dai_q6_tdm_header_put),
6200 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_3 Header",
6201 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6202 msm_dai_q6_tdm_header_get,
6203 msm_dai_q6_tdm_header_put),
6204 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_4 Header",
6205 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6206 msm_dai_q6_tdm_header_get,
6207 msm_dai_q6_tdm_header_put),
6208 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_5 Header",
6209 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6210 msm_dai_q6_tdm_header_get,
6211 msm_dai_q6_tdm_header_put),
6212 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_6 Header",
6213 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6214 msm_dai_q6_tdm_header_get,
6215 msm_dai_q6_tdm_header_put),
6216 SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_7 Header",
6217 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6218 msm_dai_q6_tdm_header_get,
6219 msm_dai_q6_tdm_header_put),
6220 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_0 Header",
6221 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6222 msm_dai_q6_tdm_header_get,
6223 msm_dai_q6_tdm_header_put),
6224 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_1 Header",
6225 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6226 msm_dai_q6_tdm_header_get,
6227 msm_dai_q6_tdm_header_put),
6228 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_2 Header",
6229 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6230 msm_dai_q6_tdm_header_get,
6231 msm_dai_q6_tdm_header_put),
6232 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_3 Header",
6233 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6234 msm_dai_q6_tdm_header_get,
6235 msm_dai_q6_tdm_header_put),
6236 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_4 Header",
6237 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6238 msm_dai_q6_tdm_header_get,
6239 msm_dai_q6_tdm_header_put),
6240 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_5 Header",
6241 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6242 msm_dai_q6_tdm_header_get,
6243 msm_dai_q6_tdm_header_put),
6244 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_6 Header",
6245 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6246 msm_dai_q6_tdm_header_get,
6247 msm_dai_q6_tdm_header_put),
6248 SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_7 Header",
6249 SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8,
6250 msm_dai_q6_tdm_header_get,
6251 msm_dai_q6_tdm_header_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306252};
6253
6254static int msm_dai_q6_tdm_set_clk(
6255 struct msm_dai_q6_tdm_dai_data *dai_data,
6256 u16 port_id, bool enable)
6257{
6258 int rc = 0;
6259
6260 dai_data->clk_set.enable = enable;
6261
6262 rc = afe_set_lpass_clock_v2(port_id,
6263 &dai_data->clk_set);
6264 if (rc < 0)
6265 pr_err("%s: afe lpass clock failed, err:%d\n",
6266 __func__, rc);
6267
6268 return rc;
6269}
6270
6271static int msm_dai_q6_dai_tdm_probe(struct snd_soc_dai *dai)
6272{
6273 int rc = 0;
6274 struct msm_dai_q6_tdm_dai_data *tdm_dai_data =
6275 dev_get_drvdata(dai->dev);
6276 struct snd_kcontrol *data_format_kcontrol = NULL;
6277 struct snd_kcontrol *header_type_kcontrol = NULL;
6278 struct snd_kcontrol *header_kcontrol = NULL;
6279 int port_idx = 0;
6280 const struct snd_kcontrol_new *data_format_ctrl = NULL;
6281 const struct snd_kcontrol_new *header_type_ctrl = NULL;
6282 const struct snd_kcontrol_new *header_ctrl = NULL;
6283
6284 msm_dai_q6_set_dai_id(dai);
6285
6286 port_idx = msm_dai_q6_get_port_idx(dai->id);
6287 if (port_idx < 0) {
6288 dev_err(dai->dev, "%s port id 0x%x not supported\n",
6289 __func__, dai->id);
6290 rc = -EINVAL;
6291 goto rtn;
6292 }
6293
6294 data_format_ctrl =
6295 &tdm_config_controls_data_format[port_idx];
6296 header_type_ctrl =
6297 &tdm_config_controls_header_type[port_idx];
6298 header_ctrl =
6299 &tdm_config_controls_header[port_idx];
6300
6301 if (data_format_ctrl) {
6302 data_format_kcontrol = snd_ctl_new1(data_format_ctrl,
6303 tdm_dai_data);
6304 rc = snd_ctl_add(dai->component->card->snd_card,
6305 data_format_kcontrol);
6306 if (rc < 0) {
6307 dev_err(dai->dev, "%s: err add data format ctrl DAI = %s\n",
6308 __func__, dai->name);
6309 goto rtn;
6310 }
6311 }
6312
6313 if (header_type_ctrl) {
6314 header_type_kcontrol = snd_ctl_new1(header_type_ctrl,
6315 tdm_dai_data);
6316 rc = snd_ctl_add(dai->component->card->snd_card,
6317 header_type_kcontrol);
6318 if (rc < 0) {
6319 if (data_format_kcontrol)
6320 snd_ctl_remove(dai->component->card->snd_card,
6321 data_format_kcontrol);
6322 dev_err(dai->dev, "%s: err add header type ctrl DAI = %s\n",
6323 __func__, dai->name);
6324 goto rtn;
6325 }
6326 }
6327
6328 if (header_ctrl) {
6329 header_kcontrol = snd_ctl_new1(header_ctrl,
6330 tdm_dai_data);
6331 rc = snd_ctl_add(dai->component->card->snd_card,
6332 header_kcontrol);
6333 if (rc < 0) {
6334 if (header_type_kcontrol)
6335 snd_ctl_remove(dai->component->card->snd_card,
6336 header_type_kcontrol);
6337 if (data_format_kcontrol)
6338 snd_ctl_remove(dai->component->card->snd_card,
6339 data_format_kcontrol);
6340 dev_err(dai->dev, "%s: err add header ctrl DAI = %s\n",
6341 __func__, dai->name);
6342 goto rtn;
6343 }
6344 }
6345
6346 rc = msm_dai_q6_dai_add_route(dai);
6347
6348rtn:
6349 return rc;
6350}
6351
6352
6353static int msm_dai_q6_dai_tdm_remove(struct snd_soc_dai *dai)
6354{
6355 int rc = 0;
6356 struct msm_dai_q6_tdm_dai_data *tdm_dai_data =
6357 dev_get_drvdata(dai->dev);
6358 u16 group_id = tdm_dai_data->group_cfg.tdm_cfg.group_id;
6359 int group_idx = 0;
6360 atomic_t *group_ref = NULL;
6361
6362 group_idx = msm_dai_q6_get_group_idx(dai->id);
6363 if (group_idx < 0) {
6364 dev_err(dai->dev, "%s port id 0x%x not supported\n",
6365 __func__, dai->id);
6366 return -EINVAL;
6367 }
6368
6369 group_ref = &tdm_group_ref[group_idx];
6370
6371 /* If AFE port is still up, close it */
6372 if (test_bit(STATUS_PORT_STARTED, tdm_dai_data->status_mask)) {
6373 rc = afe_close(dai->id); /* can block */
6374 if (rc < 0) {
6375 dev_err(dai->dev, "%s: fail to close AFE port 0x%x\n",
6376 __func__, dai->id);
6377 }
6378 atomic_dec(group_ref);
6379 clear_bit(STATUS_PORT_STARTED,
6380 tdm_dai_data->status_mask);
6381
6382 if (atomic_read(group_ref) == 0) {
6383 rc = afe_port_group_enable(group_id,
6384 NULL, false);
6385 if (rc < 0) {
6386 dev_err(dai->dev, "fail to disable AFE group 0x%x\n",
6387 group_id);
6388 }
6389 rc = msm_dai_q6_tdm_set_clk(tdm_dai_data,
6390 dai->id, false);
6391 if (rc < 0) {
6392 dev_err(dai->dev, "%s: fail to disable AFE clk 0x%x\n",
6393 __func__, dai->id);
6394 }
6395 }
6396 }
6397
6398 return 0;
6399}
6400
6401static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai,
6402 unsigned int tx_mask,
6403 unsigned int rx_mask,
6404 int slots, int slot_width)
6405{
6406 int rc = 0;
6407 struct msm_dai_q6_tdm_dai_data *dai_data =
6408 dev_get_drvdata(dai->dev);
6409 struct afe_param_id_group_device_tdm_cfg *tdm_group =
6410 &dai_data->group_cfg.tdm_cfg;
6411 unsigned int cap_mask;
6412
6413 dev_dbg(dai->dev, "%s: dai id = 0x%x\n", __func__, dai->id);
6414
6415 /* HW only supports 16 and 32 bit slot width configuration */
6416 if ((slot_width != 16) && (slot_width != 32)) {
6417 dev_err(dai->dev, "%s: invalid slot_width %d\n",
6418 __func__, slot_width);
6419 return -EINVAL;
6420 }
6421
Xiaoyu Ye1cb5ce02017-09-12 18:19:08 -07006422 /* HW supports 1-32 slots configuration. Typical: 1, 2, 4, 8, 16, 32 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306423 switch (slots) {
6424 case 2:
6425 cap_mask = 0x03;
6426 break;
Xiaoyu Ye1cb5ce02017-09-12 18:19:08 -07006427 case 4:
6428 cap_mask = 0x0F;
6429 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306430 case 8:
6431 cap_mask = 0xFF;
6432 break;
6433 case 16:
6434 cap_mask = 0xFFFF;
6435 break;
6436 default:
6437 dev_err(dai->dev, "%s: invalid slots %d\n",
6438 __func__, slots);
6439 return -EINVAL;
6440 }
6441
6442 switch (dai->id) {
6443 case AFE_PORT_ID_PRIMARY_TDM_RX:
6444 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
6445 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
6446 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
6447 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
6448 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
6449 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
6450 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
6451 case AFE_PORT_ID_SECONDARY_TDM_RX:
6452 case AFE_PORT_ID_SECONDARY_TDM_RX_1:
6453 case AFE_PORT_ID_SECONDARY_TDM_RX_2:
6454 case AFE_PORT_ID_SECONDARY_TDM_RX_3:
6455 case AFE_PORT_ID_SECONDARY_TDM_RX_4:
6456 case AFE_PORT_ID_SECONDARY_TDM_RX_5:
6457 case AFE_PORT_ID_SECONDARY_TDM_RX_6:
6458 case AFE_PORT_ID_SECONDARY_TDM_RX_7:
6459 case AFE_PORT_ID_TERTIARY_TDM_RX:
6460 case AFE_PORT_ID_TERTIARY_TDM_RX_1:
6461 case AFE_PORT_ID_TERTIARY_TDM_RX_2:
6462 case AFE_PORT_ID_TERTIARY_TDM_RX_3:
6463 case AFE_PORT_ID_TERTIARY_TDM_RX_4:
6464 case AFE_PORT_ID_TERTIARY_TDM_RX_5:
6465 case AFE_PORT_ID_TERTIARY_TDM_RX_6:
6466 case AFE_PORT_ID_TERTIARY_TDM_RX_7:
6467 case AFE_PORT_ID_QUATERNARY_TDM_RX:
6468 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
6469 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
6470 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
6471 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
6472 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
6473 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
6474 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
Rohit Kumara5077932017-09-10 22:05:05 +05306475 case AFE_PORT_ID_QUINARY_TDM_RX:
6476 case AFE_PORT_ID_QUINARY_TDM_RX_1:
6477 case AFE_PORT_ID_QUINARY_TDM_RX_2:
6478 case AFE_PORT_ID_QUINARY_TDM_RX_3:
6479 case AFE_PORT_ID_QUINARY_TDM_RX_4:
6480 case AFE_PORT_ID_QUINARY_TDM_RX_5:
6481 case AFE_PORT_ID_QUINARY_TDM_RX_6:
6482 case AFE_PORT_ID_QUINARY_TDM_RX_7:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306483 tdm_group->nslots_per_frame = slots;
6484 tdm_group->slot_width = slot_width;
6485 tdm_group->slot_mask = rx_mask & cap_mask;
6486 break;
6487 case AFE_PORT_ID_PRIMARY_TDM_TX:
6488 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
6489 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
6490 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
6491 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
6492 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
6493 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
6494 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
6495 case AFE_PORT_ID_SECONDARY_TDM_TX:
6496 case AFE_PORT_ID_SECONDARY_TDM_TX_1:
6497 case AFE_PORT_ID_SECONDARY_TDM_TX_2:
6498 case AFE_PORT_ID_SECONDARY_TDM_TX_3:
6499 case AFE_PORT_ID_SECONDARY_TDM_TX_4:
6500 case AFE_PORT_ID_SECONDARY_TDM_TX_5:
6501 case AFE_PORT_ID_SECONDARY_TDM_TX_6:
6502 case AFE_PORT_ID_SECONDARY_TDM_TX_7:
6503 case AFE_PORT_ID_TERTIARY_TDM_TX:
6504 case AFE_PORT_ID_TERTIARY_TDM_TX_1:
6505 case AFE_PORT_ID_TERTIARY_TDM_TX_2:
6506 case AFE_PORT_ID_TERTIARY_TDM_TX_3:
6507 case AFE_PORT_ID_TERTIARY_TDM_TX_4:
6508 case AFE_PORT_ID_TERTIARY_TDM_TX_5:
6509 case AFE_PORT_ID_TERTIARY_TDM_TX_6:
6510 case AFE_PORT_ID_TERTIARY_TDM_TX_7:
6511 case AFE_PORT_ID_QUATERNARY_TDM_TX:
6512 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
6513 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
6514 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
6515 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
6516 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
6517 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
6518 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
Rohit Kumara5077932017-09-10 22:05:05 +05306519 case AFE_PORT_ID_QUINARY_TDM_TX:
6520 case AFE_PORT_ID_QUINARY_TDM_TX_1:
6521 case AFE_PORT_ID_QUINARY_TDM_TX_2:
6522 case AFE_PORT_ID_QUINARY_TDM_TX_3:
6523 case AFE_PORT_ID_QUINARY_TDM_TX_4:
6524 case AFE_PORT_ID_QUINARY_TDM_TX_5:
6525 case AFE_PORT_ID_QUINARY_TDM_TX_6:
6526 case AFE_PORT_ID_QUINARY_TDM_TX_7:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306527 tdm_group->nslots_per_frame = slots;
6528 tdm_group->slot_width = slot_width;
6529 tdm_group->slot_mask = tx_mask & cap_mask;
6530 break;
6531 default:
6532 dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
6533 __func__, dai->id);
6534 return -EINVAL;
6535 }
6536
6537 return rc;
6538}
6539
Cong Tang2b6adc82017-05-26 12:06:50 +08006540static int msm_dai_q6_tdm_set_sysclk(struct snd_soc_dai *dai,
6541 int clk_id, unsigned int freq, int dir)
6542{
6543 struct msm_dai_q6_tdm_dai_data *dai_data =
6544 dev_get_drvdata(dai->dev);
6545
6546 switch (dai->id) {
6547 case AFE_PORT_ID_QUATERNARY_TDM_RX:
6548 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
6549 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
6550 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
6551 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
6552 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
6553 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
6554 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
6555 case AFE_PORT_ID_QUATERNARY_TDM_TX:
6556 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
6557 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
6558 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
6559 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
6560 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
6561 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
6562 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
6563 dai_data->clk_set.clk_freq_in_hz = freq;
6564 break;
6565 default:
6566 return -EINVAL;
6567 }
6568
6569 dev_dbg(dai->dev, "%s: dai id = 0x%x, group clk_freq = %d\n",
6570 __func__, dai->id, freq);
6571 return 0;
6572}
6573
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306574static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai,
6575 unsigned int tx_num, unsigned int *tx_slot,
6576 unsigned int rx_num, unsigned int *rx_slot)
6577{
6578 int rc = 0;
6579 struct msm_dai_q6_tdm_dai_data *dai_data =
6580 dev_get_drvdata(dai->dev);
6581 struct afe_param_id_slot_mapping_cfg *slot_mapping =
6582 &dai_data->port_cfg.slot_mapping;
6583 int i = 0;
6584
6585 dev_dbg(dai->dev, "%s: dai id = 0x%x\n", __func__, dai->id);
6586
6587 switch (dai->id) {
6588 case AFE_PORT_ID_PRIMARY_TDM_RX:
6589 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
6590 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
6591 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
6592 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
6593 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
6594 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
6595 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
6596 case AFE_PORT_ID_SECONDARY_TDM_RX:
6597 case AFE_PORT_ID_SECONDARY_TDM_RX_1:
6598 case AFE_PORT_ID_SECONDARY_TDM_RX_2:
6599 case AFE_PORT_ID_SECONDARY_TDM_RX_3:
6600 case AFE_PORT_ID_SECONDARY_TDM_RX_4:
6601 case AFE_PORT_ID_SECONDARY_TDM_RX_5:
6602 case AFE_PORT_ID_SECONDARY_TDM_RX_6:
6603 case AFE_PORT_ID_SECONDARY_TDM_RX_7:
6604 case AFE_PORT_ID_TERTIARY_TDM_RX:
6605 case AFE_PORT_ID_TERTIARY_TDM_RX_1:
6606 case AFE_PORT_ID_TERTIARY_TDM_RX_2:
6607 case AFE_PORT_ID_TERTIARY_TDM_RX_3:
6608 case AFE_PORT_ID_TERTIARY_TDM_RX_4:
6609 case AFE_PORT_ID_TERTIARY_TDM_RX_5:
6610 case AFE_PORT_ID_TERTIARY_TDM_RX_6:
6611 case AFE_PORT_ID_TERTIARY_TDM_RX_7:
6612 case AFE_PORT_ID_QUATERNARY_TDM_RX:
6613 case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
6614 case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
6615 case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
6616 case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
6617 case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
6618 case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
6619 case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
Rohit Kumara5077932017-09-10 22:05:05 +05306620 case AFE_PORT_ID_QUINARY_TDM_RX:
6621 case AFE_PORT_ID_QUINARY_TDM_RX_1:
6622 case AFE_PORT_ID_QUINARY_TDM_RX_2:
6623 case AFE_PORT_ID_QUINARY_TDM_RX_3:
6624 case AFE_PORT_ID_QUINARY_TDM_RX_4:
6625 case AFE_PORT_ID_QUINARY_TDM_RX_5:
6626 case AFE_PORT_ID_QUINARY_TDM_RX_6:
6627 case AFE_PORT_ID_QUINARY_TDM_RX_7:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306628 if (!rx_slot) {
6629 dev_err(dai->dev, "%s: rx slot not found\n", __func__);
6630 return -EINVAL;
6631 }
6632 if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
6633 dev_err(dai->dev, "%s: invalid rx num %d\n", __func__,
6634 rx_num);
6635 return -EINVAL;
6636 }
6637
6638 for (i = 0; i < rx_num; i++)
6639 slot_mapping->offset[i] = rx_slot[i];
6640 for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
6641 slot_mapping->offset[i] =
6642 AFE_SLOT_MAPPING_OFFSET_INVALID;
6643
6644 slot_mapping->num_channel = rx_num;
6645 break;
6646 case AFE_PORT_ID_PRIMARY_TDM_TX:
6647 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
6648 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
6649 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
6650 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
6651 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
6652 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
6653 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
6654 case AFE_PORT_ID_SECONDARY_TDM_TX:
6655 case AFE_PORT_ID_SECONDARY_TDM_TX_1:
6656 case AFE_PORT_ID_SECONDARY_TDM_TX_2:
6657 case AFE_PORT_ID_SECONDARY_TDM_TX_3:
6658 case AFE_PORT_ID_SECONDARY_TDM_TX_4:
6659 case AFE_PORT_ID_SECONDARY_TDM_TX_5:
6660 case AFE_PORT_ID_SECONDARY_TDM_TX_6:
6661 case AFE_PORT_ID_SECONDARY_TDM_TX_7:
6662 case AFE_PORT_ID_TERTIARY_TDM_TX:
6663 case AFE_PORT_ID_TERTIARY_TDM_TX_1:
6664 case AFE_PORT_ID_TERTIARY_TDM_TX_2:
6665 case AFE_PORT_ID_TERTIARY_TDM_TX_3:
6666 case AFE_PORT_ID_TERTIARY_TDM_TX_4:
6667 case AFE_PORT_ID_TERTIARY_TDM_TX_5:
6668 case AFE_PORT_ID_TERTIARY_TDM_TX_6:
6669 case AFE_PORT_ID_TERTIARY_TDM_TX_7:
6670 case AFE_PORT_ID_QUATERNARY_TDM_TX:
6671 case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
6672 case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
6673 case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
6674 case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
6675 case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
6676 case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
6677 case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
Rohit Kumara5077932017-09-10 22:05:05 +05306678 case AFE_PORT_ID_QUINARY_TDM_TX:
6679 case AFE_PORT_ID_QUINARY_TDM_TX_1:
6680 case AFE_PORT_ID_QUINARY_TDM_TX_2:
6681 case AFE_PORT_ID_QUINARY_TDM_TX_3:
6682 case AFE_PORT_ID_QUINARY_TDM_TX_4:
6683 case AFE_PORT_ID_QUINARY_TDM_TX_5:
6684 case AFE_PORT_ID_QUINARY_TDM_TX_6:
6685 case AFE_PORT_ID_QUINARY_TDM_TX_7:
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05306686 if (!tx_slot) {
6687 dev_err(dai->dev, "%s: tx slot not found\n", __func__);
6688 return -EINVAL;
6689 }
6690 if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
6691 dev_err(dai->dev, "%s: invalid tx num %d\n", __func__,
6692 tx_num);
6693 return -EINVAL;
6694 }
6695
6696 for (i = 0; i < tx_num; i++)
6697 slot_mapping->offset[i] = tx_slot[i];
6698 for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
6699 slot_mapping->offset[i] =
6700 AFE_SLOT_MAPPING_OFFSET_INVALID;
6701
6702 slot_mapping->num_channel = tx_num;
6703 break;
6704 default:
6705 dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
6706 __func__, dai->id);
6707 return -EINVAL;
6708 }
6709
6710 return rc;
6711}
6712
6713static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream,
6714 struct snd_pcm_hw_params *params,
6715 struct snd_soc_dai *dai)
6716{
6717 struct msm_dai_q6_tdm_dai_data *dai_data =
6718 dev_get_drvdata(dai->dev);
6719
6720 struct afe_param_id_group_device_tdm_cfg *tdm_group =
6721 &dai_data->group_cfg.tdm_cfg;
6722 struct afe_param_id_tdm_cfg *tdm =
6723 &dai_data->port_cfg.tdm;
6724 struct afe_param_id_slot_mapping_cfg *slot_mapping =
6725 &dai_data->port_cfg.slot_mapping;
6726 struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header =
6727 &dai_data->port_cfg.custom_tdm_header;
6728
6729 pr_debug("%s: dev_name: %s\n",
6730 __func__, dev_name(dai->dev));
6731
6732 if ((params_channels(params) == 0) ||
6733 (params_channels(params) > 8)) {
6734 dev_err(dai->dev, "%s: invalid param channels %d\n",
6735 __func__, params_channels(params));
6736 return -EINVAL;
6737 }
6738 switch (params_format(params)) {
6739 case SNDRV_PCM_FORMAT_S16_LE:
6740 dai_data->bitwidth = 16;
6741 break;
6742 case SNDRV_PCM_FORMAT_S24_LE:
6743 case SNDRV_PCM_FORMAT_S24_3LE:
6744 dai_data->bitwidth = 24;
6745 break;
6746 case SNDRV_PCM_FORMAT_S32_LE:
6747 dai_data->bitwidth = 32;
6748 break;
6749 default:
6750 dev_err(dai->dev, "%s: invalid param format 0x%x\n",
6751 __func__, params_format(params));
6752 return -EINVAL;
6753 }
6754 dai_data->channels = params_channels(params);
6755 dai_data->rate = params_rate(params);
6756
6757 /*
6758 * update tdm group config param
6759 * NOTE: group config is set to the same as slot config.
6760 */
6761 tdm_group->bit_width = tdm_group->slot_width;
6762 tdm_group->num_channels = tdm_group->nslots_per_frame;
6763 tdm_group->sample_rate = dai_data->rate;
6764
6765 pr_debug("%s: TDM GROUP:\n"
6766 "num_channels=%d sample_rate=%d bit_width=%d\n"
6767 "nslots_per_frame=%d slot_width=%d slot_mask=0x%x\n",
6768 __func__,
6769 tdm_group->num_channels,
6770 tdm_group->sample_rate,
6771 tdm_group->bit_width,
6772 tdm_group->nslots_per_frame,
6773 tdm_group->slot_width,
6774 tdm_group->slot_mask);
6775 pr_debug("%s: TDM GROUP:\n"
6776 "port_id[0]=0x%x port_id[1]=0x%x port_id[2]=0x%x port_id[3]=0x%x\n"
6777 "port_id[4]=0x%x port_id[5]=0x%x port_id[6]=0x%x port_id[7]=0x%x\n",
6778 __func__,
6779 tdm_group->port_id[0],
6780 tdm_group->port_id[1],
6781 tdm_group->port_id[2],
6782 tdm_group->port_id[3],
6783 tdm_group->port_id[4],
6784 tdm_group->port_id[5],
6785 tdm_group->port_id[6],
6786 tdm_group->port_id[7]);
6787
6788 /*
6789 * update tdm config param
6790 * NOTE: channels/rate/bitwidth are per stream property
6791 */
6792 tdm->num_channels = dai_data->channels;
6793 tdm->sample_rate = dai_data->rate;
6794 tdm->bit_width = dai_data->bitwidth;
6795 /*
6796 * port slot config is the same as group slot config
6797 * port slot mask should be set according to offset
6798 */
6799 tdm->nslots_per_frame = tdm_group->nslots_per_frame;
6800 tdm->slot_width = tdm_group->slot_width;
6801 tdm->slot_mask = tdm_group->slot_mask;
6802
6803 pr_debug("%s: TDM:\n"
6804 "num_channels=%d sample_rate=%d bit_width=%d\n"
6805 "nslots_per_frame=%d slot_width=%d slot_mask=0x%x\n"
6806 "data_format=0x%x sync_mode=0x%x sync_src=0x%x\n"
6807 "data_out=0x%x invert_sync=0x%x data_delay=0x%x\n",
6808 __func__,
6809 tdm->num_channels,
6810 tdm->sample_rate,
6811 tdm->bit_width,
6812 tdm->nslots_per_frame,
6813 tdm->slot_width,
6814 tdm->slot_mask,
6815 tdm->data_format,
6816 tdm->sync_mode,
6817 tdm->sync_src,
6818 tdm->ctrl_data_out_enable,
6819 tdm->ctrl_invert_sync_pulse,
6820 tdm->ctrl_sync_data_delay);
6821
6822 /*
6823 * update slot mapping config param
6824 * NOTE: channels/rate/bitwidth are per stream property
6825 */
6826 slot_mapping->bitwidth = dai_data->bitwidth;
6827
6828 pr_debug("%s: SLOT MAPPING:\n"
6829 "num_channel=%d bitwidth=%d data_align=0x%x\n",
6830 __func__,
6831 slot_mapping->num_channel,
6832 slot_mapping->bitwidth,
6833 slot_mapping->data_align_type);
6834 pr_debug("%s: SLOT MAPPING:\n"
6835 "offset[0]=0x%x offset[1]=0x%x offset[2]=0x%x offset[3]=0x%x\n"
6836 "offset[4]=0x%x offset[5]=0x%x offset[6]=0x%x offset[7]=0x%x\n",
6837 __func__,
6838 slot_mapping->offset[0],
6839 slot_mapping->offset[1],
6840 slot_mapping->offset[2],
6841 slot_mapping->offset[3],
6842 slot_mapping->offset[4],
6843 slot_mapping->offset[5],
6844 slot_mapping->offset[6],
6845 slot_mapping->offset[7]);
6846
6847 /*
6848 * update custom header config param
6849 * NOTE: channels/rate/bitwidth are per playback stream property.
6850 * custom tdm header only applicable to playback stream.
6851 */
6852 if (custom_tdm_header->header_type !=
6853 AFE_CUSTOM_TDM_HEADER_TYPE_INVALID) {
6854 pr_debug("%s: CUSTOM TDM HEADER:\n"
6855 "start_offset=0x%x header_width=%d\n"
6856 "num_frame_repeat=%d header_type=0x%x\n",
6857 __func__,
6858 custom_tdm_header->start_offset,
6859 custom_tdm_header->header_width,
6860 custom_tdm_header->num_frame_repeat,
6861 custom_tdm_header->header_type);
6862 pr_debug("%s: CUSTOM TDM HEADER:\n"
6863 "header[0]=0x%x header[1]=0x%x header[2]=0x%x header[3]=0x%x\n"
6864 "header[4]=0x%x header[5]=0x%x header[6]=0x%x header[7]=0x%x\n",
6865 __func__,
6866 custom_tdm_header->header[0],
6867 custom_tdm_header->header[1],
6868 custom_tdm_header->header[2],
6869 custom_tdm_header->header[3],
6870 custom_tdm_header->header[4],
6871 custom_tdm_header->header[5],
6872 custom_tdm_header->header[6],
6873 custom_tdm_header->header[7]);
6874 }
6875
6876 return 0;
6877}
6878
6879static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream,
6880 struct snd_soc_dai *dai)
6881{
6882 int rc = 0;
6883 struct msm_dai_q6_tdm_dai_data *dai_data =
6884 dev_get_drvdata(dai->dev);
6885 u16 group_id = dai_data->group_cfg.tdm_cfg.group_id;
6886 int group_idx = 0;
6887 atomic_t *group_ref = NULL;
6888
6889 group_idx = msm_dai_q6_get_group_idx(dai->id);
6890 if (group_idx < 0) {
6891 dev_err(dai->dev, "%s port id 0x%x not supported\n",
6892 __func__, dai->id);
6893 return -EINVAL;
6894 }
6895
6896 mutex_lock(&tdm_mutex);
6897
6898 group_ref = &tdm_group_ref[group_idx];
6899
6900 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
6901 /* PORT START should be set if prepare called
6902 * in active state.
6903 */
6904 if (atomic_read(group_ref) == 0) {
6905 /* TX and RX share the same clk.
6906 * AFE clk is enabled per group to simplify the logic.
6907 * DSP will monitor the clk count.
6908 */
6909 rc = msm_dai_q6_tdm_set_clk(dai_data,
6910 dai->id, true);
6911 if (rc < 0) {
6912 dev_err(dai->dev, "%s: fail to enable AFE clk 0x%x\n",
6913 __func__, dai->id);
6914 goto rtn;
6915 }
6916
6917 /*
6918 * if only one port, don't do group enable as there
6919 * is no group need for only one port
6920 */
6921 if (dai_data->num_group_ports > 1) {
6922 rc = afe_port_group_enable(group_id,
6923 &dai_data->group_cfg, true);
6924 if (rc < 0) {
6925 dev_err(dai->dev,
6926 "%s: fail to enable AFE group 0x%x\n",
6927 __func__, group_id);
6928 goto rtn;
6929 }
6930 }
6931 }
6932
6933 rc = afe_tdm_port_start(dai->id, &dai_data->port_cfg,
6934 dai_data->rate, dai_data->num_group_ports);
6935 if (rc < 0) {
6936 if (atomic_read(group_ref) == 0) {
6937 afe_port_group_enable(group_id,
6938 NULL, false);
6939 msm_dai_q6_tdm_set_clk(dai_data,
6940 dai->id, false);
6941 }
6942 dev_err(dai->dev, "%s: fail to open AFE port 0x%x\n",
6943 __func__, dai->id);
6944 } else {
6945 set_bit(STATUS_PORT_STARTED,
6946 dai_data->status_mask);
6947 atomic_inc(group_ref);
6948 }
6949
6950 /* TODO: need to monitor PCM/MI2S/TDM HW status */
6951 /* NOTE: AFE should error out if HW resource contention */
6952
6953 }
6954
6955rtn:
6956 mutex_unlock(&tdm_mutex);
6957 return rc;
6958}
6959
6960static void msm_dai_q6_tdm_shutdown(struct snd_pcm_substream *substream,
6961 struct snd_soc_dai *dai)
6962{
6963 int rc = 0;
6964 struct msm_dai_q6_tdm_dai_data *dai_data =
6965 dev_get_drvdata(dai->dev);
6966 u16 group_id = dai_data->group_cfg.tdm_cfg.group_id;
6967 int group_idx = 0;
6968 atomic_t *group_ref = NULL;
6969
6970 group_idx = msm_dai_q6_get_group_idx(dai->id);
6971 if (group_idx < 0) {
6972 dev_err(dai->dev, "%s port id 0x%x not supported\n",
6973 __func__, dai->id);
6974 return;
6975 }
6976
6977 mutex_lock(&tdm_mutex);
6978
6979 group_ref = &tdm_group_ref[group_idx];
6980
6981 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
6982 rc = afe_close(dai->id);
6983 if (rc < 0) {
6984 dev_err(dai->dev, "%s: fail to close AFE port 0x%x\n",
6985 __func__, dai->id);
6986 }
6987 atomic_dec(group_ref);
6988 clear_bit(STATUS_PORT_STARTED,
6989 dai_data->status_mask);
6990
6991 if (atomic_read(group_ref) == 0) {
6992 rc = afe_port_group_enable(group_id,
6993 NULL, false);
6994 if (rc < 0) {
6995 dev_err(dai->dev, "%s: fail to disable AFE group 0x%x\n",
6996 __func__, group_id);
6997 }
6998 rc = msm_dai_q6_tdm_set_clk(dai_data,
6999 dai->id, false);
7000 if (rc < 0) {
7001 dev_err(dai->dev, "%s: fail to disable AFE clk 0x%x\n",
7002 __func__, dai->id);
7003 }
7004 }
7005
7006 /* TODO: need to monitor PCM/MI2S/TDM HW status */
7007 /* NOTE: AFE should error out if HW resource contention */
7008
7009 }
7010
7011 mutex_unlock(&tdm_mutex);
7012}
7013
7014static struct snd_soc_dai_ops msm_dai_q6_tdm_ops = {
7015 .prepare = msm_dai_q6_tdm_prepare,
7016 .hw_params = msm_dai_q6_tdm_hw_params,
7017 .set_tdm_slot = msm_dai_q6_tdm_set_tdm_slot,
7018 .set_channel_map = msm_dai_q6_tdm_set_channel_map,
Cong Tang2b6adc82017-05-26 12:06:50 +08007019 .set_sysclk = msm_dai_q6_tdm_set_sysclk,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307020 .shutdown = msm_dai_q6_tdm_shutdown,
7021};
7022
7023static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
7024 {
7025 .playback = {
7026 .stream_name = "Primary TDM0 Playback",
7027 .aif_name = "PRI_TDM_RX_0",
7028 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7029 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7030 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7031 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7032 SNDRV_PCM_FMTBIT_S24_LE |
7033 SNDRV_PCM_FMTBIT_S32_LE,
7034 .channels_min = 1,
7035 .channels_max = 8,
7036 .rate_min = 8000,
7037 .rate_max = 352800,
7038 },
7039 .ops = &msm_dai_q6_tdm_ops,
7040 .id = AFE_PORT_ID_PRIMARY_TDM_RX,
7041 .probe = msm_dai_q6_dai_tdm_probe,
7042 .remove = msm_dai_q6_dai_tdm_remove,
7043 },
7044 {
7045 .playback = {
7046 .stream_name = "Primary TDM1 Playback",
7047 .aif_name = "PRI_TDM_RX_1",
7048 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7049 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7050 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7051 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7052 SNDRV_PCM_FMTBIT_S24_LE |
7053 SNDRV_PCM_FMTBIT_S32_LE,
7054 .channels_min = 1,
7055 .channels_max = 8,
7056 .rate_min = 8000,
7057 .rate_max = 352800,
7058 },
7059 .ops = &msm_dai_q6_tdm_ops,
7060 .id = AFE_PORT_ID_PRIMARY_TDM_RX_1,
7061 .probe = msm_dai_q6_dai_tdm_probe,
7062 .remove = msm_dai_q6_dai_tdm_remove,
7063 },
7064 {
7065 .playback = {
7066 .stream_name = "Primary TDM2 Playback",
7067 .aif_name = "PRI_TDM_RX_2",
7068 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7069 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7070 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7071 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7072 SNDRV_PCM_FMTBIT_S24_LE |
7073 SNDRV_PCM_FMTBIT_S32_LE,
7074 .channels_min = 1,
7075 .channels_max = 8,
7076 .rate_min = 8000,
7077 .rate_max = 352800,
7078 },
7079 .ops = &msm_dai_q6_tdm_ops,
7080 .id = AFE_PORT_ID_PRIMARY_TDM_RX_2,
7081 .probe = msm_dai_q6_dai_tdm_probe,
7082 .remove = msm_dai_q6_dai_tdm_remove,
7083 },
7084 {
7085 .playback = {
7086 .stream_name = "Primary TDM3 Playback",
7087 .aif_name = "PRI_TDM_RX_3",
7088 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7089 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7090 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7091 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7092 SNDRV_PCM_FMTBIT_S24_LE |
7093 SNDRV_PCM_FMTBIT_S32_LE,
7094 .channels_min = 1,
7095 .channels_max = 8,
7096 .rate_min = 8000,
7097 .rate_max = 352800,
7098 },
7099 .ops = &msm_dai_q6_tdm_ops,
7100 .id = AFE_PORT_ID_PRIMARY_TDM_RX_3,
7101 .probe = msm_dai_q6_dai_tdm_probe,
7102 .remove = msm_dai_q6_dai_tdm_remove,
7103 },
7104 {
7105 .playback = {
7106 .stream_name = "Primary TDM4 Playback",
7107 .aif_name = "PRI_TDM_RX_4",
7108 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7109 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7110 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7111 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7112 SNDRV_PCM_FMTBIT_S24_LE |
7113 SNDRV_PCM_FMTBIT_S32_LE,
7114 .channels_min = 1,
7115 .channels_max = 8,
7116 .rate_min = 8000,
7117 .rate_max = 352800,
7118 },
7119 .ops = &msm_dai_q6_tdm_ops,
7120 .id = AFE_PORT_ID_PRIMARY_TDM_RX_4,
7121 .probe = msm_dai_q6_dai_tdm_probe,
7122 .remove = msm_dai_q6_dai_tdm_remove,
7123 },
7124 {
7125 .playback = {
7126 .stream_name = "Primary TDM5 Playback",
7127 .aif_name = "PRI_TDM_RX_5",
7128 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7129 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7130 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7131 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7132 SNDRV_PCM_FMTBIT_S24_LE |
7133 SNDRV_PCM_FMTBIT_S32_LE,
7134 .channels_min = 1,
7135 .channels_max = 8,
7136 .rate_min = 8000,
7137 .rate_max = 352800,
7138 },
7139 .ops = &msm_dai_q6_tdm_ops,
7140 .id = AFE_PORT_ID_PRIMARY_TDM_RX_5,
7141 .probe = msm_dai_q6_dai_tdm_probe,
7142 .remove = msm_dai_q6_dai_tdm_remove,
7143 },
7144 {
7145 .playback = {
7146 .stream_name = "Primary TDM6 Playback",
7147 .aif_name = "PRI_TDM_RX_6",
7148 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7149 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7150 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7151 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7152 SNDRV_PCM_FMTBIT_S24_LE |
7153 SNDRV_PCM_FMTBIT_S32_LE,
7154 .channels_min = 1,
7155 .channels_max = 8,
7156 .rate_min = 8000,
7157 .rate_max = 352800,
7158 },
7159 .ops = &msm_dai_q6_tdm_ops,
7160 .id = AFE_PORT_ID_PRIMARY_TDM_RX_6,
7161 .probe = msm_dai_q6_dai_tdm_probe,
7162 .remove = msm_dai_q6_dai_tdm_remove,
7163 },
7164 {
7165 .playback = {
7166 .stream_name = "Primary TDM7 Playback",
7167 .aif_name = "PRI_TDM_RX_7",
7168 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7169 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7170 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7171 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7172 SNDRV_PCM_FMTBIT_S24_LE |
7173 SNDRV_PCM_FMTBIT_S32_LE,
7174 .channels_min = 1,
7175 .channels_max = 8,
7176 .rate_min = 8000,
7177 .rate_max = 352800,
7178 },
7179 .ops = &msm_dai_q6_tdm_ops,
7180 .id = AFE_PORT_ID_PRIMARY_TDM_RX_7,
7181 .probe = msm_dai_q6_dai_tdm_probe,
7182 .remove = msm_dai_q6_dai_tdm_remove,
7183 },
7184 {
7185 .capture = {
7186 .stream_name = "Primary TDM0 Capture",
7187 .aif_name = "PRI_TDM_TX_0",
7188 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7189 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7190 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7191 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7192 SNDRV_PCM_FMTBIT_S24_LE |
7193 SNDRV_PCM_FMTBIT_S32_LE,
7194 .channels_min = 1,
7195 .channels_max = 8,
7196 .rate_min = 8000,
7197 .rate_max = 352800,
7198 },
7199 .ops = &msm_dai_q6_tdm_ops,
7200 .id = AFE_PORT_ID_PRIMARY_TDM_TX,
7201 .probe = msm_dai_q6_dai_tdm_probe,
7202 .remove = msm_dai_q6_dai_tdm_remove,
7203 },
7204 {
7205 .capture = {
7206 .stream_name = "Primary TDM1 Capture",
7207 .aif_name = "PRI_TDM_TX_1",
7208 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7209 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7210 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7211 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7212 SNDRV_PCM_FMTBIT_S24_LE |
7213 SNDRV_PCM_FMTBIT_S32_LE,
7214 .channels_min = 1,
7215 .channels_max = 8,
7216 .rate_min = 8000,
7217 .rate_max = 352800,
7218 },
7219 .ops = &msm_dai_q6_tdm_ops,
7220 .id = AFE_PORT_ID_PRIMARY_TDM_TX_1,
7221 .probe = msm_dai_q6_dai_tdm_probe,
7222 .remove = msm_dai_q6_dai_tdm_remove,
7223 },
7224 {
7225 .capture = {
7226 .stream_name = "Primary TDM2 Capture",
7227 .aif_name = "PRI_TDM_TX_2",
7228 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7229 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7230 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7231 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7232 SNDRV_PCM_FMTBIT_S24_LE |
7233 SNDRV_PCM_FMTBIT_S32_LE,
7234 .channels_min = 1,
7235 .channels_max = 8,
7236 .rate_min = 8000,
7237 .rate_max = 352800,
7238 },
7239 .ops = &msm_dai_q6_tdm_ops,
7240 .id = AFE_PORT_ID_PRIMARY_TDM_TX_2,
7241 .probe = msm_dai_q6_dai_tdm_probe,
7242 .remove = msm_dai_q6_dai_tdm_remove,
7243 },
7244 {
7245 .capture = {
7246 .stream_name = "Primary TDM3 Capture",
7247 .aif_name = "PRI_TDM_TX_3",
7248 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7249 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7250 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7251 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7252 SNDRV_PCM_FMTBIT_S24_LE |
7253 SNDRV_PCM_FMTBIT_S32_LE,
7254 .channels_min = 1,
7255 .channels_max = 8,
7256 .rate_min = 8000,
7257 .rate_max = 352800,
7258 },
7259 .ops = &msm_dai_q6_tdm_ops,
7260 .id = AFE_PORT_ID_PRIMARY_TDM_TX_3,
7261 .probe = msm_dai_q6_dai_tdm_probe,
7262 .remove = msm_dai_q6_dai_tdm_remove,
7263 },
7264 {
7265 .capture = {
7266 .stream_name = "Primary TDM4 Capture",
7267 .aif_name = "PRI_TDM_TX_4",
7268 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7269 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7270 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7271 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7272 SNDRV_PCM_FMTBIT_S24_LE |
7273 SNDRV_PCM_FMTBIT_S32_LE,
7274 .channels_min = 1,
7275 .channels_max = 8,
7276 .rate_min = 8000,
7277 .rate_max = 352800,
7278 },
7279 .ops = &msm_dai_q6_tdm_ops,
7280 .id = AFE_PORT_ID_PRIMARY_TDM_TX_4,
7281 .probe = msm_dai_q6_dai_tdm_probe,
7282 .remove = msm_dai_q6_dai_tdm_remove,
7283 },
7284 {
7285 .capture = {
7286 .stream_name = "Primary TDM5 Capture",
7287 .aif_name = "PRI_TDM_TX_5",
7288 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7289 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7290 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7291 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7292 SNDRV_PCM_FMTBIT_S24_LE |
7293 SNDRV_PCM_FMTBIT_S32_LE,
7294 .channels_min = 1,
7295 .channels_max = 8,
7296 .rate_min = 8000,
7297 .rate_max = 352800,
7298 },
7299 .ops = &msm_dai_q6_tdm_ops,
7300 .id = AFE_PORT_ID_PRIMARY_TDM_TX_5,
7301 .probe = msm_dai_q6_dai_tdm_probe,
7302 .remove = msm_dai_q6_dai_tdm_remove,
7303 },
7304 {
7305 .capture = {
7306 .stream_name = "Primary TDM6 Capture",
7307 .aif_name = "PRI_TDM_TX_6",
7308 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7309 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7310 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7311 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7312 SNDRV_PCM_FMTBIT_S24_LE |
7313 SNDRV_PCM_FMTBIT_S32_LE,
7314 .channels_min = 1,
7315 .channels_max = 8,
7316 .rate_min = 8000,
7317 .rate_max = 352800,
7318 },
7319 .ops = &msm_dai_q6_tdm_ops,
7320 .id = AFE_PORT_ID_PRIMARY_TDM_TX_6,
7321 .probe = msm_dai_q6_dai_tdm_probe,
7322 .remove = msm_dai_q6_dai_tdm_remove,
7323 },
7324 {
7325 .capture = {
7326 .stream_name = "Primary TDM7 Capture",
7327 .aif_name = "PRI_TDM_TX_7",
7328 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7329 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7330 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7331 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7332 SNDRV_PCM_FMTBIT_S24_LE |
7333 SNDRV_PCM_FMTBIT_S32_LE,
7334 .channels_min = 1,
7335 .channels_max = 8,
7336 .rate_min = 8000,
7337 .rate_max = 352800,
7338 },
7339 .ops = &msm_dai_q6_tdm_ops,
7340 .id = AFE_PORT_ID_PRIMARY_TDM_TX_7,
7341 .probe = msm_dai_q6_dai_tdm_probe,
7342 .remove = msm_dai_q6_dai_tdm_remove,
7343 },
7344 {
7345 .playback = {
7346 .stream_name = "Secondary TDM0 Playback",
7347 .aif_name = "SEC_TDM_RX_0",
7348 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7349 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7350 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7351 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7352 SNDRV_PCM_FMTBIT_S24_LE |
7353 SNDRV_PCM_FMTBIT_S32_LE,
7354 .channels_min = 1,
7355 .channels_max = 8,
7356 .rate_min = 8000,
7357 .rate_max = 352800,
7358 },
7359 .ops = &msm_dai_q6_tdm_ops,
7360 .id = AFE_PORT_ID_SECONDARY_TDM_RX,
7361 .probe = msm_dai_q6_dai_tdm_probe,
7362 .remove = msm_dai_q6_dai_tdm_remove,
7363 },
7364 {
7365 .playback = {
7366 .stream_name = "Secondary TDM1 Playback",
7367 .aif_name = "SEC_TDM_RX_1",
7368 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7369 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7370 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7371 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7372 SNDRV_PCM_FMTBIT_S24_LE |
7373 SNDRV_PCM_FMTBIT_S32_LE,
7374 .channels_min = 1,
7375 .channels_max = 8,
7376 .rate_min = 8000,
7377 .rate_max = 352800,
7378 },
7379 .ops = &msm_dai_q6_tdm_ops,
7380 .id = AFE_PORT_ID_SECONDARY_TDM_RX_1,
7381 .probe = msm_dai_q6_dai_tdm_probe,
7382 .remove = msm_dai_q6_dai_tdm_remove,
7383 },
7384 {
7385 .playback = {
7386 .stream_name = "Secondary TDM2 Playback",
7387 .aif_name = "SEC_TDM_RX_2",
7388 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7389 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7390 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7391 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7392 SNDRV_PCM_FMTBIT_S24_LE |
7393 SNDRV_PCM_FMTBIT_S32_LE,
7394 .channels_min = 1,
7395 .channels_max = 8,
7396 .rate_min = 8000,
7397 .rate_max = 352800,
7398 },
7399 .ops = &msm_dai_q6_tdm_ops,
7400 .id = AFE_PORT_ID_SECONDARY_TDM_RX_2,
7401 .probe = msm_dai_q6_dai_tdm_probe,
7402 .remove = msm_dai_q6_dai_tdm_remove,
7403 },
7404 {
7405 .playback = {
7406 .stream_name = "Secondary TDM3 Playback",
7407 .aif_name = "SEC_TDM_RX_3",
7408 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7409 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7410 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7411 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7412 SNDRV_PCM_FMTBIT_S24_LE |
7413 SNDRV_PCM_FMTBIT_S32_LE,
7414 .channels_min = 1,
7415 .channels_max = 8,
7416 .rate_min = 8000,
7417 .rate_max = 352800,
7418 },
7419 .ops = &msm_dai_q6_tdm_ops,
7420 .id = AFE_PORT_ID_SECONDARY_TDM_RX_3,
7421 .probe = msm_dai_q6_dai_tdm_probe,
7422 .remove = msm_dai_q6_dai_tdm_remove,
7423 },
7424 {
7425 .playback = {
7426 .stream_name = "Secondary TDM4 Playback",
7427 .aif_name = "SEC_TDM_RX_4",
7428 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7429 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7430 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7431 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7432 SNDRV_PCM_FMTBIT_S24_LE |
7433 SNDRV_PCM_FMTBIT_S32_LE,
7434 .channels_min = 1,
7435 .channels_max = 8,
7436 .rate_min = 8000,
7437 .rate_max = 352800,
7438 },
7439 .ops = &msm_dai_q6_tdm_ops,
7440 .id = AFE_PORT_ID_SECONDARY_TDM_RX_4,
7441 .probe = msm_dai_q6_dai_tdm_probe,
7442 .remove = msm_dai_q6_dai_tdm_remove,
7443 },
7444 {
7445 .playback = {
7446 .stream_name = "Secondary TDM5 Playback",
7447 .aif_name = "SEC_TDM_RX_5",
7448 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7449 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7450 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7451 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7452 SNDRV_PCM_FMTBIT_S24_LE |
7453 SNDRV_PCM_FMTBIT_S32_LE,
7454 .channels_min = 1,
7455 .channels_max = 8,
7456 .rate_min = 8000,
7457 .rate_max = 352800,
7458 },
7459 .ops = &msm_dai_q6_tdm_ops,
7460 .id = AFE_PORT_ID_SECONDARY_TDM_RX_5,
7461 .probe = msm_dai_q6_dai_tdm_probe,
7462 .remove = msm_dai_q6_dai_tdm_remove,
7463 },
7464 {
7465 .playback = {
7466 .stream_name = "Secondary TDM6 Playback",
7467 .aif_name = "SEC_TDM_RX_6",
7468 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7469 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7470 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7471 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7472 SNDRV_PCM_FMTBIT_S24_LE |
7473 SNDRV_PCM_FMTBIT_S32_LE,
7474 .channels_min = 1,
7475 .channels_max = 8,
7476 .rate_min = 8000,
7477 .rate_max = 352800,
7478 },
7479 .ops = &msm_dai_q6_tdm_ops,
7480 .id = AFE_PORT_ID_SECONDARY_TDM_RX_6,
7481 .probe = msm_dai_q6_dai_tdm_probe,
7482 .remove = msm_dai_q6_dai_tdm_remove,
7483 },
7484 {
7485 .playback = {
7486 .stream_name = "Secondary TDM7 Playback",
7487 .aif_name = "SEC_TDM_RX_7",
7488 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7489 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7490 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7491 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7492 SNDRV_PCM_FMTBIT_S24_LE |
7493 SNDRV_PCM_FMTBIT_S32_LE,
7494 .channels_min = 1,
7495 .channels_max = 8,
7496 .rate_min = 8000,
7497 .rate_max = 352800,
7498 },
7499 .ops = &msm_dai_q6_tdm_ops,
7500 .id = AFE_PORT_ID_SECONDARY_TDM_RX_7,
7501 .probe = msm_dai_q6_dai_tdm_probe,
7502 .remove = msm_dai_q6_dai_tdm_remove,
7503 },
7504 {
7505 .capture = {
7506 .stream_name = "Secondary TDM0 Capture",
7507 .aif_name = "SEC_TDM_TX_0",
7508 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7509 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7510 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7511 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7512 SNDRV_PCM_FMTBIT_S24_LE |
7513 SNDRV_PCM_FMTBIT_S32_LE,
7514 .channels_min = 1,
7515 .channels_max = 8,
7516 .rate_min = 8000,
7517 .rate_max = 352800,
7518 },
7519 .ops = &msm_dai_q6_tdm_ops,
7520 .id = AFE_PORT_ID_SECONDARY_TDM_TX,
7521 .probe = msm_dai_q6_dai_tdm_probe,
7522 .remove = msm_dai_q6_dai_tdm_remove,
7523 },
7524 {
7525 .capture = {
7526 .stream_name = "Secondary TDM1 Capture",
7527 .aif_name = "SEC_TDM_TX_1",
7528 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7529 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7530 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7531 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7532 SNDRV_PCM_FMTBIT_S24_LE |
7533 SNDRV_PCM_FMTBIT_S32_LE,
7534 .channels_min = 1,
7535 .channels_max = 8,
7536 .rate_min = 8000,
7537 .rate_max = 352800,
7538 },
7539 .ops = &msm_dai_q6_tdm_ops,
7540 .id = AFE_PORT_ID_SECONDARY_TDM_TX_1,
7541 .probe = msm_dai_q6_dai_tdm_probe,
7542 .remove = msm_dai_q6_dai_tdm_remove,
7543 },
7544 {
7545 .capture = {
7546 .stream_name = "Secondary TDM2 Capture",
7547 .aif_name = "SEC_TDM_TX_2",
7548 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7549 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7550 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7551 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7552 SNDRV_PCM_FMTBIT_S24_LE |
7553 SNDRV_PCM_FMTBIT_S32_LE,
7554 .channels_min = 1,
7555 .channels_max = 8,
7556 .rate_min = 8000,
7557 .rate_max = 352800,
7558 },
7559 .ops = &msm_dai_q6_tdm_ops,
7560 .id = AFE_PORT_ID_SECONDARY_TDM_TX_2,
7561 .probe = msm_dai_q6_dai_tdm_probe,
7562 .remove = msm_dai_q6_dai_tdm_remove,
7563 },
7564 {
7565 .capture = {
7566 .stream_name = "Secondary TDM3 Capture",
7567 .aif_name = "SEC_TDM_TX_3",
7568 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7569 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7570 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7571 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7572 SNDRV_PCM_FMTBIT_S24_LE |
7573 SNDRV_PCM_FMTBIT_S32_LE,
7574 .channels_min = 1,
7575 .channels_max = 8,
7576 .rate_min = 8000,
7577 .rate_max = 352800,
7578 },
7579 .ops = &msm_dai_q6_tdm_ops,
7580 .id = AFE_PORT_ID_SECONDARY_TDM_TX_3,
7581 .probe = msm_dai_q6_dai_tdm_probe,
7582 .remove = msm_dai_q6_dai_tdm_remove,
7583 },
7584 {
7585 .capture = {
7586 .stream_name = "Secondary TDM4 Capture",
7587 .aif_name = "SEC_TDM_TX_4",
7588 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7589 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7590 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7591 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7592 SNDRV_PCM_FMTBIT_S24_LE |
7593 SNDRV_PCM_FMTBIT_S32_LE,
7594 .channels_min = 1,
7595 .channels_max = 8,
7596 .rate_min = 8000,
7597 .rate_max = 352800,
7598 },
7599 .ops = &msm_dai_q6_tdm_ops,
7600 .id = AFE_PORT_ID_SECONDARY_TDM_TX_4,
7601 .probe = msm_dai_q6_dai_tdm_probe,
7602 .remove = msm_dai_q6_dai_tdm_remove,
7603 },
7604 {
7605 .capture = {
7606 .stream_name = "Secondary TDM5 Capture",
7607 .aif_name = "SEC_TDM_TX_5",
7608 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7609 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7610 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7611 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7612 SNDRV_PCM_FMTBIT_S24_LE |
7613 SNDRV_PCM_FMTBIT_S32_LE,
7614 .channels_min = 1,
7615 .channels_max = 8,
7616 .rate_min = 8000,
7617 .rate_max = 352800,
7618 },
7619 .ops = &msm_dai_q6_tdm_ops,
7620 .id = AFE_PORT_ID_SECONDARY_TDM_TX_5,
7621 .probe = msm_dai_q6_dai_tdm_probe,
7622 .remove = msm_dai_q6_dai_tdm_remove,
7623 },
7624 {
7625 .capture = {
7626 .stream_name = "Secondary TDM6 Capture",
7627 .aif_name = "SEC_TDM_TX_6",
7628 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7629 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7630 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7631 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7632 SNDRV_PCM_FMTBIT_S24_LE |
7633 SNDRV_PCM_FMTBIT_S32_LE,
7634 .channels_min = 1,
7635 .channels_max = 8,
7636 .rate_min = 8000,
7637 .rate_max = 352800,
7638 },
7639 .ops = &msm_dai_q6_tdm_ops,
7640 .id = AFE_PORT_ID_SECONDARY_TDM_TX_6,
7641 .probe = msm_dai_q6_dai_tdm_probe,
7642 .remove = msm_dai_q6_dai_tdm_remove,
7643 },
7644 {
7645 .capture = {
7646 .stream_name = "Secondary TDM7 Capture",
7647 .aif_name = "SEC_TDM_TX_7",
7648 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7649 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7650 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7651 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7652 SNDRV_PCM_FMTBIT_S24_LE |
7653 SNDRV_PCM_FMTBIT_S32_LE,
7654 .channels_min = 1,
7655 .channels_max = 8,
7656 .rate_min = 8000,
7657 .rate_max = 352800,
7658 },
7659 .ops = &msm_dai_q6_tdm_ops,
7660 .id = AFE_PORT_ID_SECONDARY_TDM_TX_7,
7661 .probe = msm_dai_q6_dai_tdm_probe,
7662 .remove = msm_dai_q6_dai_tdm_remove,
7663 },
7664 {
7665 .playback = {
7666 .stream_name = "Tertiary TDM0 Playback",
7667 .aif_name = "TERT_TDM_RX_0",
7668 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7669 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7670 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7671 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7672 SNDRV_PCM_FMTBIT_S24_LE |
7673 SNDRV_PCM_FMTBIT_S32_LE,
7674 .channels_min = 1,
7675 .channels_max = 8,
7676 .rate_min = 8000,
7677 .rate_max = 352800,
7678 },
7679 .ops = &msm_dai_q6_tdm_ops,
7680 .id = AFE_PORT_ID_TERTIARY_TDM_RX,
7681 .probe = msm_dai_q6_dai_tdm_probe,
7682 .remove = msm_dai_q6_dai_tdm_remove,
7683 },
7684 {
7685 .playback = {
7686 .stream_name = "Tertiary TDM1 Playback",
7687 .aif_name = "TERT_TDM_RX_1",
7688 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7689 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7690 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7691 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7692 SNDRV_PCM_FMTBIT_S24_LE |
7693 SNDRV_PCM_FMTBIT_S32_LE,
7694 .channels_min = 1,
7695 .channels_max = 8,
7696 .rate_min = 8000,
7697 .rate_max = 352800,
7698 },
7699 .ops = &msm_dai_q6_tdm_ops,
7700 .id = AFE_PORT_ID_TERTIARY_TDM_RX_1,
7701 .probe = msm_dai_q6_dai_tdm_probe,
7702 .remove = msm_dai_q6_dai_tdm_remove,
7703 },
7704 {
7705 .playback = {
7706 .stream_name = "Tertiary TDM2 Playback",
7707 .aif_name = "TERT_TDM_RX_2",
7708 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7709 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7710 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7711 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7712 SNDRV_PCM_FMTBIT_S24_LE |
7713 SNDRV_PCM_FMTBIT_S32_LE,
7714 .channels_min = 1,
7715 .channels_max = 8,
7716 .rate_min = 8000,
7717 .rate_max = 352800,
7718 },
7719 .ops = &msm_dai_q6_tdm_ops,
7720 .id = AFE_PORT_ID_TERTIARY_TDM_RX_2,
7721 .probe = msm_dai_q6_dai_tdm_probe,
7722 .remove = msm_dai_q6_dai_tdm_remove,
7723 },
7724 {
7725 .playback = {
7726 .stream_name = "Tertiary TDM3 Playback",
7727 .aif_name = "TERT_TDM_RX_3",
7728 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7729 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7730 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7731 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7732 SNDRV_PCM_FMTBIT_S24_LE |
7733 SNDRV_PCM_FMTBIT_S32_LE,
7734 .channels_min = 1,
7735 .channels_max = 8,
7736 .rate_min = 8000,
7737 .rate_max = 352800,
7738 },
7739 .ops = &msm_dai_q6_tdm_ops,
7740 .id = AFE_PORT_ID_TERTIARY_TDM_RX_3,
7741 .probe = msm_dai_q6_dai_tdm_probe,
7742 .remove = msm_dai_q6_dai_tdm_remove,
7743 },
7744 {
7745 .playback = {
7746 .stream_name = "Tertiary TDM4 Playback",
7747 .aif_name = "TERT_TDM_RX_4",
7748 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7749 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7750 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7751 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7752 SNDRV_PCM_FMTBIT_S24_LE |
7753 SNDRV_PCM_FMTBIT_S32_LE,
7754 .channels_min = 1,
7755 .channels_max = 8,
7756 .rate_min = 8000,
7757 .rate_max = 352800,
7758 },
7759 .ops = &msm_dai_q6_tdm_ops,
7760 .id = AFE_PORT_ID_TERTIARY_TDM_RX_4,
7761 .probe = msm_dai_q6_dai_tdm_probe,
7762 .remove = msm_dai_q6_dai_tdm_remove,
7763 },
7764 {
7765 .playback = {
7766 .stream_name = "Tertiary TDM5 Playback",
7767 .aif_name = "TERT_TDM_RX_5",
7768 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7769 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7770 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7771 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7772 SNDRV_PCM_FMTBIT_S24_LE |
7773 SNDRV_PCM_FMTBIT_S32_LE,
7774 .channels_min = 1,
7775 .channels_max = 8,
7776 .rate_min = 8000,
7777 .rate_max = 352800,
7778 },
7779 .ops = &msm_dai_q6_tdm_ops,
7780 .id = AFE_PORT_ID_TERTIARY_TDM_RX_5,
7781 .probe = msm_dai_q6_dai_tdm_probe,
7782 .remove = msm_dai_q6_dai_tdm_remove,
7783 },
7784 {
7785 .playback = {
7786 .stream_name = "Tertiary TDM6 Playback",
7787 .aif_name = "TERT_TDM_RX_6",
7788 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7789 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7790 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7791 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7792 SNDRV_PCM_FMTBIT_S24_LE |
7793 SNDRV_PCM_FMTBIT_S32_LE,
7794 .channels_min = 1,
7795 .channels_max = 8,
7796 .rate_min = 8000,
7797 .rate_max = 352800,
7798 },
7799 .ops = &msm_dai_q6_tdm_ops,
7800 .id = AFE_PORT_ID_TERTIARY_TDM_RX_6,
7801 .probe = msm_dai_q6_dai_tdm_probe,
7802 .remove = msm_dai_q6_dai_tdm_remove,
7803 },
7804 {
7805 .playback = {
7806 .stream_name = "Tertiary TDM7 Playback",
7807 .aif_name = "TERT_TDM_RX_7",
7808 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7809 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7810 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7811 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7812 SNDRV_PCM_FMTBIT_S24_LE |
7813 SNDRV_PCM_FMTBIT_S32_LE,
7814 .channels_min = 1,
7815 .channels_max = 8,
7816 .rate_min = 8000,
7817 .rate_max = 352800,
7818 },
7819 .ops = &msm_dai_q6_tdm_ops,
7820 .id = AFE_PORT_ID_TERTIARY_TDM_RX_7,
7821 .probe = msm_dai_q6_dai_tdm_probe,
7822 .remove = msm_dai_q6_dai_tdm_remove,
7823 },
7824 {
7825 .capture = {
7826 .stream_name = "Tertiary TDM0 Capture",
7827 .aif_name = "TERT_TDM_TX_0",
7828 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7829 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7830 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7831 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7832 SNDRV_PCM_FMTBIT_S24_LE |
7833 SNDRV_PCM_FMTBIT_S32_LE,
7834 .channels_min = 1,
7835 .channels_max = 8,
7836 .rate_min = 8000,
7837 .rate_max = 352800,
7838 },
7839 .ops = &msm_dai_q6_tdm_ops,
7840 .id = AFE_PORT_ID_TERTIARY_TDM_TX,
7841 .probe = msm_dai_q6_dai_tdm_probe,
7842 .remove = msm_dai_q6_dai_tdm_remove,
7843 },
7844 {
7845 .capture = {
7846 .stream_name = "Tertiary TDM1 Capture",
7847 .aif_name = "TERT_TDM_TX_1",
7848 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7849 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7850 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7851 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7852 SNDRV_PCM_FMTBIT_S24_LE |
7853 SNDRV_PCM_FMTBIT_S32_LE,
7854 .channels_min = 1,
7855 .channels_max = 8,
7856 .rate_min = 8000,
7857 .rate_max = 352800,
7858 },
7859 .ops = &msm_dai_q6_tdm_ops,
7860 .id = AFE_PORT_ID_TERTIARY_TDM_TX_1,
7861 .probe = msm_dai_q6_dai_tdm_probe,
7862 .remove = msm_dai_q6_dai_tdm_remove,
7863 },
7864 {
7865 .capture = {
7866 .stream_name = "Tertiary TDM2 Capture",
7867 .aif_name = "TERT_TDM_TX_2",
7868 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7869 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7870 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7871 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7872 SNDRV_PCM_FMTBIT_S24_LE |
7873 SNDRV_PCM_FMTBIT_S32_LE,
7874 .channels_min = 1,
7875 .channels_max = 8,
7876 .rate_min = 8000,
7877 .rate_max = 352800,
7878 },
7879 .ops = &msm_dai_q6_tdm_ops,
7880 .id = AFE_PORT_ID_TERTIARY_TDM_TX_2,
7881 .probe = msm_dai_q6_dai_tdm_probe,
7882 .remove = msm_dai_q6_dai_tdm_remove,
7883 },
7884 {
7885 .capture = {
7886 .stream_name = "Tertiary TDM3 Capture",
7887 .aif_name = "TERT_TDM_TX_3",
7888 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7889 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7890 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7891 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7892 SNDRV_PCM_FMTBIT_S24_LE |
7893 SNDRV_PCM_FMTBIT_S32_LE,
7894 .channels_min = 1,
7895 .channels_max = 8,
7896 .rate_min = 8000,
7897 .rate_max = 352800,
7898 },
7899 .ops = &msm_dai_q6_tdm_ops,
7900 .id = AFE_PORT_ID_TERTIARY_TDM_TX_3,
7901 .probe = msm_dai_q6_dai_tdm_probe,
7902 .remove = msm_dai_q6_dai_tdm_remove,
7903 },
7904 {
7905 .capture = {
7906 .stream_name = "Tertiary TDM4 Capture",
7907 .aif_name = "TERT_TDM_TX_4",
7908 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7909 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7910 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7911 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7912 SNDRV_PCM_FMTBIT_S24_LE |
7913 SNDRV_PCM_FMTBIT_S32_LE,
7914 .channels_min = 1,
7915 .channels_max = 8,
7916 .rate_min = 8000,
7917 .rate_max = 352800,
7918 },
7919 .ops = &msm_dai_q6_tdm_ops,
7920 .id = AFE_PORT_ID_TERTIARY_TDM_TX_4,
7921 .probe = msm_dai_q6_dai_tdm_probe,
7922 .remove = msm_dai_q6_dai_tdm_remove,
7923 },
7924 {
7925 .capture = {
7926 .stream_name = "Tertiary TDM5 Capture",
7927 .aif_name = "TERT_TDM_TX_5",
7928 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7929 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7930 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7931 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7932 SNDRV_PCM_FMTBIT_S24_LE |
7933 SNDRV_PCM_FMTBIT_S32_LE,
7934 .channels_min = 1,
7935 .channels_max = 8,
7936 .rate_min = 8000,
7937 .rate_max = 352800,
7938 },
7939 .ops = &msm_dai_q6_tdm_ops,
7940 .id = AFE_PORT_ID_TERTIARY_TDM_TX_5,
7941 .probe = msm_dai_q6_dai_tdm_probe,
7942 .remove = msm_dai_q6_dai_tdm_remove,
7943 },
7944 {
7945 .capture = {
7946 .stream_name = "Tertiary TDM6 Capture",
7947 .aif_name = "TERT_TDM_TX_6",
7948 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7949 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7950 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7951 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7952 SNDRV_PCM_FMTBIT_S24_LE |
7953 SNDRV_PCM_FMTBIT_S32_LE,
7954 .channels_min = 1,
7955 .channels_max = 8,
7956 .rate_min = 8000,
7957 .rate_max = 352800,
7958 },
7959 .ops = &msm_dai_q6_tdm_ops,
7960 .id = AFE_PORT_ID_TERTIARY_TDM_TX_6,
7961 .probe = msm_dai_q6_dai_tdm_probe,
7962 .remove = msm_dai_q6_dai_tdm_remove,
7963 },
7964 {
7965 .capture = {
7966 .stream_name = "Tertiary TDM7 Capture",
7967 .aif_name = "TERT_TDM_TX_7",
7968 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
7969 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
7970 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7971 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7972 SNDRV_PCM_FMTBIT_S24_LE |
7973 SNDRV_PCM_FMTBIT_S32_LE,
7974 .channels_min = 1,
7975 .channels_max = 8,
7976 .rate_min = 8000,
7977 .rate_max = 352800,
7978 },
7979 .ops = &msm_dai_q6_tdm_ops,
7980 .id = AFE_PORT_ID_TERTIARY_TDM_TX_7,
7981 .probe = msm_dai_q6_dai_tdm_probe,
7982 .remove = msm_dai_q6_dai_tdm_remove,
7983 },
7984 {
7985 .playback = {
7986 .stream_name = "Quaternary TDM0 Playback",
7987 .aif_name = "QUAT_TDM_RX_0",
7988 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
7989 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
7990 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
7991 .formats = SNDRV_PCM_FMTBIT_S16_LE |
7992 SNDRV_PCM_FMTBIT_S24_LE |
7993 SNDRV_PCM_FMTBIT_S32_LE,
7994 .channels_min = 1,
7995 .channels_max = 8,
7996 .rate_min = 8000,
7997 .rate_max = 352800,
7998 },
7999 .ops = &msm_dai_q6_tdm_ops,
8000 .id = AFE_PORT_ID_QUATERNARY_TDM_RX,
8001 .probe = msm_dai_q6_dai_tdm_probe,
8002 .remove = msm_dai_q6_dai_tdm_remove,
8003 },
8004 {
8005 .playback = {
8006 .stream_name = "Quaternary TDM1 Playback",
8007 .aif_name = "QUAT_TDM_RX_1",
8008 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8009 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8010 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8011 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8012 SNDRV_PCM_FMTBIT_S24_LE |
8013 SNDRV_PCM_FMTBIT_S32_LE,
8014 .channels_min = 1,
8015 .channels_max = 8,
8016 .rate_min = 8000,
8017 .rate_max = 352800,
8018 },
8019 .ops = &msm_dai_q6_tdm_ops,
8020 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_1,
8021 .probe = msm_dai_q6_dai_tdm_probe,
8022 .remove = msm_dai_q6_dai_tdm_remove,
8023 },
8024 {
8025 .playback = {
8026 .stream_name = "Quaternary TDM2 Playback",
8027 .aif_name = "QUAT_TDM_RX_2",
8028 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8029 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8030 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8031 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8032 SNDRV_PCM_FMTBIT_S24_LE |
8033 SNDRV_PCM_FMTBIT_S32_LE,
8034 .channels_min = 1,
8035 .channels_max = 8,
8036 .rate_min = 8000,
8037 .rate_max = 352800,
8038 },
8039 .ops = &msm_dai_q6_tdm_ops,
8040 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_2,
8041 .probe = msm_dai_q6_dai_tdm_probe,
8042 .remove = msm_dai_q6_dai_tdm_remove,
8043 },
8044 {
8045 .playback = {
8046 .stream_name = "Quaternary TDM3 Playback",
8047 .aif_name = "QUAT_TDM_RX_3",
8048 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8049 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8050 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8051 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8052 SNDRV_PCM_FMTBIT_S24_LE |
8053 SNDRV_PCM_FMTBIT_S32_LE,
8054 .channels_min = 1,
8055 .channels_max = 8,
8056 .rate_min = 8000,
8057 .rate_max = 352800,
8058 },
8059 .ops = &msm_dai_q6_tdm_ops,
8060 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_3,
8061 .probe = msm_dai_q6_dai_tdm_probe,
8062 .remove = msm_dai_q6_dai_tdm_remove,
8063 },
8064 {
8065 .playback = {
8066 .stream_name = "Quaternary TDM4 Playback",
8067 .aif_name = "QUAT_TDM_RX_4",
8068 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8069 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8070 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8071 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8072 SNDRV_PCM_FMTBIT_S24_LE |
8073 SNDRV_PCM_FMTBIT_S32_LE,
8074 .channels_min = 1,
8075 .channels_max = 8,
8076 .rate_min = 8000,
8077 .rate_max = 352800,
8078 },
8079 .ops = &msm_dai_q6_tdm_ops,
8080 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_4,
8081 .probe = msm_dai_q6_dai_tdm_probe,
8082 .remove = msm_dai_q6_dai_tdm_remove,
8083 },
8084 {
8085 .playback = {
8086 .stream_name = "Quaternary TDM5 Playback",
8087 .aif_name = "QUAT_TDM_RX_5",
8088 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8089 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8090 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8091 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8092 SNDRV_PCM_FMTBIT_S24_LE |
8093 SNDRV_PCM_FMTBIT_S32_LE,
8094 .channels_min = 1,
8095 .channels_max = 8,
8096 .rate_min = 8000,
8097 .rate_max = 352800,
8098 },
8099 .ops = &msm_dai_q6_tdm_ops,
8100 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_5,
8101 .probe = msm_dai_q6_dai_tdm_probe,
8102 .remove = msm_dai_q6_dai_tdm_remove,
8103 },
8104 {
8105 .playback = {
8106 .stream_name = "Quaternary TDM6 Playback",
8107 .aif_name = "QUAT_TDM_RX_6",
8108 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8109 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8110 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8111 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8112 SNDRV_PCM_FMTBIT_S24_LE |
8113 SNDRV_PCM_FMTBIT_S32_LE,
8114 .channels_min = 1,
8115 .channels_max = 8,
8116 .rate_min = 8000,
8117 .rate_max = 352800,
8118 },
8119 .ops = &msm_dai_q6_tdm_ops,
8120 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_6,
8121 .probe = msm_dai_q6_dai_tdm_probe,
8122 .remove = msm_dai_q6_dai_tdm_remove,
8123 },
8124 {
8125 .playback = {
8126 .stream_name = "Quaternary TDM7 Playback",
8127 .aif_name = "QUAT_TDM_RX_7",
8128 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8129 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8130 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8131 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8132 SNDRV_PCM_FMTBIT_S24_LE |
8133 SNDRV_PCM_FMTBIT_S32_LE,
8134 .channels_min = 1,
8135 .channels_max = 8,
8136 .rate_min = 8000,
8137 .rate_max = 352800,
8138 },
8139 .ops = &msm_dai_q6_tdm_ops,
8140 .id = AFE_PORT_ID_QUATERNARY_TDM_RX_7,
8141 .probe = msm_dai_q6_dai_tdm_probe,
8142 .remove = msm_dai_q6_dai_tdm_remove,
8143 },
8144 {
8145 .capture = {
8146 .stream_name = "Quaternary TDM0 Capture",
8147 .aif_name = "QUAT_TDM_TX_0",
8148 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8149 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8150 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8151 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8152 SNDRV_PCM_FMTBIT_S24_LE |
8153 SNDRV_PCM_FMTBIT_S32_LE,
8154 .channels_min = 1,
8155 .channels_max = 8,
8156 .rate_min = 8000,
8157 .rate_max = 352800,
8158 },
8159 .ops = &msm_dai_q6_tdm_ops,
8160 .id = AFE_PORT_ID_QUATERNARY_TDM_TX,
8161 .probe = msm_dai_q6_dai_tdm_probe,
8162 .remove = msm_dai_q6_dai_tdm_remove,
8163 },
8164 {
8165 .capture = {
8166 .stream_name = "Quaternary TDM1 Capture",
8167 .aif_name = "QUAT_TDM_TX_1",
8168 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8169 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8170 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8171 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8172 SNDRV_PCM_FMTBIT_S24_LE |
8173 SNDRV_PCM_FMTBIT_S32_LE,
8174 .channels_min = 1,
8175 .channels_max = 8,
8176 .rate_min = 8000,
8177 .rate_max = 352800,
8178 },
8179 .ops = &msm_dai_q6_tdm_ops,
8180 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_1,
8181 .probe = msm_dai_q6_dai_tdm_probe,
8182 .remove = msm_dai_q6_dai_tdm_remove,
8183 },
8184 {
8185 .capture = {
8186 .stream_name = "Quaternary TDM2 Capture",
8187 .aif_name = "QUAT_TDM_TX_2",
8188 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8189 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8190 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8191 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8192 SNDRV_PCM_FMTBIT_S24_LE |
8193 SNDRV_PCM_FMTBIT_S32_LE,
8194 .channels_min = 1,
8195 .channels_max = 8,
8196 .rate_min = 8000,
8197 .rate_max = 352800,
8198 },
8199 .ops = &msm_dai_q6_tdm_ops,
8200 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_2,
8201 .probe = msm_dai_q6_dai_tdm_probe,
8202 .remove = msm_dai_q6_dai_tdm_remove,
8203 },
8204 {
8205 .capture = {
8206 .stream_name = "Quaternary TDM3 Capture",
8207 .aif_name = "QUAT_TDM_TX_3",
8208 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8209 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8210 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8211 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8212 SNDRV_PCM_FMTBIT_S24_LE |
8213 SNDRV_PCM_FMTBIT_S32_LE,
8214 .channels_min = 1,
8215 .channels_max = 8,
8216 .rate_min = 8000,
8217 .rate_max = 352800,
8218 },
8219 .ops = &msm_dai_q6_tdm_ops,
8220 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_3,
8221 .probe = msm_dai_q6_dai_tdm_probe,
8222 .remove = msm_dai_q6_dai_tdm_remove,
8223 },
8224 {
8225 .capture = {
8226 .stream_name = "Quaternary TDM4 Capture",
8227 .aif_name = "QUAT_TDM_TX_4",
8228 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8229 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8230 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8231 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8232 SNDRV_PCM_FMTBIT_S24_LE |
8233 SNDRV_PCM_FMTBIT_S32_LE,
8234 .channels_min = 1,
8235 .channels_max = 8,
8236 .rate_min = 8000,
8237 .rate_max = 352800,
8238 },
8239 .ops = &msm_dai_q6_tdm_ops,
8240 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_4,
8241 .probe = msm_dai_q6_dai_tdm_probe,
8242 .remove = msm_dai_q6_dai_tdm_remove,
8243 },
8244 {
8245 .capture = {
8246 .stream_name = "Quaternary TDM5 Capture",
8247 .aif_name = "QUAT_TDM_TX_5",
8248 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8249 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8250 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8251 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8252 SNDRV_PCM_FMTBIT_S24_LE |
8253 SNDRV_PCM_FMTBIT_S32_LE,
8254 .channels_min = 1,
8255 .channels_max = 8,
8256 .rate_min = 8000,
8257 .rate_max = 352800,
8258 },
8259 .ops = &msm_dai_q6_tdm_ops,
8260 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_5,
8261 .probe = msm_dai_q6_dai_tdm_probe,
8262 .remove = msm_dai_q6_dai_tdm_remove,
8263 },
8264 {
8265 .capture = {
8266 .stream_name = "Quaternary TDM6 Capture",
8267 .aif_name = "QUAT_TDM_TX_6",
8268 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8269 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8270 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8271 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8272 SNDRV_PCM_FMTBIT_S24_LE |
8273 SNDRV_PCM_FMTBIT_S32_LE,
8274 .channels_min = 1,
8275 .channels_max = 8,
8276 .rate_min = 8000,
8277 .rate_max = 352800,
8278 },
8279 .ops = &msm_dai_q6_tdm_ops,
8280 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_6,
8281 .probe = msm_dai_q6_dai_tdm_probe,
8282 .remove = msm_dai_q6_dai_tdm_remove,
8283 },
8284 {
8285 .capture = {
8286 .stream_name = "Quaternary TDM7 Capture",
8287 .aif_name = "QUAT_TDM_TX_7",
8288 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8289 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8290 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8291 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8292 SNDRV_PCM_FMTBIT_S24_LE |
8293 SNDRV_PCM_FMTBIT_S32_LE,
8294 .channels_min = 1,
8295 .channels_max = 8,
8296 .rate_min = 8000,
8297 .rate_max = 352800,
8298 },
8299 .ops = &msm_dai_q6_tdm_ops,
8300 .id = AFE_PORT_ID_QUATERNARY_TDM_TX_7,
8301 .probe = msm_dai_q6_dai_tdm_probe,
8302 .remove = msm_dai_q6_dai_tdm_remove,
8303 },
Rohit Kumara5077932017-09-10 22:05:05 +05308304 {
8305 .playback = {
8306 .stream_name = "Quinary TDM0 Playback",
8307 .aif_name = "QUIN_TDM_RX_0",
8308 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
8309 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
8310 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8311 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8312 SNDRV_PCM_FMTBIT_S24_LE |
8313 SNDRV_PCM_FMTBIT_S32_LE,
8314 .channels_min = 1,
8315 .channels_max = 8,
8316 .rate_min = 8000,
8317 .rate_max = 352800,
8318 },
8319 .ops = &msm_dai_q6_tdm_ops,
8320 .id = AFE_PORT_ID_QUINARY_TDM_RX,
8321 .probe = msm_dai_q6_dai_tdm_probe,
8322 .remove = msm_dai_q6_dai_tdm_remove,
8323 },
8324 {
8325 .playback = {
8326 .stream_name = "Quinary TDM1 Playback",
8327 .aif_name = "QUIN_TDM_RX_1",
8328 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
8329 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
8330 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8331 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8332 SNDRV_PCM_FMTBIT_S24_LE |
8333 SNDRV_PCM_FMTBIT_S32_LE,
8334 .channels_min = 1,
8335 .channels_max = 8,
8336 .rate_min = 8000,
8337 .rate_max = 352800,
8338 },
8339 .ops = &msm_dai_q6_tdm_ops,
8340 .id = AFE_PORT_ID_QUINARY_TDM_RX_1,
8341 .probe = msm_dai_q6_dai_tdm_probe,
8342 .remove = msm_dai_q6_dai_tdm_remove,
8343 },
8344 {
8345 .playback = {
8346 .stream_name = "Quinary TDM2 Playback",
8347 .aif_name = "QUIN_TDM_RX_2",
8348 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
8349 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
8350 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8351 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8352 SNDRV_PCM_FMTBIT_S24_LE |
8353 SNDRV_PCM_FMTBIT_S32_LE,
8354 .channels_min = 1,
8355 .channels_max = 8,
8356 .rate_min = 8000,
8357 .rate_max = 352800,
8358 },
8359 .ops = &msm_dai_q6_tdm_ops,
8360 .id = AFE_PORT_ID_QUINARY_TDM_RX_2,
8361 .probe = msm_dai_q6_dai_tdm_probe,
8362 .remove = msm_dai_q6_dai_tdm_remove,
8363 },
8364 {
8365 .playback = {
8366 .stream_name = "Quinary TDM3 Playback",
8367 .aif_name = "QUIN_TDM_RX_3",
8368 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
8369 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
8370 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8371 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8372 SNDRV_PCM_FMTBIT_S24_LE |
8373 SNDRV_PCM_FMTBIT_S32_LE,
8374 .channels_min = 1,
8375 .channels_max = 8,
8376 .rate_min = 8000,
8377 .rate_max = 352800,
8378 },
8379 .ops = &msm_dai_q6_tdm_ops,
8380 .id = AFE_PORT_ID_QUINARY_TDM_RX_3,
8381 .probe = msm_dai_q6_dai_tdm_probe,
8382 .remove = msm_dai_q6_dai_tdm_remove,
8383 },
8384 {
8385 .playback = {
8386 .stream_name = "Quinary TDM4 Playback",
8387 .aif_name = "QUIN_TDM_RX_4",
8388 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
8389 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
8390 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8391 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8392 SNDRV_PCM_FMTBIT_S24_LE |
8393 SNDRV_PCM_FMTBIT_S32_LE,
8394 .channels_min = 1,
8395 .channels_max = 8,
8396 .rate_min = 8000,
8397 .rate_max = 352800,
8398 },
8399 .ops = &msm_dai_q6_tdm_ops,
8400 .id = AFE_PORT_ID_QUINARY_TDM_RX_4,
8401 .probe = msm_dai_q6_dai_tdm_probe,
8402 .remove = msm_dai_q6_dai_tdm_remove,
8403 },
8404 {
8405 .playback = {
8406 .stream_name = "Quinary TDM5 Playback",
8407 .aif_name = "QUIN_TDM_RX_5",
8408 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
8409 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
8410 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8411 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8412 SNDRV_PCM_FMTBIT_S24_LE |
8413 SNDRV_PCM_FMTBIT_S32_LE,
8414 .channels_min = 1,
8415 .channels_max = 8,
8416 .rate_min = 8000,
8417 .rate_max = 352800,
8418 },
8419 .ops = &msm_dai_q6_tdm_ops,
8420 .id = AFE_PORT_ID_QUINARY_TDM_RX_5,
8421 .probe = msm_dai_q6_dai_tdm_probe,
8422 .remove = msm_dai_q6_dai_tdm_remove,
8423 },
8424 {
8425 .playback = {
8426 .stream_name = "Quinary TDM6 Playback",
8427 .aif_name = "QUIN_TDM_RX_6",
8428 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
8429 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
8430 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8431 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8432 SNDRV_PCM_FMTBIT_S24_LE |
8433 SNDRV_PCM_FMTBIT_S32_LE,
8434 .channels_min = 1,
8435 .channels_max = 8,
8436 .rate_min = 8000,
8437 .rate_max = 352800,
8438 },
8439 .ops = &msm_dai_q6_tdm_ops,
8440 .id = AFE_PORT_ID_QUINARY_TDM_RX_6,
8441 .probe = msm_dai_q6_dai_tdm_probe,
8442 .remove = msm_dai_q6_dai_tdm_remove,
8443 },
8444 {
8445 .playback = {
8446 .stream_name = "Quinary TDM7 Playback",
8447 .aif_name = "QUIN_TDM_RX_7",
8448 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
8449 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
8450 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8451 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8452 SNDRV_PCM_FMTBIT_S24_LE |
8453 SNDRV_PCM_FMTBIT_S32_LE,
8454 .channels_min = 1,
8455 .channels_max = 8,
8456 .rate_min = 8000,
8457 .rate_max = 352800,
8458 },
8459 .ops = &msm_dai_q6_tdm_ops,
8460 .id = AFE_PORT_ID_QUINARY_TDM_RX_7,
8461 .probe = msm_dai_q6_dai_tdm_probe,
8462 .remove = msm_dai_q6_dai_tdm_remove,
8463 },
8464 {
8465 .capture = {
8466 .stream_name = "Quinary TDM0 Capture",
8467 .aif_name = "QUIN_TDM_TX_0",
8468 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8469 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8470 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8471 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8472 SNDRV_PCM_FMTBIT_S24_LE |
8473 SNDRV_PCM_FMTBIT_S32_LE,
8474 .channels_min = 1,
8475 .channels_max = 8,
8476 .rate_min = 8000,
8477 .rate_max = 352800,
8478 },
8479 .ops = &msm_dai_q6_tdm_ops,
8480 .id = AFE_PORT_ID_QUINARY_TDM_TX,
8481 .probe = msm_dai_q6_dai_tdm_probe,
8482 .remove = msm_dai_q6_dai_tdm_remove,
8483 },
8484 {
8485 .capture = {
8486 .stream_name = "Quinary TDM1 Capture",
8487 .aif_name = "QUIN_TDM_TX_1",
8488 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8489 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8490 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8491 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8492 SNDRV_PCM_FMTBIT_S24_LE |
8493 SNDRV_PCM_FMTBIT_S32_LE,
8494 .channels_min = 1,
8495 .channels_max = 8,
8496 .rate_min = 8000,
8497 .rate_max = 352800,
8498 },
8499 .ops = &msm_dai_q6_tdm_ops,
8500 .id = AFE_PORT_ID_QUINARY_TDM_TX_1,
8501 .probe = msm_dai_q6_dai_tdm_probe,
8502 .remove = msm_dai_q6_dai_tdm_remove,
8503 },
8504 {
8505 .capture = {
8506 .stream_name = "Quinary TDM2 Capture",
8507 .aif_name = "QUIN_TDM_TX_2",
8508 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8509 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8510 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8511 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8512 SNDRV_PCM_FMTBIT_S24_LE |
8513 SNDRV_PCM_FMTBIT_S32_LE,
8514 .channels_min = 1,
8515 .channels_max = 8,
8516 .rate_min = 8000,
8517 .rate_max = 352800,
8518 },
8519 .ops = &msm_dai_q6_tdm_ops,
8520 .id = AFE_PORT_ID_QUINARY_TDM_TX_2,
8521 .probe = msm_dai_q6_dai_tdm_probe,
8522 .remove = msm_dai_q6_dai_tdm_remove,
8523 },
8524 {
8525 .capture = {
8526 .stream_name = "Quinary TDM3 Capture",
8527 .aif_name = "QUIN_TDM_TX_3",
8528 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8529 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8530 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8531 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8532 SNDRV_PCM_FMTBIT_S24_LE |
8533 SNDRV_PCM_FMTBIT_S32_LE,
8534 .channels_min = 1,
8535 .channels_max = 8,
8536 .rate_min = 8000,
8537 .rate_max = 352800,
8538 },
8539 .ops = &msm_dai_q6_tdm_ops,
8540 .id = AFE_PORT_ID_QUINARY_TDM_TX_3,
8541 .probe = msm_dai_q6_dai_tdm_probe,
8542 .remove = msm_dai_q6_dai_tdm_remove,
8543 },
8544 {
8545 .capture = {
8546 .stream_name = "Quinary TDM4 Capture",
8547 .aif_name = "QUIN_TDM_TX_4",
8548 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8549 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8550 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8551 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8552 SNDRV_PCM_FMTBIT_S24_LE |
8553 SNDRV_PCM_FMTBIT_S32_LE,
8554 .channels_min = 1,
8555 .channels_max = 8,
8556 .rate_min = 8000,
8557 .rate_max = 352800,
8558 },
8559 .ops = &msm_dai_q6_tdm_ops,
8560 .id = AFE_PORT_ID_QUINARY_TDM_TX_4,
8561 .probe = msm_dai_q6_dai_tdm_probe,
8562 .remove = msm_dai_q6_dai_tdm_remove,
8563 },
8564 {
8565 .capture = {
8566 .stream_name = "Quinary TDM5 Capture",
8567 .aif_name = "QUIN_TDM_TX_5",
8568 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8569 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8570 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8571 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8572 SNDRV_PCM_FMTBIT_S24_LE |
8573 SNDRV_PCM_FMTBIT_S32_LE,
8574 .channels_min = 1,
8575 .channels_max = 8,
8576 .rate_min = 8000,
8577 .rate_max = 352800,
8578 },
8579 .ops = &msm_dai_q6_tdm_ops,
8580 .id = AFE_PORT_ID_QUINARY_TDM_TX_5,
8581 .probe = msm_dai_q6_dai_tdm_probe,
8582 .remove = msm_dai_q6_dai_tdm_remove,
8583 },
8584 {
8585 .capture = {
8586 .stream_name = "Quinary TDM6 Capture",
8587 .aif_name = "QUIN_TDM_TX_6",
8588 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8589 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8590 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8591 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8592 SNDRV_PCM_FMTBIT_S24_LE |
8593 SNDRV_PCM_FMTBIT_S32_LE,
8594 .channels_min = 1,
8595 .channels_max = 8,
8596 .rate_min = 8000,
8597 .rate_max = 352800,
8598 },
8599 .ops = &msm_dai_q6_tdm_ops,
8600 .id = AFE_PORT_ID_QUINARY_TDM_TX_6,
8601 .probe = msm_dai_q6_dai_tdm_probe,
8602 .remove = msm_dai_q6_dai_tdm_remove,
8603 },
8604 {
8605 .capture = {
8606 .stream_name = "Quinary TDM7 Capture",
8607 .aif_name = "QUIN_TDM_TX_7",
8608 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
8609 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
8610 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
8611 .formats = SNDRV_PCM_FMTBIT_S16_LE |
8612 SNDRV_PCM_FMTBIT_S24_LE |
8613 SNDRV_PCM_FMTBIT_S32_LE,
8614 .channels_min = 1,
8615 .channels_max = 8,
8616 .rate_min = 8000,
8617 .rate_max = 352800,
8618 },
8619 .ops = &msm_dai_q6_tdm_ops,
8620 .id = AFE_PORT_ID_QUINARY_TDM_TX_7,
8621 .probe = msm_dai_q6_dai_tdm_probe,
8622 .remove = msm_dai_q6_dai_tdm_remove,
8623 },
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308624};
8625
8626static const struct snd_soc_component_driver msm_q6_tdm_dai_component = {
8627 .name = "msm-dai-q6-tdm",
8628};
8629
8630static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev)
8631{
8632 struct msm_dai_q6_tdm_dai_data *dai_data = NULL;
8633 struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header = NULL;
8634 int rc = 0;
8635 u32 tdm_dev_id = 0;
8636 int port_idx = 0;
8637 struct device_node *tdm_parent_node = NULL;
8638
8639 /* retrieve device/afe id */
8640 rc = of_property_read_u32(pdev->dev.of_node,
8641 "qcom,msm-cpudai-tdm-dev-id",
8642 &tdm_dev_id);
8643 if (rc) {
8644 dev_err(&pdev->dev, "%s: Device ID missing in DT file\n",
8645 __func__);
8646 goto rtn;
8647 }
8648 if ((tdm_dev_id < AFE_PORT_ID_TDM_PORT_RANGE_START) ||
8649 (tdm_dev_id > AFE_PORT_ID_TDM_PORT_RANGE_END)) {
8650 dev_err(&pdev->dev, "%s: Invalid TDM Device ID 0x%x in DT file\n",
8651 __func__, tdm_dev_id);
8652 rc = -ENXIO;
8653 goto rtn;
8654 }
8655 pdev->id = tdm_dev_id;
8656
8657 dev_info(&pdev->dev, "%s: dev_name: %s dev_id: 0x%x\n",
8658 __func__, dev_name(&pdev->dev), tdm_dev_id);
8659
8660 dai_data = kzalloc(sizeof(struct msm_dai_q6_tdm_dai_data),
8661 GFP_KERNEL);
8662 if (!dai_data) {
8663 rc = -ENOMEM;
8664 dev_err(&pdev->dev,
8665 "%s Failed to allocate memory for tdm dai_data\n",
8666 __func__);
8667 goto rtn;
8668 }
8669 memset(dai_data, 0, sizeof(*dai_data));
8670
8671 /* TDM CFG */
8672 tdm_parent_node = of_get_parent(pdev->dev.of_node);
8673 rc = of_property_read_u32(tdm_parent_node,
8674 "qcom,msm-cpudai-tdm-sync-mode",
8675 (u32 *)&dai_data->port_cfg.tdm.sync_mode);
8676 if (rc) {
8677 dev_err(&pdev->dev, "%s: Sync Mode from DT file %s\n",
8678 __func__, "qcom,msm-cpudai-tdm-sync-mode");
8679 goto free_dai_data;
8680 }
8681 dev_dbg(&pdev->dev, "%s: Sync Mode from DT file 0x%x\n",
8682 __func__, dai_data->port_cfg.tdm.sync_mode);
8683
8684 rc = of_property_read_u32(tdm_parent_node,
8685 "qcom,msm-cpudai-tdm-sync-src",
8686 (u32 *)&dai_data->port_cfg.tdm.sync_src);
8687 if (rc) {
8688 dev_err(&pdev->dev, "%s: Sync Src from DT file %s\n",
8689 __func__, "qcom,msm-cpudai-tdm-sync-src");
8690 goto free_dai_data;
8691 }
8692 dev_dbg(&pdev->dev, "%s: Sync Src from DT file 0x%x\n",
8693 __func__, dai_data->port_cfg.tdm.sync_src);
8694
8695 rc = of_property_read_u32(tdm_parent_node,
8696 "qcom,msm-cpudai-tdm-data-out",
8697 (u32 *)&dai_data->port_cfg.tdm.ctrl_data_out_enable);
8698 if (rc) {
8699 dev_err(&pdev->dev, "%s: Data Out from DT file %s\n",
8700 __func__, "qcom,msm-cpudai-tdm-data-out");
8701 goto free_dai_data;
8702 }
8703 dev_dbg(&pdev->dev, "%s: Data Out from DT file 0x%x\n",
8704 __func__, dai_data->port_cfg.tdm.ctrl_data_out_enable);
8705
8706 rc = of_property_read_u32(tdm_parent_node,
8707 "qcom,msm-cpudai-tdm-invert-sync",
8708 (u32 *)&dai_data->port_cfg.tdm.ctrl_invert_sync_pulse);
8709 if (rc) {
8710 dev_err(&pdev->dev, "%s: Invert Sync from DT file %s\n",
8711 __func__, "qcom,msm-cpudai-tdm-invert-sync");
8712 goto free_dai_data;
8713 }
8714 dev_dbg(&pdev->dev, "%s: Invert Sync from DT file 0x%x\n",
8715 __func__, dai_data->port_cfg.tdm.ctrl_invert_sync_pulse);
8716
8717 rc = of_property_read_u32(tdm_parent_node,
8718 "qcom,msm-cpudai-tdm-data-delay",
8719 (u32 *)&dai_data->port_cfg.tdm.ctrl_sync_data_delay);
8720 if (rc) {
8721 dev_err(&pdev->dev, "%s: Data Delay from DT file %s\n",
8722 __func__, "qcom,msm-cpudai-tdm-data-delay");
8723 goto free_dai_data;
8724 }
8725 dev_dbg(&pdev->dev, "%s: Data Delay from DT file 0x%x\n",
8726 __func__, dai_data->port_cfg.tdm.ctrl_sync_data_delay);
8727
8728 /* TDM CFG -- set default */
8729 dai_data->port_cfg.tdm.data_format = AFE_LINEAR_PCM_DATA;
8730 dai_data->port_cfg.tdm.tdm_cfg_minor_version =
8731 AFE_API_VERSION_TDM_CONFIG;
8732
8733 /* TDM SLOT MAPPING CFG */
8734 rc = of_property_read_u32(pdev->dev.of_node,
8735 "qcom,msm-cpudai-tdm-data-align",
8736 &dai_data->port_cfg.slot_mapping.data_align_type);
8737 if (rc) {
8738 dev_err(&pdev->dev, "%s: Data Align from DT file %s\n",
8739 __func__,
8740 "qcom,msm-cpudai-tdm-data-align");
8741 goto free_dai_data;
8742 }
8743 dev_dbg(&pdev->dev, "%s: Data Align from DT file 0x%x\n",
8744 __func__, dai_data->port_cfg.slot_mapping.data_align_type);
8745
8746 /* TDM SLOT MAPPING CFG -- set default */
8747 dai_data->port_cfg.slot_mapping.minor_version =
8748 AFE_API_VERSION_SLOT_MAPPING_CONFIG;
8749
8750 /* CUSTOM TDM HEADER CFG */
8751 custom_tdm_header = &dai_data->port_cfg.custom_tdm_header;
8752 if (of_find_property(pdev->dev.of_node,
8753 "qcom,msm-cpudai-tdm-header-start-offset", NULL) &&
8754 of_find_property(pdev->dev.of_node,
8755 "qcom,msm-cpudai-tdm-header-width", NULL) &&
8756 of_find_property(pdev->dev.of_node,
8757 "qcom,msm-cpudai-tdm-header-num-frame-repeat", NULL)) {
8758 /* if the property exist */
8759 rc = of_property_read_u32(pdev->dev.of_node,
8760 "qcom,msm-cpudai-tdm-header-start-offset",
8761 (u32 *)&custom_tdm_header->start_offset);
8762 if (rc) {
8763 dev_err(&pdev->dev, "%s: Header Start Offset from DT file %s\n",
8764 __func__,
8765 "qcom,msm-cpudai-tdm-header-start-offset");
8766 goto free_dai_data;
8767 }
8768 dev_dbg(&pdev->dev, "%s: Header Start Offset from DT file 0x%x\n",
8769 __func__, custom_tdm_header->start_offset);
8770
8771 rc = of_property_read_u32(pdev->dev.of_node,
8772 "qcom,msm-cpudai-tdm-header-width",
8773 (u32 *)&custom_tdm_header->header_width);
8774 if (rc) {
8775 dev_err(&pdev->dev, "%s: Header Width from DT file %s\n",
8776 __func__, "qcom,msm-cpudai-tdm-header-width");
8777 goto free_dai_data;
8778 }
8779 dev_dbg(&pdev->dev, "%s: Header Width from DT file 0x%x\n",
8780 __func__, custom_tdm_header->header_width);
8781
8782 rc = of_property_read_u32(pdev->dev.of_node,
8783 "qcom,msm-cpudai-tdm-header-num-frame-repeat",
8784 (u32 *)&custom_tdm_header->num_frame_repeat);
8785 if (rc) {
8786 dev_err(&pdev->dev, "%s: Header Num Frame Repeat from DT file %s\n",
8787 __func__,
8788 "qcom,msm-cpudai-tdm-header-num-frame-repeat");
8789 goto free_dai_data;
8790 }
8791 dev_dbg(&pdev->dev, "%s: Header Num Frame Repeat from DT file 0x%x\n",
8792 __func__, custom_tdm_header->num_frame_repeat);
8793
8794 /* CUSTOM TDM HEADER CFG -- set default */
8795 custom_tdm_header->minor_version =
8796 AFE_API_VERSION_CUSTOM_TDM_HEADER_CONFIG;
8797 custom_tdm_header->header_type =
8798 AFE_CUSTOM_TDM_HEADER_TYPE_INVALID;
8799 } else {
8800 dev_info(&pdev->dev,
8801 "%s: Custom tdm header not supported\n", __func__);
8802 /* CUSTOM TDM HEADER CFG -- set default */
8803 custom_tdm_header->header_type =
8804 AFE_CUSTOM_TDM_HEADER_TYPE_INVALID;
8805 /* proceed with probe */
8806 }
8807
8808 /* copy static clk per parent node */
8809 dai_data->clk_set = tdm_clk_set;
8810 /* copy static group cfg per parent node */
8811 dai_data->group_cfg.tdm_cfg = tdm_group_cfg;
8812 /* copy static num group ports per parent node */
8813 dai_data->num_group_ports = num_tdm_group_ports;
8814
8815
8816 dev_set_drvdata(&pdev->dev, dai_data);
8817
8818 port_idx = msm_dai_q6_get_port_idx(tdm_dev_id);
8819 if (port_idx < 0) {
8820 dev_err(&pdev->dev, "%s Port id 0x%x not supported\n",
8821 __func__, tdm_dev_id);
8822 rc = -EINVAL;
8823 goto free_dai_data;
8824 }
8825
8826 rc = snd_soc_register_component(&pdev->dev,
8827 &msm_q6_tdm_dai_component,
8828 &msm_dai_q6_tdm_dai[port_idx], 1);
8829
8830 if (rc) {
8831 dev_err(&pdev->dev, "%s: TDM dai 0x%x register failed, rc=%d\n",
8832 __func__, tdm_dev_id, rc);
8833 goto err_register;
8834 }
8835
8836 return 0;
8837
8838err_register:
8839free_dai_data:
8840 kfree(dai_data);
8841rtn:
8842 return rc;
8843}
8844
8845static int msm_dai_q6_tdm_dev_remove(struct platform_device *pdev)
8846{
8847 struct msm_dai_q6_tdm_dai_data *dai_data =
8848 dev_get_drvdata(&pdev->dev);
8849
8850 snd_soc_unregister_component(&pdev->dev);
8851
8852 kfree(dai_data);
8853
8854 return 0;
8855}
8856
8857static const struct of_device_id msm_dai_q6_tdm_dev_dt_match[] = {
8858 { .compatible = "qcom,msm-dai-q6-tdm", },
8859 {}
8860};
8861
8862MODULE_DEVICE_TABLE(of, msm_dai_q6_tdm_dev_dt_match);
8863
8864static struct platform_driver msm_dai_q6_tdm_driver = {
8865 .probe = msm_dai_q6_tdm_dev_probe,
8866 .remove = msm_dai_q6_tdm_dev_remove,
8867 .driver = {
8868 .name = "msm-dai-q6-tdm",
8869 .owner = THIS_MODULE,
8870 .of_match_table = msm_dai_q6_tdm_dev_dt_match,
8871 },
8872};
8873
8874static int __init msm_dai_q6_init(void)
8875{
8876 int rc;
8877
8878 rc = platform_driver_register(&msm_auxpcm_dev_driver);
8879 if (rc) {
8880 pr_err("%s: fail to register auxpcm dev driver", __func__);
8881 goto fail;
8882 }
8883
8884 rc = platform_driver_register(&msm_dai_q6);
8885 if (rc) {
8886 pr_err("%s: fail to register dai q6 driver", __func__);
8887 goto dai_q6_fail;
8888 }
8889
8890 rc = platform_driver_register(&msm_dai_q6_dev);
8891 if (rc) {
8892 pr_err("%s: fail to register dai q6 dev driver", __func__);
8893 goto dai_q6_dev_fail;
8894 }
8895
8896 rc = platform_driver_register(&msm_dai_q6_mi2s_driver);
8897 if (rc) {
8898 pr_err("%s: fail to register dai MI2S dev drv\n", __func__);
8899 goto dai_q6_mi2s_drv_fail;
8900 }
8901
8902 rc = platform_driver_register(&msm_dai_mi2s_q6);
8903 if (rc) {
8904 pr_err("%s: fail to register dai MI2S\n", __func__);
8905 goto dai_mi2s_q6_fail;
8906 }
8907
8908 rc = platform_driver_register(&msm_dai_q6_spdif_driver);
8909 if (rc) {
8910 pr_err("%s: fail to register dai SPDIF\n", __func__);
8911 goto dai_spdif_q6_fail;
8912 }
8913
8914 rc = platform_driver_register(&msm_dai_q6_tdm_driver);
8915 if (rc) {
8916 pr_err("%s: fail to register dai TDM dev drv\n", __func__);
8917 goto dai_q6_tdm_drv_fail;
8918 }
8919
8920 rc = platform_driver_register(&msm_dai_tdm_q6);
8921 if (rc) {
8922 pr_err("%s: fail to register dai TDM\n", __func__);
8923 goto dai_tdm_q6_fail;
8924 }
8925 return rc;
8926
8927dai_tdm_q6_fail:
8928 platform_driver_unregister(&msm_dai_q6_tdm_driver);
8929dai_q6_tdm_drv_fail:
8930 platform_driver_unregister(&msm_dai_q6_spdif_driver);
8931dai_spdif_q6_fail:
8932 platform_driver_unregister(&msm_dai_mi2s_q6);
8933dai_mi2s_q6_fail:
8934 platform_driver_unregister(&msm_dai_q6_mi2s_driver);
8935dai_q6_mi2s_drv_fail:
8936 platform_driver_unregister(&msm_dai_q6_dev);
8937dai_q6_dev_fail:
8938 platform_driver_unregister(&msm_dai_q6);
8939dai_q6_fail:
8940 platform_driver_unregister(&msm_auxpcm_dev_driver);
8941fail:
8942 return rc;
8943}
8944module_init(msm_dai_q6_init);
8945
8946static void __exit msm_dai_q6_exit(void)
8947{
8948 platform_driver_unregister(&msm_dai_q6_dev);
8949 platform_driver_unregister(&msm_dai_q6);
8950 platform_driver_unregister(&msm_auxpcm_dev_driver);
8951 platform_driver_unregister(&msm_dai_q6_spdif_driver);
8952}
8953module_exit(msm_dai_q6_exit);
8954
8955/* Module information */
8956MODULE_DESCRIPTION("MSM DSP DAI driver");
8957MODULE_LICENSE("GPL v2");