blob: 3461006d522bff5950536cc5ad222bce44b3193a [file] [log] [blame]
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/of_gpio.h>
14#include <linux/platform_device.h>
15#include <linux/module.h>
Laxminath Kasamad0f6962016-12-14 20:00:35 +053016#include <linux/mfd/msm-cdc-pinctrl.h>
Banajit Goswami0530e2f2016-12-09 21:34:37 -080017#include <sound/pcm_params.h>
18#include "qdsp6v2/msm-pcm-routing-v2.h"
Neeraj Upadhyay49934422016-12-27 19:03:35 +053019#include "sdm660-common.h"
20#include "../codecs/sdm660_cdc/msm-digital-cdc.h"
21#include "../codecs/sdm660_cdc/msm-analog-cdc.h"
Laxminath Kasam2d20bc92016-11-24 17:31:45 +053022#include "../codecs/msm_sdw/msm_sdw.h"
Banajit Goswami0530e2f2016-12-09 21:34:37 -080023
Neeraj Upadhyay49934422016-12-27 19:03:35 +053024#define __CHIPSET__ "SDM660 "
Banajit Goswami0530e2f2016-12-09 21:34:37 -080025#define MSM_DAILINK_NAME(name) (__CHIPSET__#name)
26
27#define DEFAULT_MCLK_RATE 9600000
28#define NATIVE_MCLK_RATE 11289600
29
30#define WCD_MBHC_DEF_RLOADS 5
31
32#define WCN_CDC_SLIM_RX_CH_MAX 2
33#define WCN_CDC_SLIM_TX_CH_MAX 3
34
Laxminath Kasam2d20bc92016-11-24 17:31:45 +053035#define WSA8810_NAME_1 "wsa881x.20170211"
36#define WSA8810_NAME_2 "wsa881x.20170212"
37
Banajit Goswami0530e2f2016-12-09 21:34:37 -080038enum {
39 INT0_MI2S = 0,
40 INT1_MI2S,
41 INT2_MI2S,
42 INT3_MI2S,
43 INT4_MI2S,
44 INT5_MI2S,
45 INT6_MI2S,
46 INT_MI2S_MAX,
47};
48
49enum {
50 BT_SLIM7,
51 FM_SLIM8,
52 SLIM_MAX,
53};
54
55/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */
56static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = {
57 {0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */
58 {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */
59 {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */
60 {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */
61 {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */
62 {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */
63 {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */
64 {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */
65};
66
67static struct afe_clk_set int_mi2s_clk[INT_MI2S_MAX] = {
68 {
69 AFE_API_VERSION_I2S_CONFIG,
70 Q6AFE_LPASS_CLK_ID_INT0_MI2S_IBIT,
71 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
72 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
73 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
74 0,
75 },
76 {
77 AFE_API_VERSION_I2S_CONFIG,
78 Q6AFE_LPASS_CLK_ID_INT1_MI2S_IBIT,
79 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
80 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
81 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
82 0,
83 },
84 {
85 AFE_API_VERSION_I2S_CONFIG,
86 Q6AFE_LPASS_CLK_ID_INT2_MI2S_IBIT,
87 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
88 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
89 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
90 0,
91 },
92 {
93 AFE_API_VERSION_I2S_CONFIG,
94 Q6AFE_LPASS_CLK_ID_INT3_MI2S_IBIT,
95 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
96 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
97 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
98 0,
99 },
100 {
101 AFE_API_VERSION_I2S_CONFIG,
102 Q6AFE_LPASS_CLK_ID_INT4_MI2S_IBIT,
103 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
104 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
105 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
106 0,
107 },
108 {
109 AFE_API_VERSION_I2S_CONFIG,
110 Q6AFE_LPASS_CLK_ID_INT5_MI2S_IBIT,
111 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
112 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
113 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
114 0,
115 },
116 {
117 AFE_API_VERSION_I2S_CONFIG,
118 Q6AFE_LPASS_CLK_ID_INT6_MI2S_IBIT,
119 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
120 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
121 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
122 0,
123 },
124};
125
126struct dev_config {
127 u32 sample_rate;
128 u32 bit_format;
129 u32 channels;
130};
131
132/* Default configuration of MI2S channels */
133static struct dev_config int_mi2s_cfg[] = {
134 [INT0_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
135 [INT1_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
136 [INT2_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
137 [INT3_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
138 [INT4_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
139 [INT5_MI2S] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
140 [INT6_MI2S] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
141};
142
143static struct dev_config bt_fm_cfg[] = {
144 [BT_SLIM7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
145 [FM_SLIM8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
146};
147
148static char const *int_mi2s_rate_text[] = {"KHZ_8", "KHZ_16",
149 "KHZ_32", "KHZ_44P1", "KHZ_48",
150 "KHZ_96", "KHZ_192"};
151static const char *const int_mi2s_ch_text[] = {"One", "Two"};
152static const char *const int_mi2s_tx_ch_text[] = {"One", "Two",
153 "Three", "Four"};
154static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"};
155static const char *const loopback_mclk_text[] = {"DISABLE", "ENABLE"};
156static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_48"};
157
158static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_sample_rate, int_mi2s_rate_text);
159static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_chs, int_mi2s_ch_text);
160static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_format, bit_format_text);
161static SOC_ENUM_SINGLE_EXT_DECL(int2_mi2s_tx_sample_rate, int_mi2s_rate_text);
162static SOC_ENUM_SINGLE_EXT_DECL(int2_mi2s_tx_chs, int_mi2s_tx_ch_text);
163static SOC_ENUM_SINGLE_EXT_DECL(int2_mi2s_tx_format, bit_format_text);
164static SOC_ENUM_SINGLE_EXT_DECL(int3_mi2s_tx_sample_rate, int_mi2s_rate_text);
165static SOC_ENUM_SINGLE_EXT_DECL(int3_mi2s_tx_chs, int_mi2s_tx_ch_text);
166static SOC_ENUM_SINGLE_EXT_DECL(int3_mi2s_tx_format, bit_format_text);
167static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_sample_rate, int_mi2s_rate_text);
168static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_chs, int_mi2s_ch_text);
169static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_format, bit_format_text);
170static SOC_ENUM_SINGLE_EXT_DECL(int5_mi2s_tx_chs, int_mi2s_ch_text);
171static SOC_ENUM_SINGLE_EXT_DECL(loopback_mclk_en, loopback_mclk_text);
172static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text);
173
174static int msm_dmic_event(struct snd_soc_dapm_widget *w,
175 struct snd_kcontrol *kcontrol, int event);
176static int msm_int_enable_dig_cdc_clk(struct snd_soc_codec *codec, int enable,
177 bool dapm);
178static int msm_int_mclk0_event(struct snd_soc_dapm_widget *w,
179 struct snd_kcontrol *kcontrol, int event);
180static int msm_int_mi2s_snd_startup(struct snd_pcm_substream *substream);
181static void msm_int_mi2s_snd_shutdown(struct snd_pcm_substream *substream);
182
183static struct wcd_mbhc_config *mbhc_cfg_ptr;
Laxminath Kasam4e444572017-01-15 20:00:11 +0530184static struct snd_info_entry *codec_root;
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800185
186static int int_mi2s_get_bit_format_val(int bit_format)
187{
188 int val = 0;
189
190 switch (bit_format) {
191 case SNDRV_PCM_FORMAT_S24_3LE:
192 val = 2;
193 break;
194 case SNDRV_PCM_FORMAT_S24_LE:
195 val = 1;
196 break;
197 case SNDRV_PCM_FORMAT_S16_LE:
198 default:
199 val = 0;
200 break;
201 }
202 return val;
203}
204
205static int int_mi2s_get_bit_format(int val)
206{
207 int bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
208
209 switch (val) {
210 case 0:
211 bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
212 break;
213 case 1:
214 bit_fmt = SNDRV_PCM_FORMAT_S24_LE;
215 break;
216 case 2:
217 bit_fmt = SNDRV_PCM_FORMAT_S24_3LE;
218 break;
219 default:
220 bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
221 break;
222 }
223 return bit_fmt;
224}
225
226static int int_mi2s_get_port_idx(struct snd_kcontrol *kcontrol)
227{
228 int port_id = 0;
229
230 if (strnstr(kcontrol->id.name, "INT0_MI2S", sizeof("INT0_MI2S")))
231 port_id = INT0_MI2S;
232 else if (strnstr(kcontrol->id.name, "INT2_MI2S", sizeof("INT2_MI2S")))
233 port_id = INT2_MI2S;
234 else if (strnstr(kcontrol->id.name, "INT3_MI2S", sizeof("INT3_MI2S")))
235 port_id = INT3_MI2S;
236 else if (strnstr(kcontrol->id.name, "INT4_MI2S", sizeof("INT4_MI2S")))
237 port_id = INT4_MI2S;
238 else {
239 pr_err("%s: unsupported channel: %s",
240 __func__, kcontrol->id.name);
241 return -EINVAL;
242 }
243
244 return port_id;
245}
246
247static int int_mi2s_bit_format_get(struct snd_kcontrol *kcontrol,
248 struct snd_ctl_elem_value *ucontrol)
249{
250 int ch_num = int_mi2s_get_port_idx(kcontrol);
251
252 if (ch_num < 0)
253 return ch_num;
254
255 ucontrol->value.enumerated.item[0] =
256 int_mi2s_get_bit_format_val(int_mi2s_cfg[ch_num].bit_format);
257
258 pr_debug("%s: int_mi2s[%d]_bit_format = %d, ucontrol value = %d\n",
259 __func__, ch_num, int_mi2s_cfg[ch_num].bit_format,
260 ucontrol->value.enumerated.item[0]);
261
262 return 0;
263}
264
265static int int_mi2s_bit_format_put(struct snd_kcontrol *kcontrol,
266 struct snd_ctl_elem_value *ucontrol)
267{
268 int ch_num = int_mi2s_get_port_idx(kcontrol);
269
270 if (ch_num < 0)
271 return ch_num;
272
273 int_mi2s_cfg[ch_num].bit_format =
274 int_mi2s_get_bit_format(ucontrol->value.enumerated.item[0]);
275
276 pr_debug("%s: int_mi2s[%d]_rx_bit_format = %d, ucontrol value = %d\n",
277 __func__, ch_num, int_mi2s_cfg[ch_num].bit_format,
278 ucontrol->value.enumerated.item[0]);
279
280 return 0;
281}
282
283static inline int param_is_mask(int p)
284{
285 return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
286 (p <= SNDRV_PCM_HW_PARAM_LAST_MASK);
287}
288
289static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p,
290 int n)
291{
292 return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
293}
294
295static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit)
296{
297 if (bit >= SNDRV_MASK_MAX)
298 return;
299 if (param_is_mask(n)) {
300 struct snd_mask *m = param_to_mask(p, n);
301
302 m->bits[0] = 0;
303 m->bits[1] = 0;
304 m->bits[bit >> 5] |= (1 << (bit & 31));
305 }
306}
307
308static int int_mi2s_get_sample_rate_val(int sample_rate)
309{
310 int sample_rate_val;
311
312 switch (sample_rate) {
313 case SAMPLING_RATE_8KHZ:
314 sample_rate_val = 0;
315 break;
316 case SAMPLING_RATE_16KHZ:
317 sample_rate_val = 1;
318 break;
319 case SAMPLING_RATE_32KHZ:
320 sample_rate_val = 2;
321 break;
322 case SAMPLING_RATE_44P1KHZ:
323 sample_rate_val = 3;
324 break;
325 case SAMPLING_RATE_48KHZ:
326 sample_rate_val = 4;
327 break;
328 case SAMPLING_RATE_96KHZ:
329 sample_rate_val = 5;
330 break;
331 case SAMPLING_RATE_192KHZ:
332 sample_rate_val = 6;
333 break;
334 default:
335 sample_rate_val = 4;
336 break;
337 }
338 return sample_rate_val;
339}
340
341static int int_mi2s_get_sample_rate(int value)
342{
343 int sample_rate;
344
345 switch (value) {
346 case 0:
347 sample_rate = SAMPLING_RATE_8KHZ;
348 break;
349 case 1:
350 sample_rate = SAMPLING_RATE_16KHZ;
351 break;
352 case 2:
353 sample_rate = SAMPLING_RATE_32KHZ;
354 break;
355 case 3:
356 sample_rate = SAMPLING_RATE_44P1KHZ;
357 break;
358 case 4:
359 sample_rate = SAMPLING_RATE_48KHZ;
360 break;
361 case 5:
362 sample_rate = SAMPLING_RATE_96KHZ;
363 break;
364 case 6:
365 sample_rate = SAMPLING_RATE_192KHZ;
366 break;
367 default:
368 sample_rate = SAMPLING_RATE_48KHZ;
369 break;
370 }
371 return sample_rate;
372}
373
374static int int_mi2s_sample_rate_put(struct snd_kcontrol *kcontrol,
375 struct snd_ctl_elem_value *ucontrol)
376{
377 int idx = int_mi2s_get_port_idx(kcontrol);
378
379 if (idx < 0)
380 return idx;
381
382 int_mi2s_cfg[idx].sample_rate =
383 int_mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]);
384
385 pr_debug("%s: idx[%d]_sample_rate = %d, item = %d\n", __func__,
386 idx, int_mi2s_cfg[idx].sample_rate,
387 ucontrol->value.enumerated.item[0]);
388
389 return 0;
390}
391
392static int int_mi2s_sample_rate_get(struct snd_kcontrol *kcontrol,
393 struct snd_ctl_elem_value *ucontrol)
394{
395 int idx = int_mi2s_get_port_idx(kcontrol);
396
397 if (idx < 0)
398 return idx;
399
400 ucontrol->value.enumerated.item[0] =
401 int_mi2s_get_sample_rate_val(int_mi2s_cfg[idx].sample_rate);
402
403 pr_debug("%s: idx[%d]_sample_rate = %d, item = %d\n", __func__,
404 idx, int_mi2s_cfg[idx].sample_rate,
405 ucontrol->value.enumerated.item[0]);
406
407 return 0;
408}
409
410static int int_mi2s_ch_get(struct snd_kcontrol *kcontrol,
411 struct snd_ctl_elem_value *ucontrol)
412{
413 int idx = int_mi2s_get_port_idx(kcontrol);
414
415 if (idx < 0)
416 return idx;
417
418 pr_debug("%s: int_mi2s_[%d]_rx_ch = %d\n", __func__,
419 idx, int_mi2s_cfg[idx].channels);
420 ucontrol->value.enumerated.item[0] = int_mi2s_cfg[idx].channels - 1;
421
422 return 0;
423}
424
425static int int_mi2s_ch_put(struct snd_kcontrol *kcontrol,
426 struct snd_ctl_elem_value *ucontrol)
427{
428 int idx = int_mi2s_get_port_idx(kcontrol);
429
430 if (idx < 0)
431 return idx;
432
433 int_mi2s_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1;
434 pr_debug("%s: int_mi2s_[%d]_ch = %d\n", __func__,
435 idx, int_mi2s_cfg[idx].channels);
436
437 return 1;
438}
439
440static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = {
441 SND_SOC_DAPM_SUPPLY_S("INT_MCLK0", -1, SND_SOC_NOPM, 0, 0,
442 msm_int_mclk0_event, SND_SOC_DAPM_POST_PMD),
443 SND_SOC_DAPM_MIC("Handset Mic", NULL),
444 SND_SOC_DAPM_MIC("Headset Mic", NULL),
445 SND_SOC_DAPM_MIC("Secondary Mic", NULL),
446 SND_SOC_DAPM_MIC("Digital Mic1", msm_dmic_event),
447 SND_SOC_DAPM_MIC("Digital Mic2", msm_dmic_event),
448 SND_SOC_DAPM_MIC("Digital Mic3", msm_dmic_event),
449 SND_SOC_DAPM_MIC("Digital Mic4", msm_dmic_event),
450};
451
Laxminath Kasamad0f6962016-12-14 20:00:35 +0530452static int msm_config_hph_compander_gpio(bool enable,
453 struct snd_soc_codec *codec)
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800454{
Laxminath Kasamad0f6962016-12-14 20:00:35 +0530455 struct snd_soc_card *card = codec->component.card;
456 struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800457 int ret = 0;
458
459 pr_debug("%s: %s HPH Compander\n", __func__,
460 enable ? "Enable" : "Disable");
461
462 if (enable) {
Laxminath Kasamad0f6962016-12-14 20:00:35 +0530463 ret = msm_cdc_pinctrl_select_active_state(pdata->comp_gpio_p);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800464 if (ret) {
465 pr_err("%s: gpio set cannot be activated %s\n",
466 __func__, "comp_gpio");
467 goto done;
468 }
469 } else {
Laxminath Kasamad0f6962016-12-14 20:00:35 +0530470 ret = msm_cdc_pinctrl_select_sleep_state(pdata->comp_gpio_p);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800471 if (ret) {
472 pr_err("%s: gpio set cannot be de-activated %s\n",
473 __func__, "comp_gpio");
474 goto done;
475 }
476 }
477
478done:
479 return ret;
480}
481
482static int is_ext_spk_gpio_support(struct platform_device *pdev,
483 struct msm_asoc_mach_data *pdata)
484{
485 const char *spk_ext_pa = "qcom,msm-spk-ext-pa";
486
487 pr_debug("%s:Enter\n", __func__);
488
489 pdata->spk_ext_pa_gpio = of_get_named_gpio(pdev->dev.of_node,
490 spk_ext_pa, 0);
491
492 if (pdata->spk_ext_pa_gpio < 0) {
493 dev_dbg(&pdev->dev,
494 "%s: missing %s in dt node\n", __func__, spk_ext_pa);
495 } else {
496 if (!gpio_is_valid(pdata->spk_ext_pa_gpio)) {
497 pr_err("%s: Invalid external speaker gpio: %d",
498 __func__, pdata->spk_ext_pa_gpio);
499 return -EINVAL;
500 }
501 }
502 return 0;
503}
504
505static int enable_spk_ext_pa(struct snd_soc_codec *codec, int enable)
506{
507 struct snd_soc_card *card = codec->component.card;
508 struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
509 int ret;
510
511 if (!gpio_is_valid(pdata->spk_ext_pa_gpio)) {
512 pr_err("%s: Invalid gpio: %d\n", __func__,
513 pdata->spk_ext_pa_gpio);
514 return false;
515 }
516
517 pr_debug("%s: %s external speaker PA\n", __func__,
518 enable ? "Enable" : "Disable");
519
520 if (enable) {
Laxminath Kasamad0f6962016-12-14 20:00:35 +0530521 ret = msm_cdc_pinctrl_select_active_state(
522 pdata->ext_spk_gpio_p);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800523 if (ret) {
524 pr_err("%s: gpio set cannot be de-activated %s\n",
525 __func__, "ext_spk_gpio");
526 return ret;
527 }
528 gpio_set_value_cansleep(pdata->spk_ext_pa_gpio, enable);
529 } else {
530 gpio_set_value_cansleep(pdata->spk_ext_pa_gpio, enable);
Laxminath Kasamad0f6962016-12-14 20:00:35 +0530531 ret = msm_cdc_pinctrl_select_sleep_state(
532 pdata->ext_spk_gpio_p);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800533 if (ret) {
534 pr_err("%s: gpio set cannot be de-activated %s\n",
535 __func__, "ext_spk_gpio");
536 return ret;
537 }
538 }
539 return 0;
540}
541
542static int int_mi2s_get_idx_from_beid(int32_t be_id)
543{
544 int idx = 0;
545
546 switch (be_id) {
547 case MSM_BACKEND_DAI_INT0_MI2S_RX:
548 idx = INT0_MI2S;
549 break;
550 case MSM_BACKEND_DAI_INT2_MI2S_TX:
551 idx = INT2_MI2S;
552 break;
553 case MSM_BACKEND_DAI_INT3_MI2S_TX:
554 idx = INT3_MI2S;
555 break;
556 case MSM_BACKEND_DAI_INT4_MI2S_RX:
557 idx = INT4_MI2S;
558 break;
559 case MSM_BACKEND_DAI_INT5_MI2S_TX:
560 idx = INT5_MI2S;
561 break;
562 default:
563 idx = INT0_MI2S;
564 break;
565 }
566
567 return idx;
568}
569
570static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
571 struct snd_pcm_hw_params *params)
572{
573 struct snd_interval *rate = hw_param_interval(params,
574 SNDRV_PCM_HW_PARAM_RATE);
575
576 struct snd_interval *channels = hw_param_interval(params,
577 SNDRV_PCM_HW_PARAM_CHANNELS);
578
579 pr_debug("%s()\n", __func__);
580 rate->min = rate->max = 48000;
581 channels->min = channels->max = 2;
582
583 return 0;
584}
585
586static int int_mi2s_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
587 struct snd_pcm_hw_params *params)
588{
589 struct snd_soc_dai_link *dai_link = rtd->dai_link;
590 struct snd_interval *rate = hw_param_interval(params,
591 SNDRV_PCM_HW_PARAM_RATE);
592 struct snd_interval *channels = hw_param_interval(params,
593 SNDRV_PCM_HW_PARAM_CHANNELS);
594 int idx;
595
596 pr_debug("%s: format = %d, rate = %d\n",
597 __func__, params_format(params), params_rate(params));
598
599 switch (dai_link->be_id) {
600 case MSM_BACKEND_DAI_INT0_MI2S_RX:
601 case MSM_BACKEND_DAI_INT2_MI2S_TX:
602 case MSM_BACKEND_DAI_INT3_MI2S_TX:
603 case MSM_BACKEND_DAI_INT4_MI2S_RX:
604 case MSM_BACKEND_DAI_INT5_MI2S_TX:
605 idx = int_mi2s_get_idx_from_beid(dai_link->be_id);
606 rate->min = rate->max = int_mi2s_cfg[idx].sample_rate;
607 channels->min = channels->max =
608 int_mi2s_cfg[idx].channels;
609 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
610 int_mi2s_cfg[idx].bit_format);
611 break;
612 default:
613 rate->min = rate->max = SAMPLING_RATE_48KHZ;
614 break;
615 }
616 return 0;
617}
618
619static int msm_btfm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
620 struct snd_pcm_hw_params *params)
621{
622 struct snd_soc_dai_link *dai_link = rtd->dai_link;
623 struct snd_interval *rate = hw_param_interval(params,
624 SNDRV_PCM_HW_PARAM_RATE);
625 struct snd_interval *channels = hw_param_interval(params,
626 SNDRV_PCM_HW_PARAM_CHANNELS);
627
628 switch (dai_link->be_id) {
629 case MSM_BACKEND_DAI_SLIMBUS_7_RX:
630 case MSM_BACKEND_DAI_SLIMBUS_7_TX:
631 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
632 bt_fm_cfg[BT_SLIM7].bit_format);
633 rate->min = rate->max = bt_fm_cfg[BT_SLIM7].sample_rate;
634 channels->min = channels->max =
635 bt_fm_cfg[BT_SLIM7].channels;
636 break;
637
638 case MSM_BACKEND_DAI_SLIMBUS_8_TX:
639 rate->min = rate->max = bt_fm_cfg[FM_SLIM8].sample_rate;
640 channels->min = channels->max =
641 bt_fm_cfg[FM_SLIM8].channels;
642 break;
643
644 default:
645 rate->min = rate->max = SAMPLING_RATE_48KHZ;
646 break;
647 }
648 return 0;
649}
650
651static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol,
652 struct snd_ctl_elem_value *ucontrol)
653{
654 ucontrol->value.integer.value[0] =
655 (int_mi2s_cfg[INT5_MI2S].channels/2 - 1);
656 pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__,
657 ucontrol->value.integer.value[0]);
658 return 0;
659}
660
661static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol,
662 struct snd_ctl_elem_value *ucontrol)
663{
664 int_mi2s_cfg[INT5_MI2S].channels =
665 roundup_pow_of_two(ucontrol->value.integer.value[0] + 2);
666
667 pr_debug("%s: msm_vi_feed_tx_ch = %d\n",
668 __func__, int_mi2s_cfg[INT5_MI2S].channels);
669 return 1;
670}
671
672static int msm_int_enable_dig_cdc_clk(struct snd_soc_codec *codec,
673 int enable, bool dapm)
674{
675 int ret = 0;
676 struct msm_asoc_mach_data *pdata = NULL;
677 int clk_freq_in_hz;
678 bool int_mclk0_freq_chg = false;
679
680 pdata = snd_soc_card_get_drvdata(codec->component.card);
681 pr_debug("%s: enable %d mclk ref counter %d\n",
682 __func__, enable,
683 atomic_read(&pdata->int_mclk0_rsc_ref));
684 if (enable) {
685 if (int_mi2s_cfg[INT0_MI2S].sample_rate ==
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530686 SAMPLING_RATE_44P1KHZ) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800687 clk_freq_in_hz = NATIVE_MCLK_RATE;
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530688 pdata->native_clk_set = true;
689 } else {
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800690 clk_freq_in_hz = pdata->mclk_freq;
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530691 pdata->native_clk_set = false;
692 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800693
694 if (pdata->digital_cdc_core_clk.clk_freq_in_hz
695 != clk_freq_in_hz)
696 int_mclk0_freq_chg = true;
697 if (!atomic_read(&pdata->int_mclk0_rsc_ref) ||
698 int_mclk0_freq_chg) {
699 cancel_delayed_work_sync(
700 &pdata->disable_int_mclk0_work);
701 mutex_lock(&pdata->cdc_int_mclk0_mutex);
702 if (atomic_read(&pdata->int_mclk0_enabled) == false ||
703 int_mclk0_freq_chg) {
Laxminath Kasam24f049a2017-01-24 18:05:32 +0530704 if (atomic_read(&pdata->int_mclk0_enabled)) {
705 pdata->digital_cdc_core_clk.enable = 0;
706 afe_set_lpass_clock_v2(
707 AFE_PORT_ID_INT0_MI2S_RX,
708 &pdata->digital_cdc_core_clk);
709 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800710 pdata->digital_cdc_core_clk.clk_freq_in_hz =
711 clk_freq_in_hz;
712 pdata->digital_cdc_core_clk.enable = 1;
713 ret = afe_set_lpass_clock_v2(
714 AFE_PORT_ID_INT0_MI2S_RX,
715 &pdata->digital_cdc_core_clk);
716 if (ret < 0) {
717 pr_err("%s: failed to enable CCLK\n",
718 __func__);
719 mutex_unlock(
720 &pdata->cdc_int_mclk0_mutex);
721 return ret;
722 }
723 pr_debug("enabled digital codec core clk\n");
724 atomic_set(&pdata->int_mclk0_enabled, true);
725 }
726 mutex_unlock(&pdata->cdc_int_mclk0_mutex);
727 }
728 atomic_inc(&pdata->int_mclk0_rsc_ref);
729 } else {
730 cancel_delayed_work_sync(&pdata->disable_int_mclk0_work);
731 mutex_lock(&pdata->cdc_int_mclk0_mutex);
732 if (atomic_read(&pdata->int_mclk0_enabled) == true) {
733 pdata->digital_cdc_core_clk.enable = 0;
734 ret = afe_set_lpass_clock_v2(
735 AFE_PORT_ID_INT0_MI2S_RX,
736 &pdata->digital_cdc_core_clk);
737 if (ret < 0)
738 pr_err("%s: failed to disable CCLK\n",
739 __func__);
740 atomic_set(&pdata->int_mclk0_enabled, false);
741 }
742 mutex_unlock(&pdata->cdc_int_mclk0_mutex);
743 }
744 return ret;
745}
746
747static int loopback_mclk_get(struct snd_kcontrol *kcontrol,
748 struct snd_ctl_elem_value *ucontrol)
749{
750 pr_debug("%s\n", __func__);
751 return 0;
752}
753
754static int loopback_mclk_put(struct snd_kcontrol *kcontrol,
755 struct snd_ctl_elem_value *ucontrol)
756{
757 int ret = -EINVAL;
758 struct msm_asoc_mach_data *pdata = NULL;
759 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
760
761 pdata = snd_soc_card_get_drvdata(codec->component.card);
762 pr_debug("%s: mclk_rsc_ref %d enable %ld\n",
763 __func__, atomic_read(&pdata->int_mclk0_rsc_ref),
764 ucontrol->value.integer.value[0]);
765 switch (ucontrol->value.integer.value[0]) {
766 case 1:
Laxminath Kasamad0f6962016-12-14 20:00:35 +0530767 ret = msm_cdc_pinctrl_select_active_state(pdata->pdm_gpio_p);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800768 if (ret) {
769 pr_err("%s: failed to enable the pri gpios: %d\n",
770 __func__, ret);
771 break;
772 }
773 mutex_lock(&pdata->cdc_int_mclk0_mutex);
774 if ((!atomic_read(&pdata->int_mclk0_rsc_ref)) &&
775 (!atomic_read(&pdata->int_mclk0_enabled))) {
776 pdata->digital_cdc_core_clk.enable = 1;
777 ret = afe_set_lpass_clock_v2(
778 AFE_PORT_ID_INT0_MI2S_RX,
779 &pdata->digital_cdc_core_clk);
780 if (ret < 0) {
781 pr_err("%s: failed to enable the MCLK: %d\n",
782 __func__, ret);
783 mutex_unlock(&pdata->cdc_int_mclk0_mutex);
Laxminath Kasamad0f6962016-12-14 20:00:35 +0530784 ret = msm_cdc_pinctrl_select_sleep_state(
785 pdata->pdm_gpio_p);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800786 if (ret)
787 pr_err("%s: failed to disable the pri gpios: %d\n",
788 __func__, ret);
789 break;
790 }
791 atomic_set(&pdata->int_mclk0_enabled, true);
792 }
793 mutex_unlock(&pdata->cdc_int_mclk0_mutex);
794 atomic_inc(&pdata->int_mclk0_rsc_ref);
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530795 msm_anlg_cdc_mclk_enable(codec, 1, true);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800796 break;
797 case 0:
798 if (atomic_read(&pdata->int_mclk0_rsc_ref) <= 0)
799 break;
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530800 msm_anlg_cdc_mclk_enable(codec, 0, true);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800801 mutex_lock(&pdata->cdc_int_mclk0_mutex);
802 if ((!atomic_dec_return(&pdata->int_mclk0_rsc_ref)) &&
803 (atomic_read(&pdata->int_mclk0_enabled))) {
804 pdata->digital_cdc_core_clk.enable = 0;
805 ret = afe_set_lpass_clock_v2(
806 AFE_PORT_ID_INT0_MI2S_RX,
807 &pdata->digital_cdc_core_clk);
808 if (ret < 0) {
809 pr_err("%s: failed to disable the CCLK: %d\n",
810 __func__, ret);
811 mutex_unlock(&pdata->cdc_int_mclk0_mutex);
812 break;
813 }
814 atomic_set(&pdata->int_mclk0_enabled, false);
815 }
816 mutex_unlock(&pdata->cdc_int_mclk0_mutex);
Laxminath Kasamad0f6962016-12-14 20:00:35 +0530817 ret = msm_cdc_pinctrl_select_sleep_state(pdata->pdm_gpio_p);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800818 if (ret)
819 pr_err("%s: failed to disable the pri gpios: %d\n",
820 __func__, ret);
821 break;
822 default:
823 pr_err("%s: Unexpected input value\n", __func__);
824 break;
825 }
826 return ret;
827}
828
829static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol,
830 struct snd_ctl_elem_value *ucontrol)
831{
832 /*
833 * Slimbus_7_Rx/Tx sample rate values should always be in sync (same)
834 * when used for BT_SCO use case. Return either Rx or Tx sample rate
835 * value.
836 */
837 switch (bt_fm_cfg[BT_SLIM7].sample_rate) {
838 case SAMPLING_RATE_48KHZ:
839 ucontrol->value.integer.value[0] = 2;
840 break;
841 case SAMPLING_RATE_16KHZ:
842 ucontrol->value.integer.value[0] = 1;
843 break;
844 case SAMPLING_RATE_8KHZ:
845 default:
846 ucontrol->value.integer.value[0] = 0;
847 break;
848 }
849 pr_debug("%s: sample rate = %d", __func__,
850 bt_fm_cfg[BT_SLIM7].sample_rate);
851
852 return 0;
853}
854
855static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol,
856 struct snd_ctl_elem_value *ucontrol)
857{
858 switch (ucontrol->value.integer.value[0]) {
859 case 1:
860 bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_16KHZ;
861 break;
862 case 2:
863 bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_48KHZ;
864 break;
865 case 0:
866 default:
867 bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_8KHZ;
868 break;
869 }
870 pr_debug("%s: sample rates: slim7_rx = %d, value = %d\n",
871 __func__,
872 bt_fm_cfg[BT_SLIM7].sample_rate,
873 ucontrol->value.enumerated.item[0]);
874
875 return 0;
876}
877
878static const struct snd_kcontrol_new msm_snd_controls[] = {
879 SOC_ENUM_EXT("INT0_MI2S_RX Format", int0_mi2s_rx_format,
880 int_mi2s_bit_format_get, int_mi2s_bit_format_put),
881 SOC_ENUM_EXT("INT2_MI2S_TX Format", int2_mi2s_tx_format,
882 int_mi2s_bit_format_get, int_mi2s_bit_format_put),
883 SOC_ENUM_EXT("INT3_MI2S_TX Format", int3_mi2s_tx_format,
884 int_mi2s_bit_format_get, int_mi2s_bit_format_put),
885 SOC_ENUM_EXT("INT0_MI2S_RX SampleRate", int0_mi2s_rx_sample_rate,
886 int_mi2s_sample_rate_get,
887 int_mi2s_sample_rate_put),
888 SOC_ENUM_EXT("INT2_MI2S_TX SampleRate", int2_mi2s_tx_sample_rate,
889 int_mi2s_sample_rate_get,
890 int_mi2s_sample_rate_put),
891 SOC_ENUM_EXT("INT3_MI2S_TX SampleRate", int3_mi2s_tx_sample_rate,
892 int_mi2s_sample_rate_get,
893 int_mi2s_sample_rate_put),
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800894 SOC_ENUM_EXT("INT0_MI2S_RX Channels", int0_mi2s_rx_chs,
895 int_mi2s_ch_get, int_mi2s_ch_put),
896 SOC_ENUM_EXT("INT2_MI2S_TX Channels", int2_mi2s_tx_chs,
897 int_mi2s_ch_get, int_mi2s_ch_put),
898 SOC_ENUM_EXT("INT3_MI2S_TX Channels", int3_mi2s_tx_chs,
899 int_mi2s_ch_get, int_mi2s_ch_put),
900 SOC_ENUM_EXT("Loopback MCLK", loopback_mclk_en,
901 loopback_mclk_get, loopback_mclk_put),
902 SOC_ENUM_EXT("BT SampleRate", bt_sample_rate,
903 msm_bt_sample_rate_get,
904 msm_bt_sample_rate_put),
905};
906
Laxminath Kasam2d20bc92016-11-24 17:31:45 +0530907static const struct snd_kcontrol_new msm_sdw_controls[] = {
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800908 SOC_ENUM_EXT("INT4_MI2S_RX Format", int4_mi2s_rx_format,
909 int_mi2s_bit_format_get, int_mi2s_bit_format_put),
910 SOC_ENUM_EXT("INT4_MI2S_RX SampleRate", int4_mi2s_rx_sample_rate,
911 int_mi2s_sample_rate_get,
912 int_mi2s_sample_rate_put),
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800913 SOC_ENUM_EXT("INT4_MI2S_RX Channels", int4_mi2s_rx_chs,
914 int_mi2s_ch_get, int_mi2s_ch_put),
915 SOC_ENUM_EXT("VI_FEED_TX Channels", int5_mi2s_tx_chs,
916 msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put),
917};
918
919static int msm_dmic_event(struct snd_soc_dapm_widget *w,
920 struct snd_kcontrol *kcontrol, int event)
921{
922 struct msm_asoc_mach_data *pdata = NULL;
923 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
924 int ret = 0;
925
926 pdata = snd_soc_card_get_drvdata(codec->component.card);
927 pr_debug("%s: event = %d\n", __func__, event);
928 switch (event) {
929 case SND_SOC_DAPM_PRE_PMU:
Laxminath Kasamad0f6962016-12-14 20:00:35 +0530930 ret = msm_cdc_pinctrl_select_active_state(pdata->dmic_gpio_p);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800931 if (ret < 0) {
932 pr_err("%s: gpio set cannot be activated %sd",
933 __func__, "dmic_gpio");
934 return ret;
935 }
936 break;
937 case SND_SOC_DAPM_POST_PMD:
Laxminath Kasamad0f6962016-12-14 20:00:35 +0530938 ret = msm_cdc_pinctrl_select_sleep_state(pdata->dmic_gpio_p);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800939 if (ret < 0) {
940 pr_err("%s: gpio set cannot be de-activated %sd",
941 __func__, "dmic_gpio");
942 return ret;
943 }
944 break;
945 default:
946 pr_err("%s: invalid DAPM event %d\n", __func__, event);
947 return -EINVAL;
948 }
949 return 0;
950}
951
952static int msm_int_mclk0_event(struct snd_soc_dapm_widget *w,
953 struct snd_kcontrol *kcontrol, int event)
954{
955 struct msm_asoc_mach_data *pdata = NULL;
956 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
957 int ret = 0;
958
959 pdata = snd_soc_card_get_drvdata(codec->component.card);
960 pr_debug("%s: event = %d\n", __func__, event);
961 switch (event) {
962 case SND_SOC_DAPM_POST_PMD:
963 pr_debug("%s: mclk_res_ref = %d\n",
964 __func__, atomic_read(&pdata->int_mclk0_rsc_ref));
Laxminath Kasamad0f6962016-12-14 20:00:35 +0530965 ret = msm_cdc_pinctrl_select_sleep_state(pdata->pdm_gpio_p);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800966 if (ret < 0) {
967 pr_err("%s: gpio set cannot be de-activated %sd",
968 __func__, "int_pdm");
969 return ret;
970 }
971 if (atomic_read(&pdata->int_mclk0_rsc_ref) == 0) {
972 pr_debug("%s: disabling MCLK\n", __func__);
973 /* disable the codec mclk config*/
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530974 msm_anlg_cdc_mclk_enable(codec, 0, true);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800975 msm_int_enable_dig_cdc_clk(codec, 0, true);
976 }
977 break;
978 default:
979 pr_err("%s: invalid DAPM event %d\n", __func__, event);
980 return -EINVAL;
981 }
982 return 0;
983}
984
985static int int_mi2s_get_port_id(int be_id)
986{
987 int afe_port_id;
988
989 switch (be_id) {
990 case MSM_BACKEND_DAI_INT0_MI2S_RX:
991 afe_port_id = AFE_PORT_ID_INT0_MI2S_RX;
992 break;
993 case MSM_BACKEND_DAI_INT2_MI2S_TX:
994 afe_port_id = AFE_PORT_ID_INT2_MI2S_TX;
995 break;
996 case MSM_BACKEND_DAI_INT3_MI2S_TX:
997 afe_port_id = AFE_PORT_ID_INT3_MI2S_TX;
998 break;
999 case MSM_BACKEND_DAI_INT4_MI2S_RX:
1000 afe_port_id = AFE_PORT_ID_INT4_MI2S_RX;
1001 break;
1002 case MSM_BACKEND_DAI_INT5_MI2S_TX:
1003 afe_port_id = AFE_PORT_ID_INT5_MI2S_TX;
1004 break;
1005 default:
1006 pr_err("%s: Invalid be_id: %d\n", __func__, be_id);
1007 afe_port_id = -EINVAL;
1008 }
1009
1010 return afe_port_id;
1011}
1012
1013static int int_mi2s_get_index(int port_id)
1014{
1015 int index;
1016
1017 switch (port_id) {
1018 case AFE_PORT_ID_INT0_MI2S_RX:
1019 index = INT0_MI2S;
1020 break;
1021 case AFE_PORT_ID_INT2_MI2S_TX:
1022 index = INT2_MI2S;
1023 break;
1024 case AFE_PORT_ID_INT3_MI2S_TX:
1025 index = INT3_MI2S;
1026 break;
1027 case AFE_PORT_ID_INT4_MI2S_RX:
1028 index = INT4_MI2S;
1029 break;
1030 case AFE_PORT_ID_INT5_MI2S_TX:
1031 index = INT5_MI2S;
1032 break;
1033 default:
1034 pr_err("%s: Invalid port_id: %d\n", __func__, port_id);
1035 index = -EINVAL;
1036 }
1037
1038 return index;
1039}
1040
1041static u32 get_int_mi2s_bits_per_sample(u32 bit_format)
1042{
1043 u32 bit_per_sample;
1044
1045 switch (bit_format) {
1046 case SNDRV_PCM_FORMAT_S24_3LE:
1047 case SNDRV_PCM_FORMAT_S24_LE:
1048 bit_per_sample = 32;
1049 break;
1050 case SNDRV_PCM_FORMAT_S16_LE:
1051 default:
1052 bit_per_sample = 16;
1053 break;
1054 }
1055
1056 return bit_per_sample;
1057}
1058
1059static void update_int_mi2s_clk_val(int idx, int stream)
1060{
1061 u32 bit_per_sample;
1062
1063 bit_per_sample =
1064 get_int_mi2s_bits_per_sample(int_mi2s_cfg[idx].bit_format);
1065 int_mi2s_clk[idx].clk_freq_in_hz =
Laxminath Kasam24f049a2017-01-24 18:05:32 +05301066 (int_mi2s_cfg[idx].sample_rate * 2 * bit_per_sample);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001067}
1068
1069static int int_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable)
1070{
1071 int ret = 0;
1072 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1073 int port_id = 0;
1074 int index;
1075
1076 port_id = int_mi2s_get_port_id(rtd->dai_link->be_id);
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -08001077 if (port_id < 0) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001078 dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__);
1079 ret = port_id;
1080 goto done;
1081 }
1082 index = int_mi2s_get_index(port_id);
1083 if (index < 0) {
1084 dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__);
1085 ret = port_id;
1086 goto done;
1087 }
1088 if (enable) {
1089 update_int_mi2s_clk_val(index, substream->stream);
1090 dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__,
1091 int_mi2s_clk[index].clk_freq_in_hz);
1092 }
1093
1094 int_mi2s_clk[index].enable = enable;
1095 ret = afe_set_lpass_clock_v2(port_id,
1096 &int_mi2s_clk[index]);
1097 if (ret < 0) {
1098 dev_err(rtd->card->dev,
1099 "%s: afe lpass clock failed for port 0x%x , err:%d\n",
1100 __func__, port_id, ret);
1101 goto done;
1102 }
1103
1104done:
1105 return ret;
1106}
1107
Laxminath Kasam2d20bc92016-11-24 17:31:45 +05301108static int msm_sdw_mi2s_snd_startup(struct snd_pcm_substream *substream)
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001109{
1110 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1111 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1112 int ret = 0;
1113
1114 pr_debug("%s(): substream = %s stream = %d\n", __func__,
1115 substream->name, substream->stream);
1116
1117 ret = int_mi2s_set_sclk(substream, true);
1118 if (ret < 0) {
1119 pr_err("%s: failed to enable sclk %d\n",
1120 __func__, ret);
1121 return ret;
1122 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001123 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS);
1124 if (ret < 0)
1125 pr_err("%s: set fmt cpu dai failed; ret=%d\n", __func__, ret);
1126
1127 return ret;
1128}
1129
Laxminath Kasam2d20bc92016-11-24 17:31:45 +05301130static void msm_sdw_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001131{
1132 int ret;
1133
1134 pr_debug("%s(): substream = %s stream = %d\n", __func__,
1135 substream->name, substream->stream);
1136
1137 ret = int_mi2s_set_sclk(substream, false);
1138 if (ret < 0)
1139 pr_err("%s:clock disable failed; ret=%d\n", __func__,
1140 ret);
1141}
1142
1143static int msm_int_mi2s_snd_startup(struct snd_pcm_substream *substream)
1144{
1145 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1146 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301147 struct snd_soc_codec *codec = rtd->codec_dais[ANA_CDC]->codec;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001148 int ret = 0;
Laxminath Kasamad0f6962016-12-14 20:00:35 +05301149 struct msm_asoc_mach_data *pdata = NULL;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001150
Laxminath Kasamad0f6962016-12-14 20:00:35 +05301151 pdata = snd_soc_card_get_drvdata(codec->component.card);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001152 pr_debug("%s(): substream = %s stream = %d\n", __func__,
1153 substream->name, substream->stream);
1154
1155 ret = int_mi2s_set_sclk(substream, true);
1156 if (ret < 0) {
1157 pr_err("%s: failed to enable sclk %d\n",
1158 __func__, ret);
1159 return ret;
1160 }
1161 ret = msm_int_enable_dig_cdc_clk(codec, 1, true);
1162 if (ret < 0) {
1163 pr_err("failed to enable mclk\n");
1164 return ret;
1165 }
1166 /* Enable the codec mclk config */
Laxminath Kasamad0f6962016-12-14 20:00:35 +05301167 ret = msm_cdc_pinctrl_select_active_state(pdata->pdm_gpio_p);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001168 if (ret < 0) {
1169 pr_err("%s: gpio set cannot be activated %s\n",
1170 __func__, "int_pdm");
1171 return ret;
1172 }
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301173 msm_anlg_cdc_mclk_enable(codec, 1, true);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001174 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS);
1175 if (ret < 0)
1176 pr_err("%s: set fmt cpu dai failed; ret=%d\n", __func__, ret);
1177
1178 return ret;
1179}
1180
1181static void msm_int_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
1182{
1183 int ret;
1184 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1185 struct snd_soc_card *card = rtd->card;
1186 struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
1187
1188 pr_debug("%s(): substream = %s stream = %d\n", __func__,
1189 substream->name, substream->stream);
1190
1191 ret = int_mi2s_set_sclk(substream, false);
1192 if (ret < 0)
1193 pr_err("%s:clock disable failed; ret=%d\n", __func__,
1194 ret);
1195 if (atomic_read(&pdata->int_mclk0_rsc_ref) > 0) {
1196 atomic_dec(&pdata->int_mclk0_rsc_ref);
1197 pr_debug("%s: decrementing mclk_res_ref %d\n",
1198 __func__,
1199 atomic_read(&pdata->int_mclk0_rsc_ref));
1200 }
1201}
1202
1203static void *def_msm_int_wcd_mbhc_cal(void)
1204{
1205 void *msm_int_wcd_cal;
1206 struct wcd_mbhc_btn_detect_cfg *btn_cfg;
1207 u16 *btn_low, *btn_high;
1208
1209 msm_int_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS,
1210 WCD_MBHC_DEF_RLOADS), GFP_KERNEL);
1211 if (!msm_int_wcd_cal)
1212 return NULL;
1213
1214#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(msm_int_wcd_cal)->X) = (Y))
1215 S(v_hs_max, 1500);
1216#undef S
1217#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(msm_int_wcd_cal)->X) = (Y))
1218 S(num_btn, WCD_MBHC_DEF_BUTTONS);
1219#undef S
1220
1221
1222 btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(msm_int_wcd_cal);
1223 btn_low = btn_cfg->_v_btn_low;
1224 btn_high = ((void *)&btn_cfg->_v_btn_low) +
1225 (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn);
1226
1227 /*
1228 * In SW we are maintaining two sets of threshold register
1229 * one for current source and another for Micbias.
1230 * all btn_low corresponds to threshold for current source
1231 * all bt_high corresponds to threshold for Micbias
1232 * Below thresholds are based on following resistances
1233 * 0-70 == Button 0
1234 * 110-180 == Button 1
1235 * 210-290 == Button 2
1236 * 360-680 == Button 3
1237 */
1238 btn_low[0] = 75;
1239 btn_high[0] = 75;
1240 btn_low[1] = 150;
1241 btn_high[1] = 150;
1242 btn_low[2] = 225;
1243 btn_high[2] = 225;
1244 btn_low[3] = 450;
1245 btn_high[3] = 450;
1246 btn_low[4] = 500;
1247 btn_high[4] = 500;
1248
1249 return msm_int_wcd_cal;
1250}
1251
1252static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
1253{
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301254 struct snd_soc_codec *dig_cdc = rtd->codec_dais[DIG_CDC]->codec;
1255 struct snd_soc_codec *ana_cdc = rtd->codec_dais[ANA_CDC]->codec;
1256 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(ana_cdc);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001257 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
Laxminath Kasam2d20bc92016-11-24 17:31:45 +05301258 struct snd_soc_pcm_runtime *rtd_aux = rtd->card->rtd_aux;
Laxminath Kasama7bf1bc2017-02-04 01:40:31 +05301259 struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card);
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301260 struct snd_card *card;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001261 int ret = -ENOMEM;
1262
1263 pr_debug("%s(),dev_name%s\n", __func__, dev_name(cpu_dai->dev));
1264
Laxminath Kasam35a610e2016-12-30 15:02:33 +05301265 ret = snd_soc_add_codec_controls(ana_cdc, msm_snd_controls,
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301266 ARRAY_SIZE(msm_snd_controls));
Laxminath Kasam35a610e2016-12-30 15:02:33 +05301267 if (ret < 0) {
1268 pr_err("%s: add_codec_controls failed: %d\n",
1269 __func__, ret);
1270 return ret;
1271 }
1272 ret = snd_soc_add_codec_controls(ana_cdc, msm_common_snd_controls,
1273 msm_common_snd_controls_size());
1274 if (ret < 0) {
1275 pr_err("%s: add common snd controls failed: %d\n",
1276 __func__, ret);
1277 return ret;
1278 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001279
1280 snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets,
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301281 ARRAY_SIZE(msm_int_dapm_widgets));
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001282
1283 snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
1284 snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
1285 snd_soc_dapm_ignore_suspend(dapm, "Secondary Mic");
1286 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1");
1287 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2");
1288
1289 snd_soc_dapm_ignore_suspend(dapm, "EAR");
1290 snd_soc_dapm_ignore_suspend(dapm, "HEADPHONE");
1291 snd_soc_dapm_ignore_suspend(dapm, "SPK_OUT");
1292 snd_soc_dapm_ignore_suspend(dapm, "AMIC1");
1293 snd_soc_dapm_ignore_suspend(dapm, "AMIC2");
1294 snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
1295 snd_soc_dapm_ignore_suspend(dapm, "DMIC1");
1296 snd_soc_dapm_ignore_suspend(dapm, "DMIC2");
1297 snd_soc_dapm_ignore_suspend(dapm, "DMIC3");
1298 snd_soc_dapm_ignore_suspend(dapm, "DMIC4");
1299
1300 snd_soc_dapm_sync(dapm);
1301
Laxminath Kasam2d20bc92016-11-24 17:31:45 +05301302 /*
1303 * Send speaker configuration only for WSA8810.
1304 * Defalut configuration is for WSA8815.
1305 */
1306 if (rtd_aux && rtd_aux->component)
1307 if (!strcmp(rtd_aux->component->name, WSA8810_NAME_1) ||
1308 !strcmp(rtd_aux->component->name, WSA8810_NAME_2)) {
1309 msm_sdw_set_spkr_mode(rtd->codec, SPKR_MODE_1);
1310 msm_sdw_set_spkr_gain_offset(rtd->codec,
1311 RX_GAIN_OFFSET_M1P5_DB);
1312 }
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301313 msm_anlg_cdc_spk_ext_pa_cb(enable_spk_ext_pa, ana_cdc);
1314 msm_dig_cdc_hph_comp_cb(msm_config_hph_compander_gpio, dig_cdc);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001315
1316 mbhc_cfg_ptr->calibration = def_msm_int_wcd_mbhc_cal();
1317 if (mbhc_cfg_ptr->calibration) {
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301318 ret = msm_anlg_cdc_hs_detect(ana_cdc, mbhc_cfg_ptr);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001319 if (ret) {
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301320 pr_err("%s: msm_anlg_cdc_hs_detect failed\n", __func__);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001321 kfree(mbhc_cfg_ptr->calibration);
1322 return ret;
1323 }
1324 }
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301325 card = rtd->card->snd_card;
Laxminath Kasam4e444572017-01-15 20:00:11 +05301326 if (!codec_root)
1327 codec_root = snd_register_module_info(card->module, "codecs",
1328 card->proc_root);
1329 if (!codec_root) {
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301330 pr_debug("%s: Cannot create codecs module entry\n",
1331 __func__);
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301332 goto done;
1333 }
Laxminath Kasama7bf1bc2017-02-04 01:40:31 +05301334 pdata->codec_root = codec_root;
Laxminath Kasam4e444572017-01-15 20:00:11 +05301335 msm_dig_codec_info_create_codec_entry(codec_root, dig_cdc);
1336 msm_anlg_codec_info_create_codec_entry(codec_root, ana_cdc);
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301337done:
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001338 return 0;
1339}
1340
Laxminath Kasam2d20bc92016-11-24 17:31:45 +05301341static int msm_sdw_audrx_init(struct snd_soc_pcm_runtime *rtd)
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001342{
1343 struct snd_soc_codec *codec = rtd->codec;
1344 struct snd_soc_dapm_context *dapm =
1345 snd_soc_codec_get_dapm(codec);
Laxminath Kasama7bf1bc2017-02-04 01:40:31 +05301346 struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card);
Laxminath Kasam2d20bc92016-11-24 17:31:45 +05301347 struct snd_card *card;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001348
Laxminath Kasam2d20bc92016-11-24 17:31:45 +05301349 snd_soc_add_codec_controls(codec, msm_sdw_controls,
1350 ARRAY_SIZE(msm_sdw_controls));
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001351
Laxminath Kasam2d20bc92016-11-24 17:31:45 +05301352 snd_soc_dapm_ignore_suspend(dapm, "AIF1_SDW Playback");
1353 snd_soc_dapm_ignore_suspend(dapm, "VIfeed_SDW");
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001354 snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT");
1355 snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT");
Laxminath Kasam2d20bc92016-11-24 17:31:45 +05301356 snd_soc_dapm_ignore_suspend(dapm, "AIF1_SDW VI");
1357 snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_SDW");
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001358
1359 snd_soc_dapm_sync(dapm);
Laxminath Kasam2d20bc92016-11-24 17:31:45 +05301360 card = rtd->card->snd_card;
Laxminath Kasam4e444572017-01-15 20:00:11 +05301361 if (!codec_root)
1362 codec_root = snd_register_module_info(card->module, "codecs",
1363 card->proc_root);
1364 if (!codec_root) {
Laxminath Kasam2d20bc92016-11-24 17:31:45 +05301365 pr_debug("%s: Cannot create codecs module entry\n",
1366 __func__);
Laxminath Kasam2d20bc92016-11-24 17:31:45 +05301367 goto done;
1368 }
Laxminath Kasama7bf1bc2017-02-04 01:40:31 +05301369 pdata->codec_root = codec_root;
Laxminath Kasam4e444572017-01-15 20:00:11 +05301370 msm_sdw_codec_info_create_codec_entry(codec_root, codec);
Laxminath Kasam2d20bc92016-11-24 17:31:45 +05301371done:
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001372 return 0;
1373}
1374
1375static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd)
1376{
1377 unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158};
1378 unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161};
1379 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1380
1381 return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
1382 tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
1383}
1384
1385static int msm_wcn_hw_params(struct snd_pcm_substream *substream,
1386 struct snd_pcm_hw_params *params)
1387{
1388 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1389 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1390 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1391 struct snd_soc_dai_link *dai_link = rtd->dai_link;
1392 u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX];
1393 u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
1394 int ret;
1395
1396 dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__,
1397 codec_dai->name, codec_dai->id);
1398 ret = snd_soc_dai_get_channel_map(codec_dai,
1399 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
1400 if (ret) {
1401 dev_err(rtd->dev,
1402 "%s: failed to get BTFM codec chan map\n, err:%d\n",
1403 __func__, ret);
1404 goto exit;
1405 }
1406
1407 dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) be_id %d\n",
1408 __func__, tx_ch_cnt, dai_link->be_id);
1409
1410 ret = snd_soc_dai_set_channel_map(cpu_dai,
1411 tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch);
1412 if (ret)
1413 dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n",
1414 __func__, ret);
1415
1416exit:
1417 return ret;
1418}
1419
1420static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width,
1421 int slots)
1422{
1423 unsigned int slot_mask = 0;
1424 int i, j;
1425 unsigned int *slot_offset;
1426
1427 for (i = TDM_0; i < TDM_PORT_MAX; i++) {
1428 slot_offset = tdm_slot_offset[i];
1429
1430 for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) {
1431 if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID)
1432 slot_mask |=
1433 (1 << ((slot_offset[j] * 8) / slot_width));
1434 else
1435 break;
1436 }
1437 }
1438
1439 return slot_mask;
1440}
1441
1442static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream,
1443 struct snd_pcm_hw_params *params)
1444{
1445 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1446 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1447 int ret = 0;
1448 int channels, slot_width, slots;
1449 unsigned int slot_mask;
1450 unsigned int *slot_offset;
1451 int offset_channels = 0;
1452 int i;
1453
1454 pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
1455
1456 channels = params_channels(params);
1457 switch (channels) {
1458 case 1:
1459 case 2:
1460 case 3:
1461 case 4:
1462 case 5:
1463 case 6:
1464 case 7:
1465 case 8:
1466 switch (params_format(params)) {
1467 case SNDRV_PCM_FORMAT_S32_LE:
1468 case SNDRV_PCM_FORMAT_S24_LE:
1469 case SNDRV_PCM_FORMAT_S16_LE:
1470 /*
1471 * up to 8 channels HW config should
1472 * use 32 bit slot width for max support of
1473 * stream bit width. (slot_width > bit_width)
1474 */
1475 slot_width = 32;
1476 break;
1477 default:
1478 pr_err("%s: invalid param format 0x%x\n",
1479 __func__, params_format(params));
1480 return -EINVAL;
1481 }
1482 slots = 8;
1483 slot_mask = tdm_param_set_slot_mask(cpu_dai->id,
1484 slot_width,
1485 slots);
1486 if (!slot_mask) {
1487 pr_err("%s: invalid slot_mask 0x%x\n",
1488 __func__, slot_mask);
1489 return -EINVAL;
1490 }
1491 break;
1492 default:
1493 pr_err("%s: invalid param channels %d\n",
1494 __func__, channels);
1495 return -EINVAL;
1496 }
1497 /* currently only supporting TDM_RX_0 and TDM_TX_0 */
1498 switch (cpu_dai->id) {
1499 case AFE_PORT_ID_PRIMARY_TDM_RX:
1500 case AFE_PORT_ID_SECONDARY_TDM_RX:
1501 case AFE_PORT_ID_TERTIARY_TDM_RX:
1502 case AFE_PORT_ID_QUATERNARY_TDM_RX:
1503 case AFE_PORT_ID_PRIMARY_TDM_TX:
1504 case AFE_PORT_ID_SECONDARY_TDM_TX:
1505 case AFE_PORT_ID_TERTIARY_TDM_TX:
1506 case AFE_PORT_ID_QUATERNARY_TDM_TX:
1507 slot_offset = tdm_slot_offset[TDM_0];
1508 break;
1509 default:
1510 pr_err("%s: dai id 0x%x not supported\n",
1511 __func__, cpu_dai->id);
1512 return -EINVAL;
1513 }
1514
1515 for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) {
1516 if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID)
1517 offset_channels++;
1518 else
1519 break;
1520 }
1521
1522 if (offset_channels == 0) {
1523 pr_err("%s: slot offset not supported, offset_channels %d\n",
1524 __func__, offset_channels);
1525 return -EINVAL;
1526 }
1527
1528 if (channels > offset_channels) {
1529 pr_err("%s: channels %d exceed offset_channels %d\n",
1530 __func__, channels, offset_channels);
1531 return -EINVAL;
1532 }
1533
1534 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1535 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
1536 slots, slot_width);
1537 if (ret < 0) {
1538 pr_err("%s: failed to set tdm slot, err:%d\n",
1539 __func__, ret);
1540 goto end;
1541 }
1542
1543 ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
1544 channels, slot_offset);
1545 if (ret < 0) {
1546 pr_err("%s: failed to set channel map, err:%d\n",
1547 __func__, ret);
1548 goto end;
1549 }
1550 } else {
1551 ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0,
1552 slots, slot_width);
1553 if (ret < 0) {
1554 pr_err("%s: failed to set tdm slot, err:%d\n",
1555 __func__, ret);
1556 goto end;
1557 }
1558
1559 ret = snd_soc_dai_set_channel_map(cpu_dai, channels,
1560 slot_offset, 0, NULL);
1561 if (ret < 0) {
1562 pr_err("%s: failed to set channel map, err:%d\n",
1563 __func__, ret);
1564 goto end;
1565 }
1566 }
1567end:
1568 return ret;
1569}
1570
1571static struct snd_soc_ops msm_tdm_be_ops = {
1572 .hw_params = msm_tdm_snd_hw_params
1573};
1574
1575static struct snd_soc_ops msm_wcn_ops = {
1576 .hw_params = msm_wcn_hw_params,
1577};
1578
1579static struct snd_soc_ops msm_mi2s_be_ops = {
1580 .startup = msm_mi2s_snd_startup,
1581 .shutdown = msm_mi2s_snd_shutdown,
1582};
1583
1584static struct snd_soc_ops msm_aux_pcm_be_ops = {
1585 .startup = msm_aux_pcm_snd_startup,
1586 .shutdown = msm_aux_pcm_snd_shutdown,
1587};
1588
1589static struct snd_soc_ops msm_int_mi2s_be_ops = {
1590 .startup = msm_int_mi2s_snd_startup,
1591 .shutdown = msm_int_mi2s_snd_shutdown,
1592};
1593
Laxminath Kasam2d20bc92016-11-24 17:31:45 +05301594static struct snd_soc_ops msm_sdw_mi2s_be_ops = {
1595 .startup = msm_sdw_mi2s_snd_startup,
1596 .shutdown = msm_sdw_mi2s_snd_shutdown,
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001597};
1598
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301599struct snd_soc_dai_link_component dlc_rx1[] = {
1600 {
1601 .of_node = NULL,
1602 .dai_name = "msm_dig_cdc_dai_rx1",
1603 },
1604 {
1605 .of_node = NULL,
1606 .dai_name = "msm_anlg_cdc_i2s_rx1",
1607 },
1608};
1609
1610struct snd_soc_dai_link_component dlc_tx1[] = {
1611 {
1612 .of_node = NULL,
1613 .dai_name = "msm_dig_cdc_dai_tx1",
1614 },
1615 {
1616 .of_node = NULL,
1617 .dai_name = "msm_anlg_cdc_i2s_tx1",
1618 },
1619};
1620
1621struct snd_soc_dai_link_component dlc_tx2[] = {
1622 {
1623 .of_node = NULL,
1624 .dai_name = "msm_dig_cdc_dai_tx2",
1625 },
1626 {
1627 .of_node = NULL,
1628 .dai_name = "msm_anlg_cdc_i2s_tx2",
1629 },
1630};
1631
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001632/* Digital audio interface glue - connects codec <---> CPU */
1633static struct snd_soc_dai_link msm_int_dai[] = {
1634 /* FrontEnd DAI Links */
1635 {/* hw:x,0 */
1636 .name = MSM_DAILINK_NAME(Media1),
1637 .stream_name = "MultiMedia1",
1638 .cpu_dai_name = "MultiMedia1",
1639 .platform_name = "msm-pcm-dsp.0",
1640 .dynamic = 1,
1641 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1642 SND_SOC_DPCM_TRIGGER_POST},
1643 .codec_dai_name = "snd-soc-dummy-dai",
1644 .codec_name = "snd-soc-dummy",
1645 .ignore_suspend = 1,
1646 .dpcm_playback = 1,
1647 .dpcm_capture = 1,
1648 /* this dai link has playback support */
1649 .ignore_pmdown_time = 1,
1650 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA1
1651 },
1652 {/* hw:x,1 */
1653 .name = MSM_DAILINK_NAME(Media2),
1654 .stream_name = "MultiMedia2",
1655 .cpu_dai_name = "MultiMedia2",
1656 .platform_name = "msm-pcm-dsp.0",
1657 .dynamic = 1,
1658 .dpcm_playback = 1,
1659 .dpcm_capture = 1,
1660 .codec_dai_name = "snd-soc-dummy-dai",
1661 .codec_name = "snd-soc-dummy",
1662 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1663 SND_SOC_DPCM_TRIGGER_POST},
1664 .ignore_suspend = 1,
1665 /* this dai link has playback support */
1666 .ignore_pmdown_time = 1,
1667 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA2,
1668 },
1669 {/* hw:x,2 */
1670 .name = "VoiceMMode1",
1671 .stream_name = "VoiceMMode1",
1672 .cpu_dai_name = "VoiceMMode1",
1673 .platform_name = "msm-pcm-voice",
1674 .dynamic = 1,
1675 .dpcm_capture = 1,
1676 .dpcm_playback = 1,
1677 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1678 SND_SOC_DPCM_TRIGGER_POST},
1679 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1680 .ignore_suspend = 1,
1681 .ignore_pmdown_time = 1,
1682 .codec_dai_name = "snd-soc-dummy-dai",
1683 .codec_name = "snd-soc-dummy",
1684 .be_id = MSM_FRONTEND_DAI_VOICEMMODE1,
1685 },
1686 {/* hw:x,3 */
1687 .name = "MSM VoIP",
1688 .stream_name = "VoIP",
1689 .cpu_dai_name = "VoIP",
1690 .platform_name = "msm-voip-dsp",
1691 .dynamic = 1,
1692 .dpcm_playback = 1,
1693 .dpcm_capture = 1,
1694 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1695 SND_SOC_DPCM_TRIGGER_POST},
1696 .codec_dai_name = "snd-soc-dummy-dai",
1697 .codec_name = "snd-soc-dummy",
1698 .ignore_suspend = 1,
1699 /* this dai link has playback support */
1700 .ignore_pmdown_time = 1,
1701 .be_id = MSM_FRONTEND_DAI_VOIP,
1702 },
1703 {/* hw:x,4 */
1704 .name = MSM_DAILINK_NAME(ULL),
1705 .stream_name = "ULL",
1706 .cpu_dai_name = "MultiMedia3",
1707 .platform_name = "msm-pcm-dsp.2",
1708 .dynamic = 1,
1709 .dpcm_playback = 1,
1710 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1711 SND_SOC_DPCM_TRIGGER_POST},
1712 .codec_dai_name = "snd-soc-dummy-dai",
1713 .codec_name = "snd-soc-dummy",
1714 .ignore_suspend = 1,
1715 /* this dai link has playback support */
1716 .ignore_pmdown_time = 1,
1717 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA3,
1718 },
1719 /* Hostless PCM purpose */
1720 {/* hw:x,5 */
1721 .name = "INT4 MI2S_RX Hostless",
1722 .stream_name = "INT4 MI2S_RX Hostless",
1723 .cpu_dai_name = "INT4_MI2S_RX_HOSTLESS",
1724 .platform_name = "msm-pcm-hostless",
1725 .dynamic = 1,
1726 .dpcm_playback = 1,
1727 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1728 SND_SOC_DPCM_TRIGGER_POST},
1729 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1730 .ignore_suspend = 1,
1731 /* this dailink has playback support */
1732 .ignore_pmdown_time = 1,
1733 /* This dainlink has MI2S support */
1734 .codec_dai_name = "snd-soc-dummy-dai",
1735 .codec_name = "snd-soc-dummy",
1736 },
1737 {/* hw:x,6 */
1738 .name = "MSM AFE-PCM RX",
1739 .stream_name = "AFE-PROXY RX",
1740 .cpu_dai_name = "msm-dai-q6-dev.241",
1741 .codec_name = "msm-stub-codec.1",
1742 .codec_dai_name = "msm-stub-rx",
1743 .platform_name = "msm-pcm-afe",
1744 .ignore_suspend = 1,
1745 /* this dai link has playback support */
1746 .ignore_pmdown_time = 1,
1747 },
1748 {/* hw:x,7 */
1749 .name = "MSM AFE-PCM TX",
1750 .stream_name = "AFE-PROXY TX",
1751 .cpu_dai_name = "msm-dai-q6-dev.240",
1752 .codec_name = "msm-stub-codec.1",
1753 .codec_dai_name = "msm-stub-tx",
1754 .platform_name = "msm-pcm-afe",
1755 .ignore_suspend = 1,
1756 },
1757 {/* hw:x,8 */
1758 .name = MSM_DAILINK_NAME(Compress1),
1759 .stream_name = "Compress1",
1760 .cpu_dai_name = "MultiMedia4",
1761 .platform_name = "msm-compress-dsp",
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301762 .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS,
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001763 .dynamic = 1,
1764 .dpcm_capture = 1,
1765 .dpcm_playback = 1,
1766 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1767 SND_SOC_DPCM_TRIGGER_POST},
1768 .codec_dai_name = "snd-soc-dummy-dai",
1769 .codec_name = "snd-soc-dummy",
1770 .ignore_suspend = 1,
1771 .ignore_pmdown_time = 1,
1772 /* this dai link has playback support */
1773 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA4,
1774 },
1775 {/* hw:x,9*/
1776 .name = "AUXPCM Hostless",
1777 .stream_name = "AUXPCM Hostless",
1778 .cpu_dai_name = "AUXPCM_HOSTLESS",
1779 .platform_name = "msm-pcm-hostless",
1780 .dynamic = 1,
1781 .dpcm_capture = 1,
1782 .dpcm_playback = 1,
1783 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1784 SND_SOC_DPCM_TRIGGER_POST},
1785 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1786 .ignore_suspend = 1,
1787 /* this dai link has playback support */
1788 .ignore_pmdown_time = 1,
1789 .codec_dai_name = "snd-soc-dummy-dai",
1790 .codec_name = "snd-soc-dummy",
1791 },
1792 {/* hw:x,10 */
1793 .name = "SLIMBUS_1 Hostless",
1794 .stream_name = "SLIMBUS_1 Hostless",
1795 .cpu_dai_name = "SLIMBUS1_HOSTLESS",
1796 .platform_name = "msm-pcm-hostless",
1797 .dynamic = 1,
1798 .dpcm_capture = 1,
1799 .dpcm_playback = 1,
1800 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1801 SND_SOC_DPCM_TRIGGER_POST},
1802 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1803 .ignore_suspend = 1,
1804 .ignore_pmdown_time = 1, /* dai link has playback support */
1805 .codec_dai_name = "snd-soc-dummy-dai",
1806 .codec_name = "snd-soc-dummy",
1807 },
1808 {/* hw:x,11 */
Laxminath Kasamfc19e022016-12-14 22:20:11 +05301809 .name = "INT3 MI2S_TX Hostless",
1810 .stream_name = "INT3 MI2S_TX Hostless",
1811 .cpu_dai_name = "INT3_MI2S_TX_HOSTLESS",
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001812 .platform_name = "msm-pcm-hostless",
1813 .dynamic = 1,
1814 .dpcm_capture = 1,
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001815 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1816 SND_SOC_DPCM_TRIGGER_POST},
1817 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1818 .ignore_suspend = 1,
Laxminath Kasamfc19e022016-12-14 22:20:11 +05301819 .ignore_pmdown_time = 1,
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001820 .codec_dai_name = "snd-soc-dummy-dai",
1821 .codec_name = "snd-soc-dummy",
1822 },
1823 {/* hw:x,12 */
Laxminath Kasamfc19e022016-12-14 22:20:11 +05301824 .name = "SLIMBUS_7 Hostless",
1825 .stream_name = "SLIMBUS_7 Hostless",
1826 .cpu_dai_name = "SLIMBUS7_HOSTLESS",
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001827 .platform_name = "msm-pcm-hostless",
1828 .dynamic = 1,
1829 .dpcm_capture = 1,
1830 .dpcm_playback = 1,
1831 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1832 SND_SOC_DPCM_TRIGGER_POST},
1833 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1834 .ignore_suspend = 1,
1835 .ignore_pmdown_time = 1, /* dai link has playback support */
1836 .codec_dai_name = "snd-soc-dummy-dai",
1837 .codec_name = "snd-soc-dummy",
1838 },
1839 {/* hw:x,13 */
1840 .name = MSM_DAILINK_NAME(LowLatency),
1841 .stream_name = "MultiMedia5",
1842 .cpu_dai_name = "MultiMedia5",
1843 .platform_name = "msm-pcm-dsp.1",
1844 .dynamic = 1,
1845 .dpcm_capture = 1,
1846 .dpcm_playback = 1,
1847 .codec_dai_name = "snd-soc-dummy-dai",
1848 .codec_name = "snd-soc-dummy",
1849 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1850 SND_SOC_DPCM_TRIGGER_POST},
1851 .ignore_suspend = 1,
1852 /* this dai link has playback support */
1853 .ignore_pmdown_time = 1,
1854 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA5,
1855 },
1856 /* LSM FE */
1857 {/* hw:x,14 */
1858 .name = "Listen 1 Audio Service",
1859 .stream_name = "Listen 1 Audio Service",
1860 .cpu_dai_name = "LSM1",
1861 .platform_name = "msm-lsm-client",
1862 .dynamic = 1,
1863 .dpcm_capture = 1,
1864 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1865 SND_SOC_DPCM_TRIGGER_POST },
1866 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1867 .ignore_suspend = 1,
1868 .ignore_pmdown_time = 1,
1869 .codec_dai_name = "snd-soc-dummy-dai",
1870 .codec_name = "snd-soc-dummy",
1871 .be_id = MSM_FRONTEND_DAI_LSM1,
1872 },
1873 {/* hw:x,15 */
1874 .name = MSM_DAILINK_NAME(Compress2),
1875 .stream_name = "Compress2",
1876 .cpu_dai_name = "MultiMedia7",
1877 .platform_name = "msm-compress-dsp",
1878 .dynamic = 1,
1879 .dpcm_capture = 1,
1880 .dpcm_playback = 1,
1881 .codec_dai_name = "snd-soc-dummy-dai",
1882 .codec_name = "snd-soc-dummy",
1883 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1884 SND_SOC_DPCM_TRIGGER_POST},
1885 .ignore_suspend = 1,
1886 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA7,
1887 },
1888 {/* hw:x,16 */
1889 .name = MSM_DAILINK_NAME(Compress3),
1890 .stream_name = "Compress3",
1891 .cpu_dai_name = "MultiMedia10",
1892 .platform_name = "msm-compress-dsp",
1893 .dynamic = 1,
1894 .dpcm_capture = 1,
1895 .dpcm_playback = 1,
1896 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1897 SND_SOC_DPCM_TRIGGER_POST},
1898 .codec_dai_name = "snd-soc-dummy-dai",
1899 .codec_name = "snd-soc-dummy",
1900 .ignore_suspend = 1,
1901 .ignore_pmdown_time = 1,
1902 /* this dai link has playback support */
1903 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA10,
1904 },
1905 {/* hw:x,17 */
1906 .name = MSM_DAILINK_NAME(ULL_NOIRQ),
1907 .stream_name = "MM_NOIRQ",
1908 .cpu_dai_name = "MultiMedia8",
1909 .platform_name = "msm-pcm-dsp-noirq",
1910 .dynamic = 1,
1911 .dpcm_capture = 1,
1912 .dpcm_playback = 1,
1913 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1914 SND_SOC_DPCM_TRIGGER_POST},
1915 .codec_dai_name = "snd-soc-dummy-dai",
1916 .codec_name = "snd-soc-dummy",
1917 .ignore_suspend = 1,
1918 .ignore_pmdown_time = 1,
1919 /* this dai link has playback support */
1920 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
1921 },
1922 {/* hw:x,18 */
1923 .name = "HDMI_RX_HOSTLESS",
1924 .stream_name = "HDMI_RX_HOSTLESS",
1925 .cpu_dai_name = "HDMI_HOSTLESS",
1926 .platform_name = "msm-pcm-hostless",
1927 .dynamic = 1,
1928 .dpcm_playback = 1,
1929 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1930 SND_SOC_DPCM_TRIGGER_POST},
1931 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1932 .ignore_suspend = 1,
1933 .ignore_pmdown_time = 1,
1934 .codec_dai_name = "snd-soc-dummy-dai",
1935 .codec_name = "snd-soc-dummy",
1936 },
1937 {/* hw:x,19 */
1938 .name = "VoiceMMode2",
1939 .stream_name = "VoiceMMode2",
1940 .cpu_dai_name = "VoiceMMode2",
1941 .platform_name = "msm-pcm-voice",
1942 .dynamic = 1,
1943 .dpcm_capture = 1,
1944 .dpcm_playback = 1,
1945 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1946 SND_SOC_DPCM_TRIGGER_POST},
1947 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1948 .ignore_suspend = 1,
1949 .ignore_pmdown_time = 1,
1950 .codec_dai_name = "snd-soc-dummy-dai",
1951 .codec_name = "snd-soc-dummy",
1952 .be_id = MSM_FRONTEND_DAI_VOICEMMODE2,
1953 },
1954 {/* hw:x,20 */
1955 .name = "Listen 2 Audio Service",
1956 .stream_name = "Listen 2 Audio Service",
1957 .cpu_dai_name = "LSM2",
1958 .platform_name = "msm-lsm-client",
1959 .dynamic = 1,
1960 .dpcm_capture = 1,
1961 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1962 SND_SOC_DPCM_TRIGGER_POST },
1963 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1964 .ignore_suspend = 1,
1965 .ignore_pmdown_time = 1,
1966 .codec_dai_name = "snd-soc-dummy-dai",
1967 .codec_name = "snd-soc-dummy",
1968 .be_id = MSM_FRONTEND_DAI_LSM2,
1969 },
1970 {/* hw:x,21 */
1971 .name = "Listen 3 Audio Service",
1972 .stream_name = "Listen 3 Audio Service",
1973 .cpu_dai_name = "LSM3",
1974 .platform_name = "msm-lsm-client",
1975 .dynamic = 1,
1976 .dpcm_capture = 1,
1977 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1978 SND_SOC_DPCM_TRIGGER_POST },
1979 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1980 .ignore_suspend = 1,
1981 .ignore_pmdown_time = 1,
1982 .codec_dai_name = "snd-soc-dummy-dai",
1983 .codec_name = "snd-soc-dummy",
1984 .be_id = MSM_FRONTEND_DAI_LSM3,
1985 },
1986 {/* hw:x,22 */
1987 .name = "Listen 4 Audio Service",
1988 .stream_name = "Listen 4 Audio Service",
1989 .cpu_dai_name = "LSM4",
1990 .platform_name = "msm-lsm-client",
1991 .dynamic = 1,
1992 .dpcm_capture = 1,
1993 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1994 SND_SOC_DPCM_TRIGGER_POST },
1995 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1996 .ignore_suspend = 1,
1997 .ignore_pmdown_time = 1,
1998 .codec_dai_name = "snd-soc-dummy-dai",
1999 .codec_name = "snd-soc-dummy",
2000 .be_id = MSM_FRONTEND_DAI_LSM4,
2001 },
2002 {/* hw:x,23 */
2003 .name = "Listen 5 Audio Service",
2004 .stream_name = "Listen 5 Audio Service",
2005 .cpu_dai_name = "LSM5",
2006 .platform_name = "msm-lsm-client",
2007 .dynamic = 1,
2008 .dpcm_capture = 1,
2009 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2010 SND_SOC_DPCM_TRIGGER_POST },
2011 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
2012 .ignore_suspend = 1,
2013 .ignore_pmdown_time = 1,
2014 .codec_dai_name = "snd-soc-dummy-dai",
2015 .codec_name = "snd-soc-dummy",
2016 .be_id = MSM_FRONTEND_DAI_LSM5,
2017 },
2018 {/* hw:x,24 */
2019 .name = "Listen 6 Audio Service",
2020 .stream_name = "Listen 6 Audio Service",
2021 .cpu_dai_name = "LSM6",
2022 .platform_name = "msm-lsm-client",
2023 .dynamic = 1,
2024 .dpcm_capture = 1,
2025 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2026 SND_SOC_DPCM_TRIGGER_POST },
2027 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
2028 .ignore_suspend = 1,
2029 .ignore_pmdown_time = 1,
2030 .codec_dai_name = "snd-soc-dummy-dai",
2031 .codec_name = "snd-soc-dummy",
2032 .be_id = MSM_FRONTEND_DAI_LSM6
2033 },
2034 {/* hw:x,25 */
2035 .name = "Listen 7 Audio Service",
2036 .stream_name = "Listen 7 Audio Service",
2037 .cpu_dai_name = "LSM7",
2038 .platform_name = "msm-lsm-client",
2039 .dynamic = 1,
2040 .dpcm_capture = 1,
2041 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2042 SND_SOC_DPCM_TRIGGER_POST },
2043 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
2044 .ignore_suspend = 1,
2045 .ignore_pmdown_time = 1,
2046 .codec_dai_name = "snd-soc-dummy-dai",
2047 .codec_name = "snd-soc-dummy",
2048 .be_id = MSM_FRONTEND_DAI_LSM7,
2049 },
2050 {/* hw:x,26 */
2051 .name = "Listen 8 Audio Service",
2052 .stream_name = "Listen 8 Audio Service",
2053 .cpu_dai_name = "LSM8",
2054 .platform_name = "msm-lsm-client",
2055 .dynamic = 1,
2056 .dpcm_capture = 1,
2057 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2058 SND_SOC_DPCM_TRIGGER_POST },
2059 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
2060 .ignore_suspend = 1,
2061 .ignore_pmdown_time = 1,
2062 .codec_dai_name = "snd-soc-dummy-dai",
2063 .codec_name = "snd-soc-dummy",
2064 .be_id = MSM_FRONTEND_DAI_LSM8,
2065 },
2066 {/* hw:x,27 */
2067 .name = MSM_DAILINK_NAME(Media9),
2068 .stream_name = "MultiMedia9",
2069 .cpu_dai_name = "MultiMedia9",
2070 .platform_name = "msm-pcm-dsp.0",
2071 .dynamic = 1,
2072 .dpcm_capture = 1,
2073 .dpcm_playback = 1,
2074 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2075 SND_SOC_DPCM_TRIGGER_POST},
2076 .codec_dai_name = "snd-soc-dummy-dai",
2077 .codec_name = "snd-soc-dummy",
2078 .ignore_suspend = 1,
2079 .ignore_pmdown_time = 1,
2080 /* this dai link has playback support */
2081 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA9,
2082 },
2083 {/* hw:x,28 */
2084 .name = MSM_DAILINK_NAME(Compress4),
2085 .stream_name = "Compress4",
2086 .cpu_dai_name = "MultiMedia11",
2087 .platform_name = "msm-compress-dsp",
2088 .dynamic = 1,
2089 .dpcm_capture = 1,
2090 .dpcm_playback = 1,
2091 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2092 SND_SOC_DPCM_TRIGGER_POST},
2093 .codec_dai_name = "snd-soc-dummy-dai",
2094 .codec_name = "snd-soc-dummy",
2095 .ignore_suspend = 1,
2096 .ignore_pmdown_time = 1,
2097 /* this dai link has playback support */
2098 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA11,
2099 },
2100 {/* hw:x,29 */
2101 .name = MSM_DAILINK_NAME(Compress5),
2102 .stream_name = "Compress5",
2103 .cpu_dai_name = "MultiMedia12",
2104 .platform_name = "msm-compress-dsp",
2105 .dynamic = 1,
2106 .dpcm_capture = 1,
2107 .dpcm_playback = 1,
2108 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2109 SND_SOC_DPCM_TRIGGER_POST},
2110 .codec_dai_name = "snd-soc-dummy-dai",
2111 .codec_name = "snd-soc-dummy",
2112 .ignore_suspend = 1,
2113 .ignore_pmdown_time = 1,
2114 /* this dai link has playback support */
2115 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA12,
2116 },
2117 {/* hw:x,30 */
2118 .name = MSM_DAILINK_NAME(Compress6),
2119 .stream_name = "Compress6",
2120 .cpu_dai_name = "MultiMedia13",
2121 .platform_name = "msm-compress-dsp",
2122 .dynamic = 1,
2123 .dpcm_capture = 1,
2124 .dpcm_playback = 1,
2125 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2126 SND_SOC_DPCM_TRIGGER_POST},
2127 .codec_dai_name = "snd-soc-dummy-dai",
2128 .codec_name = "snd-soc-dummy",
2129 .ignore_suspend = 1,
2130 .ignore_pmdown_time = 1,
2131 /* this dai link has playback support */
2132 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA13,
2133 },
2134 {/* hw:x,31 */
2135 .name = MSM_DAILINK_NAME(Compress7),
2136 .stream_name = "Compress7",
2137 .cpu_dai_name = "MultiMedia14",
2138 .platform_name = "msm-compress-dsp",
2139 .dynamic = 1,
2140 .dpcm_capture = 1,
2141 .dpcm_playback = 1,
2142 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2143 SND_SOC_DPCM_TRIGGER_POST},
2144 .codec_dai_name = "snd-soc-dummy-dai",
2145 .codec_name = "snd-soc-dummy",
2146 .ignore_suspend = 1,
2147 .ignore_pmdown_time = 1,
2148 /* this dai link has playback support */
2149 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA14,
2150 },
2151 {/* hw:x,32 */
2152 .name = MSM_DAILINK_NAME(Compress8),
2153 .stream_name = "Compress8",
2154 .cpu_dai_name = "MultiMedia15",
2155 .platform_name = "msm-compress-dsp",
2156 .dynamic = 1,
2157 .dpcm_capture = 1,
2158 .dpcm_playback = 1,
2159 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2160 SND_SOC_DPCM_TRIGGER_POST},
2161 .codec_dai_name = "snd-soc-dummy-dai",
2162 .codec_name = "snd-soc-dummy",
2163 .ignore_suspend = 1,
2164 .ignore_pmdown_time = 1,
2165 /* this dai link has playback support */
2166 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA15,
2167 },
2168 {/* hw:x,33 */
2169 .name = MSM_DAILINK_NAME(Compress9),
2170 .stream_name = "Compress9",
2171 .cpu_dai_name = "MultiMedia16",
2172 .platform_name = "msm-compress-dsp",
2173 .dynamic = 1,
2174 .dpcm_capture = 1,
2175 .dpcm_playback = 1,
2176 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2177 SND_SOC_DPCM_TRIGGER_POST},
2178 .codec_dai_name = "snd-soc-dummy-dai",
2179 .codec_name = "snd-soc-dummy",
2180 .ignore_suspend = 1,
2181 .ignore_pmdown_time = 1,
2182 /* this dai link has playback support */
2183 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA16,
2184 },
2185 {/* hw:x,34 */
2186 .name = "SLIMBUS_8 Hostless",
2187 .stream_name = "SLIMBUS8_HOSTLESS Capture",
2188 .cpu_dai_name = "SLIMBUS8_HOSTLESS",
2189 .platform_name = "msm-pcm-hostless",
2190 .dynamic = 1,
2191 .dpcm_capture = 1,
2192 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2193 SND_SOC_DPCM_TRIGGER_POST},
2194 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
2195 .ignore_suspend = 1,
2196 .ignore_pmdown_time = 1,
2197 .codec_dai_name = "snd-soc-dummy-dai",
2198 .codec_name = "snd-soc-dummy",
2199 },
2200 {/* hw:x,35 */
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002201 .name = "Primary MI2S_RX Hostless",
2202 .stream_name = "Primary MI2S_RX Hostless",
2203 .cpu_dai_name = "PRI_MI2S_RX_HOSTLESS",
2204 .platform_name = "msm-pcm-hostless",
2205 .dynamic = 1,
2206 .dpcm_playback = 1,
2207 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2208 SND_SOC_DPCM_TRIGGER_POST},
2209 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
2210 .ignore_suspend = 1,
2211 /* this dailink has playback support */
2212 .ignore_pmdown_time = 1,
2213 /* This dainlink has MI2S support */
2214 .codec_dai_name = "snd-soc-dummy-dai",
2215 .codec_name = "snd-soc-dummy",
2216 },
Laxminath Kasam82f136f2017-01-24 00:52:55 +05302217 {/* hw:x,36 */
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002218 .name = "Secondary MI2S_RX Hostless",
2219 .stream_name = "Secondary MI2S_RX Hostless",
2220 .cpu_dai_name = "SEC_MI2S_RX_HOSTLESS",
2221 .platform_name = "msm-pcm-hostless",
2222 .dynamic = 1,
2223 .dpcm_playback = 1,
2224 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2225 SND_SOC_DPCM_TRIGGER_POST},
2226 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
2227 .ignore_suspend = 1,
2228 /* this dailink has playback support */
2229 .ignore_pmdown_time = 1,
2230 /* This dainlink has MI2S support */
2231 .codec_dai_name = "snd-soc-dummy-dai",
2232 .codec_name = "snd-soc-dummy",
2233 },
Laxminath Kasam82f136f2017-01-24 00:52:55 +05302234 {/* hw:x,37 */
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002235 .name = "Tertiary MI2S_RX Hostless",
2236 .stream_name = "Tertiary MI2S_RX Hostless",
2237 .cpu_dai_name = "TERT_MI2S_RX_HOSTLESS",
2238 .platform_name = "msm-pcm-hostless",
2239 .dynamic = 1,
2240 .dpcm_playback = 1,
2241 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2242 SND_SOC_DPCM_TRIGGER_POST},
2243 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
2244 .ignore_suspend = 1,
2245 /* this dailink has playback support */
2246 .ignore_pmdown_time = 1,
2247 /* This dainlink has MI2S support */
2248 .codec_dai_name = "snd-soc-dummy-dai",
2249 .codec_name = "snd-soc-dummy",
2250 },
Laxminath Kasam82f136f2017-01-24 00:52:55 +05302251 {/* hw:x,38 */
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002252 .name = "INT0 MI2S_RX Hostless",
2253 .stream_name = "INT0 MI2S_RX Hostless",
2254 .cpu_dai_name = "INT0_MI2S_RX_HOSTLESS",
2255 .platform_name = "msm-pcm-hostless",
2256 .dynamic = 1,
2257 .dpcm_playback = 1,
2258 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2259 SND_SOC_DPCM_TRIGGER_POST},
2260 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
2261 .ignore_suspend = 1,
2262 /* this dailink has playback support */
2263 .ignore_pmdown_time = 1,
2264 /* This dainlink has MI2S support */
2265 .codec_dai_name = "snd-soc-dummy-dai",
2266 .codec_name = "snd-soc-dummy",
2267 },
Satya Krishna Pindiprolif7a6d712017-02-03 16:49:14 +05302268 {/* hw:x,39 */
2269 .name = "SDM660 HFP TX",
2270 .stream_name = "MultiMedia6",
2271 .cpu_dai_name = "MultiMedia6",
2272 .platform_name = "msm-pcm-loopback",
2273 .dynamic = 1,
2274 .dpcm_playback = 1,
2275 .dpcm_capture = 1,
2276 .codec_dai_name = "snd-soc-dummy-dai",
2277 .codec_name = "snd-soc-dummy",
2278 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
2279 SND_SOC_DPCM_TRIGGER_POST},
2280 .ignore_suspend = 1,
2281 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
2282 .ignore_pmdown_time = 1,
2283 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA6,
2284 },
Laxminath Kasam82f136f2017-01-24 00:52:55 +05302285};
2286
2287
2288static struct snd_soc_dai_link msm_int_wsa_dai[] = {
Satya Krishna Pindiprolif7a6d712017-02-03 16:49:14 +05302289 {/* hw:x,40 */
Laxminath Kasam82f136f2017-01-24 00:52:55 +05302290 .name = LPASS_BE_INT5_MI2S_TX,
2291 .stream_name = "INT5_mi2s Capture",
2292 .cpu_dai_name = "msm-dai-q6-mi2s.12",
2293 .platform_name = "msm-pcm-hostless",
2294 .codec_name = "msm_sdw_codec",
2295 .codec_dai_name = "msm_sdw_vifeedback",
2296 .be_id = MSM_BACKEND_DAI_INT5_MI2S_TX,
2297 .be_hw_params_fixup = int_mi2s_be_hw_params_fixup,
2298 .ops = &msm_sdw_mi2s_be_ops,
2299 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
2300 .ignore_suspend = 1,
2301 .dpcm_capture = 1,
2302 .ignore_pmdown_time = 1,
2303 },
2304};
2305
2306static struct snd_soc_dai_link msm_int_be_dai[] = {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002307 /* Backend I2S DAI Links */
2308 {
2309 .name = LPASS_BE_INT0_MI2S_RX,
2310 .stream_name = "INT0 MI2S Playback",
2311 .cpu_dai_name = "msm-dai-q6-mi2s.7",
2312 .platform_name = "msm-pcm-routing",
Laxminath Kasame68e94f2016-12-09 12:08:00 +05302313 .codecs = dlc_rx1,
2314 .num_codecs = CODECS_MAX,
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002315 .no_pcm = 1,
2316 .dpcm_playback = 1,
2317 .async_ops = ASYNC_DPCM_SND_SOC_PREPARE |
2318 ASYNC_DPCM_SND_SOC_HW_PARAMS,
2319 .be_id = MSM_BACKEND_DAI_INT0_MI2S_RX,
2320 .init = &msm_audrx_init,
2321 .be_hw_params_fixup = int_mi2s_be_hw_params_fixup,
2322 .ops = &msm_int_mi2s_be_ops,
2323 .ignore_suspend = 1,
2324 },
2325 {
Laxminath Kasame68e94f2016-12-09 12:08:00 +05302326 .name = LPASS_BE_INT3_MI2S_TX,
2327 .stream_name = "INT3 MI2S Capture",
2328 .cpu_dai_name = "msm-dai-q6-mi2s.10",
2329 .platform_name = "msm-pcm-routing",
2330 .codecs = dlc_tx1,
2331 .num_codecs = CODECS_MAX,
2332 .no_pcm = 1,
2333 .dpcm_capture = 1,
2334 .async_ops = ASYNC_DPCM_SND_SOC_PREPARE |
2335 ASYNC_DPCM_SND_SOC_HW_PARAMS,
2336 .be_id = MSM_BACKEND_DAI_INT3_MI2S_TX,
Laxminath Kasama5cc5332017-02-04 01:36:04 +05302337 .be_hw_params_fixup = int_mi2s_be_hw_params_fixup,
Laxminath Kasame68e94f2016-12-09 12:08:00 +05302338 .ops = &msm_int_mi2s_be_ops,
2339 .ignore_suspend = 1,
2340 },
2341 {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002342 .name = LPASS_BE_INT2_MI2S_TX,
2343 .stream_name = "INT2 MI2S Capture",
2344 .cpu_dai_name = "msm-dai-q6-mi2s.9",
2345 .platform_name = "msm-pcm-routing",
Laxminath Kasame68e94f2016-12-09 12:08:00 +05302346 .codecs = dlc_tx2,
2347 .num_codecs = CODECS_MAX,
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002348 .no_pcm = 1,
2349 .dpcm_capture = 1,
2350 .async_ops = ASYNC_DPCM_SND_SOC_PREPARE |
2351 ASYNC_DPCM_SND_SOC_HW_PARAMS,
2352 .be_id = MSM_BACKEND_DAI_INT2_MI2S_TX,
2353 .be_hw_params_fixup = int_mi2s_be_hw_params_fixup,
2354 .ops = &msm_int_mi2s_be_ops,
2355 .ignore_suspend = 1,
2356 },
2357 {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002358 .name = LPASS_BE_AFE_PCM_RX,
2359 .stream_name = "AFE Playback",
2360 .cpu_dai_name = "msm-dai-q6-dev.224",
2361 .platform_name = "msm-pcm-routing",
2362 .codec_name = "msm-stub-codec.1",
2363 .codec_dai_name = "msm-stub-rx",
2364 .no_pcm = 1,
2365 .dpcm_playback = 1,
2366 .be_id = MSM_BACKEND_DAI_AFE_PCM_RX,
2367 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2368 /* this dainlink has playback support */
2369 .ignore_pmdown_time = 1,
2370 .ignore_suspend = 1,
2371 },
2372 {
2373 .name = LPASS_BE_AFE_PCM_TX,
2374 .stream_name = "AFE Capture",
2375 .cpu_dai_name = "msm-dai-q6-dev.225",
2376 .platform_name = "msm-pcm-routing",
2377 .codec_name = "msm-stub-codec.1",
2378 .codec_dai_name = "msm-stub-tx",
2379 .no_pcm = 1,
2380 .dpcm_capture = 1,
2381 .be_id = MSM_BACKEND_DAI_AFE_PCM_TX,
2382 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2383 .ignore_suspend = 1,
2384 },
2385 /* Incall Record Uplink BACK END DAI Link */
2386 {
2387 .name = LPASS_BE_INCALL_RECORD_TX,
2388 .stream_name = "Voice Uplink Capture",
2389 .cpu_dai_name = "msm-dai-q6-dev.32772",
2390 .platform_name = "msm-pcm-routing",
2391 .codec_name = "msm-stub-codec.1",
2392 .codec_dai_name = "msm-stub-tx",
2393 .no_pcm = 1,
2394 .dpcm_capture = 1,
2395 .be_id = MSM_BACKEND_DAI_INCALL_RECORD_TX,
2396 .be_hw_params_fixup = msm_be_hw_params_fixup,
2397 .ignore_suspend = 1,
2398 },
2399 /* Incall Record Downlink BACK END DAI Link */
2400 {
2401 .name = LPASS_BE_INCALL_RECORD_RX,
2402 .stream_name = "Voice Downlink Capture",
2403 .cpu_dai_name = "msm-dai-q6-dev.32771",
2404 .platform_name = "msm-pcm-routing",
2405 .codec_name = "msm-stub-codec.1",
2406 .codec_dai_name = "msm-stub-tx",
2407 .no_pcm = 1,
2408 .dpcm_capture = 1,
2409 .be_id = MSM_BACKEND_DAI_INCALL_RECORD_RX,
2410 .be_hw_params_fixup = msm_be_hw_params_fixup,
2411 .ignore_suspend = 1,
2412 },
2413 /* Incall Music BACK END DAI Link */
2414 {
2415 .name = LPASS_BE_VOICE_PLAYBACK_TX,
2416 .stream_name = "Voice Farend Playback",
2417 .cpu_dai_name = "msm-dai-q6-dev.32773",
2418 .platform_name = "msm-pcm-routing",
2419 .codec_name = "msm-stub-codec.1",
2420 .codec_dai_name = "msm-stub-rx",
2421 .no_pcm = 1,
2422 .dpcm_playback = 1,
2423 .be_id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
2424 .be_hw_params_fixup = msm_be_hw_params_fixup,
2425 .ignore_suspend = 1,
2426 },
2427 /* Incall Music 2 BACK END DAI Link */
2428 {
2429 .name = LPASS_BE_VOICE2_PLAYBACK_TX,
2430 .stream_name = "Voice2 Farend Playback",
2431 .cpu_dai_name = "msm-dai-q6-dev.32770",
2432 .platform_name = "msm-pcm-routing",
2433 .codec_name = "msm-stub-codec.1",
2434 .codec_dai_name = "msm-stub-rx",
2435 .no_pcm = 1,
2436 .dpcm_playback = 1,
2437 .be_id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX,
2438 .be_hw_params_fixup = msm_be_hw_params_fixup,
2439 .ignore_suspend = 1,
2440 },
2441 {
2442 .name = LPASS_BE_USB_AUDIO_RX,
2443 .stream_name = "USB Audio Playback",
2444 .cpu_dai_name = "msm-dai-q6-dev.28672",
2445 .platform_name = "msm-pcm-routing",
2446 .codec_name = "msm-stub-codec.1",
2447 .codec_dai_name = "msm-stub-rx",
2448 .no_pcm = 1,
2449 .dpcm_playback = 1,
2450 .be_id = MSM_BACKEND_DAI_USB_RX,
2451 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2452 .ignore_pmdown_time = 1,
2453 .ignore_suspend = 1,
2454 },
2455 {
2456 .name = LPASS_BE_USB_AUDIO_TX,
2457 .stream_name = "USB Audio Capture",
2458 .cpu_dai_name = "msm-dai-q6-dev.28673",
2459 .platform_name = "msm-pcm-routing",
2460 .codec_name = "msm-stub-codec.1",
2461 .codec_dai_name = "msm-stub-tx",
2462 .no_pcm = 1,
2463 .dpcm_capture = 1,
2464 .be_id = MSM_BACKEND_DAI_USB_TX,
2465 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2466 .ignore_suspend = 1,
2467 },
2468 {
2469 .name = LPASS_BE_PRI_TDM_RX_0,
2470 .stream_name = "Primary TDM0 Playback",
2471 .cpu_dai_name = "msm-dai-q6-tdm.36864",
2472 .platform_name = "msm-pcm-routing",
2473 .codec_name = "msm-stub-codec.1",
2474 .codec_dai_name = "msm-stub-rx",
2475 .no_pcm = 1,
2476 .dpcm_playback = 1,
2477 .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_0,
2478 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2479 .ops = &msm_tdm_be_ops,
2480 .ignore_suspend = 1,
2481 },
2482 {
2483 .name = LPASS_BE_PRI_TDM_TX_0,
2484 .stream_name = "Primary TDM0 Capture",
2485 .cpu_dai_name = "msm-dai-q6-tdm.36865",
2486 .platform_name = "msm-pcm-routing",
2487 .codec_name = "msm-stub-codec.1",
2488 .codec_dai_name = "msm-stub-tx",
2489 .no_pcm = 1,
2490 .dpcm_capture = 1,
2491 .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_0,
2492 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2493 .ops = &msm_tdm_be_ops,
2494 .ignore_suspend = 1,
2495 },
2496 {
2497 .name = LPASS_BE_SEC_TDM_RX_0,
2498 .stream_name = "Secondary TDM0 Playback",
2499 .cpu_dai_name = "msm-dai-q6-tdm.36880",
2500 .platform_name = "msm-pcm-routing",
2501 .codec_name = "msm-stub-codec.1",
2502 .codec_dai_name = "msm-stub-rx",
2503 .no_pcm = 1,
2504 .dpcm_playback = 1,
2505 .be_id = MSM_BACKEND_DAI_SEC_TDM_RX_0,
2506 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2507 .ops = &msm_tdm_be_ops,
2508 .ignore_suspend = 1,
2509 },
2510 {
2511 .name = LPASS_BE_SEC_TDM_TX_0,
2512 .stream_name = "Secondary TDM0 Capture",
2513 .cpu_dai_name = "msm-dai-q6-tdm.36881",
2514 .platform_name = "msm-pcm-routing",
2515 .codec_name = "msm-stub-codec.1",
2516 .codec_dai_name = "msm-stub-tx",
2517 .no_pcm = 1,
2518 .dpcm_capture = 1,
2519 .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_0,
2520 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2521 .ops = &msm_tdm_be_ops,
2522 .ignore_suspend = 1,
2523 },
2524 {
2525 .name = LPASS_BE_TERT_TDM_RX_0,
2526 .stream_name = "Tertiary TDM0 Playback",
2527 .cpu_dai_name = "msm-dai-q6-tdm.36896",
2528 .platform_name = "msm-pcm-routing",
2529 .codec_name = "msm-stub-codec.1",
2530 .codec_dai_name = "msm-stub-rx",
2531 .no_pcm = 1,
2532 .dpcm_playback = 1,
2533 .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_0,
2534 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2535 .ops = &msm_tdm_be_ops,
2536 .ignore_suspend = 1,
2537 },
2538 {
2539 .name = LPASS_BE_TERT_TDM_TX_0,
2540 .stream_name = "Tertiary TDM0 Capture",
2541 .cpu_dai_name = "msm-dai-q6-tdm.36897",
2542 .platform_name = "msm-pcm-routing",
2543 .codec_name = "msm-stub-codec.1",
2544 .codec_dai_name = "msm-stub-tx",
2545 .no_pcm = 1,
2546 .dpcm_capture = 1,
2547 .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_0,
2548 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2549 .ops = &msm_tdm_be_ops,
2550 .ignore_suspend = 1,
2551 },
2552 {
2553 .name = LPASS_BE_QUAT_TDM_RX_0,
2554 .stream_name = "Quaternary TDM0 Playback",
2555 .cpu_dai_name = "msm-dai-q6-tdm.36912",
2556 .platform_name = "msm-pcm-routing",
2557 .codec_name = "msm-stub-codec.1",
2558 .codec_dai_name = "msm-stub-rx",
2559 .no_pcm = 1,
2560 .dpcm_playback = 1,
2561 .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_0,
2562 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2563 .ops = &msm_tdm_be_ops,
2564 .ignore_suspend = 1,
2565 },
2566 {
2567 .name = LPASS_BE_QUAT_TDM_TX_0,
2568 .stream_name = "Quaternary TDM0 Capture",
2569 .cpu_dai_name = "msm-dai-q6-tdm.36913",
2570 .platform_name = "msm-pcm-routing",
2571 .codec_name = "msm-stub-codec.1",
2572 .codec_dai_name = "msm-stub-tx",
2573 .no_pcm = 1,
2574 .dpcm_capture = 1,
2575 .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_0,
2576 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2577 .ops = &msm_tdm_be_ops,
2578 .ignore_suspend = 1,
2579 },
2580};
2581
2582static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = {
2583 {
2584 .name = LPASS_BE_PRI_MI2S_RX,
2585 .stream_name = "Primary MI2S Playback",
2586 .cpu_dai_name = "msm-dai-q6-mi2s.0",
2587 .platform_name = "msm-pcm-routing",
2588 .codec_name = "msm-stub-codec.1",
2589 .codec_dai_name = "msm-stub-rx",
2590 .no_pcm = 1,
2591 .dpcm_playback = 1,
2592 .be_id = MSM_BACKEND_DAI_PRI_MI2S_RX,
2593 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2594 .ops = &msm_mi2s_be_ops,
2595 .ignore_suspend = 1,
2596 .ignore_pmdown_time = 1,
2597 },
2598 {
2599 .name = LPASS_BE_PRI_MI2S_TX,
2600 .stream_name = "Primary MI2S Capture",
2601 .cpu_dai_name = "msm-dai-q6-mi2s.0",
2602 .platform_name = "msm-pcm-routing",
2603 .codec_name = "msm-stub-codec.1",
2604 .codec_dai_name = "msm-stub-tx",
2605 .no_pcm = 1,
2606 .dpcm_capture = 1,
2607 .be_id = MSM_BACKEND_DAI_PRI_MI2S_TX,
2608 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2609 .ops = &msm_mi2s_be_ops,
2610 .ignore_suspend = 1,
2611 },
2612 {
2613 .name = LPASS_BE_SEC_MI2S_RX,
2614 .stream_name = "Secondary MI2S Playback",
2615 .cpu_dai_name = "msm-dai-q6-mi2s.1",
2616 .platform_name = "msm-pcm-routing",
2617 .codec_name = "msm-stub-codec.1",
2618 .codec_dai_name = "msm-stub-rx",
2619 .no_pcm = 1,
2620 .dpcm_playback = 1,
2621 .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
2622 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2623 .ops = &msm_mi2s_be_ops,
2624 .ignore_suspend = 1,
2625 .ignore_pmdown_time = 1,
2626 },
2627 {
2628 .name = LPASS_BE_SEC_MI2S_TX,
2629 .stream_name = "Secondary MI2S Capture",
2630 .cpu_dai_name = "msm-dai-q6-mi2s.1",
2631 .platform_name = "msm-pcm-routing",
2632 .codec_name = "msm-stub-codec.1",
2633 .codec_dai_name = "msm-stub-tx",
2634 .no_pcm = 1,
2635 .dpcm_capture = 1,
2636 .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
2637 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2638 .ops = &msm_mi2s_be_ops,
2639 .ignore_suspend = 1,
2640 },
2641 {
2642 .name = LPASS_BE_TERT_MI2S_RX,
2643 .stream_name = "Tertiary MI2S Playback",
2644 .cpu_dai_name = "msm-dai-q6-mi2s.2",
2645 .platform_name = "msm-pcm-routing",
2646 .codec_name = "msm-stub-codec.1",
2647 .codec_dai_name = "msm-stub-rx",
2648 .no_pcm = 1,
2649 .dpcm_playback = 1,
2650 .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX,
2651 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2652 .ops = &msm_mi2s_be_ops,
2653 .ignore_suspend = 1,
2654 .ignore_pmdown_time = 1,
2655 },
2656 {
2657 .name = LPASS_BE_TERT_MI2S_TX,
2658 .stream_name = "Tertiary MI2S Capture",
2659 .cpu_dai_name = "msm-dai-q6-mi2s.2",
2660 .platform_name = "msm-pcm-routing",
2661 .codec_name = "msm-stub-codec.1",
2662 .codec_dai_name = "msm-stub-tx",
2663 .no_pcm = 1,
2664 .dpcm_capture = 1,
2665 .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
2666 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2667 .ops = &msm_mi2s_be_ops,
2668 .ignore_suspend = 1,
2669 },
2670 {
2671 .name = LPASS_BE_QUAT_MI2S_RX,
2672 .stream_name = "Quaternary MI2S Playback",
2673 .cpu_dai_name = "msm-dai-q6-mi2s.3",
2674 .platform_name = "msm-pcm-routing",
2675 .codec_name = "msm-stub-codec.1",
2676 .codec_dai_name = "msm-stub-rx",
2677 .no_pcm = 1,
2678 .dpcm_playback = 1,
2679 .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,
2680 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2681 .ops = &msm_mi2s_be_ops,
2682 .ignore_suspend = 1,
2683 .ignore_pmdown_time = 1,
2684 },
2685 {
2686 .name = LPASS_BE_QUAT_MI2S_TX,
2687 .stream_name = "Quaternary MI2S Capture",
2688 .cpu_dai_name = "msm-dai-q6-mi2s.3",
2689 .platform_name = "msm-pcm-routing",
2690 .codec_name = "msm-stub-codec.1",
2691 .codec_dai_name = "msm-stub-tx",
2692 .no_pcm = 1,
2693 .dpcm_capture = 1,
2694 .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
2695 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2696 .ops = &msm_mi2s_be_ops,
2697 .ignore_suspend = 1,
2698 },
2699};
2700
2701static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = {
2702 /* Primary AUX PCM Backend DAI Links */
2703 {
2704 .name = LPASS_BE_AUXPCM_RX,
2705 .stream_name = "AUX PCM Playback",
2706 .cpu_dai_name = "msm-dai-q6-auxpcm.1",
2707 .platform_name = "msm-pcm-routing",
2708 .codec_name = "msm-stub-codec.1",
2709 .codec_dai_name = "msm-stub-rx",
2710 .no_pcm = 1,
2711 .dpcm_playback = 1,
2712 .be_id = MSM_BACKEND_DAI_AUXPCM_RX,
2713 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2714 .ignore_pmdown_time = 1,
2715 .ignore_suspend = 1,
2716 .ops = &msm_aux_pcm_be_ops,
2717 },
2718 {
2719 .name = LPASS_BE_AUXPCM_TX,
2720 .stream_name = "AUX PCM Capture",
2721 .cpu_dai_name = "msm-dai-q6-auxpcm.1",
2722 .platform_name = "msm-pcm-routing",
2723 .codec_name = "msm-stub-codec.1",
2724 .codec_dai_name = "msm-stub-tx",
2725 .no_pcm = 1,
2726 .dpcm_capture = 1,
2727 .be_id = MSM_BACKEND_DAI_AUXPCM_TX,
2728 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2729 .ignore_pmdown_time = 1,
2730 .ignore_suspend = 1,
2731 .ops = &msm_aux_pcm_be_ops,
2732 },
2733 /* Secondary AUX PCM Backend DAI Links */
2734 {
2735 .name = LPASS_BE_SEC_AUXPCM_RX,
2736 .stream_name = "Sec AUX PCM Playback",
2737 .cpu_dai_name = "msm-dai-q6-auxpcm.2",
2738 .platform_name = "msm-pcm-routing",
2739 .codec_name = "msm-stub-codec.1",
2740 .codec_dai_name = "msm-stub-rx",
2741 .no_pcm = 1,
2742 .dpcm_playback = 1,
2743 .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_RX,
2744 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2745 .ignore_pmdown_time = 1,
2746 .ignore_suspend = 1,
2747 .ops = &msm_aux_pcm_be_ops,
2748 },
2749 {
2750 .name = LPASS_BE_SEC_AUXPCM_TX,
2751 .stream_name = "Sec AUX PCM Capture",
2752 .cpu_dai_name = "msm-dai-q6-auxpcm.2",
2753 .platform_name = "msm-pcm-routing",
2754 .codec_name = "msm-stub-codec.1",
2755 .codec_dai_name = "msm-stub-tx",
2756 .no_pcm = 1,
2757 .dpcm_capture = 1,
2758 .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_TX,
2759 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2760 .ignore_suspend = 1,
2761 .ignore_pmdown_time = 1,
2762 .ops = &msm_aux_pcm_be_ops,
2763 },
2764 /* Tertiary AUX PCM Backend DAI Links */
2765 {
2766 .name = LPASS_BE_TERT_AUXPCM_RX,
2767 .stream_name = "Tert AUX PCM Playback",
2768 .cpu_dai_name = "msm-dai-q6-auxpcm.3",
2769 .platform_name = "msm-pcm-routing",
2770 .codec_name = "msm-stub-codec.1",
2771 .codec_dai_name = "msm-stub-rx",
2772 .no_pcm = 1,
2773 .dpcm_playback = 1,
2774 .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_RX,
2775 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2776 .ignore_pmdown_time = 1,
2777 .ignore_suspend = 1,
2778 .ops = &msm_aux_pcm_be_ops,
2779 },
2780 {
2781 .name = LPASS_BE_TERT_AUXPCM_TX,
2782 .stream_name = "Tert AUX PCM Capture",
2783 .cpu_dai_name = "msm-dai-q6-auxpcm.3",
2784 .platform_name = "msm-pcm-routing",
2785 .codec_name = "msm-stub-codec.1",
2786 .codec_dai_name = "msm-stub-tx",
2787 .no_pcm = 1,
2788 .dpcm_capture = 1,
2789 .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_TX,
2790 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2791 .ignore_suspend = 1,
2792 .ignore_pmdown_time = 1,
2793 .ops = &msm_aux_pcm_be_ops,
2794 },
2795 /* Quaternary AUX PCM Backend DAI Links */
2796 {
2797 .name = LPASS_BE_QUAT_AUXPCM_RX,
2798 .stream_name = "Quat AUX PCM Playback",
2799 .cpu_dai_name = "msm-dai-q6-auxpcm.4",
2800 .platform_name = "msm-pcm-routing",
2801 .codec_name = "msm-stub-codec.1",
2802 .codec_dai_name = "msm-stub-rx",
2803 .no_pcm = 1,
2804 .dpcm_playback = 1,
2805 .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX,
2806 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2807 .ignore_pmdown_time = 1,
2808 .ignore_suspend = 1,
2809 .ops = &msm_aux_pcm_be_ops,
2810 },
2811 {
2812 .name = LPASS_BE_QUAT_AUXPCM_TX,
2813 .stream_name = "Quat AUX PCM Capture",
2814 .cpu_dai_name = "msm-dai-q6-auxpcm.4",
2815 .platform_name = "msm-pcm-routing",
2816 .codec_name = "msm-stub-codec.1",
2817 .codec_dai_name = "msm-stub-tx",
2818 .no_pcm = 1,
2819 .dpcm_capture = 1,
2820 .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX,
2821 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2822 .ignore_suspend = 1,
2823 .ignore_pmdown_time = 1,
2824 .ops = &msm_aux_pcm_be_ops,
2825 },
2826};
2827
2828
2829static struct snd_soc_dai_link msm_wcn_be_dai_links[] = {
2830 {
2831 .name = LPASS_BE_SLIMBUS_7_RX,
2832 .stream_name = "Slimbus7 Playback",
2833 .cpu_dai_name = "msm-dai-q6-dev.16398",
2834 .platform_name = "msm-pcm-routing",
2835 .codec_name = "btfmslim_slave",
2836 /* BT codec driver determines capabilities based on
2837 * dai name, bt codecdai name should always contains
2838 * supported usecase information
2839 */
2840 .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx",
2841 .no_pcm = 1,
2842 .dpcm_playback = 1,
2843 .be_id = MSM_BACKEND_DAI_SLIMBUS_7_RX,
2844 .be_hw_params_fixup = msm_btfm_be_hw_params_fixup,
2845 .ops = &msm_wcn_ops,
2846 /* dai link has playback support */
2847 .ignore_pmdown_time = 1,
2848 .ignore_suspend = 1,
2849 },
2850 {
2851 .name = LPASS_BE_SLIMBUS_7_TX,
2852 .stream_name = "Slimbus7 Capture",
2853 .cpu_dai_name = "msm-dai-q6-dev.16399",
2854 .platform_name = "msm-pcm-routing",
2855 .codec_name = "btfmslim_slave",
2856 .codec_dai_name = "btfm_bt_sco_slim_tx",
2857 .no_pcm = 1,
2858 .dpcm_capture = 1,
2859 .be_id = MSM_BACKEND_DAI_SLIMBUS_7_TX,
2860 .be_hw_params_fixup = msm_btfm_be_hw_params_fixup,
2861 .ops = &msm_wcn_ops,
2862 .ignore_suspend = 1,
2863 },
2864 {
2865 .name = LPASS_BE_SLIMBUS_8_TX,
2866 .stream_name = "Slimbus8 Capture",
2867 .cpu_dai_name = "msm-dai-q6-dev.16401",
2868 .platform_name = "msm-pcm-routing",
2869 .codec_name = "btfmslim_slave",
2870 .codec_dai_name = "btfm_fm_slim_tx",
2871 .no_pcm = 1,
2872 .dpcm_capture = 1,
2873 .be_id = MSM_BACKEND_DAI_SLIMBUS_8_TX,
2874 .be_hw_params_fixup = msm_btfm_be_hw_params_fixup,
2875 .init = &msm_wcn_init,
2876 .ops = &msm_wcn_ops,
2877 .ignore_suspend = 1,
2878 },
2879};
2880
Laxminath Kasam82f136f2017-01-24 00:52:55 +05302881static struct snd_soc_dai_link msm_wsa_be_dai_links[] = {
2882 {
2883 .name = LPASS_BE_INT4_MI2S_RX,
2884 .stream_name = "INT4 MI2S Playback",
2885 .cpu_dai_name = "msm-dai-q6-mi2s.11",
2886 .platform_name = "msm-pcm-routing",
2887 .codec_name = "msm_sdw_codec",
2888 .codec_dai_name = "msm_sdw_i2s_rx1",
2889 .no_pcm = 1,
2890 .dpcm_playback = 1,
2891 .be_id = MSM_BACKEND_DAI_INT4_MI2S_RX,
2892 .init = &msm_sdw_audrx_init,
2893 .be_hw_params_fixup = int_mi2s_be_hw_params_fixup,
2894 .ops = &msm_sdw_mi2s_be_ops,
2895 .ignore_suspend = 1,
2896 },
2897};
2898
Rohit Kumar0bd27132016-12-06 14:48:58 +05302899static struct snd_soc_dai_link ext_disp_be_dai_link[] = {
2900 /* DISP PORT BACK END DAI Link */
2901 {
2902 .name = LPASS_BE_DISPLAY_PORT,
2903 .stream_name = "Display Port Playback",
2904 .cpu_dai_name = "msm-dai-q6-dp.24608",
2905 .platform_name = "msm-pcm-routing",
2906 .codec_name = "msm-ext-disp-audio-codec-rx",
2907 .codec_dai_name = "msm_dp_audio_codec_rx_dai",
2908 .no_pcm = 1,
2909 .dpcm_playback = 1,
2910 .be_id = MSM_BACKEND_DAI_DISPLAY_PORT_RX,
2911 .be_hw_params_fixup = msm_common_be_hw_params_fixup,
2912 .ignore_pmdown_time = 1,
2913 .ignore_suspend = 1,
2914 },
2915};
2916
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002917static struct snd_soc_dai_link msm_int_dai_links[
2918ARRAY_SIZE(msm_int_dai) +
Laxminath Kasam82f136f2017-01-24 00:52:55 +05302919ARRAY_SIZE(msm_int_wsa_dai) +
2920ARRAY_SIZE(msm_int_be_dai) +
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002921ARRAY_SIZE(msm_mi2s_be_dai_links) +
2922ARRAY_SIZE(msm_auxpcm_be_dai_links)+
Laxminath Kasam82f136f2017-01-24 00:52:55 +05302923ARRAY_SIZE(msm_wcn_be_dai_links) +
Rohit Kumar0bd27132016-12-06 14:48:58 +05302924ARRAY_SIZE(msm_wsa_be_dai_links) +
2925ARRAY_SIZE(ext_disp_be_dai_link)];
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002926
Neeraj Upadhyay49934422016-12-27 19:03:35 +05302927static struct snd_soc_card sdm660_card = {
2928 /* snd_soc_card_sdm660 */
2929 .name = "sdm660-snd-card",
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002930 .dai_link = msm_int_dai,
2931 .num_links = ARRAY_SIZE(msm_int_dai),
2932};
2933
2934static void msm_disable_int_mclk0(struct work_struct *work)
2935{
2936 struct msm_asoc_mach_data *pdata = NULL;
2937 struct delayed_work *dwork;
2938 int ret = 0;
2939
2940 dwork = to_delayed_work(work);
2941 pdata = container_of(dwork, struct msm_asoc_mach_data,
2942 disable_int_mclk0_work);
2943 mutex_lock(&pdata->cdc_int_mclk0_mutex);
2944 pr_debug("%s: mclk_enabled %d mclk_rsc_ref %d\n", __func__,
2945 atomic_read(&pdata->int_mclk0_enabled),
2946 atomic_read(&pdata->int_mclk0_rsc_ref));
2947
2948 if (atomic_read(&pdata->int_mclk0_enabled) == true
2949 && atomic_read(&pdata->int_mclk0_rsc_ref) == 0) {
2950 pr_debug("Disable the mclk\n");
2951 pdata->digital_cdc_core_clk.enable = 0;
2952 ret = afe_set_lpass_clock_v2(
2953 AFE_PORT_ID_INT0_MI2S_RX,
2954 &pdata->digital_cdc_core_clk);
2955 if (ret < 0)
2956 pr_err("%s failed to disable the CCLK\n", __func__);
2957 atomic_set(&pdata->int_mclk0_enabled, false);
2958 }
2959 mutex_unlock(&pdata->cdc_int_mclk0_mutex);
2960}
2961
2962static void msm_int_dt_parse_cap_info(struct platform_device *pdev,
2963 struct msm_asoc_mach_data *pdata)
2964{
2965 const char *ext1_cap = "qcom,msm-micbias1-ext-cap";
2966 const char *ext2_cap = "qcom,msm-micbias2-ext-cap";
2967
2968 pdata->micbias1_cap_mode =
2969 (of_property_read_bool(pdev->dev.of_node, ext1_cap) ?
2970 MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);
2971
2972 pdata->micbias2_cap_mode =
2973 (of_property_read_bool(pdev->dev.of_node, ext2_cap) ?
2974 MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);
2975}
2976
2977static struct snd_soc_card *msm_int_populate_sndcard_dailinks(
2978 struct device *dev)
2979{
Neeraj Upadhyay49934422016-12-27 19:03:35 +05302980 struct snd_soc_card *card = &sdm660_card;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002981 struct snd_soc_dai_link *dailink;
2982 int len1;
2983
2984 card->name = dev_name(dev);
2985 len1 = ARRAY_SIZE(msm_int_dai);
2986 memcpy(msm_int_dai_links, msm_int_dai, sizeof(msm_int_dai));
2987 dailink = msm_int_dai_links;
Laxminath Kasam82f136f2017-01-24 00:52:55 +05302988 if (!of_property_read_bool(dev->of_node,
2989 "qcom,wsa-disable")) {
2990 memcpy(dailink + len1,
2991 msm_int_wsa_dai,
2992 sizeof(msm_int_wsa_dai));
2993 len1 += ARRAY_SIZE(msm_int_wsa_dai);
2994 }
2995 memcpy(dailink + len1, msm_int_be_dai, sizeof(msm_int_be_dai));
2996 len1 += ARRAY_SIZE(msm_int_be_dai);
2997
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002998 if (of_property_read_bool(dev->of_node,
2999 "qcom,mi2s-audio-intf")) {
3000 memcpy(dailink + len1,
3001 msm_mi2s_be_dai_links,
3002 sizeof(msm_mi2s_be_dai_links));
3003 len1 += ARRAY_SIZE(msm_mi2s_be_dai_links);
3004 }
3005 if (of_property_read_bool(dev->of_node,
3006 "qcom,auxpcm-audio-intf")) {
3007 memcpy(dailink + len1,
3008 msm_auxpcm_be_dai_links,
3009 sizeof(msm_auxpcm_be_dai_links));
3010 len1 += ARRAY_SIZE(msm_auxpcm_be_dai_links);
3011 }
3012 if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) {
3013 dev_dbg(dev, "%s(): WCN BTFM support present\n",
3014 __func__);
3015 memcpy(dailink + len1,
3016 msm_wcn_be_dai_links,
3017 sizeof(msm_wcn_be_dai_links));
3018 len1 += ARRAY_SIZE(msm_wcn_be_dai_links);
3019 }
Laxminath Kasam82f136f2017-01-24 00:52:55 +05303020 if (!of_property_read_bool(dev->of_node, "qcom,wsa-disable")) {
3021 memcpy(dailink + len1,
3022 msm_wsa_be_dai_links,
3023 sizeof(msm_wsa_be_dai_links));
3024 len1 += ARRAY_SIZE(msm_wsa_be_dai_links);
3025 }
Rohit Kumar0bd27132016-12-06 14:48:58 +05303026 if (of_property_read_bool(dev->of_node, "qcom,ext-disp-audio-rx")) {
3027 dev_dbg(dev, "%s(): ext disp audio support present\n",
3028 __func__);
3029 memcpy(dailink + len1,
3030 ext_disp_be_dai_link,
3031 sizeof(ext_disp_be_dai_link));
3032 len1 += ARRAY_SIZE(ext_disp_be_dai_link);
3033 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003034 card->dai_link = dailink;
3035 card->num_links = len1;
3036 return card;
3037}
3038
3039static int msm_internal_init(struct platform_device *pdev,
3040 struct msm_asoc_mach_data *pdata,
3041 struct snd_soc_card *card)
3042{
3043 const char *type = NULL;
3044 const char *hs_micbias_type = "qcom,msm-hs-micbias-type";
3045 int ret;
3046
3047 ret = is_ext_spk_gpio_support(pdev, pdata);
3048 if (ret < 0)
3049 dev_dbg(&pdev->dev,
3050 "%s: doesn't support external speaker pa\n",
3051 __func__);
3052
3053 ret = of_property_read_string(pdev->dev.of_node,
3054 hs_micbias_type, &type);
3055 if (ret) {
3056 dev_err(&pdev->dev, "%s: missing %s in dt node\n",
3057 __func__, hs_micbias_type);
3058 goto err;
3059 }
3060 if (!strcmp(type, "external")) {
3061 dev_dbg(&pdev->dev, "Headset is using external micbias\n");
3062 mbhc_cfg_ptr->hs_ext_micbias = true;
3063 } else {
3064 dev_dbg(&pdev->dev, "Headset is using internal micbias\n");
3065 mbhc_cfg_ptr->hs_ext_micbias = false;
3066 }
3067
3068 /* initialize the int_mclk0 */
3069 pdata->digital_cdc_core_clk.clk_set_minor_version =
3070 AFE_API_VERSION_I2S_CONFIG;
3071 pdata->digital_cdc_core_clk.clk_id =
3072 Q6AFE_LPASS_CLK_ID_INT_MCLK_0;
Tanya Dixit73a3a262016-12-08 22:25:56 +05303073 pdata->digital_cdc_core_clk.clk_freq_in_hz = pdata->mclk_freq;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003074 pdata->digital_cdc_core_clk.clk_attri =
3075 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO;
3076 pdata->digital_cdc_core_clk.clk_root =
3077 Q6AFE_LPASS_CLK_ROOT_DEFAULT;
3078 pdata->digital_cdc_core_clk.enable = 1;
3079
3080 /* Initialize loopback mode to false */
3081 pdata->lb_mode = false;
3082
3083 msm_int_dt_parse_cap_info(pdev, pdata);
3084
3085 card->dev = &pdev->dev;
3086 platform_set_drvdata(pdev, card);
3087 snd_soc_card_set_drvdata(card, pdata);
3088 ret = snd_soc_of_parse_card_name(card, "qcom,model");
3089 if (ret)
3090 goto err;
3091 /* initialize timer */
3092 INIT_DELAYED_WORK(&pdata->disable_int_mclk0_work,
3093 msm_disable_int_mclk0);
3094 mutex_init(&pdata->cdc_int_mclk0_mutex);
3095 atomic_set(&pdata->int_mclk0_rsc_ref, 0);
3096 atomic_set(&pdata->int_mclk0_enabled, false);
3097
3098 dev_info(&pdev->dev, "%s: default codec configured\n", __func__);
3099
3100 return 0;
3101err:
3102 return ret;
3103}
3104
3105/**
3106 * msm_int_cdc_init - internal codec machine specific init.
3107 *
3108 * @pdev: platform device handle
3109 * @pdata: private data of machine driver
3110 * @card: sound card pointer reference
3111 * @mbhc_cfg: MBHC config reference
3112 *
3113 * Returns 0.
3114 */
3115int msm_int_cdc_init(struct platform_device *pdev,
3116 struct msm_asoc_mach_data *pdata,
3117 struct snd_soc_card **card,
3118 struct wcd_mbhc_config *mbhc_cfg)
3119{
3120 mbhc_cfg_ptr = mbhc_cfg;
3121
3122 *card = msm_int_populate_sndcard_dailinks(&pdev->dev);
3123 msm_internal_init(pdev, pdata, *card);
3124 return 0;
3125}
3126EXPORT_SYMBOL(msm_int_cdc_init);