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