blob: 2f80b7163815a0fffd5fd547396a438e8f091d77 [file] [log] [blame]
Sundara Vinayagam43ce7c92018-05-21 16:34:47 +05301
2/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#define pr_fmt(fmt) "%s: " fmt "\n", __func__
15
16#include <linux/clk.h>
17#include <linux/of_gpio.h>
18#include <linux/platform_device.h>
19#include <linux/io.h>
20#include <linux/module.h>
21#include <linux/workqueue.h>
22#include <linux/input.h>
23#include <linux/regulator/consumer.h>
24#include <sound/core.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <dsp/q6afe-v2.h>
30#include <dsp/q6core.h>
31#include <soc/qcom/socinfo.h>
32#include "msm-pcm-routing-v2.h"
Sundara Vinayagam9c86c8d2018-05-14 21:57:42 +053033#include "codecs/msm-cdc-pinctrl.h"
Sundara Vinayagam43ce7c92018-05-21 16:34:47 +053034
35#define DRV_NAME "msm-bg-asoc-wcd"
36
37#define SPEAK_VREG_NAME "vdd-spkr"
38
39#define BTSCO_RATE_8KHZ 8000
40#define BTSCO_RATE_16KHZ 16000
41
42#define SAMPLING_RATE_16KHZ 16000
43#define SAMPLING_RATE_48KHZ 48000
44#define SAMPLING_RATE_96KHZ 96000
45#define SAMPLING_RATE_192KHZ 192000
46
47#define PRI_MI2S_ID (1 << 0)
48#define SEC_MI2S_ID (1 << 1)
49#define TER_MI2S_ID (1 << 2)
50#define QUAT_MI2S_ID (1 << 3)
51#define QUIN_MI2S_ID (1 << 4)
52
53#define DEFAULT_MCLK_RATE 9600000
54
55#define TDM_SLOT_OFFSET_MAX 4
56
57enum btsco_rates {
58 RATE_8KHZ_ID,
59 RATE_16KHZ_ID,
60};
61
62enum {
63 PRIMARY_TDM_RX_0,
64 PRIMARY_TDM_RX_1,
65 PRIMARY_TDM_RX_2,
66 PRIMARY_TDM_RX_3,
67 PRIMARY_TDM_TX_0,
68 PRIMARY_TDM_TX_1,
69 PRIMARY_TDM_TX_2,
70 PRIMARY_TDM_TX_3,
71 TDM_MAX,
72};
73
74/* dummy definition of deprecated FE DAI's */
75enum {
76 MSM_FRONTEND_DAI_CS_VOICE = 39,
77 MSM_FRONTEND_DAI_VOICE2,
78 MSM_FRONTEND_DAI_VOLTE,
79 MSM_FRONTEND_DAI_VOWLAN,
80};
81
82static int msm_btsco_rate = BTSCO_RATE_8KHZ;
83static int msm_proxy_rx_ch = 2;
84
85/* TDM default channels */
86static int msm_pri_tdm_rx_0_ch = 1;
87static int msm_pri_tdm_tx_0_ch = 1;
88
89static int msm_sec_tdm_rx_0_ch = 4;
90static int msm_sec_tdm_tx_0_ch = 4;
91
92/* TDM default bit format */
93static int msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
94static int msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
95
96static int msm_sec_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
97static int msm_sec_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
98
99/* TDM default sampling rate */
100static int msm_pri_tdm_rx_0_sample_rate = SAMPLING_RATE_48KHZ;
101static int msm_pri_tdm_tx_0_sample_rate = SAMPLING_RATE_48KHZ;
102
103static int msm_sec_tdm_rx_0_sample_rate = SAMPLING_RATE_48KHZ;
104static int msm_sec_tdm_tx_0_sample_rate = SAMPLING_RATE_48KHZ;
105
106static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four"};
107static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
108 "S32_LE"};
109static char const *tdm_sample_rate_text[] = {"KHZ_16", "KHZ_48"};
110
Sundara Vinayagam9c86c8d2018-05-14 21:57:42 +0530111static const char *const pin_states[] = {"sleep", "i2s-active",
112 "tdm-active"};
Sundara Vinayagam43ce7c92018-05-21 16:34:47 +0530113/* TDM default offset for individual MIC */
114static unsigned int tdm_slot_offset[TDM_MAX][TDM_SLOT_OFFSET_MAX] = {
115 /* PRI_TDM_RX */
116 {0, 0xFFFF},
117 {2, 0xFFFF},
118 {4, 0xFFFF},
119 {6, 0xFFFF},
120 /* PRI_TDM_TX */
121 {0, 0xFFFF},
122 {2, 0xFFFF},
123 {4, 0xFFFF},
124 {6, 0xFFFF},
125};
126
127/* TDM default offset for stereo MIC */
128static unsigned int tdm_slot_offset1[TDM_MAX][TDM_SLOT_OFFSET_MAX] = {
129 /* PRI_TDM_RX */
130 {0, 0xFFFF},
131 {4, 0xFFFF},
132 {8, 0xFFFF},
133 {12, 0xFFFF},
134 /* PRI_TDM_TX */
135 {0, 0xFFFF},
136 {4, 0xFFFF},
137 {8, 0xFFFF},
138 {0xFFFF},
139};
140
141static char const *rx_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"};
142static const char *const loopback_mclk_text[] = {"DISABLE", "ENABLE"};
143static const char *const btsco_rate_text[] = {"BTSCO_RATE_8KHZ",
144 "BTSCO_RATE_16KHZ"};
145static const char *const proxy_rx_ch_text[] = {"One", "Two", "Three", "Four",
146 "Five", "Six", "Seven", "Eight"};
147static const char *const vi_feed_ch_text[] = {"One", "Two"};
148
149
150struct msm8916_asoc_mach_data {
151 int ext_pa;
152 int afe_clk_ver;
153 atomic_t primary_tdm_ref_count;
154 void __iomem *vaddr_gpio_mux_spkr_ctl;
155 void __iomem *vaddr_gpio_mux_mic_ctl;
156 void __iomem *vaddr_gpio_mux_quin_ctl;
157 void __iomem *vaddr_gpio_mux_pcm_ctl;
158 void __iomem *vaddr_gpio_mux_sec_pcm_ctl;
159 struct device_node *pri_mi2s_gpio_p;
160};
161
162static inline int param_is_mask(int p)
163{
164 return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
165 (p <= SNDRV_PCM_HW_PARAM_LAST_MASK);
166}
167
168static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, int n)
169{
170 return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
171}
172
173static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned bit)
174{
175 if (bit >= SNDRV_MASK_MAX)
176 return;
177 if (param_is_mask(n)) {
178 struct snd_mask *m = param_to_mask(p, n);
179
180 m->bits[0] = 0;
181 m->bits[1] = 0;
182 m->bits[bit >> 5] |= (1 << (bit & 31));
183 }
184}
185
186static const struct snd_soc_dapm_widget msm_bg_dapm_widgets[] = {
187
188 SND_SOC_DAPM_MIC("Handset Mic", NULL),
189 SND_SOC_DAPM_MIC("Secondary Mic", NULL),
190 SND_SOC_DAPM_MIC("Digital Mic1", NULL),
191 SND_SOC_DAPM_MIC("Digital Mic2", NULL),
192};
193
194static int msm_proxy_rx_ch_get(struct snd_kcontrol *kcontrol,
195 struct snd_ctl_elem_value *ucontrol)
196{
197 pr_debug("msm_proxy_rx_ch = %d", msm_proxy_rx_ch);
198 ucontrol->value.integer.value[0] = msm_proxy_rx_ch - 1;
199 return 0;
200}
201
202static int msm_proxy_rx_ch_put(struct snd_kcontrol *kcontrol,
203 struct snd_ctl_elem_value *ucontrol)
204{
205 msm_proxy_rx_ch = ucontrol->value.integer.value[0] + 1;
206 pr_debug("msm_proxy_rx_ch = %d", msm_proxy_rx_ch);
207 return 0;
208}
209
210static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
211 struct snd_pcm_hw_params *params)
212{
213 struct snd_interval *rate = hw_param_interval(params,
214 SNDRV_PCM_HW_PARAM_RATE);
215 struct snd_interval *channels = hw_param_interval(params,
216 SNDRV_PCM_HW_PARAM_CHANNELS);
217
218 pr_debug("enter");
219 rate->min = rate->max = 48000;
220 channels->min = channels->max = 2;
221
222 return 0;
223}
224
225static int msm_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
226 struct snd_pcm_hw_params *params)
227{
228 struct snd_interval *rate = hw_param_interval(params,
229 SNDRV_PCM_HW_PARAM_RATE);
230 struct snd_interval *channels = hw_param_interval(params,
231 SNDRV_PCM_HW_PARAM_CHANNELS);
232 pr_debug("enter");
233 rate->min = rate->max = msm_btsco_rate;
234 channels->min = channels->max = 1;
235 return 0;
236}
237
238static int msm_btsco_rate_get(struct snd_kcontrol *kcontrol,
239 struct snd_ctl_elem_value *ucontrol)
240{
241 pr_debug("msm_btsco_rate = %d", msm_btsco_rate);
242
243 switch (msm_btsco_rate) {
244 case BTSCO_RATE_8KHZ:
245 ucontrol->value.integer.value[0] = RATE_8KHZ_ID;
246 break;
247 case BTSCO_RATE_16KHZ:
248 ucontrol->value.integer.value[0] = RATE_16KHZ_ID;
249 break;
250 default:
251 ucontrol->value.integer.value[0] = RATE_8KHZ_ID;
252 break;
253 }
254 return 0;
255}
256
257static int msm_btsco_rate_put(struct snd_kcontrol *kcontrol,
258 struct snd_ctl_elem_value *ucontrol)
259{
260 switch (ucontrol->value.integer.value[0]) {
261 case RATE_8KHZ_ID:
262 msm_btsco_rate = BTSCO_RATE_8KHZ;
263 break;
264 case RATE_16KHZ_ID:
265 msm_btsco_rate = BTSCO_RATE_16KHZ;
266 break;
267 default:
268 msm_btsco_rate = BTSCO_RATE_8KHZ;
269 break;
270 }
271
272 pr_debug("msm_btsco_rate = %d", msm_btsco_rate);
273 return 0;
274}
275
276static int msm_pri_tdm_rx_0_ch_get(struct snd_kcontrol *kcontrol,
277 struct snd_ctl_elem_value *ucontrol)
278{
279 pr_debug("msm_pri_tdm_rx_0_ch = %d",
280 msm_pri_tdm_rx_0_ch);
281 ucontrol->value.integer.value[0] = msm_pri_tdm_rx_0_ch - 1;
282 return 0;
283}
284
285static int msm_pri_tdm_rx_0_ch_put(struct snd_kcontrol *kcontrol,
286 struct snd_ctl_elem_value *ucontrol)
287{
288 msm_pri_tdm_rx_0_ch = ucontrol->value.integer.value[0] + 1;
289 pr_debug("msm_pri_tdm_rx_0_ch = %d",
290 msm_pri_tdm_rx_0_ch);
291 return 0;
292}
293
294static int msm_pri_tdm_tx_0_ch_get(struct snd_kcontrol *kcontrol,
295 struct snd_ctl_elem_value *ucontrol)
296{
297 pr_debug("msm_pri_tdm_tx_0_ch = %d",
298 msm_pri_tdm_tx_0_ch);
299 ucontrol->value.integer.value[0] = msm_pri_tdm_tx_0_ch - 1;
300 return 0;
301}
302
303static int msm_pri_tdm_tx_0_ch_put(struct snd_kcontrol *kcontrol,
304 struct snd_ctl_elem_value *ucontrol)
305{
306 msm_pri_tdm_tx_0_ch = ucontrol->value.integer.value[0] + 1;
307 pr_debug("msm_pri_tdm_tx_0_ch = %d",
308 msm_pri_tdm_tx_0_ch);
309 return 0;
310}
311
312static int msm_sec_tdm_rx_0_ch_get(struct snd_kcontrol *kcontrol,
313 struct snd_ctl_elem_value *ucontrol)
314{
315 pr_debug("msm_sec_tdm_rx_0_ch = %d",
316 msm_sec_tdm_rx_0_ch);
317 ucontrol->value.integer.value[0] = msm_sec_tdm_rx_0_ch - 1;
318 return 0;
319}
320
321static int msm_sec_tdm_rx_0_ch_put(struct snd_kcontrol *kcontrol,
322 struct snd_ctl_elem_value *ucontrol)
323{
324 msm_sec_tdm_rx_0_ch = ucontrol->value.integer.value[0] + 1;
325 pr_debug("msm_sec_tdm_rx_0_ch = %d",
326 msm_sec_tdm_rx_0_ch);
327 return 0;
328}
329
330static int msm_sec_tdm_tx_0_ch_get(struct snd_kcontrol *kcontrol,
331 struct snd_ctl_elem_value *ucontrol)
332{
333 pr_debug("msm_sec_tdm_tx_0_ch = %d",
334 msm_sec_tdm_tx_0_ch);
335 ucontrol->value.integer.value[0] = msm_sec_tdm_tx_0_ch - 1;
336 return 0;
337}
338
339static int msm_sec_tdm_tx_0_ch_put(struct snd_kcontrol *kcontrol,
340 struct snd_ctl_elem_value *ucontrol)
341{
342 msm_sec_tdm_tx_0_ch = ucontrol->value.integer.value[0] + 1;
343 pr_debug("msm_sec_tdm_tx_0_ch = %d",
344 msm_sec_tdm_tx_0_ch);
345 return 0;
346}
347
348static int msm_pri_tdm_rx_0_bit_format_get(struct snd_kcontrol *kcontrol,
349 struct snd_ctl_elem_value *ucontrol)
350{
351 switch (msm_pri_tdm_rx_0_bit_format) {
352 case SNDRV_PCM_FORMAT_S32_LE:
353 ucontrol->value.integer.value[0] = 3;
354 break;
355 case SNDRV_PCM_FORMAT_S24_3LE:
356 ucontrol->value.integer.value[0] = 2;
357 break;
358 case SNDRV_PCM_FORMAT_S24_LE:
359 ucontrol->value.integer.value[0] = 1;
360 break;
361 case SNDRV_PCM_FORMAT_S16_LE:
362 default:
363 ucontrol->value.integer.value[0] = 0;
364 break;
365 }
366 pr_debug("msm_pri_tdm_rx_0_bit_format = %ld",
367 ucontrol->value.integer.value[0]);
368 return 0;
369}
370
371static int msm_pri_tdm_rx_0_bit_format_put(struct snd_kcontrol *kcontrol,
372 struct snd_ctl_elem_value *ucontrol)
373{
374 switch (ucontrol->value.integer.value[0]) {
375 case 3:
376 msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S32_LE;
377 break;
378 case 2:
379 msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S24_3LE;
380 break;
381 case 1:
382 msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE;
383 break;
384 case 0:
385 default:
386 msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
387 break;
388 }
389 pr_debug("msm_pri_tdm_rx_0_bit_format = %d",
390 msm_pri_tdm_rx_0_bit_format);
391 return 0;
392}
393
394static int msm_pri_tdm_tx_0_bit_format_get(struct snd_kcontrol *kcontrol,
395 struct snd_ctl_elem_value *ucontrol)
396{
397 switch (msm_pri_tdm_tx_0_bit_format) {
398 case SNDRV_PCM_FORMAT_S32_LE:
399 ucontrol->value.integer.value[0] = 3;
400 break;
401 case SNDRV_PCM_FORMAT_S24_3LE:
402 ucontrol->value.integer.value[0] = 2;
403 break;
404 case SNDRV_PCM_FORMAT_S24_LE:
405 ucontrol->value.integer.value[0] = 1;
406 break;
407 case SNDRV_PCM_FORMAT_S16_LE:
408 default:
409 ucontrol->value.integer.value[0] = 0;
410 break;
411 }
412 pr_debug("msm_pri_tdm_tx_0_bit_format = %ld",
413 ucontrol->value.integer.value[0]);
414 return 0;
415}
416
417static int msm_pri_tdm_tx_0_bit_format_put(struct snd_kcontrol *kcontrol,
418 struct snd_ctl_elem_value *ucontrol)
419{
420 switch (ucontrol->value.integer.value[0]) {
421 case 3:
422 msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S32_LE;
423 break;
424 case 2:
425 msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S24_3LE;
426 break;
427 case 1:
428 msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE;
429 break;
430 case 0:
431 default:
432 msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
433 break;
434 }
435 pr_debug("msm_pri_tdm_tx_0_bit_format = %d",
436 msm_pri_tdm_tx_0_bit_format);
437 return 0;
438}
439
440static int msm_sec_tdm_rx_0_bit_format_get(struct snd_kcontrol *kcontrol,
441 struct snd_ctl_elem_value *ucontrol)
442{
443 switch (msm_sec_tdm_rx_0_bit_format) {
444 case SNDRV_PCM_FORMAT_S32_LE:
445 ucontrol->value.integer.value[0] = 3;
446 break;
447 case SNDRV_PCM_FORMAT_S24_3LE:
448 ucontrol->value.integer.value[0] = 2;
449 break;
450 case SNDRV_PCM_FORMAT_S24_LE:
451 ucontrol->value.integer.value[0] = 1;
452 break;
453 case SNDRV_PCM_FORMAT_S16_LE:
454 default:
455 ucontrol->value.integer.value[0] = 0;
456 break;
457 }
458 pr_debug("msm_sec_tdm_rx_0_bit_format = %ld",
459 ucontrol->value.integer.value[0]);
460 return 0;
461}
462
463static int msm_sec_tdm_rx_0_bit_format_put(struct snd_kcontrol *kcontrol,
464 struct snd_ctl_elem_value *ucontrol)
465{
466 switch (ucontrol->value.integer.value[0]) {
467 case 3:
468 msm_sec_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S32_LE;
469 break;
470 case 2:
471 msm_sec_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S24_3LE;
472 break;
473 case 1:
474 msm_sec_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE;
475 break;
476 case 0:
477 default:
478 msm_sec_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
479 break;
480 }
481 pr_debug("msm_sec_tdm_rx_0_bit_format = %d",
482 msm_sec_tdm_rx_0_bit_format);
483 return 0;
484}
485
486static int msm_sec_tdm_tx_0_bit_format_get(struct snd_kcontrol *kcontrol,
487 struct snd_ctl_elem_value *ucontrol)
488{
489 switch (msm_sec_tdm_tx_0_bit_format) {
490 case SNDRV_PCM_FORMAT_S32_LE:
491 ucontrol->value.integer.value[0] = 3;
492 break;
493 case SNDRV_PCM_FORMAT_S24_3LE:
494 ucontrol->value.integer.value[0] = 2;
495 break;
496 case SNDRV_PCM_FORMAT_S24_LE:
497 ucontrol->value.integer.value[0] = 1;
498 break;
499 case SNDRV_PCM_FORMAT_S16_LE:
500 default:
501 ucontrol->value.integer.value[0] = 0;
502 break;
503 }
504 pr_debug("msm_sec_tdm_tx_0_bit_format = %ld",
505 ucontrol->value.integer.value[0]);
506 return 0;
507}
508
509static int msm_sec_tdm_tx_0_bit_format_put(struct snd_kcontrol *kcontrol,
510 struct snd_ctl_elem_value *ucontrol)
511{
512 switch (ucontrol->value.integer.value[0]) {
513 case 3:
514 msm_sec_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S32_LE;
515 break;
516 case 2:
517 msm_sec_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S24_3LE;
518 break;
519 case 1:
520 msm_sec_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE;
521 break;
522 case 0:
523 default:
524 msm_sec_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
525 break;
526 }
527 pr_debug("msm_sec_tdm_tx_0_bit_format = %d",
528 msm_sec_tdm_tx_0_bit_format);
529 return 0;
530}
531
532static int msm_pri_tdm_rx_0_sample_rate_get(struct snd_kcontrol *kcontrol,
533 struct snd_ctl_elem_value *ucontrol)
534{
535 switch (msm_pri_tdm_rx_0_sample_rate) {
536 case SAMPLING_RATE_16KHZ:
537 ucontrol->value.integer.value[0] = 0;
538 break;
539 case SAMPLING_RATE_48KHZ:
540 default:
541 ucontrol->value.integer.value[0] = 1;
542 break;
543 }
544 pr_debug("msm_pri_tdm_rx_0_sample_rate = %ld",
545 ucontrol->value.integer.value[0]);
546 return 0;
547}
548
549static int msm_pri_tdm_rx_0_sample_rate_put(struct snd_kcontrol *kcontrol,
550 struct snd_ctl_elem_value *ucontrol)
551{
552 switch (ucontrol->value.integer.value[0]) {
553 case 0:
554 msm_pri_tdm_rx_0_sample_rate = SAMPLING_RATE_16KHZ;
555 break;
556 case 1:
557 default:
558 msm_pri_tdm_rx_0_sample_rate = SAMPLING_RATE_48KHZ;
559 break;
560 }
561 pr_debug("msm_pri_tdm_rx_0_sample_rate = %d",
562 msm_pri_tdm_rx_0_sample_rate);
563 return 0;
564}
565
566static int msm_sec_tdm_rx_0_sample_rate_get(struct snd_kcontrol *kcontrol,
567 struct snd_ctl_elem_value *ucontrol)
568{
569 switch (msm_sec_tdm_rx_0_sample_rate) {
570 case SAMPLING_RATE_16KHZ:
571 ucontrol->value.integer.value[0] = 0;
572 break;
573 case SAMPLING_RATE_48KHZ:
574 default:
575 ucontrol->value.integer.value[0] = 1;
576 break;
577 }
578 pr_debug("msm_sec_tdm_rx_0_sample_rate = %ld",
579 ucontrol->value.integer.value[0]);
580 return 0;
581}
582
583static int msm_sec_tdm_rx_0_sample_rate_put(struct snd_kcontrol *kcontrol,
584 struct snd_ctl_elem_value *ucontrol)
585{
586 switch (ucontrol->value.integer.value[0]) {
587 case 0:
588 msm_sec_tdm_rx_0_sample_rate = SAMPLING_RATE_16KHZ;
589 break;
590 case 1:
591 default:
592 msm_sec_tdm_rx_0_sample_rate = SAMPLING_RATE_48KHZ;
593 break;
594 }
595 pr_debug("msm_sec_tdm_rx_0_sample_rate = %d",
596 msm_sec_tdm_rx_0_sample_rate);
597 return 0;
598}
599
600static int msm_pri_tdm_tx_0_sample_rate_get(struct snd_kcontrol *kcontrol,
601 struct snd_ctl_elem_value *ucontrol)
602{
603 switch (msm_pri_tdm_tx_0_sample_rate) {
604 case SAMPLING_RATE_16KHZ:
605 ucontrol->value.integer.value[0] = 0;
606 break;
607 case SAMPLING_RATE_48KHZ:
608 default:
609 ucontrol->value.integer.value[0] = 1;
610 break;
611 }
612 pr_debug("msm_pri_tdm_tx_0_sample_rate = %ld",
613 ucontrol->value.integer.value[0]);
614 return 0;
615}
616
617static int msm_pri_tdm_tx_0_sample_rate_put(struct snd_kcontrol *kcontrol,
618 struct snd_ctl_elem_value *ucontrol)
619{
620 switch (ucontrol->value.integer.value[0]) {
621 case 0:
622 msm_pri_tdm_tx_0_sample_rate = SAMPLING_RATE_16KHZ;
623 break;
624 case 1:
625 default:
626 msm_pri_tdm_tx_0_sample_rate = SAMPLING_RATE_48KHZ;
627 break;
628 }
629 pr_debug("msm_pri_tdm_tx_0_sample_rate = %d",
630 msm_pri_tdm_tx_0_sample_rate);
631 return 0;
632}
633
634static int msm_sec_tdm_tx_0_sample_rate_get(struct snd_kcontrol *kcontrol,
635 struct snd_ctl_elem_value *ucontrol)
636{
637 switch (msm_sec_tdm_tx_0_sample_rate) {
638 case SAMPLING_RATE_16KHZ:
639 ucontrol->value.integer.value[0] = 0;
640 break;
641 case SAMPLING_RATE_48KHZ:
642 default:
643 ucontrol->value.integer.value[0] = 1;
644 break;
645 }
646 pr_debug("msm_sec_tdm_tx_0_sample_rate = %ld",
647 ucontrol->value.integer.value[0]);
648 return 0;
649}
650
651static int msm_sec_tdm_tx_0_sample_rate_put(struct snd_kcontrol *kcontrol,
652 struct snd_ctl_elem_value *ucontrol)
653{
654 switch (ucontrol->value.integer.value[0]) {
655 case 0:
656 msm_sec_tdm_tx_0_sample_rate = SAMPLING_RATE_16KHZ;
657 break;
658 case 1:
659 default:
660 msm_sec_tdm_tx_0_sample_rate = SAMPLING_RATE_48KHZ;
661 break;
662 }
663 pr_debug("msm_sec_tdm_tx_0_sample_rate = %d",
664 msm_sec_tdm_tx_0_sample_rate);
665 return 0;
666}
667
668static const struct soc_enum msm_snd_enum[] = {
669 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_bit_format_text),
670 rx_bit_format_text),
671 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(btsco_rate_text),
672 btsco_rate_text),
673 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(proxy_rx_ch_text),
674 proxy_rx_ch_text),
675 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_ch_text),
676 tdm_ch_text),
677 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_bit_format_text),
678 tdm_bit_format_text),
679 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_sample_rate_text),
680 tdm_sample_rate_text),
681};
682
683static const struct snd_kcontrol_new msm_snd_controls[] = {
684 SOC_ENUM_EXT("Internal BTSCO SampleRate", msm_snd_enum[1],
685 msm_btsco_rate_get, msm_btsco_rate_put),
686 SOC_ENUM_EXT("PROXY_RX Channels", msm_snd_enum[2],
687 msm_proxy_rx_ch_get, msm_proxy_rx_ch_put),
688 SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", msm_snd_enum[3],
689 msm_pri_tdm_rx_0_ch_get, msm_pri_tdm_rx_0_ch_put),
690 SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", msm_snd_enum[3],
691 msm_pri_tdm_tx_0_ch_get, msm_pri_tdm_tx_0_ch_put),
692 SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", msm_snd_enum[3],
693 msm_sec_tdm_rx_0_ch_get, msm_sec_tdm_rx_0_ch_put),
694 SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", msm_snd_enum[3],
695 msm_sec_tdm_tx_0_ch_get, msm_sec_tdm_tx_0_ch_put),
696 SOC_ENUM_EXT("PRI_TDM_RX_0 Bit Format", msm_snd_enum[4],
697 msm_pri_tdm_rx_0_bit_format_get,
698 msm_pri_tdm_rx_0_bit_format_put),
699 SOC_ENUM_EXT("PRI_TDM_TX_0 Bit Format", msm_snd_enum[4],
700 msm_pri_tdm_tx_0_bit_format_get,
701 msm_pri_tdm_tx_0_bit_format_put),
702 SOC_ENUM_EXT("SEC_TDM_RX_0 Bit Format", msm_snd_enum[4],
703 msm_sec_tdm_rx_0_bit_format_get,
704 msm_sec_tdm_rx_0_bit_format_put),
705 SOC_ENUM_EXT("SEC_TDM_TX_0 Bit Format", msm_snd_enum[4],
706 msm_sec_tdm_tx_0_bit_format_get,
707 msm_sec_tdm_tx_0_bit_format_put),
708 SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", msm_snd_enum[5],
709 msm_pri_tdm_rx_0_sample_rate_get,
710 msm_pri_tdm_rx_0_sample_rate_put),
711 SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", msm_snd_enum[5],
712 msm_pri_tdm_tx_0_sample_rate_get,
713 msm_pri_tdm_tx_0_sample_rate_put),
714 SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", msm_snd_enum[5],
715 msm_sec_tdm_rx_0_sample_rate_get,
716 msm_sec_tdm_rx_0_sample_rate_put),
717 SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", msm_snd_enum[5],
718 msm_sec_tdm_tx_0_sample_rate_get,
719 msm_sec_tdm_tx_0_sample_rate_put),
720};
721
Sundara Vinayagam43ce7c92018-05-21 16:34:47 +0530722static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
723 struct snd_pcm_hw_params *params)
724{
725 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
726 struct snd_interval *rate = hw_param_interval(params,
727 SNDRV_PCM_HW_PARAM_RATE);
728 struct snd_interval *channels = hw_param_interval(params,
729 SNDRV_PCM_HW_PARAM_CHANNELS);
730
731 switch (cpu_dai->id) {
732 case AFE_PORT_ID_PRIMARY_TDM_RX:
733 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
734 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
735 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
736 channels->min = channels->max = msm_pri_tdm_rx_0_ch;
737 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
738 msm_pri_tdm_rx_0_bit_format);
739 rate->min = rate->max = msm_pri_tdm_rx_0_sample_rate;
740 break;
741 case AFE_PORT_ID_PRIMARY_TDM_TX:
742 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
743 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
744 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
745 channels->min = channels->max = msm_pri_tdm_tx_0_ch;
746 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
747 msm_pri_tdm_tx_0_bit_format);
748 rate->min = rate->max = msm_pri_tdm_tx_0_sample_rate;
749 break;
750 case AFE_PORT_ID_SECONDARY_TDM_RX:
751 channels->min = channels->max = msm_sec_tdm_rx_0_ch;
752 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
753 msm_sec_tdm_rx_0_bit_format);
754 rate->min = rate->max = msm_sec_tdm_rx_0_sample_rate;
755 break;
756 case AFE_PORT_ID_SECONDARY_TDM_TX:
757 channels->min = channels->max = msm_sec_tdm_tx_0_ch;
758 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
759 msm_sec_tdm_tx_0_bit_format);
760 rate->min = rate->max = msm_sec_tdm_tx_0_sample_rate;
761 break;
762 default:
763 pr_err("dai id 0x%x not supported", cpu_dai->id);
764 return -EINVAL;
765 }
766
767 pr_debug("dai id = 0x%x channels = %d rate = %d",
768 cpu_dai->id, channels->max, rate->max);
769
770 return 0;
771}
772
773static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width,
774 int slots, unsigned int tdm_slot_offset2[][TDM_SLOT_OFFSET_MAX])
775{
776 unsigned int slot_mask = 0;
777 int upper, lower, i, j;
778 unsigned int *slot_offset;
779
780 switch (port_id) {
781 case AFE_PORT_ID_PRIMARY_TDM_RX:
782 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
783 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
784 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
785 lower = PRIMARY_TDM_RX_0;
786 upper = PRIMARY_TDM_RX_3;
787 break;
788 case AFE_PORT_ID_PRIMARY_TDM_TX:
789 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
790 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
791 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
792 lower = PRIMARY_TDM_TX_0;
793 upper = PRIMARY_TDM_TX_3;
794 break;
795 default:
796 return slot_mask;
797 }
798
799 for (i = lower; i <= upper; i++) {
800 slot_offset = tdm_slot_offset2[i];
801 for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) {
802 pr_debug("j=%d slot_offst[j]= %x", j, slot_offset[j]);
803 if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID) {
804 /*
805 * set the mask of active slot according to
806 * the offset table for the group of devices
807 */
808 slot_mask |=
809 (1 << ((slot_offset[j] * 8) / slot_width));
810 pr_debug("slot_mask = %x", slot_mask);
811 } else {
812 break;
813 }
814 }
815 }
816
817 return slot_mask;
818}
819
820static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream,
821 struct snd_pcm_hw_params *params)
822{
823 struct snd_soc_pcm_runtime *rtd = substream->private_data;
824 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
825 int ret = 0;
826 int channels;
827 int slot_width = 16;
828 int slots = 0;
829 unsigned int slot_mask = 0;
830 unsigned int *slot_offset;
831 int offset_channels = 0;
832 int i;
833 unsigned int tdm_slot_offset2[TDM_MAX][TDM_SLOT_OFFSET_MAX];
834
835 pr_debug("dai id = 0x%x", cpu_dai->id);
836
837 channels = params_channels(params);
838 switch (channels) {
839 case 2:
840 /*
841 * If no.of channels is 2 in record session then use
842 * tdm_slot_offset1
843 */
844 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
845 memcpy(tdm_slot_offset2, tdm_slot_offset1,
846 sizeof(tdm_slot_offset2));
847 else
848 memcpy(tdm_slot_offset2, tdm_slot_offset,
849 sizeof(tdm_slot_offset2));
850 break;
851 case 1:
852 case 3:
853 case 4:
854 case 6:
855 case 8:
856 memcpy(tdm_slot_offset2, tdm_slot_offset,
857 sizeof(tdm_slot_offset2));
858 switch (params_format(params)) {
859 case SNDRV_PCM_FORMAT_S32_LE:
860 case SNDRV_PCM_FORMAT_S24_LE:
861 case SNDRV_PCM_FORMAT_S16_LE:
862 /*
863 * up to 8 channel HW configuration should
864 * use 32 bit slot width for max support of
865 * stream bit width. (slot_width > bit_width)
866 */
867 slot_width = 16;
868 break;
869 default:
870 pr_err("invalid param format 0x%x",
871 params_format(params));
872 return -EINVAL;
873 }
874 slots = 4;
875 slot_mask = tdm_param_set_slot_mask(cpu_dai->id,
876 slot_width, slots, tdm_slot_offset2);
877 if (!slot_mask) {
878 pr_err("invalid slot_mask 0x%x", slot_mask);
879 return -EINVAL;
880 }
881 break;
882 default:
883 pr_err("invalid param channels %d", channels);
884 return -EINVAL;
885 }
886
887 switch (cpu_dai->id) {
888 case AFE_PORT_ID_PRIMARY_TDM_RX:
889 slot_offset = tdm_slot_offset2[PRIMARY_TDM_RX_0];
890 break;
891 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
892 slot_offset = tdm_slot_offset2[PRIMARY_TDM_RX_1];
893 break;
894 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
895 slot_offset = tdm_slot_offset2[PRIMARY_TDM_RX_2];
896 break;
897 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
898 slot_offset = tdm_slot_offset2[PRIMARY_TDM_RX_3];
899 break;
900 case AFE_PORT_ID_PRIMARY_TDM_TX:
901 slot_offset = tdm_slot_offset2[PRIMARY_TDM_TX_0];
902 break;
903 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
904 slot_offset = tdm_slot_offset2[PRIMARY_TDM_TX_1];
905 break;
906 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
907 slot_offset = tdm_slot_offset2[PRIMARY_TDM_TX_2];
908 break;
909 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
910 slot_offset = tdm_slot_offset2[PRIMARY_TDM_TX_3];
911 break;
912 default:
913 pr_err("dai id 0x%x not supported", cpu_dai->id);
914 return -EINVAL;
915 }
916
917 for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) {
918 if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID)
919 offset_channels++;
920 else
921 break;
922 }
923
924 if (offset_channels == 0) {
925 pr_err("slot offset not supported, offset_channels %d",
926 offset_channels);
927 return -EINVAL;
928 }
929
930 if (channels > offset_channels) {
931 pr_err("channels %d exceed offset_channels %d",
932 channels, offset_channels);
933 return -EINVAL;
934 }
935
936 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
937 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
938 slots, slot_width);
939 if (ret < 0) {
940 pr_err("failed to set tdm slot, err:%d", ret);
941 goto end;
942 }
943
944 ret = snd_soc_dai_set_channel_map(cpu_dai,
945 0, NULL, channels, slot_offset);
946 if (ret < 0) {
947 pr_err("failed to set channel map, err:%d", ret);
948 goto end;
949 }
950 } else {
951 ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0,
952 slots, slot_width);
953 if (ret < 0) {
954 pr_err("failed to set tdm slot, err:%d", ret);
955 goto end;
956 }
957
958 ret = snd_soc_dai_set_channel_map(cpu_dai,
959 channels, slot_offset, 0, NULL);
960 if (ret < 0) {
961 pr_err("failed to set channel map, err:%d", ret);
962 goto end;
963 }
964 }
965
966end:
967 return ret;
968}
969
970static int msm_tdm_startup(struct snd_pcm_substream *substream)
971{
972 struct snd_soc_pcm_runtime *rtd = substream->private_data;
973 struct snd_soc_card *card = rtd->card;
974 struct msm8916_asoc_mach_data *pdata =
975 snd_soc_card_get_drvdata(card);
976 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
977 int ret = 0, val = 0;
978
979 pr_debug("substream = %s stream = %d",
980 substream->name, substream->stream);
981 pr_debug("dai id = 0x%x", cpu_dai->id);
982
983 if (!q6core_is_adsp_ready()) {
984 pr_err_ratelimited("%s: ADSP Audio isn't ready\n",
985 __func__);
986 return -EINVAL;
987 }
988
989 switch (cpu_dai->id) {
990 case AFE_PORT_ID_PRIMARY_TDM_RX:
991 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
992 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
993 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
994 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
995 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
996 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
997 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
998 case AFE_PORT_ID_PRIMARY_TDM_TX:
999 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
1000 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
1001 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
1002 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
1003 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
1004 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
1005 case AFE_PORT_ID_PRIMARY_TDM_TX_7:
1006 atomic_inc(&pdata->primary_tdm_ref_count);
1007 if (atomic_read(&pdata->primary_tdm_ref_count) == 1) {
1008 /* Configure mux for Primary TDM */
1009 if (pdata->vaddr_gpio_mux_pcm_ctl) {
1010 val = ioread32(pdata->vaddr_gpio_mux_pcm_ctl);
1011 val = val | 0x00000001;
1012 iowrite32(val, pdata->vaddr_gpio_mux_pcm_ctl);
1013 } else {
1014 goto err;
1015 }
1016 if (pdata->vaddr_gpio_mux_mic_ctl) {
1017 val = ioread32(pdata->vaddr_gpio_mux_mic_ctl);
1018 /*0x02020002 Use this value for master mode*/
1019 val = val | 0x1808000; /*for slave mode*/
1020 iowrite32(val, pdata->vaddr_gpio_mux_mic_ctl);
1021 } else {
1022 goto err;
1023 }
Sundara Vinayagam9c86c8d2018-05-14 21:57:42 +05301024 if (pdata->pri_mi2s_gpio_p) {
1025 ret = msm_cdc_pinctrl_select_active_state(
1026 pdata->pri_mi2s_gpio_p);
1027 if (ret < 0)
1028 pr_err("%s: failed to activate sec TDM gpio\n",
1029 __func__);
1030 }
Sundara Vinayagam43ce7c92018-05-21 16:34:47 +05301031 }
1032 break;
1033 default:
1034 pr_err("dai id 0x%x not supported", cpu_dai->id);
1035 break;
1036 }
1037 return ret;
1038err:
1039 return -EINVAL;
1040}
1041
1042static void msm_tdm_shutdown(struct snd_pcm_substream *substream)
1043{
1044 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1045 struct snd_soc_card *card = rtd->card;
1046 struct msm8916_asoc_mach_data *pdata =
1047 snd_soc_card_get_drvdata(card);
Sundara Vinayagam9c86c8d2018-05-14 21:57:42 +05301048 int ret = 0, val = 0;
Sundara Vinayagam43ce7c92018-05-21 16:34:47 +05301049
1050 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1051
1052 switch (cpu_dai->id) {
1053 case AFE_PORT_ID_PRIMARY_TDM_RX:
1054 case AFE_PORT_ID_PRIMARY_TDM_RX_1:
1055 case AFE_PORT_ID_PRIMARY_TDM_RX_2:
1056 case AFE_PORT_ID_PRIMARY_TDM_RX_3:
1057 case AFE_PORT_ID_PRIMARY_TDM_RX_4:
1058 case AFE_PORT_ID_PRIMARY_TDM_RX_5:
1059 case AFE_PORT_ID_PRIMARY_TDM_RX_6:
1060 case AFE_PORT_ID_PRIMARY_TDM_RX_7:
1061 case AFE_PORT_ID_PRIMARY_TDM_TX:
1062 case AFE_PORT_ID_PRIMARY_TDM_TX_1:
1063 case AFE_PORT_ID_PRIMARY_TDM_TX_2:
1064 case AFE_PORT_ID_PRIMARY_TDM_TX_3:
1065 case AFE_PORT_ID_PRIMARY_TDM_TX_4:
1066 case AFE_PORT_ID_PRIMARY_TDM_TX_5:
1067 case AFE_PORT_ID_PRIMARY_TDM_TX_6:
1068 if (atomic_read(&pdata->primary_tdm_ref_count) > 0)
1069 atomic_dec(&pdata->primary_tdm_ref_count);
1070 if (atomic_read(&pdata->primary_tdm_ref_count) == 0) {
1071 if (!q6core_is_adsp_ready()) {
1072 pr_err("%s(): adsp not ready\n", __func__);
1073 goto err;
1074 }
1075
1076 /* Reset Configuration of mux for Primary TDM */
1077 if (pdata->vaddr_gpio_mux_pcm_ctl) {
1078 val = ioread32(pdata->vaddr_gpio_mux_pcm_ctl);
1079 val = val & (~0x00000001);
1080 iowrite32(val, pdata->vaddr_gpio_mux_pcm_ctl);
1081 } else {
1082 goto err;
1083 }
1084 if (pdata->vaddr_gpio_mux_mic_ctl) {
1085 val = ioread32(pdata->vaddr_gpio_mux_mic_ctl);
1086 /*0x02020002 Use this value for master mode*/
1087 val = val & (~0x1808000); /*for slave mode*/
1088 iowrite32(val, pdata->vaddr_gpio_mux_mic_ctl);
1089 } else {
1090 goto err;
1091 }
Sundara Vinayagam9c86c8d2018-05-14 21:57:42 +05301092 if (pdata->pri_mi2s_gpio_p) {
1093 ret = msm_cdc_pinctrl_select_sleep_state(
1094 pdata->pri_mi2s_gpio_p);
1095 if (ret < 0) {
1096 pr_err("%s: gpio cannot be de-activated %s\n",
1097 __func__, "pri_tdm");
1098 return;
1099 }
1100 }
1101 break;
Sundara Vinayagam43ce7c92018-05-21 16:34:47 +05301102 }
1103 break;
1104 default:
1105 break;
1106 }
1107err:
1108 return;
1109}
1110
1111static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
1112{
1113 struct snd_soc_codec *codec = rtd->codec;
1114 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1115
1116 pr_debug("dev_name%s", dev_name(cpu_dai->dev));
1117
1118 snd_soc_add_codec_controls(codec, msm_snd_controls,
1119 ARRAY_SIZE(msm_snd_controls));
1120 return 0;
1121}
1122
1123static struct snd_soc_ops msm_tdm_be_ops = {
1124 .startup = msm_tdm_startup,
1125 .hw_params = msm_tdm_snd_hw_params,
1126 .shutdown = msm_tdm_shutdown,
1127};
1128
1129/* Digital audio interface glue - connects codec <---> CPU */
1130static struct snd_soc_dai_link msm_bg_dai[] = {
1131 /* FrontEnd DAI Links */
1132 {/* hw:x,0 */
1133 .name = "MSM8952 Media1",
1134 .stream_name = "MultiMedia1",
1135 .cpu_dai_name = "MultiMedia1",
1136 .platform_name = "msm-pcm-dsp.0",
1137 .dynamic = 1,
1138 .dpcm_playback = 1,
1139 .dpcm_capture = 1,
1140 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1141 SND_SOC_DPCM_TRIGGER_POST},
1142 .codec_dai_name = "snd-soc-dummy-dai",
1143 .codec_name = "snd-soc-dummy",
1144 .ignore_suspend = 1,
1145 /* this dainlink has playback support */
1146 .ignore_pmdown_time = 1,
1147 .id = MSM_FRONTEND_DAI_MULTIMEDIA1
1148 },
1149 {/* hw:x,1 */
1150 .name = "MSM8952 Media2",
1151 .stream_name = "MultiMedia2",
1152 .cpu_dai_name = "MultiMedia2",
1153 .platform_name = "msm-pcm-dsp.0",
1154 .dynamic = 1,
1155 .dpcm_playback = 1,
1156 .dpcm_capture = 1,
1157 .codec_dai_name = "snd-soc-dummy-dai",
1158 .codec_name = "snd-soc-dummy",
1159 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1160 SND_SOC_DPCM_TRIGGER_POST},
1161 .ignore_suspend = 1,
1162 /* this dainlink has playback support */
1163 .ignore_pmdown_time = 1,
1164 .id = MSM_FRONTEND_DAI_MULTIMEDIA2,
1165 },
1166 {/* hw:x,2 */
1167 .name = "Circuit-Switch Voice",
1168 .stream_name = "CS-Voice",
1169 .cpu_dai_name = "VoiceMMode1",
1170 .platform_name = "msm-pcm-voice",
1171 .dynamic = 1,
1172 .dpcm_playback = 1,
1173 .dpcm_capture = 1,
1174 .codec_dai_name = "snd-soc-dummy-dai",
1175 .codec_name = "snd-soc-dummy",
1176 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1177 SND_SOC_DPCM_TRIGGER_POST},
1178 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1179 .ignore_suspend = 1,
1180 /* this dainlink has playback support */
1181 .ignore_pmdown_time = 1,
1182 .id = MSM_FRONTEND_DAI_CS_VOICE,
1183 },
1184 {/* hw:x,3 */
1185 .name = "MSM VoIP",
1186 .stream_name = "VoIP",
1187 .cpu_dai_name = "VoIP",
1188 .platform_name = "msm-voip-dsp",
1189 .dynamic = 1,
1190 .dpcm_playback = 1,
1191 .dpcm_capture = 1,
1192 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1193 SND_SOC_DPCM_TRIGGER_POST},
1194 .codec_dai_name = "snd-soc-dummy-dai",
1195 .codec_name = "snd-soc-dummy",
1196 .ignore_suspend = 1,
1197 /* this dainlink has playback support */
1198 .ignore_pmdown_time = 1,
1199 .id = MSM_FRONTEND_DAI_VOIP,
1200 },
1201 {/* hw:x,4 */
1202 .name = "MSM8X16 ULL",
1203 .stream_name = "ULL",
1204 .cpu_dai_name = "MultiMedia3",
1205 .platform_name = "msm-pcm-dsp.2",
1206 .dynamic = 1,
1207 .dpcm_playback = 1,
1208 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1209 SND_SOC_DPCM_TRIGGER_POST},
1210 .codec_dai_name = "snd-soc-dummy-dai",
1211 .codec_name = "snd-soc-dummy",
1212 .ignore_suspend = 1,
1213 /* this dainlink has playback support */
1214 .ignore_pmdown_time = 1,
1215 .id = MSM_FRONTEND_DAI_MULTIMEDIA3,
1216 },
1217 /* Hostless PCM purpose */
1218 {/* hw:x,5 */
1219 .name = "Primary MI2S_RX Hostless",
1220 .stream_name = "Primary MI2S_RX Hostless",
1221 .cpu_dai_name = "PRI_MI2S_RX_HOSTLESS",
1222 .platform_name = "msm-pcm-hostless",
1223 .dynamic = 1,
1224 .dpcm_playback = 1,
1225 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1226 SND_SOC_DPCM_TRIGGER_POST},
1227 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1228 .ignore_suspend = 1,
1229 /* this dailink has playback support */
1230 .ignore_pmdown_time = 1,
1231 /* This dainlink has MI2S support */
1232 .codec_dai_name = "snd-soc-dummy-dai",
1233 .codec_name = "snd-soc-dummy",
1234 },
1235 {/* hw:x,6 */
1236 .name = "INT_FM Hostless",
1237 .stream_name = "INT_FM Hostless",
1238 .cpu_dai_name = "INT_FM_HOSTLESS",
1239 .platform_name = "msm-pcm-hostless",
1240 .dynamic = 1,
1241 .dpcm_capture = 1,
1242 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1243 SND_SOC_DPCM_TRIGGER_POST},
1244 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1245 .ignore_suspend = 1,
1246 /* this dainlink has playback support */
1247 .ignore_pmdown_time = 1,
1248 .codec_dai_name = "snd-soc-dummy-dai",
1249 .codec_name = "snd-soc-dummy",
1250 },
1251 {/* hw:x,7 */
1252 .name = "MSM AFE-PCM RX",
1253 .stream_name = "AFE-PROXY RX",
1254 .cpu_dai_name = "msm-dai-q6-dev.241",
1255 .codec_name = "msm-stub-codec.1",
1256 .codec_dai_name = "msm-stub-rx",
1257 .platform_name = "msm-pcm-afe",
1258 .ignore_suspend = 1,
1259 /* this dainlink has playback support */
1260 .ignore_pmdown_time = 1,
1261 },
1262 {/* hw:x,8 */
1263 .name = "MSM AFE-PCM TX",
1264 .stream_name = "AFE-PROXY TX",
1265 .cpu_dai_name = "msm-dai-q6-dev.240",
1266 .codec_name = "msm-stub-codec.1",
1267 .codec_dai_name = "msm-stub-tx",
1268 .platform_name = "msm-pcm-afe",
1269 .ignore_suspend = 1,
1270 },
1271 {/* hw:x,9 */
1272 .name = "MSM8952 Compress1",
1273 .stream_name = "Compress1",
1274 .cpu_dai_name = "MultiMedia4",
1275 .platform_name = "msm-compress-dsp",
1276 .dynamic = 1,
1277 .dpcm_playback = 1,
1278 .dpcm_capture = 1,
1279 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1280 SND_SOC_DPCM_TRIGGER_POST},
1281 .codec_dai_name = "snd-soc-dummy-dai",
1282 .codec_name = "snd-soc-dummy",
1283 .ignore_suspend = 1,
1284 .ignore_pmdown_time = 1,
1285 /* this dainlink has playback support */
1286 .id = MSM_FRONTEND_DAI_MULTIMEDIA4,
1287 },
1288 {/* hw:x,10 */
1289 .name = "AUXPCM Hostless",
1290 .stream_name = "AUXPCM Hostless",
1291 .cpu_dai_name = "AUXPCM_HOSTLESS",
1292 .platform_name = "msm-pcm-hostless",
1293 .dynamic = 1,
1294 .dpcm_playback = 1,
1295 .dpcm_capture = 1,
1296 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1297 SND_SOC_DPCM_TRIGGER_POST},
1298 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1299 .ignore_suspend = 1,
1300 /* this dainlink has playback support */
1301 .ignore_pmdown_time = 1,
1302 .codec_dai_name = "snd-soc-dummy-dai",
1303 .codec_name = "snd-soc-dummy",
1304 },
1305 {/* hw:x,11 */
1306 .name = "Tertiary MI2S_TX Hostless",
1307 .stream_name = "Tertiary MI2S_TX Hostless",
1308 .cpu_dai_name = "TERT_MI2S_TX_HOSTLESS",
1309 .platform_name = "msm-pcm-hostless",
1310 .dynamic = 1,
1311 .dpcm_capture = 1,
1312 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1313 SND_SOC_DPCM_TRIGGER_POST},
1314 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1315 .ignore_suspend = 1,
1316 .ignore_pmdown_time = 1, /* dai link has playback support */
1317 .codec_dai_name = "snd-soc-dummy-dai",
1318 .codec_name = "snd-soc-dummy",
1319 },
1320 {/* hw:x,12 */
1321 .name = "MSM8x16 LowLatency",
1322 .stream_name = "MultiMedia5",
1323 .cpu_dai_name = "MultiMedia5",
1324 .platform_name = "msm-pcm-dsp.1",
1325 .dynamic = 1,
1326 .dpcm_playback = 1,
1327 .dpcm_capture = 1,
1328 .codec_dai_name = "snd-soc-dummy-dai",
1329 .codec_name = "snd-soc-dummy",
1330 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1331 SND_SOC_DPCM_TRIGGER_POST},
1332 .ignore_suspend = 1,
1333 /* this dainlink has playback support */
1334 .ignore_pmdown_time = 1,
1335 .id = MSM_FRONTEND_DAI_MULTIMEDIA5,
1336 },
1337 {/* hw:x,13 */
1338 .name = "Voice2",
1339 .stream_name = "Voice2",
1340 .cpu_dai_name = "VoiceMMode1",
1341 .platform_name = "msm-pcm-voice",
1342 .dynamic = 1,
1343 .dpcm_playback = 1,
1344 .dpcm_capture = 1,
1345 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1346 SND_SOC_DPCM_TRIGGER_POST},
1347 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1348 .ignore_suspend = 1,
1349 /* this dainlink has playback support */
1350 .ignore_pmdown_time = 1,
1351 .codec_dai_name = "snd-soc-dummy-dai",
1352 .codec_name = "snd-soc-dummy",
1353 .id = MSM_FRONTEND_DAI_VOICE2,
1354 },
1355 {/* hw:x,14 */
1356 .name = "MSM8x16 Media9",
1357 .stream_name = "MultiMedia9",
1358 .cpu_dai_name = "MultiMedia9",
1359 .platform_name = "msm-pcm-dsp.0",
1360 .dynamic = 1,
1361 .dpcm_playback = 1,
1362 .dpcm_capture = 1,
1363 .codec_dai_name = "snd-soc-dummy-dai",
1364 .codec_name = "snd-soc-dummy",
1365 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1366 SND_SOC_DPCM_TRIGGER_POST},
1367 .ignore_suspend = 1,
1368 /* This dailink has playback support */
1369 .ignore_pmdown_time = 1,
1370 .id = MSM_FRONTEND_DAI_MULTIMEDIA9,
1371 },
1372 { /* hw:x,15 */
1373 .name = "VoLTE",
1374 .stream_name = "VoLTE",
1375 .cpu_dai_name = "VoiceMMode1",
1376 .platform_name = "msm-pcm-voice",
1377 .dynamic = 1,
1378 .dpcm_playback = 1,
1379 .dpcm_capture = 1,
1380 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1381 SND_SOC_DPCM_TRIGGER_POST},
1382 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1383 .ignore_suspend = 1,
1384 /* this dainlink has playback support */
1385 .ignore_pmdown_time = 1,
1386 .codec_dai_name = "snd-soc-dummy-dai",
1387 .codec_name = "snd-soc-dummy",
1388 .id = MSM_FRONTEND_DAI_VOLTE,
1389 },
1390 { /* hw:x,16 */
1391 .name = "VoWLAN",
1392 .stream_name = "VoWLAN",
1393 .cpu_dai_name = "VoiceMMode1",
1394 .platform_name = "msm-pcm-voice",
1395 .dynamic = 1,
1396 .dpcm_playback = 1,
1397 .dpcm_capture = 1,
1398 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1399 SND_SOC_DPCM_TRIGGER_POST},
1400 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1401 .ignore_suspend = 1,
1402 .ignore_pmdown_time = 1,
1403 .codec_dai_name = "snd-soc-dummy-dai",
1404 .codec_name = "snd-soc-dummy",
1405 .id = MSM_FRONTEND_DAI_VOWLAN,
1406 },
1407 {/* hw:x,17 */
1408 .name = "INT_HFP_BT Hostless",
1409 .stream_name = "INT_HFP_BT Hostless",
1410 .cpu_dai_name = "INT_HFP_BT_HOSTLESS",
1411 .platform_name = "msm-pcm-hostless",
1412 .dynamic = 1,
1413 .dpcm_playback = 1,
1414 .dpcm_capture = 1,
1415 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1416 SND_SOC_DPCM_TRIGGER_POST},
1417 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1418 .ignore_suspend = 1,
1419 /* this dai link has playback support */
1420 .ignore_pmdown_time = 1,
1421 .codec_dai_name = "snd-soc-dummy-dai",
1422 .codec_name = "snd-soc-dummy",
1423 },
1424 {/* hw:x,18 */
1425 .name = "MSM8916 HFP",
1426 .stream_name = "MultiMedia6",
1427 .cpu_dai_name = "MultiMedia6",
1428 .platform_name = "msm-pcm-loopback",
1429 .dynamic = 1,
1430 .dpcm_playback = 1,
1431 .dpcm_capture = 1,
1432 .codec_dai_name = "snd-soc-dummy-dai",
1433 .codec_name = "snd-soc-dummy",
1434 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1435 SND_SOC_DPCM_TRIGGER_POST},
1436 .ignore_suspend = 1,
1437 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1438 /* this dai link has playback support */
1439 .ignore_pmdown_time = 1,
1440 .id = MSM_FRONTEND_DAI_MULTIMEDIA6,
1441 },
1442 /* LSM FE */
1443 {/* hw:x,19 */
1444 .name = "Listen 1 Audio Service",
1445 .stream_name = "Listen 1 Audio Service",
1446 .cpu_dai_name = "LSM1",
1447 .platform_name = "msm-lsm-client",
1448 .dynamic = 1,
1449 .dpcm_capture = 1,
1450 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1451 SND_SOC_DPCM_TRIGGER_POST },
1452 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1453 .ignore_suspend = 1,
1454 .ignore_pmdown_time = 1,
1455 .codec_dai_name = "snd-soc-dummy-dai",
1456 .codec_name = "snd-soc-dummy",
1457 .id = MSM_FRONTEND_DAI_LSM1,
1458 },
1459 {/* hw:x,20 */
1460 .name = "Listen 2 Audio Service",
1461 .stream_name = "Listen 2 Audio Service",
1462 .cpu_dai_name = "LSM2",
1463 .platform_name = "msm-lsm-client",
1464 .dynamic = 1,
1465 .dpcm_capture = 1,
1466 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1467 SND_SOC_DPCM_TRIGGER_POST },
1468 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1469 .ignore_suspend = 1,
1470 .ignore_pmdown_time = 1,
1471 .codec_dai_name = "snd-soc-dummy-dai",
1472 .codec_name = "snd-soc-dummy",
1473 .id = MSM_FRONTEND_DAI_LSM2,
1474 },
1475 {/* hw:x,21 */
1476 .name = "Listen 3 Audio Service",
1477 .stream_name = "Listen 3 Audio Service",
1478 .cpu_dai_name = "LSM3",
1479 .platform_name = "msm-lsm-client",
1480 .dynamic = 1,
1481 .dpcm_capture = 1,
1482 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1483 SND_SOC_DPCM_TRIGGER_POST },
1484 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1485 .ignore_suspend = 1,
1486 .ignore_pmdown_time = 1,
1487 .codec_dai_name = "snd-soc-dummy-dai",
1488 .codec_name = "snd-soc-dummy",
1489 .id = MSM_FRONTEND_DAI_LSM3,
1490 },
1491 {/* hw:x,22 */
1492 .name = "Listen 4 Audio Service",
1493 .stream_name = "Listen 4 Audio Service",
1494 .cpu_dai_name = "LSM4",
1495 .platform_name = "msm-lsm-client",
1496 .dynamic = 1,
1497 .dpcm_capture = 1,
1498 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1499 SND_SOC_DPCM_TRIGGER_POST },
1500 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1501 .ignore_suspend = 1,
1502 .ignore_pmdown_time = 1,
1503 .codec_dai_name = "snd-soc-dummy-dai",
1504 .codec_name = "snd-soc-dummy",
1505 .id = MSM_FRONTEND_DAI_LSM4,
1506 },
1507 {/* hw:x,23 */
1508 .name = "Listen 5 Audio Service",
1509 .stream_name = "Listen 5 Audio Service",
1510 .cpu_dai_name = "LSM5",
1511 .platform_name = "msm-lsm-client",
1512 .dynamic = 1,
1513 .dpcm_capture = 1,
1514 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1515 SND_SOC_DPCM_TRIGGER_POST },
1516 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1517 .ignore_suspend = 1,
1518 .ignore_pmdown_time = 1,
1519 .codec_dai_name = "snd-soc-dummy-dai",
1520 .codec_name = "snd-soc-dummy",
1521 .id = MSM_FRONTEND_DAI_LSM5,
1522 },
1523 { /* hw:x,24 */
1524 .name = "MSM8X16 Compress2",
1525 .stream_name = "Compress2",
1526 .cpu_dai_name = "MultiMedia7",
1527 .platform_name = "msm-compress-dsp",
1528 .dynamic = 1,
1529 .dpcm_playback = 1,
1530 .codec_dai_name = "snd-soc-dummy-dai",
1531 .codec_name = "snd-soc-dummy",
1532 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1533 SND_SOC_DPCM_TRIGGER_POST},
1534 .ignore_suspend = 1,
1535 /* this dainlink has playback support */
1536 .ignore_pmdown_time = 1,
1537 .id = MSM_FRONTEND_DAI_MULTIMEDIA7,
1538 },
1539 { /* hw:x,25 */
1540 .name = "QUAT_MI2S Hostless",
1541 .stream_name = "QUAT_MI2S Hostless",
1542 .cpu_dai_name = "QUAT_MI2S_RX_HOSTLESS",
1543 .platform_name = "msm-pcm-hostless",
1544 .dynamic = 1,
1545 .dpcm_playback = 1,
1546 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1547 SND_SOC_DPCM_TRIGGER_POST},
1548 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1549 .ignore_suspend = 1,
1550 /* this dainlink has playback support */
1551 .ignore_pmdown_time = 1,
1552 .codec_dai_name = "snd-soc-dummy-dai",
1553 .codec_name = "snd-soc-dummy",
1554 },
1555 {/* hw:x,27 */
1556 .name = "MSM8X16 Compress3",
1557 .stream_name = "Compress3",
1558 .cpu_dai_name = "MultiMedia10",
1559 .platform_name = "msm-pcm-dsp.1",
1560 .dynamic = 1,
1561 .dpcm_playback = 1,
1562 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1563 SND_SOC_DPCM_TRIGGER_POST},
1564 .codec_dai_name = "snd-soc-dummy-dai",
1565 .codec_name = "snd-soc-dummy",
1566 .ignore_suspend = 1,
1567 .ignore_pmdown_time = 1,
1568 /* this dai link has playback support */
1569 .id = MSM_FRONTEND_DAI_MULTIMEDIA10,
1570 },
1571 {/* hw:x,28 */
1572 .name = "MSM8X16 Compress4",
1573 .stream_name = "Compress4",
1574 .cpu_dai_name = "MultiMedia11",
1575 .platform_name = "msm-compress-dsp",
1576 .dynamic = 1,
1577 .dpcm_playback = 1,
1578 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1579 SND_SOC_DPCM_TRIGGER_POST},
1580 .codec_dai_name = "snd-soc-dummy-dai",
1581 .codec_name = "snd-soc-dummy",
1582 .ignore_suspend = 1,
1583 .ignore_pmdown_time = 1,
1584 /* this dai link has playback support */
1585 .id = MSM_FRONTEND_DAI_MULTIMEDIA11,
1586 },
1587 {/* hw:x,29 */
1588 .name = "MSM8X16 Compress5",
1589 .stream_name = "Compress5",
1590 .cpu_dai_name = "MultiMedia12",
1591 .platform_name = "msm-compress-dsp",
1592 .dynamic = 1,
1593 .dpcm_playback = 1,
1594 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1595 SND_SOC_DPCM_TRIGGER_POST},
1596 .codec_dai_name = "snd-soc-dummy-dai",
1597 .codec_name = "snd-soc-dummy",
1598 .ignore_suspend = 1,
1599 .ignore_pmdown_time = 1,
1600 /* this dai link has playback support */
1601 .id = MSM_FRONTEND_DAI_MULTIMEDIA12,
1602 },
1603 {/* hw:x,30 */
1604 .name = "MSM8X16 Compress6",
1605 .stream_name = "Compress6",
1606 .cpu_dai_name = "MultiMedia13",
1607 .platform_name = "msm-compress-dsp",
1608 .dynamic = 1,
1609 .dpcm_playback = 1,
1610 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1611 SND_SOC_DPCM_TRIGGER_POST},
1612 .codec_dai_name = "snd-soc-dummy-dai",
1613 .codec_name = "snd-soc-dummy",
1614 .ignore_suspend = 1,
1615 .ignore_pmdown_time = 1,
1616 /* this dai link has playback support */
1617 .id = MSM_FRONTEND_DAI_MULTIMEDIA13,
1618 },
1619 {/* hw:x,31 */
1620 .name = "MSM8X16 Compress7",
1621 .stream_name = "Compress7",
1622 .cpu_dai_name = "MultiMedia14",
1623 .platform_name = "msm-compress-dsp",
1624 .dynamic = 1,
1625 .dpcm_playback = 1,
1626 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1627 SND_SOC_DPCM_TRIGGER_POST},
1628 .codec_dai_name = "snd-soc-dummy-dai",
1629 .codec_name = "snd-soc-dummy",
1630 .ignore_suspend = 1,
1631 .ignore_pmdown_time = 1,
1632 /* this dai link has playback support */
1633 .id = MSM_FRONTEND_DAI_MULTIMEDIA14,
1634 },
1635 {/* hw:x,32 */
1636 .name = "MSM8X16 Compress8",
1637 .stream_name = "Compress8",
1638 .cpu_dai_name = "MultiMedia15",
1639 .platform_name = "msm-compress-dsp",
1640 .dynamic = 1,
1641 .dpcm_playback = 1,
1642 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1643 SND_SOC_DPCM_TRIGGER_POST},
1644 .codec_dai_name = "snd-soc-dummy-dai",
1645 .codec_name = "snd-soc-dummy",
1646 .ignore_suspend = 1,
1647 .ignore_pmdown_time = 1,
1648 /* this dai link has playback support */
1649 .id = MSM_FRONTEND_DAI_MULTIMEDIA15,
1650 },
1651 {/* hw:x,33 */
1652 .name = "MSM8X16 Compress10",
1653 .stream_name = "Compress10",
1654 .cpu_dai_name = "MultiMedia17",
1655 .platform_name = "msm-compress-dsp",
1656 .dynamic = 1,
1657 .dpcm_playback = 1,
1658 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1659 SND_SOC_DPCM_TRIGGER_POST},
1660 .codec_dai_name = "snd-soc-dummy-dai",
1661 .codec_name = "snd-soc-dummy",
1662 .ignore_suspend = 1,
1663 .ignore_pmdown_time = 1,
1664 /* this dai link has playback support */
1665 .id = MSM_FRONTEND_DAI_MULTIMEDIA17,
1666 },
1667 {/* hw:x,34 */
1668 .name = "VoiceMMode1",
1669 .stream_name = "VoiceMMode1",
1670 .cpu_dai_name = "VoiceMMode1",
1671 .platform_name = "msm-pcm-voice",
1672 .dynamic = 1,
1673 .dpcm_playback = 1,
1674 .dpcm_capture = 1,
1675 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1676 SND_SOC_DPCM_TRIGGER_POST},
1677 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1678 .ignore_suspend = 1,
1679 .ignore_pmdown_time = 1,
1680 .codec_dai_name = "snd-soc-dummy-dai",
1681 .codec_name = "snd-soc-dummy",
1682 .id = MSM_FRONTEND_DAI_VOICEMMODE1,
1683 },
1684 {/* hw:x,35 */
1685 .name = "VoiceMMode2",
1686 .stream_name = "VoiceMMode2",
1687 .cpu_dai_name = "VoiceMMode2",
1688 .platform_name = "msm-pcm-voice",
1689 .dynamic = 1,
1690 .dpcm_playback = 1,
1691 .dpcm_capture = 1,
1692 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1693 SND_SOC_DPCM_TRIGGER_POST},
1694 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1695 .ignore_suspend = 1,
1696 .ignore_pmdown_time = 1,
1697 .codec_dai_name = "snd-soc-dummy-dai",
1698 .codec_name = "snd-soc-dummy",
1699 .id = MSM_FRONTEND_DAI_VOICEMMODE2,
1700 },
1701 {/* hw:x,36 */
1702 .name = "MSM8916 HFP Loopback2",
1703 .stream_name = "MultiMedia8",
1704 .cpu_dai_name = "MultiMedia8",
1705 .platform_name = "msm-pcm-loopback",
1706 .dynamic = 1,
1707 .dpcm_playback = 1,
1708 .dpcm_capture = 1,
1709 .codec_dai_name = "snd-soc-dummy-dai",
1710 .codec_name = "snd-soc-dummy",
1711 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1712 SND_SOC_DPCM_TRIGGER_POST},
1713 .ignore_suspend = 1,
1714 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1715 /* this dai link has playback support */
1716 .ignore_pmdown_time = 1,
1717 .id = MSM_FRONTEND_DAI_MULTIMEDIA8,
1718 },
1719 {/* hw:x,37 */
1720 .name = "QCHAT",
1721 .stream_name = "QCHAT",
1722 .cpu_dai_name = "QCHAT",
1723 .platform_name = "msm-pcm-voice",
1724 .dynamic = 1,
1725 .dpcm_playback = 1,
1726 .dpcm_capture = 1,
1727 .codec_dai_name = "snd-soc-dummy-dai",
1728 .codec_name = "snd-soc-dummy",
1729 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1730 SND_SOC_DPCM_TRIGGER_POST},
1731 .ignore_suspend = 1,
1732 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1733 /* this dai link has playback support */
1734 .ignore_pmdown_time = 1,
1735 .id = MSM_FRONTEND_DAI_QCHAT,
1736 },
1737 {/* hw:x,38 */
1738 .name = "MSM8X16 Compress11",
1739 .stream_name = "Compress11",
1740 .cpu_dai_name = "MultiMedia18",
1741 .platform_name = "msm-compress-dsp",
1742 .dynamic = 1,
1743 .dpcm_capture = 1,
1744 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1745 SND_SOC_DPCM_TRIGGER_POST},
1746 .codec_dai_name = "snd-soc-dummy-dai",
1747 .codec_name = "snd-soc-dummy",
1748 .ignore_suspend = 1,
1749 .ignore_pmdown_time = 1,
1750 .id = MSM_FRONTEND_DAI_MULTIMEDIA18,
1751 },
1752 {/* hw:x,39 */
1753 .name = "MSM8X16 Compress12",
1754 .stream_name = "Compress12",
1755 .cpu_dai_name = "MultiMedia19",
1756 .platform_name = "msm-compress-dsp",
1757 .dynamic = 1,
1758 .dpcm_capture = 1,
1759 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1760 SND_SOC_DPCM_TRIGGER_POST},
1761 .codec_dai_name = "snd-soc-dummy-dai",
1762 .codec_name = "snd-soc-dummy",
1763 .ignore_suspend = 1,
1764 .ignore_pmdown_time = 1,
1765 .id = MSM_FRONTEND_DAI_MULTIMEDIA19,
1766 },
1767};
1768
1769static struct snd_soc_dai_link msm_bg_tdm_fe_dai[] = {
1770 /* FE TDM DAI links */
1771 {
1772 .name = "Primary TDM RX 0 Hostless",
1773 .stream_name = "Primary TDM RX 0 Hostless",
1774 .cpu_dai_name = "PRI_TDM_RX_0_HOSTLESS",
1775 .platform_name = "msm-pcm-hostless",
1776 .dynamic = 1,
1777 .dpcm_playback = 1,
1778 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1779 SND_SOC_DPCM_TRIGGER_POST},
1780 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1781 .ignore_suspend = 1,
1782 .ignore_pmdown_time = 1,
1783 .codec_dai_name = "snd-soc-dummy-dai",
1784 .codec_name = "snd-soc-dummy",
1785 },
1786 {
1787 .name = "Primary TDM TX 0 Hostless",
1788 .stream_name = "Primary TDM TX 0 Hostless",
1789 .cpu_dai_name = "PRI_TDM_TX_0_HOSTLESS",
1790 .platform_name = "msm-pcm-hostless",
1791 .dynamic = 1,
1792 .dpcm_capture = 1,
1793 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1794 SND_SOC_DPCM_TRIGGER_POST},
1795 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1796 .ignore_suspend = 1,
1797 .ignore_pmdown_time = 1,
1798 .codec_dai_name = "snd-soc-dummy-dai",
1799 .codec_name = "snd-soc-dummy",
1800 },
1801 {
1802 .name = "Secondary TDM RX 0 Hostless",
1803 .stream_name = "Secondary TDM RX 0 Hostless",
1804 .cpu_dai_name = "SEC_TDM_RX_0_HOSTLESS",
1805 .platform_name = "msm-pcm-hostless",
1806 .dynamic = 1,
1807 .dpcm_playback = 1,
1808 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1809 SND_SOC_DPCM_TRIGGER_POST},
1810 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1811 .ignore_suspend = 1,
1812 .ignore_pmdown_time = 1,
1813 .codec_dai_name = "snd-soc-dummy-dai",
1814 .codec_name = "snd-soc-dummy",
1815 },
1816 {
1817 .name = "Secondary TDM TX 0 Hostless",
1818 .stream_name = "Secondary TDM TX 0 Hostless",
1819 .cpu_dai_name = "SEC_TDM_TX_0_HOSTLESS",
1820 .platform_name = "msm-pcm-hostless",
1821 .dynamic = 1,
1822 .dpcm_capture = 1,
1823 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1824 SND_SOC_DPCM_TRIGGER_POST},
1825 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1826 .ignore_suspend = 1,
1827 .ignore_pmdown_time = 1,
1828 .codec_dai_name = "snd-soc-dummy-dai",
1829 .codec_name = "snd-soc-dummy",
1830 },
1831};
1832
1833static struct snd_soc_dai_link msm_bg_tdm_be_dai[] = {
1834 /* TDM be dai links */
1835 {
1836 .name = LPASS_BE_PRI_TDM_RX_0,
1837 .stream_name = "Primary TDM0 Playback",
1838 .cpu_dai_name = "msm-dai-q6-tdm.36864",
1839 .platform_name = "msm-pcm-routing",
1840 .init = &msm_audrx_init,
1841 .codec_name = "soc:bg_codec",
1842 .codec_dai_name = "bg_cdc_rx1",
1843 .no_pcm = 1,
1844 .dpcm_playback = 1,
1845 .id = MSM_BACKEND_DAI_PRI_TDM_RX_0,
1846 .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
1847 .ops = &msm_tdm_be_ops,
1848 .ignore_suspend = 1,
1849 },
1850 {
1851 .name = LPASS_BE_PRI_TDM_TX_0,
1852 .stream_name = "Primary TDM0 Capture",
1853 .cpu_dai_name = "msm-dai-q6-tdm.36865",
1854 .platform_name = "msm-pcm-routing",
1855 .codec_name = "soc:bg_codec",
1856 .codec_dai_name = "bg_cdc_tx1",
1857 .no_pcm = 1,
1858 .dpcm_capture = 1,
1859 .id = MSM_BACKEND_DAI_PRI_TDM_TX_0,
1860 .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
1861 .ops = &msm_tdm_be_ops,
1862 .ignore_suspend = 1,
1863 },
1864 {
1865 .name = LPASS_BE_PRI_TDM_RX_1,
1866 .stream_name = "Primary TDM1 Playback",
1867 .cpu_dai_name = "msm-dai-q6-tdm.36866",
1868 .platform_name = "msm-pcm-routing",
1869 .codec_name = "soc:bg_codec",
1870 .codec_dai_name = "bg_cdc_rx2",
1871 .no_pcm = 1,
1872 .dpcm_playback = 1,
1873 .id = MSM_BACKEND_DAI_PRI_TDM_RX_1,
1874 .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
1875 .ops = &msm_tdm_be_ops,
1876 .ignore_suspend = 1,
1877 },
1878 {
1879 .name = LPASS_BE_PRI_TDM_TX_1,
1880 .stream_name = "Primary TDM1 Capture",
1881 .cpu_dai_name = "msm-dai-q6-tdm.36867",
1882 .platform_name = "msm-pcm-routing",
1883 .codec_name = "soc:bg_codec",
1884 .codec_dai_name = "bg_cdc_tx2",
1885 .no_pcm = 1,
1886 .dpcm_capture = 1,
1887 .id = MSM_BACKEND_DAI_PRI_TDM_TX_1,
1888 .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
1889 .ops = &msm_tdm_be_ops,
1890 .ignore_suspend = 1,
1891 },
1892 {
1893 .name = LPASS_BE_PRI_TDM_RX_2,
1894 .stream_name = "Primary TDM2 Playback",
1895 .cpu_dai_name = "msm-dai-q6-tdm.36868",
1896 .platform_name = "msm-pcm-routing",
1897 .codec_name = "soc:bg_codec",
1898 .codec_dai_name = "bg_cdc_rx3",
1899 .no_pcm = 1,
1900 .dpcm_playback = 1,
1901 .id = MSM_BACKEND_DAI_PRI_TDM_RX_2,
1902 .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
1903 .ops = &msm_tdm_be_ops,
1904 .ignore_suspend = 1,
1905 },
1906 {
1907 .name = LPASS_BE_PRI_TDM_TX_2,
1908 .stream_name = "Primary TDM2 Capture",
1909 .cpu_dai_name = "msm-dai-q6-tdm.36869",
1910 .platform_name = "msm-pcm-routing",
1911 .codec_name = "soc:bg_codec",
1912 .codec_dai_name = "bg_cdc_tx3",
1913 .no_pcm = 1,
1914 .dpcm_capture = 1,
1915 .id = MSM_BACKEND_DAI_PRI_TDM_TX_2,
1916 .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
1917 .ops = &msm_tdm_be_ops,
1918 .ignore_suspend = 1,
1919 },
1920 {
1921 .name = LPASS_BE_PRI_TDM_RX_3,
1922 .stream_name = "Primary TDM3 Playback",
1923 .cpu_dai_name = "msm-dai-q6-tdm.36870",
1924 .platform_name = "msm-pcm-routing",
1925 .codec_name = "soc:bg_codec",
1926 .codec_dai_name = "bg_cdc_rx4",
1927 .no_pcm = 1,
1928 .dpcm_playback = 1,
1929 .id = MSM_BACKEND_DAI_PRI_TDM_RX_3,
1930 .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
1931 .ops = &msm_tdm_be_ops,
1932 .ignore_suspend = 1,
1933 },
1934 {
1935 .name = LPASS_BE_PRI_TDM_TX_3,
1936 .stream_name = "Primary TDM3 Capture",
1937 .cpu_dai_name = "msm-dai-q6-tdm.36871",
1938 .platform_name = "msm-pcm-routing",
1939 .codec_name = "soc:bg_codec",
1940 .codec_dai_name = "bg_cdc_tx4",
1941 .no_pcm = 1,
1942 .dpcm_capture = 1,
1943 .id = MSM_BACKEND_DAI_PRI_TDM_TX_3,
1944 .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
1945 .ops = &msm_tdm_be_ops,
1946 .ignore_suspend = 1,
1947 },
1948 {
1949 .name = LPASS_BE_INT_BT_SCO_RX,
1950 .stream_name = "Internal BT-SCO Playback",
1951 .cpu_dai_name = "msm-dai-q6-dev.12288",
1952 .platform_name = "msm-pcm-routing",
1953 .codec_name = "msm-stub-codec.1",
1954 .codec_dai_name = "msm-stub-rx",
1955 .no_pcm = 1,
1956 .dpcm_playback = 1,
1957 .id = MSM_BACKEND_DAI_INT_BT_SCO_RX,
1958 .be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
1959 /* this dainlink has playback support */
1960 .ignore_pmdown_time = 1,
1961 .ignore_suspend = 1,
1962 },
1963 {
1964 .name = LPASS_BE_INT_BT_SCO_TX,
1965 .stream_name = "Internal BT-SCO Capture",
1966 .cpu_dai_name = "msm-dai-q6-dev.12289",
1967 .platform_name = "msm-pcm-routing",
1968 .codec_name = "msm-stub-codec.1",
1969 .codec_dai_name = "msm-stub-tx",
1970 .no_pcm = 1,
1971 .dpcm_capture = 1,
1972 .id = MSM_BACKEND_DAI_INT_BT_SCO_TX,
1973 .be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
1974 .ignore_suspend = 1,
1975 },
1976};
1977
1978static struct snd_soc_dai_link msm_bg_split_a2dp_dai_link[] = {
1979 {
1980 .name = LPASS_BE_INT_BT_A2DP_RX,
1981 .stream_name = "Internal BT-A2DP Playback",
1982 .cpu_dai_name = "msm-dai-q6-dev.12290",
1983 .platform_name = "msm-pcm-routing",
1984 .codec_dai_name = "msm-stub-rx",
1985 .codec_name = "msm-stub-codec.1",
1986 .no_pcm = 1,
1987 .dpcm_playback = 1,
1988 .id = MSM_BACKEND_DAI_INT_BT_A2DP_RX,
1989 .be_hw_params_fixup = msm_be_hw_params_fixup,
1990 .ignore_pmdown_time = 1, /* dai link has playback support */
1991 .ignore_suspend = 1,
1992 },
1993};
1994
1995static struct snd_soc_dai_link msm_bg_dai_links[
1996ARRAY_SIZE(msm_bg_dai) +
1997ARRAY_SIZE(msm_bg_tdm_fe_dai) +
1998ARRAY_SIZE(msm_bg_tdm_be_dai) +
1999ARRAY_SIZE(msm_bg_split_a2dp_dai_link)];
2000
2001static struct snd_soc_card bear_card = {
2002 /* snd_soc_card_msm_bg */
2003 .name = "msm_bg-snd-card",
2004 .dai_link = msm_bg_dai,
2005 .num_links = ARRAY_SIZE(msm_bg_dai),
2006};
2007
Sundara Vinayagam9c86c8d2018-05-14 21:57:42 +05302008static const struct of_device_id msm_bg_asoc_machine_of_match[] = {
2009 { .compatible = "qcom,msm-bg-audio-codec", },
2010 {},
2011};
2012
Sundara Vinayagam43ce7c92018-05-21 16:34:47 +05302013static int msm_bg_populate_dai_link_component_of_node(
2014 struct snd_soc_card *card)
2015{
2016 int i, index, ret = 0;
2017 struct device *cdev = card->dev;
2018 struct snd_soc_dai_link *dai_link = card->dai_link;
2019 struct device_node *phandle;
2020
2021 if (!cdev) {
2022 pr_err("Sound card device memory NULL");
2023 return -ENODEV;
2024 }
2025
2026 for (i = 0; i < card->num_links; i++) {
2027 if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node)
2028 continue;
2029
2030 /* populate platform_of_node for snd card dai links */
2031 if (dai_link[i].platform_name &&
2032 !dai_link[i].platform_of_node) {
2033 index = of_property_match_string(cdev->of_node,
2034 "asoc-platform-names",
2035 dai_link[i].platform_name);
2036 if (index < 0) {
2037 pr_err("No match found for platform name: %s",
2038 dai_link[i].platform_name);
2039 ret = index;
2040 goto cpu_dai;
2041 }
2042 phandle = of_parse_phandle(cdev->of_node,
2043 "asoc-platform",
2044 index);
2045 if (!phandle) {
2046 pr_err("retrieving phandle for platform %s, index %d failed",
2047 dai_link[i].platform_name,
2048 index);
2049 ret = -ENODEV;
2050 goto err;
2051 }
2052 dai_link[i].platform_of_node = phandle;
2053 dai_link[i].platform_name = NULL;
2054 }
2055cpu_dai:
2056 /* populate cpu_of_node for snd card dai links */
2057 if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) {
2058 index = of_property_match_string(cdev->of_node,
2059 "asoc-cpu-names",
2060 dai_link[i].cpu_dai_name);
2061 if (index < 0)
2062 goto codec_dai;
2063 phandle = of_parse_phandle(cdev->of_node, "asoc-cpu",
2064 index);
2065 if (!phandle) {
2066 pr_err("retrieving phandle for cpu dai %s failed",
2067 dai_link[i].cpu_dai_name);
2068 ret = -ENODEV;
2069 goto err;
2070 }
2071 dai_link[i].cpu_of_node = phandle;
2072 dai_link[i].cpu_dai_name = NULL;
2073 }
2074codec_dai:
2075 /* populate codec_of_node for snd card dai links */
2076 if (dai_link[i].codec_name && !dai_link[i].codec_of_node) {
2077 index = of_property_match_string(cdev->of_node,
2078 "asoc-codec-names",
2079 dai_link[i].codec_name);
2080 if (index < 0)
2081 continue;
2082 phandle = of_parse_phandle(cdev->of_node, "asoc-codec",
2083 index);
2084 if (!phandle) {
2085 pr_err("retrieving phandle for codec dai %s failed",
2086 dai_link[i].codec_name);
2087 ret = -ENODEV;
2088 goto err;
2089 }
2090 dai_link[i].codec_of_node = phandle;
2091 dai_link[i].codec_name = NULL;
2092 }
2093 }
2094err:
2095 return ret;
2096}
2097
2098static struct snd_soc_card *msm_bg_populate_sndcard_dailinks(
2099 struct device *dev)
2100{
2101 struct snd_soc_card *card = &bear_card;
2102 struct snd_soc_dai_link *dailink;
2103 int len1;
2104
2105 card->name = dev_name(dev);
2106 len1 = ARRAY_SIZE(msm_bg_dai);
2107 memcpy(msm_bg_dai_links, msm_bg_dai, sizeof(msm_bg_dai));
2108 dailink = msm_bg_dai_links;
2109
2110 if (of_property_read_bool(dev->of_node,
2111 "qcom,tdm-audio-intf")) {
2112 memcpy(dailink + len1, msm_bg_tdm_fe_dai,
2113 sizeof(msm_bg_tdm_fe_dai));
2114 len1 += ARRAY_SIZE(msm_bg_tdm_fe_dai);
2115 memcpy(dailink + len1, msm_bg_tdm_be_dai,
2116 sizeof(msm_bg_tdm_be_dai));
2117 len1 += ARRAY_SIZE(msm_bg_tdm_be_dai);
2118 }
2119
2120 if (of_property_read_bool(dev->of_node,
2121 "qcom,split-a2dp")) {
2122 dev_dbg(dev, "%s: split a2dp support present\n", __func__);
2123 memcpy(dailink + len1, msm_bg_split_a2dp_dai_link,
2124 sizeof(msm_bg_split_a2dp_dai_link));
2125 len1 += ARRAY_SIZE(msm_bg_split_a2dp_dai_link);
2126 }
2127 card->dai_link = dailink;
2128 card->num_links = len1;
2129 return card;
2130}
2131
2132static int msm_bg_asoc_machine_probe(struct platform_device *pdev)
2133{
2134 struct snd_soc_card *card;
2135 struct msm8916_asoc_mach_data *pdata = NULL;
2136 const char *ext_pa = "qcom,msm-ext-pa";
Sundara Vinayagam9c86c8d2018-05-14 21:57:42 +05302137 const struct of_device_id *match;
Sundara Vinayagam43ce7c92018-05-21 16:34:47 +05302138 int num_strings;
2139 int ret, /*id,*/ val;
2140 struct resource *muxsel;
2141
2142 pdata = devm_kzalloc(&pdev->dev,
2143 sizeof(struct msm8916_asoc_mach_data), GFP_KERNEL);
2144 if (!pdata)
2145 return -ENOMEM;
2146
Sundara Vinayagam9c86c8d2018-05-14 21:57:42 +05302147 card = msm_bg_populate_sndcard_dailinks(&pdev->dev);
2148 if (!card) {
2149 dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__);
2150 ret = -EINVAL;
2151 goto err;
2152 }
2153
2154 card->dev = &pdev->dev;
2155 platform_set_drvdata(pdev, card);
2156 snd_soc_card_set_drvdata(card, pdata);
2157
2158 ret = snd_soc_of_parse_card_name(card, "qcom,model");
2159 if (ret)
2160 goto err;
2161
2162 ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing");
2163 if (ret) {
2164 dev_err(&pdev->dev, "parse audio routing failed, err:%d\n",
2165 ret);
2166 goto err;
2167 }
2168 match = of_match_node(msm_bg_asoc_machine_of_match,
2169 pdev->dev.of_node);
2170 if (!match) {
2171 dev_err(&pdev->dev, "%s: no matched codec is found.\n",
2172 __func__);
2173 goto err;
2174 }
2175
Sundara Vinayagam43ce7c92018-05-21 16:34:47 +05302176 muxsel = platform_get_resource_byname(pdev, IORESOURCE_MEM,
2177 "csr_gp_io_mux_mic_ctl");
2178 if (!muxsel) {
2179 dev_err(&pdev->dev, "MUX addr invalid for MI2S\n");
2180 ret = -ENODEV;
2181 goto err1;
2182 }
2183 pdata->vaddr_gpio_mux_mic_ctl =
2184 ioremap(muxsel->start, resource_size(muxsel));
2185 if (pdata->vaddr_gpio_mux_mic_ctl == NULL) {
2186 pr_err("ioremap failure for muxsel virt addr");
2187 ret = -ENOMEM;
2188 goto err1;
2189 }
2190
2191 muxsel = platform_get_resource_byname(pdev, IORESOURCE_MEM,
2192 "csr_gp_io_mux_spkr_ctl");
2193 if (!muxsel) {
2194 dev_err(&pdev->dev, "MUX addr invalid for MI2S\n");
2195 ret = -ENODEV;
2196 goto err;
2197 }
Sundara Vinayagam9c86c8d2018-05-14 21:57:42 +05302198
2199 pdata->vaddr_gpio_mux_quin_ctl =
2200 ioremap(muxsel->start, resource_size(muxsel));
2201 if (pdata->vaddr_gpio_mux_quin_ctl == NULL) {
2202 pr_err("%s ioremap failure for muxsel virt addr\n",
2203 __func__);
2204 ret = -ENOMEM;
2205 goto err;
2206 }
2207
Sundara Vinayagam43ce7c92018-05-21 16:34:47 +05302208 pdata->vaddr_gpio_mux_spkr_ctl =
2209 ioremap(muxsel->start, resource_size(muxsel));
2210 if (pdata->vaddr_gpio_mux_spkr_ctl == NULL) {
2211 pr_err("ioremap failure for muxsel virt addr");
2212 ret = -ENOMEM;
2213 goto err;
2214 }
2215
2216 muxsel = platform_get_resource_byname(pdev, IORESOURCE_MEM,
2217 "csr_gp_io_lpaif_pri_pcm_pri_mode_muxsel");
2218 if (!muxsel) {
2219 dev_err(&pdev->dev, "pri pcm addr invalid for MI2S\n");
2220 ret = -ENODEV;
2221 goto err;
2222 }
2223 pdata->vaddr_gpio_mux_pcm_ctl =
2224 ioremap(muxsel->start, resource_size(muxsel));
2225 if (pdata->vaddr_gpio_mux_pcm_ctl == NULL) {
2226 pr_err("ioremap failure for muxsel virt addr");
2227 ret = -ENOMEM;
2228 goto err;
2229 }
2230
2231 muxsel = platform_get_resource_byname(pdev, IORESOURCE_MEM,
2232 "csr_gp_io_lpaif_sec_pcm_sec_mode_muxsel");
2233 if (!muxsel) {
2234 dev_err(&pdev->dev, "sec pcm addr invalid for MI2S\n");
2235 ret = -ENODEV;
2236 goto err;
2237 }
2238 pdata->vaddr_gpio_mux_sec_pcm_ctl =
2239 ioremap(muxsel->start, resource_size(muxsel));
2240 if (pdata->vaddr_gpio_mux_sec_pcm_ctl == NULL) {
2241 pr_err("ioremap failure for sec pcm muxsel virt addr");
2242 ret = -ENOMEM;
2243 goto err;
2244 }
2245
2246 pdata->pri_mi2s_gpio_p = of_parse_phandle(pdev->dev.of_node,
2247 "qcom,pri-mi2s-gpios", 0);
2248 if (!pdata->pri_mi2s_gpio_p)
2249 dev_err(&pdev->dev, " invalid phandle pri-mi2s-gpios\n");
2250
Sundara Vinayagam43ce7c92018-05-21 16:34:47 +05302251 num_strings = of_property_count_strings(pdev->dev.of_node,
2252 ext_pa);
2253 if (num_strings < 0) {
2254 dev_err(&pdev->dev,
2255 "%s: missing %s in dt node or length is incorrect\n",
2256 __func__, ext_pa);
2257 ret = -EINVAL;
2258 goto err;
2259 }
2260
2261 ret = of_property_read_u32(pdev->dev.of_node,
2262 "qcom,msm-afe-clk-ver", &val);
2263 if (ret)
2264 pdata->afe_clk_ver = AFE_CLK_VERSION_V2;
2265 else
2266 pdata->afe_clk_ver = val;
2267
Sundara Vinayagam43ce7c92018-05-21 16:34:47 +05302268 ret = msm_bg_populate_dai_link_component_of_node(card);
2269 if (ret) {
2270 ret = -EPROBE_DEFER;
2271 goto err;
2272 }
2273
2274 ret = snd_soc_register_card(card);
2275 if (ret) {
2276 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
2277 ret);
2278 goto err;
2279 }
2280 atomic_set(&pdata->primary_tdm_ref_count, 0);
2281 return 0;
2282err:
2283 if (pdata->vaddr_gpio_mux_spkr_ctl)
2284 iounmap(pdata->vaddr_gpio_mux_spkr_ctl);
2285 if (pdata->vaddr_gpio_mux_mic_ctl)
2286 iounmap(pdata->vaddr_gpio_mux_mic_ctl);
2287 if (pdata->vaddr_gpio_mux_pcm_ctl)
2288 iounmap(pdata->vaddr_gpio_mux_pcm_ctl);
2289 if (pdata->vaddr_gpio_mux_sec_pcm_ctl)
2290 iounmap(pdata->vaddr_gpio_mux_sec_pcm_ctl);
2291err1:
2292 devm_kfree(&pdev->dev, pdata);
2293 return ret;
2294}
2295
2296static int msm_bg_asoc_machine_remove(struct platform_device *pdev)
2297{
2298 struct snd_soc_card *card = platform_get_drvdata(pdev);
2299 struct msm8916_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
2300
2301 if (pdata->vaddr_gpio_mux_spkr_ctl)
2302 iounmap(pdata->vaddr_gpio_mux_spkr_ctl);
2303 if (pdata->vaddr_gpio_mux_mic_ctl)
2304 iounmap(pdata->vaddr_gpio_mux_mic_ctl);
2305 if (pdata->vaddr_gpio_mux_pcm_ctl)
2306 iounmap(pdata->vaddr_gpio_mux_pcm_ctl);
2307 if (pdata->vaddr_gpio_mux_sec_pcm_ctl)
2308 iounmap(pdata->vaddr_gpio_mux_sec_pcm_ctl);
2309 snd_soc_unregister_card(card);
2310 return 0;
2311}
2312
Sundara Vinayagam43ce7c92018-05-21 16:34:47 +05302313static struct platform_driver msm_bg_asoc_machine_driver = {
2314 .driver = {
2315 .name = DRV_NAME,
2316 .owner = THIS_MODULE,
2317 .pm = &snd_soc_pm_ops,
2318 .of_match_table = msm_bg_asoc_machine_of_match,
2319 },
2320 .probe = msm_bg_asoc_machine_probe,
2321 .remove = msm_bg_asoc_machine_remove,
2322};
2323
2324static int __init msm_bg_machine_init(void)
2325{
2326 return platform_driver_register(&msm_bg_asoc_machine_driver);
2327}
2328late_initcall(msm_bg_machine_init);
2329
2330static void __exit msm_bg_machine_exit(void)
2331{
2332 return platform_driver_unregister(&msm_bg_asoc_machine_driver);
2333}
2334module_exit(msm_bg_machine_exit);
2335
2336MODULE_DESCRIPTION("ALSA SoC msm");
2337MODULE_LICENSE("GPL v2");
2338MODULE_ALIAS("platform:" DRV_NAME);
2339MODULE_DEVICE_TABLE(of, msm_bg_asoc_machine_of_match);