blob: f1998b44c5804b9cef9d7aef481a022a105257b5 [file] [log] [blame]
Xiaoyu Yee7df5cc2017-10-02 18:47:29 -07001/* Copyright (c) 2014-2018, 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/clk.h>
14#include <linux/delay.h>
15#include <linux/gpio.h>
16#include <linux/of_gpio.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19#include <linux/io.h>
20#include <linux/module.h>
21#include <linux/input.h>
22#include <linux/of_device.h>
23#include <sound/core.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/pcm.h>
27#include <sound/jack.h>
28#include <sound/pcm_params.h>
29#include <sound/info.h>
30#include <device_event.h>
31#include <dsp/audio_notifier.h>
32#include <dsp/q6afe-v2.h>
33#include <dsp/q6core.h>
34#include "msm-pcm-routing-v2.h"
35#include "codecs/msm-cdc-pinctrl.h"
36#include "codecs/wcd934x/wcd934x.h"
37#include "codecs/wcd934x/wcd934x-mbhc.h"
38#include "codecs/wsa881x.h"
39
40/* Machine driver Name */
41#define DRV_NAME "sdx-asoc-tavil"
42
43#define __CHIPSET__ "SDX "
44#define SDX_DAILINK_NAME(name) (__CHIPSET__#name)
45
46#define SAMPLE_RATE_8KHZ 8000
47#define SAMPLE_RATE_16KHZ 16000
48#define SAMPLE_RATE_48KHZ 48000
49#define NUM_OF_BITS_PER_SAMPLE 16
50#define DEV_NAME_STR_LEN 32
51
Karthikeyan Mani88373be2017-12-11 00:06:49 -080052#define LPAIF_OFFSET 0x01a00000
Xiaoyu Yee7df5cc2017-10-02 18:47:29 -070053#define LPAIF_PRI_MODE_MUXSEL (LPAIF_OFFSET + 0x2008)
54#define LPAIF_SEC_MODE_MUXSEL (LPAIF_OFFSET + 0x200c)
55#define LPASS_CSR_GP_IO_MUX_SPKR_CTL (LPAIF_OFFSET + 0x2004)
56#define LPASS_CSR_GP_IO_MUX_MIC_CTL (LPAIF_OFFSET + 0x2000)
57
58#define I2S_SEL 0
59#define PCM_SEL 1
60#define I2S_PCM_SEL_OFFSET 0
61#define I2S_PCM_MASTER_MODE 1
62#define I2S_PCM_SLAVE_MODE 0
63
64#define PRI_TLMM_CLKS_EN_MASTER 0x4
65#define SEC_TLMM_CLKS_EN_MASTER 0x2
66#define PRI_TLMM_CLKS_EN_SLAVE 0x100000
67#define SEC_TLMM_CLKS_EN_SLAVE 0x800000
68#define CLOCK_ON 1
69#define CLOCK_OFF 0
70
71#define WCD9XXX_MBHC_DEF_BUTTONS 8
72#define WCD9XXX_MBHC_DEF_RLOADS 5
73
74/* Spk control */
75#define SDX_SPK_ON 1
76#define SDX_HIFI_ON 1
77
78enum mi2s_types {
79 PRI_MI2S,
80 SEC_MI2S,
81};
82
83struct sdx_machine_data {
84 u32 mclk_freq;
85 u16 prim_mi2s_mode;
86 u16 sec_mi2s_mode;
87 u16 prim_auxpcm_mode;
88 struct device_node *prim_master_p;
89 struct device_node *prim_slave_p;
90 u16 sec_auxpcm_mode;
91 struct device_node *sec_master_p;
92 struct device_node *sec_slave_p;
93 u32 prim_clk_usrs;
94 int hph_en1_gpio;
95 int hph_en0_gpio;
96 struct snd_info_entry *codec_root;
97 void __iomem *lpaif_pri_muxsel_virt_addr;
98 void __iomem *lpaif_sec_muxsel_virt_addr;
99 void __iomem *lpass_mux_spkr_ctl_virt_addr;
100 void __iomem *lpass_mux_mic_ctl_virt_addr;
101};
102
103struct sdx_wsa881x_dev_info {
104 struct device_node *of_node;
105 u32 index;
106};
107
108static void *def_tavil_mbhc_cal(void);
109static void *adsp_state_notifier;
110static bool dummy_device_registered;
111
112static struct wcd_mbhc_config wcd_mbhc_cfg = {
113 .read_fw_bin = false,
114 .calibration = NULL,
115 .detect_extn_cable = true,
116 .mono_stero_detection = false,
117 .swap_gnd_mic = NULL,
118 .hs_ext_micbias = true,
119};
120
121static const struct afe_clk_set lpass_default_v2 = {
122 AFE_API_VERSION_I2S_CONFIG,
123 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
124 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
125 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
126 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
127 0,
128};
129
130static struct snd_soc_aux_dev *sdx_aux_dev;
131static struct snd_soc_codec_conf *sdx_codec_conf;
132
133static int sdx_auxpcm_rate = 8000;
134
135static struct mutex cdc_mclk_mutex;
136static int sdx_mi2s_rx_ch = 1;
137static int sdx_mi2s_tx_ch = 1;
138static int sdx_sec_mi2s_rx_ch = 1;
139static int sdx_sec_mi2s_tx_ch = 1;
140static int sdx_mi2s_rate = SAMPLE_RATE_48KHZ;
141static int sdx_sec_mi2s_rate = SAMPLE_RATE_48KHZ;
142
143static int sdx_mi2s_mode = I2S_PCM_MASTER_MODE;
144static int sdx_sec_mi2s_mode = I2S_PCM_MASTER_MODE;
145static int sdx_auxpcm_mode = I2S_PCM_MASTER_MODE;
146static int sdx_sec_auxpcm_mode = I2S_PCM_MASTER_MODE;
147
148static int sdx_spk_control = 1;
149static int sdx_hifi_control;
150static atomic_t mi2s_ref_count;
151static atomic_t sec_mi2s_ref_count;
152
153static int sdx_wsa881x_init(struct snd_soc_component *component)
154{
155 u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106};
156 u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107};
157 unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200};
158 unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3};
159 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
160 struct sdx_machine_data *pdata;
161 struct snd_soc_dapm_context *dapm;
162
163 if (!codec) {
164 pr_err("%s codec is NULL\n", __func__);
165 return -EINVAL;
166 }
167
168 dapm = snd_soc_codec_get_dapm(codec);
169
170 if (!strcmp(component->name_prefix, "SpkrLeft")) {
171 dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n",
172 __func__, codec->component.name);
173 wsa881x_set_channel_map(codec, &spkleft_ports[0],
174 WSA881X_MAX_SWR_PORTS, &ch_mask[0],
175 &ch_rate[0]);
176 if (dapm->component) {
177 snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN");
178 snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR");
179 }
180 } else if (!strcmp(component->name_prefix, "SpkrRight")) {
181 dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n",
182 __func__, codec->component.name);
183 wsa881x_set_channel_map(codec, &spkright_ports[0],
184 WSA881X_MAX_SWR_PORTS, &ch_mask[0],
185 &ch_rate[0]);
186 if (dapm->component) {
187 snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN");
188 snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR");
189 }
190 } else {
191 dev_err(codec->dev, "%s: wrong codec name %s\n", __func__,
192 codec->component.name);
193 return -EINVAL;
194 }
195 pdata = snd_soc_card_get_drvdata(component->card);
196 if (pdata && pdata->codec_root)
197 wsa881x_codec_info_create_codec_entry(pdata->codec_root,
198 codec);
199
200 return 0;
201}
202
203static int sdx_mi2s_clk_ctl(struct snd_soc_pcm_runtime *rtd, bool enable,
204 enum mi2s_types mi2s_type, int rate, u16 mode)
205{
206 struct snd_soc_card *card = rtd->card;
207 struct sdx_machine_data *pdata = snd_soc_card_get_drvdata(card);
208 struct afe_clk_set m_clk = lpass_default_v2;
209 struct afe_clk_set ibit_clk = lpass_default_v2;
210 u16 mi2s_port;
211 u16 ibit_clk_id;
212 int bit_clk_freq = (rate * 2 * NUM_OF_BITS_PER_SAMPLE);
213 int ret = 0;
214
215 dev_dbg(card->dev, "%s: setting lpass clock using v2\n", __func__);
216
217 if (pdata == NULL) {
218 dev_err(card->dev, "%s: platform data is null\n", __func__);
219 ret = -ENOMEM;
220 goto done;
221 }
222
223 if (mi2s_type == PRI_MI2S) {
224 mi2s_port = AFE_PORT_ID_PRIMARY_MI2S_RX;
225 ibit_clk_id = Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT;
226 } else {
227 mi2s_port = AFE_PORT_ID_SECONDARY_MI2S_RX;
228 ibit_clk_id = Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT;
229 }
230
231 /* Set both mclk and ibit clocks when using LPASS_CLK_VER_2 */
232 m_clk.clk_id = Q6AFE_LPASS_CLK_ID_MCLK_3;
233 m_clk.clk_freq_in_hz = pdata->mclk_freq;
234 m_clk.enable = enable;
235 ret = afe_set_lpass_clock_v2(mi2s_port, &m_clk);
236 if (ret < 0) {
237 dev_err(card->dev,
238 "%s: afe_set_lpass_clock_v2 failed for mclk_3 with ret %d\n",
239 __func__, ret);
240 goto done;
241 }
242
243 if (mode) {
244 ibit_clk.clk_id = ibit_clk_id;
245 ibit_clk.clk_freq_in_hz = bit_clk_freq;
246 ibit_clk.enable = enable;
247 ret = afe_set_lpass_clock_v2(mi2s_port, &ibit_clk);
248 if (ret < 0) {
249 dev_err(card->dev,
250 "%s: afe_set_lpass_clock_v2 failed for ibit with ret %d\n",
251 __func__, ret);
252 goto err_ibit_clk_set;
253 }
254 }
255 ret = 0;
256
257done:
258 return ret;
259
260err_ibit_clk_set:
261 m_clk.enable = false;
262 if (afe_set_lpass_clock_v2(mi2s_port, &m_clk))
263 dev_err(card->dev, "%s: afe_set_lpass_clock_v2 failed for mclk_3\n",
264 __func__);
265
266 return ret;
267}
268
269static void sdx_mi2s_shutdown(struct snd_pcm_substream *substream)
270{
271 struct snd_soc_pcm_runtime *rtd = substream->private_data;
272 int ret;
273 struct snd_soc_card *card = rtd->card;
274 struct sdx_machine_data *pdata = snd_soc_card_get_drvdata(card);
275
276 if (atomic_dec_return(&mi2s_ref_count) == 0) {
277 ret = sdx_mi2s_clk_ctl(rtd, false, PRI_MI2S, 0,
278 pdata->prim_mi2s_mode);
279 if (ret < 0)
280 pr_err("%s Clock disable failed\n", __func__);
281
282 if (pdata->prim_mi2s_mode == 1)
283 ret = msm_cdc_pinctrl_select_sleep_state
284 (pdata->prim_master_p);
285 else
286 ret = msm_cdc_pinctrl_select_sleep_state
287 (pdata->prim_slave_p);
288 if (ret)
289 pr_err("%s: failed to set pri gpios to sleep: %d\n",
290 __func__, ret);
291 }
292}
293
294static int sdx_mi2s_startup(struct snd_pcm_substream *substream)
295{
296 struct snd_soc_pcm_runtime *rtd = substream->private_data;
297 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
298 struct snd_soc_dai *codec_dai = rtd->codec_dai;
299 struct snd_soc_card *card = rtd->card;
300 struct sdx_machine_data *pdata = snd_soc_card_get_drvdata(card);
301 int ret = 0;
302
303 pdata->prim_mi2s_mode = sdx_mi2s_mode;
304 if (atomic_inc_return(&mi2s_ref_count) == 1) {
305 if (pdata->lpaif_pri_muxsel_virt_addr != NULL) {
306 ret = afe_enable_lpass_core_shared_clock(MI2S_RX,
307 CLOCK_ON);
308 if (ret < 0) {
309 ret = -EINVAL;
310 goto done;
311 }
312 iowrite32(I2S_SEL << I2S_PCM_SEL_OFFSET,
313 pdata->lpaif_pri_muxsel_virt_addr);
314 if (pdata->lpass_mux_spkr_ctl_virt_addr != NULL) {
315 if (pdata->prim_mi2s_mode == 1)
316 iowrite32(PRI_TLMM_CLKS_EN_MASTER,
317 pdata->lpass_mux_spkr_ctl_virt_addr);
318 else
319 iowrite32(PRI_TLMM_CLKS_EN_SLAVE,
320 pdata->lpass_mux_spkr_ctl_virt_addr);
321 } else {
322 dev_err(card->dev, "%s: mux spkr ctl virt addr is NULL\n",
323 __func__);
324
325 ret = -EINVAL;
326 goto err;
327 }
328 } else {
329 dev_err(card->dev, "%s lpaif_pri_muxsel_virt_addr is NULL\n",
330 __func__);
331
332 ret = -EINVAL;
333 goto done;
334 }
335 /*
336 * This sets the CONFIG PARAMETER WS_SRC.
337 * 1 means internal clock master mode.
338 * 0 means external clock slave mode.
339 */
340 if (pdata->prim_mi2s_mode == 1) {
341 ret = msm_cdc_pinctrl_select_active_state
342 (pdata->prim_master_p);
343 if (ret < 0) {
344 pr_err("%s pinctrl set failed\n", __func__);
345 goto err;
346 }
347 ret = sdx_mi2s_clk_ctl(rtd, true, PRI_MI2S,
348 sdx_mi2s_rate,
349 pdata->prim_mi2s_mode);
350 if (ret < 0) {
351 dev_err(card->dev, "%s clock enable failed\n",
352 __func__);
353 goto err;
354 }
355 ret = snd_soc_dai_set_fmt(cpu_dai,
356 SND_SOC_DAIFMT_CBS_CFS);
357 if (ret < 0) {
358 sdx_mi2s_clk_ctl(rtd, false, PRI_MI2S,
359 0, pdata->prim_mi2s_mode);
360 dev_err(card->dev,
361 "%s Set fmt for cpu dai failed\n",
362 __func__);
363 goto err;
364 }
365 ret = snd_soc_dai_set_fmt(codec_dai,
366 SND_SOC_DAIFMT_CBS_CFS);
367 if (ret < 0) {
368 sdx_mi2s_clk_ctl(rtd, false, PRI_MI2S,
369 0, pdata->prim_mi2s_mode);
370 dev_err(card->dev,
371 "%s Set fmt for codec dai failed\n",
372 __func__);
373 }
374 } else {
375 /*
376 * Disable bit clk in slave mode for QC codec.
377 * Enable only mclk.
378 */
379 ret = msm_cdc_pinctrl_select_active_state
380 (pdata->prim_slave_p);
381 if (ret < 0) {
382 pr_err("%s pinctrl set failed\n", __func__);
383 goto err;
384 }
385 ret = sdx_mi2s_clk_ctl(rtd, false, PRI_MI2S, 0,
386 pdata->prim_mi2s_mode);
387 if (ret < 0) {
388 dev_err(card->dev,
389 "%s clock enable failed\n", __func__);
390 goto err;
391 }
392 ret = snd_soc_dai_set_fmt(cpu_dai,
393 SND_SOC_DAIFMT_CBM_CFM);
394 if (ret < 0) {
395 dev_err(card->dev,
396 "%s Set fmt for cpu dai failed\n",
397 __func__);
398 goto err;
399 }
400 }
401err:
402 afe_enable_lpass_core_shared_clock(MI2S_RX, CLOCK_OFF);
403 }
404done:
405 if (ret)
406 atomic_dec_return(&mi2s_ref_count);
407 return ret;
408}
409
410static void sdx_sec_mi2s_shutdown(struct snd_pcm_substream *substream)
411{
412 struct snd_soc_pcm_runtime *rtd = substream->private_data;
413 int ret;
414 struct snd_soc_card *card = rtd->card;
415 struct sdx_machine_data *pdata = snd_soc_card_get_drvdata(card);
416
417 if (atomic_dec_return(&sec_mi2s_ref_count) == 0) {
418 ret = sdx_mi2s_clk_ctl(rtd, false, SEC_MI2S,
419 0, pdata->sec_mi2s_mode);
420 if (ret < 0)
421 pr_err("%s Clock disable failed\n", __func__);
422
423 if (pdata->sec_mi2s_mode == 1)
424 ret = msm_cdc_pinctrl_select_sleep_state
425 (pdata->sec_master_p);
426 else
427 ret = msm_cdc_pinctrl_select_sleep_state
428 (pdata->sec_slave_p);
429 if (ret)
430 pr_err("%s: failed to set sec gpios to sleep: %d\n",
431 __func__, ret);
432 }
433}
434
435static int sdx_sec_mi2s_startup(struct snd_pcm_substream *substream)
436{
437 struct snd_soc_pcm_runtime *rtd = substream->private_data;
438 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
439 struct snd_soc_card *card = rtd->card;
440 struct sdx_machine_data *pdata = snd_soc_card_get_drvdata(card);
441 int ret = 0;
442
443 pdata->sec_mi2s_mode = sdx_sec_mi2s_mode;
444 if (atomic_inc_return(&sec_mi2s_ref_count) == 1) {
445 if (pdata->lpaif_sec_muxsel_virt_addr != NULL) {
446 ret = afe_enable_lpass_core_shared_clock(
447 SECONDARY_I2S_RX, CLOCK_ON);
448 if (ret < 0) {
449 ret = -EINVAL;
450 goto done;
451 }
452 iowrite32(I2S_SEL << I2S_PCM_SEL_OFFSET,
453 pdata->lpaif_sec_muxsel_virt_addr);
454
455 if (pdata->lpass_mux_mic_ctl_virt_addr != NULL) {
456 if (pdata->sec_mi2s_mode == 1)
457 iowrite32(SEC_TLMM_CLKS_EN_MASTER,
458 pdata->lpass_mux_mic_ctl_virt_addr);
459 else
460 iowrite32(SEC_TLMM_CLKS_EN_SLAVE,
461 pdata->lpass_mux_mic_ctl_virt_addr);
462 } else {
463 dev_err(card->dev,
464 "%s: mux spkr ctl virt addr is NULL\n",
465 __func__);
466 ret = -EINVAL;
467 goto err;
468 }
469 } else {
470 dev_err(card->dev, "%s lpaif_sec_muxsel_virt_addr is NULL\n",
471 __func__);
472 ret = -EINVAL;
473 goto done;
474 }
475 /*
476 * This sets the CONFIG PARAMETER WS_SRC.
477 * 1 means internal clock master mode.
478 * 0 means external clock slave mode.
479 */
480 if (pdata->sec_mi2s_mode == 1) {
481 ret = msm_cdc_pinctrl_select_active_state
482 (pdata->sec_master_p);
483 if (ret < 0) {
484 pr_err("%s pinctrl set failed\n", __func__);
485 goto err;
486 }
487 ret = sdx_mi2s_clk_ctl(rtd, true, SEC_MI2S,
488 sdx_sec_mi2s_rate,
489 pdata->sec_mi2s_mode);
490 if (ret < 0) {
491 dev_err(card->dev, "%s clock enable failed\n",
492 __func__);
493 goto err;
494 }
495 ret = snd_soc_dai_set_fmt(cpu_dai,
496 SND_SOC_DAIFMT_CBS_CFS);
497 if (ret < 0) {
498 ret = sdx_mi2s_clk_ctl(rtd, false, SEC_MI2S,
499 0,
500 pdata->sec_mi2s_mode);
501 dev_err(card->dev, "%s Set fmt for cpu dai failed\n",
502 __func__);
503 }
504 } else {
505 /*
506 * Enable mclk here, if needed for external codecs.
507 * Optional. Refer primary mi2s slave interface.
508 */
509 ret = msm_cdc_pinctrl_select_active_state
510 (pdata->sec_slave_p);
511 if (ret < 0) {
512 pr_err("%s pinctrl set failed\n", __func__);
513 goto err;
514 }
515 ret = sdx_mi2s_clk_ctl(rtd, false, SEC_MI2S, 0,
516 pdata->sec_mi2s_mode);
517 if (ret < 0) {
518 dev_err(card->dev,
519 "%s clock enable failed\n", __func__);
520 goto err;
521 }
522 ret = snd_soc_dai_set_fmt(cpu_dai,
523 SND_SOC_DAIFMT_CBM_CFM);
524 if (ret < 0)
525 dev_err(card->dev, "%s Set fmt for cpu dai failed\n",
526 __func__);
527 }
528err:
529 afe_enable_lpass_core_shared_clock(SECONDARY_I2S_RX,
530 CLOCK_OFF);
531 }
532done:
533 if (ret)
534 atomic_dec_return(&sec_mi2s_ref_count);
535 return ret;
536}
537
538static struct snd_soc_ops sdx_mi2s_be_ops = {
539 .startup = sdx_mi2s_startup,
540 .shutdown = sdx_mi2s_shutdown,
541};
542
543static struct snd_soc_ops sdx_sec_mi2s_be_ops = {
544 .startup = sdx_sec_mi2s_startup,
545 .shutdown = sdx_sec_mi2s_shutdown,
546};
547
548static int sdx_mi2s_rate_get(struct snd_kcontrol *kcontrol,
549 struct snd_ctl_elem_value *ucontrol)
550{
551 pr_debug("%s: sdx_i2s_rate = %d", __func__, sdx_mi2s_rate);
552 ucontrol->value.integer.value[0] = sdx_mi2s_rate;
553 return 0;
554}
555
556static int sdx_sec_mi2s_rate_get(struct snd_kcontrol *kcontrol,
557 struct snd_ctl_elem_value *ucontrol)
558{
559 pr_debug("%s: sdx_sec_i2s_rate = %d", __func__, sdx_sec_mi2s_rate);
560 ucontrol->value.integer.value[0] = sdx_sec_mi2s_rate;
561 return 0;
562}
563
564static int sdx_mi2s_rate_put(struct snd_kcontrol *kcontrol,
565 struct snd_ctl_elem_value *ucontrol)
566{
567 switch (ucontrol->value.integer.value[0]) {
568 case 0:
569 sdx_mi2s_rate = SAMPLE_RATE_8KHZ;
570 break;
571 case 1:
572 sdx_mi2s_rate = SAMPLE_RATE_16KHZ;
573 break;
574 case 2:
575 default:
576 sdx_mi2s_rate = SAMPLE_RATE_48KHZ;
577 break;
578 }
579 pr_debug("%s: sdx_i2s_rate = %d ucontrol->value = %d\n",
580 __func__, sdx_mi2s_rate,
581 (int)ucontrol->value.integer.value[0]);
582 return 0;
583}
584
585static int sdx_sec_mi2s_rate_put(struct snd_kcontrol *kcontrol,
586 struct snd_ctl_elem_value *ucontrol)
587{
588 switch (ucontrol->value.integer.value[0]) {
589 case 0:
590 sdx_sec_mi2s_rate = SAMPLE_RATE_8KHZ;
591 break;
592 case 1:
593 sdx_sec_mi2s_rate = SAMPLE_RATE_16KHZ;
594 break;
595 case 2:
596 default:
597 sdx_sec_mi2s_rate = SAMPLE_RATE_48KHZ;
598 break;
599 }
600 pr_debug("%s: sdx_sec_mi2s_rate = %d ucontrol->value = %d\n",
601 __func__, sdx_sec_mi2s_rate,
602 (int)ucontrol->value.integer.value[0]);
603 return 0;
604}
605
606static void param_set_mask(struct snd_pcm_hw_params *p, int n,
607 unsigned int bit)
608{
609 struct snd_mask *m = NULL;
610
611 if (bit >= SNDRV_MASK_MAX)
612 return;
613 if ((n >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
614 (n <= SNDRV_PCM_HW_PARAM_LAST_MASK)) {
615 m = &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
616
617 m->bits[0] = 0;
618 m->bits[1] = 0;
619 m->bits[bit >> 5] |= (1 << (bit & 31));
620 }
621}
622
623static int sdx_mi2s_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rt,
624 struct snd_pcm_hw_params *params)
625{
626 struct snd_interval *rate = hw_param_interval(params,
627 SNDRV_PCM_HW_PARAM_RATE);
628 struct snd_interval *channels = hw_param_interval(params,
629 SNDRV_PCM_HW_PARAM_CHANNELS);
630 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
631 SNDRV_PCM_FORMAT_S16_LE);
632 rate->min = rate->max = sdx_mi2s_rate;
633 channels->min = channels->max = sdx_mi2s_rx_ch;
634 return 0;
635}
636
637static int sdx_sec_mi2s_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rt,
638 struct snd_pcm_hw_params *params)
639{
640 struct snd_interval *rate = hw_param_interval(params,
641 SNDRV_PCM_HW_PARAM_RATE);
642 struct snd_interval *channels = hw_param_interval(params,
643 SNDRV_PCM_HW_PARAM_CHANNELS);
644 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
645 SNDRV_PCM_FORMAT_S16_LE);
646 rate->min = rate->max = sdx_sec_mi2s_rate;
647 channels->min = channels->max = sdx_sec_mi2s_rx_ch;
648 return 0;
649}
650
651static int sdx_mi2s_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rt,
652 struct snd_pcm_hw_params *params)
653{
654 struct snd_interval *rate = hw_param_interval(params,
655 SNDRV_PCM_HW_PARAM_RATE);
656 struct snd_interval *channels = hw_param_interval(params,
657 SNDRV_PCM_HW_PARAM_CHANNELS);
658 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
659 SNDRV_PCM_FORMAT_S16_LE);
660 rate->min = rate->max = sdx_mi2s_rate;
661 channels->min = channels->max = sdx_mi2s_tx_ch;
662 return 0;
663}
664
665static int sdx_sec_mi2s_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rt,
666 struct snd_pcm_hw_params *params)
667{
668 struct snd_interval *rate = hw_param_interval(params,
669 SNDRV_PCM_HW_PARAM_RATE);
670 struct snd_interval *channels = hw_param_interval(params,
671 SNDRV_PCM_HW_PARAM_CHANNELS);
672 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
673 SNDRV_PCM_FORMAT_S16_LE);
674 rate->min = rate->max = sdx_sec_mi2s_rate;
675 channels->min = channels->max = sdx_sec_mi2s_tx_ch;
676 return 0;
677}
678
679static int sdx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rt,
680 struct snd_pcm_hw_params *params)
681{
682 struct snd_interval *rate = hw_param_interval(params,
683 SNDRV_PCM_HW_PARAM_RATE);
684 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
685 SNDRV_PCM_FORMAT_S16_LE);
686 rate->min = rate->max = sdx_mi2s_rate;
687 return 0;
688}
689
690static int sdx_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol,
691 struct snd_ctl_elem_value *ucontrol)
692{
693 pr_debug("%s sdx_mi2s_rx_ch %d\n", __func__, sdx_mi2s_rx_ch);
694 ucontrol->value.integer.value[0] = sdx_mi2s_rx_ch - 1;
695 return 0;
696}
697
698static int sdx_sec_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol,
699 struct snd_ctl_elem_value *ucontrol)
700{
701 pr_debug("%s sdx_sec_mi2s_rx_ch %d\n", __func__, sdx_mi2s_rx_ch);
702 ucontrol->value.integer.value[0] = sdx_sec_mi2s_rx_ch - 1;
703 return 0;
704}
705
706static int sdx_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol,
707 struct snd_ctl_elem_value *ucontrol)
708{
709 sdx_mi2s_rx_ch = ucontrol->value.integer.value[0] + 1;
710 pr_debug("%s sdx_mi2s_rx_ch %d\n", __func__, sdx_mi2s_rx_ch);
711 return 1;
712}
713
714static int sdx_sec_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol,
715 struct snd_ctl_elem_value *ucontrol)
716{
717 sdx_mi2s_rx_ch = ucontrol->value.integer.value[0] + 1;
718 pr_debug("%s sdx_sec_mi2s_rx_ch %d\n", __func__, sdx_sec_mi2s_rx_ch);
719 return 1;
720}
721
722static int sdx_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol,
723 struct snd_ctl_elem_value *ucontrol)
724{
725 pr_debug("%s sdx_mi2s_tx_ch %d\n", __func__, sdx_mi2s_tx_ch);
726 ucontrol->value.integer.value[0] = sdx_mi2s_tx_ch - 1;
727 return 0;
728}
729
730static int sdx_sec_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol,
731 struct snd_ctl_elem_value *ucontrol)
732{
733 pr_debug("%s sdx_sec_mi2s_tx_ch %d\n", __func__, sdx_mi2s_tx_ch);
734 ucontrol->value.integer.value[0] = sdx_sec_mi2s_tx_ch - 1;
735 return 0;
736}
737
738static int sdx_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol,
739 struct snd_ctl_elem_value *ucontrol)
740{
741 sdx_mi2s_tx_ch = ucontrol->value.integer.value[0] + 1;
742 pr_debug("%s sdx_mi2s_tx_ch %d\n", __func__, sdx_mi2s_tx_ch);
743 return 1;
744}
745
746static int sdx_sec_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol,
747 struct snd_ctl_elem_value *ucontrol)
748{
749 sdx_mi2s_tx_ch = ucontrol->value.integer.value[0] + 1;
750 pr_debug("%s sdx_sec_mi2s_tx_ch %d\n", __func__, sdx_sec_mi2s_tx_ch);
751 return 1;
752}
753
754static int sdx_mi2s_mode_get(struct snd_kcontrol *kcontrol,
755 struct snd_ctl_elem_value *ucontrol)
756{
757 pr_debug("%s sdx_mi2s_mode %d\n", __func__, sdx_mi2s_mode);
758 ucontrol->value.integer.value[0] = sdx_mi2s_mode;
759 return 0;
760}
761
762static int sdx_mi2s_mode_put(struct snd_kcontrol *kcontrol,
763 struct snd_ctl_elem_value *ucontrol)
764{
765 switch (ucontrol->value.integer.value[0]) {
766 case 0:
767 sdx_mi2s_mode = I2S_PCM_MASTER_MODE;
768 break;
769 case 1:
770 sdx_mi2s_mode = I2S_PCM_SLAVE_MODE;
771 break;
772 default:
773 sdx_mi2s_mode = I2S_PCM_MASTER_MODE;
774 break;
775 }
776 pr_debug("%s: sdx_mi2s_mode = %d ucontrol->value = %d\n",
777 __func__, sdx_mi2s_mode,
778 (int)ucontrol->value.integer.value[0]);
779 return 0;
780}
781
782static int sdx_sec_mi2s_mode_get(struct snd_kcontrol *kcontrol,
783 struct snd_ctl_elem_value *ucontrol)
784{
785 pr_debug("%s sdx_sec_mi2s_mode %d\n", __func__, sdx_sec_mi2s_mode);
786 ucontrol->value.integer.value[0] = sdx_sec_mi2s_mode;
787 return 0;
788}
789
790static int sdx_sec_mi2s_mode_put(struct snd_kcontrol *kcontrol,
791 struct snd_ctl_elem_value *ucontrol)
792{
793 switch (ucontrol->value.integer.value[0]) {
794 case 0:
795 sdx_sec_mi2s_mode = I2S_PCM_MASTER_MODE;
796 break;
797 case 1:
798 sdx_sec_mi2s_mode = I2S_PCM_SLAVE_MODE;
799 break;
800 default:
801 sdx_sec_mi2s_mode = I2S_PCM_MASTER_MODE;
802 break;
803 }
804 pr_debug("%s: sdx_sec_mi2s_mode = %d ucontrol->value = %d\n",
805 __func__, sdx_sec_mi2s_mode,
806 (int)ucontrol->value.integer.value[0]);
807 return 0;
808}
809
810static int sdx_auxpcm_mode_get(struct snd_kcontrol *kcontrol,
811 struct snd_ctl_elem_value *ucontrol)
812{
813 pr_debug("%s sdx_auxpcm_mode %d\n", __func__, sdx_auxpcm_mode);
814 ucontrol->value.integer.value[0] = sdx_auxpcm_mode;
815 return 0;
816}
817
818static int sdx_auxpcm_mode_put(struct snd_kcontrol *kcontrol,
819 struct snd_ctl_elem_value *ucontrol)
820{
821 switch (ucontrol->value.integer.value[0]) {
822 case 0:
823 sdx_auxpcm_mode = I2S_PCM_MASTER_MODE;
824 break;
825 case 1:
826 sdx_auxpcm_mode = I2S_PCM_SLAVE_MODE;
827 break;
828 default:
829 sdx_auxpcm_mode = I2S_PCM_MASTER_MODE;
830 break;
831 }
832 pr_debug("%s: sdx_auxpcm_mode = %d ucontrol->value = %d\n",
833 __func__, sdx_auxpcm_mode,
834 (int)ucontrol->value.integer.value[0]);
835 return 0;
836}
837
838static int sdx_sec_auxpcm_mode_get(struct snd_kcontrol *kcontrol,
839 struct snd_ctl_elem_value *ucontrol)
840{
841 pr_debug("%s sdx_sec_auxpcm_mode %d\n", __func__, sdx_sec_auxpcm_mode);
842 ucontrol->value.integer.value[0] = sdx_sec_auxpcm_mode;
843 return 0;
844}
845
846static int sdx_sec_auxpcm_mode_put(struct snd_kcontrol *kcontrol,
847 struct snd_ctl_elem_value *ucontrol)
848{
849 switch (ucontrol->value.integer.value[0]) {
850 case 0:
851 sdx_sec_auxpcm_mode = I2S_PCM_MASTER_MODE;
852 break;
853 case 1:
854 sdx_sec_auxpcm_mode = I2S_PCM_SLAVE_MODE;
855 break;
856 default:
857 sdx_sec_auxpcm_mode = I2S_PCM_MASTER_MODE;
858 break;
859 }
860 pr_debug("%s: sdx_sec_auxpcm_mode = %d ucontrol->value = %d\n",
861 __func__, sdx_sec_auxpcm_mode,
862 (int)ucontrol->value.integer.value[0]);
863 return 0;
864}
865
866static int sdx_mi2s_get_spk(struct snd_kcontrol *kcontrol,
867 struct snd_ctl_elem_value *ucontrol)
868{
869 pr_debug("%s sdx_spk_control %d", __func__, sdx_spk_control);
870 ucontrol->value.integer.value[0] = sdx_spk_control;
871 return 0;
872}
873
874static void sdx_ext_control(struct snd_soc_codec *codec)
875{
876 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
877
878 pr_debug("%s sdx_spk_control %d", __func__, sdx_spk_control);
879
880 if (sdx_spk_control == SDX_SPK_ON) {
881 snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp");
882 snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp");
883 } else {
884 snd_soc_dapm_disable_pin(dapm, "Lineout_1 amp");
885 snd_soc_dapm_disable_pin(dapm, "Lineout_2 amp");
886 }
887 snd_soc_dapm_sync(dapm);
888}
889
890static int sdx_mi2s_set_spk(struct snd_kcontrol *kcontrol,
891 struct snd_ctl_elem_value *ucontrol)
892{
893 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
894
895 pr_debug("%s()\n", __func__);
896
897 if (sdx_spk_control == ucontrol->value.integer.value[0])
898 return 0;
899 sdx_spk_control = ucontrol->value.integer.value[0];
900 sdx_ext_control(codec);
901 return 1;
902}
903
904static int sdx_hifi_ctrl(struct snd_soc_codec *codec)
905{
906 struct snd_soc_dapm_context *dapm =
907 snd_soc_codec_get_dapm(codec);
908 struct snd_soc_card *card = codec->component.card;
909 struct sdx_machine_data *pdata =
910 snd_soc_card_get_drvdata(card);
911
912 pr_debug("%s: sdx_hifi_control = %d", __func__, sdx_hifi_control);
913 if (pdata->hph_en1_gpio < 0) {
914 pr_err("%s: hph_en1_gpio is invalid\n", __func__);
915 return -EINVAL;
916 }
917
918 if (sdx_hifi_control == SDX_HIFI_ON) {
919 gpio_direction_output(pdata->hph_en1_gpio, 1);
920 /* 5msec delay needed as per HW requirement */
921 usleep_range(5000, 5010);
922 } else
923 gpio_direction_output(pdata->hph_en1_gpio, 0);
924
925 snd_soc_dapm_sync(dapm);
926 return 0;
927}
928
929static int sdx_hifi_get(struct snd_kcontrol *kcontrol,
930 struct snd_ctl_elem_value *ucontrol)
931{
932 pr_debug("%s: sdx_hifi_control = %d\n",
933 __func__, sdx_hifi_control);
934 ucontrol->value.integer.value[0] = sdx_hifi_control;
935 return 0;
936}
937
938static int sdx_hifi_put(struct snd_kcontrol *kcontrol,
939 struct snd_ctl_elem_value *ucontrol)
940{
941 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
942
943 pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n",
944 __func__, ucontrol->value.integer.value[0]);
945 sdx_hifi_control = ucontrol->value.integer.value[0];
946 sdx_hifi_ctrl(codec);
947 return 1;
948}
949
950static int sdx_mclk_event(struct snd_soc_dapm_widget *w,
951 struct snd_kcontrol *kcontrol, int event)
952{
953 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
954
955 pr_debug("%s event %d\n", __func__, event);
956
957 switch (event) {
958 case SND_SOC_DAPM_PRE_PMU:
959 tavil_cdc_mclk_enable(codec, 1);
960 break;
961 case SND_SOC_DAPM_POST_PMD:
962 tavil_cdc_mclk_enable(codec, 0);
963 break;
964 }
965 return 0;
966}
967
968static void sdx_auxpcm_shutdown(struct snd_pcm_substream *substream)
969{
970 struct snd_soc_pcm_runtime *rtd = substream->private_data;
971 int ret;
972 struct snd_soc_card *card = rtd->card;
973 struct sdx_machine_data *pdata = snd_soc_card_get_drvdata(card);
974
975 if (pdata->prim_auxpcm_mode == 1)
976 ret = msm_cdc_pinctrl_select_sleep_state(pdata->prim_master_p);
977 else
978 ret = msm_cdc_pinctrl_select_sleep_state(pdata->prim_slave_p);
979 if (ret)
980 pr_err("%s: failed to set prim gpios to sleep: %d\n",
981 __func__, ret);
982}
983
984static int sdx_auxpcm_startup(struct snd_pcm_substream *substream)
985{
986 int ret = 0;
987 struct snd_soc_pcm_runtime *rtd = substream->private_data;
988 struct snd_soc_card *card = rtd->card;
989 struct sdx_machine_data *pdata = snd_soc_card_get_drvdata(card);
990
991 pdata->prim_auxpcm_mode = sdx_auxpcm_mode;
992 if (pdata->lpaif_pri_muxsel_virt_addr != NULL) {
993 ret = afe_enable_lpass_core_shared_clock(MI2S_RX, CLOCK_ON);
994 if (ret < 0) {
995 ret = -EINVAL;
996 goto done;
997 }
998 iowrite32(PCM_SEL << I2S_PCM_SEL_OFFSET,
999 pdata->lpaif_pri_muxsel_virt_addr);
1000 if (pdata->lpass_mux_spkr_ctl_virt_addr != NULL) {
1001 if (pdata->prim_auxpcm_mode == 1)
1002 iowrite32(PRI_TLMM_CLKS_EN_MASTER,
1003 pdata->lpass_mux_spkr_ctl_virt_addr);
1004 else
1005 iowrite32(PRI_TLMM_CLKS_EN_SLAVE,
1006 pdata->lpass_mux_spkr_ctl_virt_addr);
1007 } else {
1008 dev_err(card->dev, "%s lpass_mux_spkr_ctl_virt_addr is NULL\n",
1009 __func__);
1010 ret = -EINVAL;
1011 }
1012 } else {
1013 dev_err(card->dev, "%s lpaif_pri_muxsel_virt_addr is NULL\n",
1014 __func__);
1015 ret = -EINVAL;
1016 goto done;
1017 }
1018
1019 if (pdata->prim_auxpcm_mode == 1) {
1020 ret = msm_cdc_pinctrl_select_active_state
1021 (pdata->prim_master_p);
1022 if (ret < 0)
1023 pr_err("%s pinctrl set failed\n", __func__);
1024 } else {
1025 ret = msm_cdc_pinctrl_select_active_state(pdata->prim_slave_p);
1026 if (ret < 0)
1027 pr_err("%s pinctrl set failed\n", __func__);
1028 }
1029 afe_enable_lpass_core_shared_clock(MI2S_RX, CLOCK_OFF);
1030done:
1031 return ret;
1032}
1033
1034static struct snd_soc_ops sdx_auxpcm_be_ops = {
1035 .startup = sdx_auxpcm_startup,
1036 .shutdown = sdx_auxpcm_shutdown,
1037};
1038
1039static void sdx_sec_auxpcm_shutdown(struct snd_pcm_substream *substream)
1040{
1041 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1042 int ret;
1043 struct snd_soc_card *card = rtd->card;
1044 struct sdx_machine_data *pdata = snd_soc_card_get_drvdata(card);
1045
1046 if (pdata->sec_auxpcm_mode == 1)
1047 ret = msm_cdc_pinctrl_select_sleep_state(pdata->sec_master_p);
1048 else
1049 ret = msm_cdc_pinctrl_select_sleep_state(pdata->sec_slave_p);
1050 if (ret)
1051 pr_err("%s: failed to set sec gpios to sleep: %d\n",
1052 __func__, ret);
1053}
1054
1055static int sdx_sec_auxpcm_startup(struct snd_pcm_substream *substream)
1056{
1057 int ret = 0;
1058 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1059 struct snd_soc_card *card = rtd->card;
1060 struct sdx_machine_data *pdata = snd_soc_card_get_drvdata(card);
1061
1062 pdata->sec_auxpcm_mode = sdx_sec_auxpcm_mode;
1063 if (pdata->lpaif_sec_muxsel_virt_addr != NULL) {
1064 ret = afe_enable_lpass_core_shared_clock(MI2S_RX, CLOCK_ON);
1065 if (ret < 0) {
1066 ret = -EINVAL;
1067 goto done;
1068 }
1069 iowrite32(PCM_SEL << I2S_PCM_SEL_OFFSET,
1070 pdata->lpaif_sec_muxsel_virt_addr);
1071 if (pdata->lpass_mux_mic_ctl_virt_addr != NULL) {
1072 if (pdata->sec_auxpcm_mode == 1)
1073 iowrite32(SEC_TLMM_CLKS_EN_MASTER,
1074 pdata->lpass_mux_mic_ctl_virt_addr);
1075 else
1076 iowrite32(SEC_TLMM_CLKS_EN_SLAVE,
1077 pdata->lpass_mux_mic_ctl_virt_addr);
1078 } else {
1079 dev_err(card->dev,
1080 "%s lpass_mux_mic_ctl_virt_addr is NULL\n",
1081 __func__);
1082 ret = -EINVAL;
1083 }
1084 } else {
1085 dev_err(card->dev,
1086 "%s lpaif_sec_muxsel_virt_addr is NULL\n", __func__);
1087 ret = -EINVAL;
1088 goto done;
1089 }
1090
1091 if (pdata->sec_auxpcm_mode == 1) {
1092 ret = msm_cdc_pinctrl_select_active_state(pdata->sec_master_p);
1093 if (ret < 0)
1094 pr_err("%s pinctrl set failed\n", __func__);
1095 } else {
1096 ret = msm_cdc_pinctrl_select_active_state(pdata->sec_slave_p);
1097 if (ret < 0)
1098 pr_err("%s pinctrl set failed\n", __func__);
1099 }
1100 afe_enable_lpass_core_shared_clock(MI2S_RX, CLOCK_OFF);
1101done:
1102 return ret;
1103}
1104
1105static struct snd_soc_ops sdx_sec_auxpcm_be_ops = {
1106 .startup = sdx_sec_auxpcm_startup,
1107 .shutdown = sdx_sec_auxpcm_shutdown,
1108};
1109
1110static int sdx_auxpcm_rate_get(struct snd_kcontrol *kcontrol,
1111 struct snd_ctl_elem_value *ucontrol)
1112{
1113 ucontrol->value.integer.value[0] = sdx_auxpcm_rate;
1114 return 0;
1115}
1116
1117static int sdx_auxpcm_rate_put(struct snd_kcontrol *kcontrol,
1118 struct snd_ctl_elem_value *ucontrol)
1119{
1120 switch (ucontrol->value.integer.value[0]) {
1121 case 1:
1122 sdx_auxpcm_rate = 16000;
1123 break;
1124 case 0:
1125 default:
1126 sdx_auxpcm_rate = 8000;
1127 break;
1128 }
1129 return 0;
1130}
1131
1132static int sdx_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
1133 struct snd_pcm_hw_params *params)
1134{
1135 struct snd_interval *rate =
1136 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
1137
1138 struct snd_interval *channels =
1139 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
1140
1141 rate->min = rate->max = sdx_auxpcm_rate;
1142 channels->min = channels->max = 1;
1143
1144 return 0;
1145}
1146
1147static const struct snd_soc_dapm_widget sdx_dapm_widgets[] = {
1148
1149 SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
1150 sdx_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1151
1152 SND_SOC_DAPM_SPK("Lineout_1 amp", NULL),
1153 SND_SOC_DAPM_SPK("Lineout_3 amp", NULL),
1154 SND_SOC_DAPM_SPK("Lineout_2 amp", NULL),
1155 SND_SOC_DAPM_SPK("Lineout_4 amp", NULL),
1156 SND_SOC_DAPM_MIC("Handset Mic", NULL),
1157 SND_SOC_DAPM_MIC("Headset Mic", NULL),
1158 SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL),
1159 SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL),
1160 SND_SOC_DAPM_MIC("Analog Mic4", NULL),
1161 SND_SOC_DAPM_MIC("Analog Mic6", NULL),
1162 SND_SOC_DAPM_MIC("Analog Mic7", NULL),
1163 SND_SOC_DAPM_MIC("Analog Mic8", NULL),
1164
1165 SND_SOC_DAPM_MIC("Digital Mic1", NULL),
1166 SND_SOC_DAPM_MIC("Digital Mic2", NULL),
1167 SND_SOC_DAPM_MIC("Digital Mic3", NULL),
1168 SND_SOC_DAPM_MIC("Digital Mic4", NULL),
1169 SND_SOC_DAPM_MIC("Digital Mic5", NULL),
1170 SND_SOC_DAPM_MIC("Digital Mic6", NULL),
1171};
1172
1173static struct snd_soc_dapm_route wcd_audio_paths[] = {
1174 {"MIC BIAS1", NULL, "MCLK"},
1175 {"MIC BIAS2", NULL, "MCLK"},
1176 {"MIC BIAS3", NULL, "MCLK"},
1177 {"MIC BIAS4", NULL, "MCLK"},
1178};
1179
1180static const char *const spk_function[] = {"Off", "On"};
1181static const char *const hifi_function[] = {"Off", "On"};
1182static const char *const mi2s_rx_ch_text[] = {"One", "Two"};
1183static const char *const mi2s_tx_ch_text[] = {"One", "Two"};
1184static const char *const auxpcm_rate_text[] = {"rate_8000", "rate_16000"};
1185
1186static const char *const mi2s_rate_text[] = {"rate_8000",
1187 "rate_16000", "rate_48000"};
1188static const char *const mode_text[] = {"master", "slave"};
1189
1190static const struct soc_enum sdx_enum[] = {
1191 SOC_ENUM_SINGLE_EXT(2, spk_function),
1192 SOC_ENUM_SINGLE_EXT(2, mi2s_rx_ch_text),
1193 SOC_ENUM_SINGLE_EXT(2, mi2s_tx_ch_text),
1194 SOC_ENUM_SINGLE_EXT(2, auxpcm_rate_text),
1195 SOC_ENUM_SINGLE_EXT(3, mi2s_rate_text),
1196 SOC_ENUM_SINGLE_EXT(2, hifi_function),
1197 SOC_ENUM_SINGLE_EXT(2, mode_text),
1198};
1199
1200static const struct snd_kcontrol_new sdx_snd_controls[] = {
1201 SOC_ENUM_EXT("Speaker Function", sdx_enum[0],
1202 sdx_mi2s_get_spk,
1203 sdx_mi2s_set_spk),
1204 SOC_ENUM_EXT("MI2S_RX Channels", sdx_enum[1],
1205 sdx_mi2s_rx_ch_get,
1206 sdx_mi2s_rx_ch_put),
1207 SOC_ENUM_EXT("MI2S_TX Channels", sdx_enum[2],
1208 sdx_mi2s_tx_ch_get,
1209 sdx_mi2s_tx_ch_put),
1210 SOC_ENUM_EXT("AUX PCM SampleRate", sdx_enum[3],
1211 sdx_auxpcm_rate_get,
1212 sdx_auxpcm_rate_put),
1213 SOC_ENUM_EXT("MI2S SampleRate", sdx_enum[4],
1214 sdx_mi2s_rate_get,
1215 sdx_mi2s_rate_put),
1216 SOC_ENUM_EXT("SEC_MI2S_RX Channels", sdx_enum[1],
1217 sdx_sec_mi2s_rx_ch_get,
1218 sdx_sec_mi2s_rx_ch_put),
1219 SOC_ENUM_EXT("SEC_MI2S_TX Channels", sdx_enum[2],
1220 sdx_sec_mi2s_tx_ch_get,
1221 sdx_sec_mi2s_tx_ch_put),
1222 SOC_ENUM_EXT("SEC MI2S SampleRate", sdx_enum[4],
1223 sdx_sec_mi2s_rate_get,
1224 sdx_sec_mi2s_rate_put),
1225 SOC_ENUM_EXT("HiFi Function", sdx_enum[5],
1226 sdx_hifi_get,
1227 sdx_hifi_put),
1228 SOC_ENUM_EXT("MI2S Mode", sdx_enum[6],
1229 sdx_mi2s_mode_get,
1230 sdx_mi2s_mode_put),
1231 SOC_ENUM_EXT("SEC_MI2S Mode", sdx_enum[6],
1232 sdx_sec_mi2s_mode_get,
1233 sdx_sec_mi2s_mode_put),
1234 SOC_ENUM_EXT("AUXPCM Mode", sdx_enum[6],
1235 sdx_auxpcm_mode_get,
1236 sdx_auxpcm_mode_put),
1237 SOC_ENUM_EXT("SEC_AUXPCM Mode", sdx_enum[6],
1238 sdx_sec_auxpcm_mode_get,
1239 sdx_sec_auxpcm_mode_put),
1240};
1241
1242static int sdx_mi2s_audrx_init(struct snd_soc_pcm_runtime *rtd)
1243{
1244 int ret = 0;
1245 struct snd_soc_codec *codec = rtd->codec;
1246 struct snd_soc_dapm_context *dapm =
1247 snd_soc_codec_get_dapm(codec);
1248 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1249 struct snd_card *card;
1250 struct snd_info_entry *entry;
1251 struct sdx_machine_data *pdata =
1252 snd_soc_card_get_drvdata(rtd->card);
1253
1254 pr_debug("%s dev_name %s\n", __func__, dev_name(cpu_dai->dev));
1255
1256 rtd->pmdown_time = 0;
1257 ret = snd_soc_add_codec_controls(codec, sdx_snd_controls,
1258 ARRAY_SIZE(sdx_snd_controls));
1259 if (ret < 0) {
1260 pr_err("%s: add_codec_controls failed, %d\n",
1261 __func__, ret);
1262 goto done;
1263 }
1264
1265 snd_soc_dapm_new_controls(dapm, sdx_dapm_widgets,
1266 ARRAY_SIZE(sdx_dapm_widgets));
1267
1268 snd_soc_dapm_add_routes(dapm, wcd_audio_paths,
1269 ARRAY_SIZE(wcd_audio_paths));
1270
1271 /*
1272 * After DAPM Enable pins always
1273 * DAPM SYNC needs to be called.
1274 */
1275 snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp");
1276 snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp");
1277 snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp");
1278 snd_soc_dapm_enable_pin(dapm, "Lineout_4 amp");
1279
1280 snd_soc_dapm_ignore_suspend(dapm, "Lineout_1 amp");
1281 snd_soc_dapm_ignore_suspend(dapm, "Lineout_3 amp");
1282 snd_soc_dapm_ignore_suspend(dapm, "Lineout_2 amp");
1283 snd_soc_dapm_ignore_suspend(dapm, "Lineout_4 amp");
Xiaoyu Yee7df5cc2017-10-02 18:47:29 -07001284 snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
1285 snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
1286 snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic");
1287 snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic");
1288 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1");
1289 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2");
1290 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3");
1291 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4");
1292 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5");
1293 snd_soc_dapm_ignore_suspend(dapm, "Digital Mic6");
1294
1295 snd_soc_dapm_ignore_suspend(dapm, "MADINPUT");
1296 snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT");
1297 snd_soc_dapm_ignore_suspend(dapm, "EAR");
Xiaoyu Yee7df5cc2017-10-02 18:47:29 -07001298 snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1");
1299 snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2");
Xiaoyu Yee7df5cc2017-10-02 18:47:29 -07001300 snd_soc_dapm_ignore_suspend(dapm, "ANC EAR");
1301 snd_soc_dapm_ignore_suspend(dapm, "AMIC1");
1302 snd_soc_dapm_ignore_suspend(dapm, "AMIC2");
1303 snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
1304 snd_soc_dapm_ignore_suspend(dapm, "AMIC4");
1305 snd_soc_dapm_ignore_suspend(dapm, "AMIC5");
Xiaoyu Yee7df5cc2017-10-02 18:47:29 -07001306 snd_soc_dapm_ignore_suspend(dapm, "DMIC1");
1307 snd_soc_dapm_ignore_suspend(dapm, "DMIC2");
1308 snd_soc_dapm_ignore_suspend(dapm, "DMIC3");
1309 snd_soc_dapm_ignore_suspend(dapm, "DMIC4");
1310 snd_soc_dapm_ignore_suspend(dapm, "DMIC5");
Xiaoyu Yee7df5cc2017-10-02 18:47:29 -07001311 snd_soc_dapm_ignore_suspend(dapm, "DMIC0");
1312 snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT");
1313 snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT");
Xiaoyu Yee7df5cc2017-10-02 18:47:29 -07001314 snd_soc_dapm_ignore_suspend(dapm, "HPHL");
1315 snd_soc_dapm_ignore_suspend(dapm, "HPHR");
1316 snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL");
1317 snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR");
Xiaoyu Yee7df5cc2017-10-02 18:47:29 -07001318
1319 snd_soc_dapm_sync(dapm);
1320
1321 wcd_mbhc_cfg.calibration = def_tavil_mbhc_cal();
1322 if (wcd_mbhc_cfg.calibration)
1323 ret = tavil_mbhc_hs_detect(codec, &wcd_mbhc_cfg);
1324 else
1325 ret = -ENOMEM;
1326
1327 card = rtd->card->snd_card;
1328 entry = snd_info_create_subdir(card->module, "codecs",
1329 card->proc_root);
1330 if (!entry) {
1331 pr_debug("%s: Cannot create codecs module entry\n",
1332 __func__);
1333 ret = 0;
1334 goto done;
1335 }
1336 pdata->codec_root = entry;
1337 tavil_codec_info_create_codec_entry(pdata->codec_root, codec);
1338done:
1339 return ret;
1340}
1341
1342static void *def_tavil_mbhc_cal(void)
1343{
1344 void *tavil_wcd_cal;
1345 struct wcd_mbhc_btn_detect_cfg *btn_cfg;
1346 u16 *btn_high;
1347
1348 tavil_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS,
1349 WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL);
1350 if (!tavil_wcd_cal)
1351 return NULL;
1352
1353#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tavil_wcd_cal)->X) = (Y))
1354 S(v_hs_max, 1600);
1355#undef S
1356#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal)->X) = (Y))
1357 S(num_btn, WCD_MBHC_DEF_BUTTONS);
1358#undef S
1359
1360 btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal);
1361 btn_high = ((void *)&btn_cfg->_v_btn_low) +
1362 (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn);
1363
1364 btn_high[0] = 75;
1365 btn_high[1] = 150;
1366 btn_high[2] = 237;
1367 btn_high[3] = 500;
1368 btn_high[4] = 500;
1369 btn_high[5] = 500;
1370 btn_high[6] = 500;
1371 btn_high[7] = 500;
1372
1373 return tavil_wcd_cal;
1374}
1375
1376/* Digital audio interface connects codec <---> CPU */
1377static struct snd_soc_dai_link sdx_common_dai_links[] = {
1378 /* FrontEnd DAI Links */
1379 {
1380 .name = SDX_DAILINK_NAME(Media1),
1381 .stream_name = "MultiMedia1",
1382 .cpu_dai_name = "MultiMedia1",
1383 .platform_name = "msm-pcm-dsp.0",
1384 .dynamic = 1,
1385 .dpcm_playback = 1,
1386 .dpcm_capture = 1,
1387 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1388 SND_SOC_DPCM_TRIGGER_POST},
1389 .codec_dai_name = "snd-soc-dummy-dai",
1390 .codec_name = "snd-soc-dummy",
1391 .ignore_suspend = 1,
1392 /* This dainlink has playback support */
1393 .ignore_pmdown_time = 1,
1394 .id = MSM_FRONTEND_DAI_MULTIMEDIA1
1395 },
1396 {
1397 .name = "MSM VoIP",
1398 .stream_name = "VoIP",
1399 .cpu_dai_name = "VoIP",
1400 .platform_name = "msm-voip-dsp",
1401 .dynamic = 1,
1402 .dpcm_playback = 1,
1403 .dpcm_capture = 1,
1404 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1405 SND_SOC_DPCM_TRIGGER_POST},
1406 .codec_dai_name = "snd-soc-dummy-dai",
1407 .codec_name = "snd-soc-dummy",
1408 .ignore_suspend = 1,
1409 /* This dainlink has VOIP support */
1410 .ignore_pmdown_time = 1,
1411 .id = MSM_FRONTEND_DAI_VOIP,
1412 },
1413 {
1414 .name = "Primary MI2S RX Hostless",
1415 .stream_name = "Primary MI2S_RX Hostless Playback",
1416 .cpu_dai_name = "PRI_MI2S_RX_HOSTLESS",
1417 .platform_name = "msm-pcm-hostless",
1418 .dynamic = 1,
1419 .dpcm_playback = 1,
1420 .dpcm_capture = 1,
1421 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1422 SND_SOC_DPCM_TRIGGER_POST},
1423 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1424 .ignore_suspend = 1,
1425 .ignore_pmdown_time = 1,
1426 .codec_dai_name = "snd-soc-dummy-dai",
1427 .codec_name = "snd-soc-dummy",
1428 },
1429 {
1430 .name = "MSM AFE-PCM RX",
1431 .stream_name = "AFE-PROXY RX",
1432 .cpu_dai_name = "msm-dai-q6-dev.241",
1433 .codec_name = "msm-stub-codec.1",
1434 .codec_dai_name = "msm-stub-rx",
1435 .platform_name = "msm-pcm-afe",
1436 .ignore_suspend = 1,
1437 /* this dainlink has playback support */
1438 .ignore_pmdown_time = 1,
1439 },
1440 {
1441 .name = "MSM AFE-PCM TX",
1442 .stream_name = "AFE-PROXY TX",
1443 .cpu_dai_name = "msm-dai-q6-dev.240",
1444 .codec_name = "msm-stub-codec.1",
1445 .codec_dai_name = "msm-stub-tx",
1446 .platform_name = "msm-pcm-afe",
1447 .ignore_suspend = 1,
1448 },
1449 {
1450 .name = "DTMF RX Hostless",
1451 .stream_name = "DTMF RX Hostless",
1452 .cpu_dai_name = "DTMF_RX_HOSTLESS",
1453 .platform_name = "msm-pcm-dtmf",
1454 .dynamic = 1,
1455 .dpcm_playback = 1,
1456 .codec_dai_name = "snd-soc-dummy-dai",
1457 .codec_name = "snd-soc-dummy",
1458 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1459 SND_SOC_DPCM_TRIGGER_POST},
1460 .ignore_suspend = 1,
1461 .ignore_pmdown_time = 1,
1462 .id = MSM_FRONTEND_DAI_DTMF_RX,
1463 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1464 },
1465 {
1466 .name = "DTMF TX",
1467 .stream_name = "DTMF TX",
1468 .cpu_dai_name = "msm-dai-stub-dev.4",
1469 .platform_name = "msm-pcm-dtmf",
1470 .codec_name = "msm-stub-codec.1",
1471 .codec_dai_name = "msm-stub-tx",
1472 .ignore_suspend = 1,
1473 },
1474 {
1475 .name = SDX_DAILINK_NAME(Compress1),
1476 .stream_name = "COMPR",
1477 .cpu_dai_name = "MultiMedia4",
1478 .platform_name = "msm-compress-dsp",
1479 .dynamic = 1,
1480 .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS,
1481 .dpcm_playback = 1,
1482 .dpcm_capture = 1,
1483 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1484 SND_SOC_DPCM_TRIGGER_POST},
1485 .codec_dai_name = "snd-soc-dummy-dai",
1486 .codec_name = "snd-soc-dummy",
1487 .ignore_suspend = 1,
1488 .ignore_pmdown_time = 1,
1489 .id = MSM_FRONTEND_DAI_MULTIMEDIA4,
1490 },
1491 {
1492 .name = SDX_DAILINK_NAME(Media2),
1493 .stream_name = "MultiMedia2",
1494 .cpu_dai_name = "MultiMedia2",
1495 .platform_name = "msm-pcm-dsp.0",
1496 .dynamic = 1,
1497 .dpcm_playback = 1,
1498 .dpcm_capture = 1,
1499 .codec_dai_name = "snd-soc-dummy-dai",
1500 .codec_name = "snd-soc-dummy",
1501 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1502 SND_SOC_DPCM_TRIGGER_POST},
1503 .ignore_suspend = 1,
1504 .ignore_pmdown_time = 1,
1505 /* this dainlink has playback support */
1506 .id = MSM_FRONTEND_DAI_MULTIMEDIA2,
1507 },
1508 {
1509 .name = "Primary MI2S TX Hostless",
1510 .stream_name = "Primary MI2S_TX Hostless Playback",
1511 .cpu_dai_name = "PRI_MI2S_TX_HOSTLESS",
1512 .platform_name = "msm-pcm-hostless",
1513 .dynamic = 1,
1514 .dpcm_capture = 1,
1515 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1516 SND_SOC_DPCM_TRIGGER_POST},
1517 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1518 .ignore_suspend = 1,
1519 .ignore_pmdown_time = 1,
1520 .codec_dai_name = "snd-soc-dummy-dai",
1521 .codec_name = "snd-soc-dummy",
1522 },
1523 {
1524 .name = SDX_DAILINK_NAME(LowLatency),
1525 .stream_name = "MultiMedia5",
1526 .cpu_dai_name = "MultiMedia5",
1527 .platform_name = "msm-pcm-dsp.1",
1528 .dynamic = 1,
1529 .dpcm_playback = 1,
1530 .dpcm_capture = 1,
1531 .codec_dai_name = "snd-soc-dummy-dai",
1532 .codec_name = "snd-soc-dummy",
1533 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1534 SND_SOC_DPCM_TRIGGER_POST},
1535 .ignore_suspend = 1,
1536 /* this dainlink has playback support */
1537 .ignore_pmdown_time = 1,
1538 .id = MSM_FRONTEND_DAI_MULTIMEDIA5,
1539 },
1540 {
1541 .name = "SDX VoiceMMode1",
1542 .stream_name = "VoiceMMode1",
1543 .cpu_dai_name = "VoiceMMode1",
1544 .platform_name = "msm-pcm-voice",
1545 .dynamic = 1,
1546 .dpcm_playback = 1,
1547 .dpcm_capture = 1,
1548 .codec_dai_name = "snd-soc-dummy-dai",
1549 .codec_name = "snd-soc-dummy",
1550 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1551 SND_SOC_DPCM_TRIGGER_POST},
1552 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1553 .ignore_suspend = 1,
1554 /* This dainlink has Voice support */
1555 .ignore_pmdown_time = 1,
1556 .id = MSM_FRONTEND_DAI_VOICEMMODE1,
1557 },
1558 {
1559 .name = "SDX VoiceMMode2",
1560 .stream_name = "VoiceMMode2",
1561 .cpu_dai_name = "VoiceMMode2",
1562 .platform_name = "msm-pcm-voice",
1563 .dynamic = 1,
1564 .dpcm_playback = 1,
1565 .dpcm_capture = 1,
1566 .codec_dai_name = "snd-soc-dummy-dai",
1567 .codec_name = "snd-soc-dummy",
1568 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1569 SND_SOC_DPCM_TRIGGER_POST},
1570 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1571 .ignore_suspend = 1,
1572 /* This dainlink has Voice support */
1573 .ignore_pmdown_time = 1,
1574 .id = MSM_FRONTEND_DAI_VOICEMMODE2,
1575 },
1576 {
1577 .name = "VoiceMMode1 HOST RX CAPTURE",
1578 .stream_name = "VoiceMMode1 HOST RX CAPTURE",
1579 .cpu_dai_name = "msm-dai-stub-dev.5",
1580 .platform_name = "msm-voice-host-pcm",
1581 .codec_name = "msm-stub-codec.1",
1582 .codec_dai_name = "msm-stub-tx",
1583 .ignore_suspend = 1,
1584 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1585 SND_SOC_DPCM_TRIGGER_POST},
1586 },
1587 {
1588 .name = "VoiceMMode1 HOST RX PLAYBACK",
1589 .stream_name = "VoiceMMode1 HOST RX PLAYBACK",
1590 .cpu_dai_name = "msm-dai-stub-dev.6",
1591 .platform_name = "msm-voice-host-pcm",
1592 .codec_name = "msm-stub-codec.1",
1593 .codec_dai_name = "msm-stub-rx",
1594 .ignore_suspend = 1,
1595 .ignore_pmdown_time = 1,
1596 },
1597 {
1598 .name = "VoiceMMode1 HOST TX CAPTURE",
1599 .stream_name = "VoiceMMode1 HOST TX CAPTURE",
1600 .cpu_dai_name = "msm-dai-stub-dev.7",
1601 .platform_name = "msm-voice-host-pcm",
1602 .codec_name = "msm-stub-codec.1",
1603 .codec_dai_name = "msm-stub-tx",
1604 .ignore_suspend = 1,
1605 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1606 SND_SOC_DPCM_TRIGGER_POST},
1607 },
1608 {
1609 .name = "VoiceMMode1 HOST TX PLAYBACK",
1610 .stream_name = "VoiceMMode1 HOST TX PLAYBACK",
1611 .cpu_dai_name = "msm-dai-stub-dev.8",
1612 .platform_name = "msm-voice-host-pcm",
1613 .codec_name = "msm-stub-codec.1",
1614 .codec_dai_name = "msm-stub-rx",
1615 .ignore_suspend = 1,
1616 .ignore_pmdown_time = 1,
1617 },
1618 {
1619 .name = "VoiceMMode2 HOST RX CAPTURE",
1620 .stream_name = "VoiceMMode2 HOST RX CAPTURE",
1621 .cpu_dai_name = "msm-dai-stub-dev.5",
1622 .platform_name = "msm-voice-host-pcm",
1623 .codec_name = "msm-stub-codec.1",
1624 .codec_dai_name = "msm-stub-tx",
1625 .ignore_suspend = 1,
1626 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1627 SND_SOC_DPCM_TRIGGER_POST},
1628 },
1629 {
1630 .name = "VoiceMMode2 HOST RX PLAYBACK",
1631 .stream_name = "VOiceMMode2 HOST RX PLAYBACK",
1632 .cpu_dai_name = "msm-dai-stub-dev.6",
1633 .platform_name = "msm-voice-host-pcm",
1634 .codec_name = "msm-stub-codec.1",
1635 .codec_dai_name = "msm-stub-rx",
1636 .ignore_suspend = 1,
1637 .ignore_pmdown_time = 1,
1638 },
1639 {
1640 .name = "VoiceMMode2 HOST TX CAPTURE",
1641 .stream_name = "VoiceMMode2 HOST TX CAPTURE",
1642 .cpu_dai_name = "msm-dai-stub-dev.7",
1643 .platform_name = "msm-voice-host-pcm",
1644 .codec_name = "msm-stub-codec.1",
1645 .codec_dai_name = "msm-stub-tx",
1646 .ignore_suspend = 1,
1647 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1648 SND_SOC_DPCM_TRIGGER_POST},
1649 },
1650 {
1651 .name = "VoiceMMode2 HOST TX PLAYBACK",
1652 .stream_name = "VOiceMMode2 HOST TX PLAYBACK",
1653 .cpu_dai_name = "msm-dai-stub-dev.8",
1654 .platform_name = "msm-voice-host-pcm",
1655 .codec_name = "msm-stub-codec.1",
1656 .codec_dai_name = "msm-stub-rx",
1657 .ignore_suspend = 1,
1658 .ignore_pmdown_time = 1,
1659 },
1660 {
1661 .name = "Secondary MI2S RX Hostless",
1662 .stream_name = "Secondary MI2S_RX Hostless Playback",
1663 .cpu_dai_name = "SEC_MI2S_RX_HOSTLESS",
1664 .platform_name = "msm-pcm-hostless",
1665 .dynamic = 1,
1666 .dpcm_playback = 1,
1667 .dpcm_capture = 1,
1668 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1669 SND_SOC_DPCM_TRIGGER_POST},
1670 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1671 .ignore_suspend = 1,
1672 .ignore_pmdown_time = 1,
1673 .codec_dai_name = "snd-soc-dummy-dai",
1674 .codec_name = "snd-soc-dummy",
1675 },
1676 {
1677 .name = "Secondary MI2S TX Hostless",
1678 .stream_name = "Secondary MI2S_TX Hostless Playback",
1679 .cpu_dai_name = "SEC_MI2S_TX_HOSTLESS",
1680 .platform_name = "msm-pcm-hostless",
1681 .dynamic = 1,
1682 .dpcm_capture = 1,
1683 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1684 SND_SOC_DPCM_TRIGGER_POST},
1685 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1686 .ignore_suspend = 1,
1687 .ignore_pmdown_time = 1,
1688 .codec_dai_name = "snd-soc-dummy-dai",
1689 .codec_name = "snd-soc-dummy",
1690 },
1691 {
1692 .name = "Primary AUXPCM RX Hostless",
1693 .stream_name = "AUXPCM_HOSTLESS Playback",
1694 .cpu_dai_name = "AUXPCM_HOSTLESS",
1695 .platform_name = "msm-pcm-hostless",
1696 .dynamic = 1,
1697 .dpcm_playback = 1,
1698 .dpcm_capture = 1,
1699 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1700 SND_SOC_DPCM_TRIGGER_POST},
1701 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1702 .ignore_suspend = 1,
1703 .ignore_pmdown_time = 1,
1704 .codec_dai_name = "snd-soc-dummy-dai",
1705 .codec_name = "snd-soc-dummy",
1706 },
1707 {
1708 .name = "Primary AUXPCM TX Hostless",
1709 .stream_name = "AUXPCM_HOSTLESS Capture",
1710 .cpu_dai_name = "AUXPCM_HOSTLESS",
1711 .platform_name = "msm-pcm-hostless",
1712 .dynamic = 1,
1713 .dpcm_capture = 1,
1714 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1715 SND_SOC_DPCM_TRIGGER_POST},
1716 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1717 .ignore_suspend = 1,
1718 .ignore_pmdown_time = 1,
1719 .codec_dai_name = "snd-soc-dummy-dai",
1720 .codec_name = "snd-soc-dummy",
1721 },
1722 {
1723 .name = "Secondary AUXPCM RX Hostless",
1724 .stream_name = "SEC_AUXPCM_HOSTLESS Playback",
1725 .cpu_dai_name = "SEC_AUXPCM_RX_HOSTLESS",
1726 .platform_name = "msm-pcm-hostless",
1727 .dynamic = 1,
1728 .dpcm_playback = 1,
1729 .dpcm_capture = 1,
1730 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1731 SND_SOC_DPCM_TRIGGER_POST},
1732 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1733 .ignore_suspend = 1,
1734 .ignore_pmdown_time = 1,
1735 .codec_dai_name = "snd-soc-dummy-dai",
1736 .codec_name = "snd-soc-dummy",
1737 },
1738 {
1739 .name = "Secondary AUXPCM TX Hostless",
1740 .stream_name = "SEC_AUXPCM_HOSTLESS Capture",
1741 .cpu_dai_name = "SEC_AUXPCM_TX_HOSTLESS",
1742 .platform_name = "msm-pcm-hostless",
1743 .dynamic = 1,
1744 .dpcm_capture = 1,
1745 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1746 SND_SOC_DPCM_TRIGGER_POST},
1747 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1748 .ignore_suspend = 1,
1749 .ignore_pmdown_time = 1,
1750 .codec_dai_name = "snd-soc-dummy-dai",
1751 .codec_name = "snd-soc-dummy",
1752 },
1753};
1754
1755static struct snd_soc_dai_link sdx_common_misc_fe_dai_links[] = {
1756 {
1757 .name = SDX_DAILINK_NAME(ASM Loopback),
1758 .stream_name = "MultiMedia6",
1759 .cpu_dai_name = "MultiMedia6",
1760 .platform_name = "msm-pcm-loopback",
1761 .dynamic = 1,
1762 .dpcm_playback = 1,
1763 .dpcm_capture = 1,
1764 .codec_dai_name = "snd-soc-dummy-dai",
1765 .codec_name = "snd-soc-dummy",
1766 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1767 SND_SOC_DPCM_TRIGGER_POST},
1768 .ignore_suspend = 1,
1769 .ignore_pmdown_time = 1,
1770 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1771 /* this dainlink has playback support */
1772 .id = MSM_FRONTEND_DAI_MULTIMEDIA6,
1773 },
1774};
1775
1776static struct snd_soc_dai_link sdx_common_be_dai_links[] = {
1777 /* Backend AFE DAI Links */
1778 {
1779 .name = LPASS_BE_AFE_PCM_RX,
1780 .stream_name = "AFE Playback",
1781 .cpu_dai_name = "msm-dai-q6-dev.224",
1782 .platform_name = "msm-pcm-routing",
1783 .codec_name = "msm-stub-codec.1",
1784 .codec_dai_name = "msm-stub-rx",
1785 .no_pcm = 1,
1786 .dpcm_playback = 1,
1787 .id = MSM_BACKEND_DAI_AFE_PCM_RX,
1788 .ignore_suspend = 1,
1789 },
1790 {
1791 .name = LPASS_BE_AFE_PCM_TX,
1792 .stream_name = "AFE Capture",
1793 .cpu_dai_name = "msm-dai-q6-dev.225",
1794 .platform_name = "msm-pcm-routing",
1795 .codec_name = "msm-stub-codec.1",
1796 .codec_dai_name = "msm-stub-tx",
1797 .no_pcm = 1,
1798 .dpcm_capture = 1,
1799 .id = MSM_BACKEND_DAI_AFE_PCM_TX,
1800 .ignore_suspend = 1,
1801 },
1802 /* Incall Record Uplink BACK END DAI Link */
1803 {
1804 .name = LPASS_BE_INCALL_RECORD_TX,
1805 .stream_name = "Voice Uplink Capture",
1806 .cpu_dai_name = "msm-dai-q6-dev.32772",
1807 .platform_name = "msm-pcm-routing",
1808 .codec_name = "msm-stub-codec.1",
1809 .codec_dai_name = "msm-stub-tx",
1810 .no_pcm = 1,
1811 .dpcm_capture = 1,
1812 .id = MSM_BACKEND_DAI_INCALL_RECORD_TX,
1813 .be_hw_params_fixup = sdx_be_hw_params_fixup,
1814 .ignore_suspend = 1,
1815 },
1816 /* Incall Record Downlink BACK END DAI Link */
1817 {
1818 .name = LPASS_BE_INCALL_RECORD_RX,
1819 .stream_name = "Voice Downlink Capture",
1820 .cpu_dai_name = "msm-dai-q6-dev.32771",
1821 .platform_name = "msm-pcm-routing",
1822 .codec_name = "msm-stub-codec.1",
1823 .codec_dai_name = "msm-stub-tx",
1824 .no_pcm = 1,
1825 .dpcm_capture = 1,
1826 .id = MSM_BACKEND_DAI_INCALL_RECORD_RX,
1827 .be_hw_params_fixup = sdx_be_hw_params_fixup,
1828 .ignore_suspend = 1,
1829 },
1830 /* Incall Music BACK END DAI Link */
1831 {
1832 .name = LPASS_BE_VOICE_PLAYBACK_TX,
1833 .stream_name = "Voice Farend Playback",
1834 .cpu_dai_name = "msm-dai-q6-dev.32773",
1835 .platform_name = "msm-pcm-routing",
1836 .codec_name = "msm-stub-codec.1",
1837 .codec_dai_name = "msm-stub-rx",
1838 .no_pcm = 1,
1839 .dpcm_playback = 1,
1840 .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
1841 .be_hw_params_fixup = sdx_be_hw_params_fixup,
1842 .ignore_suspend = 1,
1843 },
1844};
1845
1846static struct snd_soc_dai_link sdx_mi2s_be_dai_links[] = {
1847 {
1848 .name = LPASS_BE_PRI_MI2S_RX,
1849 .stream_name = "Primary MI2S Playback",
1850 .cpu_dai_name = "msm-dai-q6-mi2s.0",
1851 .platform_name = "msm-pcm-routing",
1852 .codec_name = "tavil_codec",
1853 .codec_dai_name = "tavil_i2s_rx1",
1854 .no_pcm = 1,
1855 .dpcm_playback = 1,
1856 .id = MSM_BACKEND_DAI_PRI_MI2S_RX,
1857 .init = &sdx_mi2s_audrx_init,
1858 .be_hw_params_fixup = &sdx_mi2s_rx_be_hw_params_fixup,
1859 .ops = &sdx_mi2s_be_ops,
1860 .ignore_pmdown_time = 1,
1861 .ignore_suspend = 1,
1862 },
1863 {
1864 .name = LPASS_BE_PRI_MI2S_TX,
1865 .stream_name = "Primary MI2S Capture",
1866 .cpu_dai_name = "msm-dai-q6-mi2s.0",
1867 .platform_name = "msm-pcm-routing",
1868 .codec_name = "tavil_codec",
1869 .codec_dai_name = "tavil_i2s_tx1",
1870 .no_pcm = 1,
1871 .dpcm_capture = 1,
1872 .id = MSM_BACKEND_DAI_PRI_MI2S_TX,
1873 .be_hw_params_fixup = &sdx_mi2s_tx_be_hw_params_fixup,
1874 .ops = &sdx_mi2s_be_ops,
1875 .ignore_pmdown_time = 1,
1876 .ignore_suspend = 1,
1877 },
1878 {
1879 .name = LPASS_BE_SEC_MI2S_RX,
1880 .stream_name = "Secondary MI2S Playback",
1881 .cpu_dai_name = "msm-dai-q6-mi2s.1",
1882 .platform_name = "msm-pcm-routing",
1883 .codec_name = "msm-stub-codec.1",
1884 .codec_dai_name = "msm-stub-rx",
1885 .no_pcm = 1,
1886 .dpcm_playback = 1,
1887 .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
1888 .be_hw_params_fixup = &sdx_sec_mi2s_rx_be_hw_params_fixup,
1889 .ops = &sdx_sec_mi2s_be_ops,
1890 .ignore_pmdown_time = 1,
1891 .ignore_suspend = 1,
1892 },
1893 {
1894 .name = LPASS_BE_SEC_MI2S_TX,
1895 .stream_name = "Secondary MI2S Capture",
1896 .cpu_dai_name = "msm-dai-q6-mi2s.1",
1897 .platform_name = "msm-pcm-routing",
1898 .codec_name = "msm-stub-codec.1",
1899 .codec_dai_name = "msm-stub-tx",
1900 .no_pcm = 1,
1901 .dpcm_capture = 1,
1902 .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
1903 .be_hw_params_fixup = &sdx_sec_mi2s_tx_be_hw_params_fixup,
1904 .ops = &sdx_sec_mi2s_be_ops,
1905 .ignore_pmdown_time = 1,
1906 .ignore_suspend = 1,
1907 },
1908};
1909
1910static struct snd_soc_dai_link sdx_auxpcm_be_dai_links[] = {
1911 /* Primary AUX PCM Backend DAI Links */
1912 {
1913 .name = LPASS_BE_AUXPCM_RX,
1914 .stream_name = "AUX PCM Playback",
1915 .cpu_dai_name = "msm-dai-q6-auxpcm.1",
1916 .platform_name = "msm-pcm-routing",
1917 .codec_name = "msm-stub-codec.1",
1918 .codec_dai_name = "msm-stub-rx",
1919 .no_pcm = 1,
1920 .dpcm_playback = 1,
1921 .id = MSM_BACKEND_DAI_AUXPCM_RX,
1922 .be_hw_params_fixup = sdx_auxpcm_be_params_fixup,
1923 .ops = &sdx_auxpcm_be_ops,
1924 .ignore_pmdown_time = 1,
1925 /* this dainlink has playback support */
1926 .ignore_suspend = 1,
1927 },
1928 {
1929 .name = LPASS_BE_AUXPCM_TX,
1930 .stream_name = "AUX PCM Capture",
1931 .cpu_dai_name = "msm-dai-q6-auxpcm.1",
1932 .platform_name = "msm-pcm-routing",
1933 .codec_name = "msm-stub-codec.1",
1934 .codec_dai_name = "msm-stub-tx",
1935 .no_pcm = 1,
1936 .dpcm_capture = 1,
1937 .id = MSM_BACKEND_DAI_AUXPCM_TX,
1938 .be_hw_params_fixup = sdx_auxpcm_be_params_fixup,
1939 .ops = &sdx_auxpcm_be_ops,
1940 .ignore_suspend = 1,
1941 },
1942 /* Secondary AUX PCM Backend DAI Links */
1943 {
1944 .name = LPASS_BE_SEC_AUXPCM_RX,
1945 .stream_name = "Sec AUX PCM Playback",
1946 .cpu_dai_name = "msm-dai-q6-auxpcm.2",
1947 .platform_name = "msm-pcm-routing",
1948 .codec_name = "msm-stub-codec.1",
1949 .codec_dai_name = "msm-stub-rx",
1950 .no_pcm = 1,
1951 .dpcm_playback = 1,
1952 .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX,
1953 .be_hw_params_fixup = sdx_auxpcm_be_params_fixup,
1954 .ops = &sdx_sec_auxpcm_be_ops,
1955 .ignore_pmdown_time = 1,
1956 .ignore_suspend = 1,
1957 },
1958 {
1959 .name = LPASS_BE_SEC_AUXPCM_TX,
1960 .stream_name = "Sec AUX PCM Capture",
1961 .cpu_dai_name = "msm-dai-q6-auxpcm.2",
1962 .platform_name = "msm-pcm-routing",
1963 .codec_name = "msm-stub-codec.1",
1964 .codec_dai_name = "msm-stub-tx",
1965 .no_pcm = 1,
1966 .dpcm_capture = 1,
1967 .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX,
1968 .be_hw_params_fixup = sdx_auxpcm_be_params_fixup,
1969 .ops = &sdx_sec_auxpcm_be_ops,
1970 .ignore_suspend = 1,
1971 },
1972};
1973
1974static struct snd_soc_dai_link sdx_tavil_snd_card_dai_links[
1975 ARRAY_SIZE(sdx_common_dai_links) +
1976 ARRAY_SIZE(sdx_common_misc_fe_dai_links) +
1977 ARRAY_SIZE(sdx_common_be_dai_links) +
1978 ARRAY_SIZE(sdx_mi2s_be_dai_links) +
1979 ARRAY_SIZE(sdx_auxpcm_be_dai_links)];
1980
1981static struct snd_soc_card snd_soc_card_tavil_sdx = {
1982 .name = "sdx-tavil-i2s-snd-card",
1983};
1984
1985static int sdx_populate_dai_link_component_of_node(struct snd_soc_card *card)
1986{
1987 int i, index, ret = 0;
1988 struct device *cdev = card->dev;
1989 struct snd_soc_dai_link *dai_link = card->dai_link;
1990 struct device_node *np;
1991
1992 if (!cdev) {
1993 pr_err("%s: Sound card device memory NULL\n", __func__);
1994 return -ENODEV;
1995 }
1996
1997 for (i = 0; i < card->num_links; i++) {
1998 if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node)
1999 continue;
2000
2001 /* populate platform_of_node for snd card dai links */
2002 if (dai_link[i].platform_name &&
2003 !dai_link[i].platform_of_node) {
2004 index = of_property_match_string(cdev->of_node,
2005 "asoc-platform-names",
2006 dai_link[i].platform_name);
2007 if (index < 0) {
2008 pr_debug("%s: No match found for platform name: %s\n",
2009 __func__, dai_link[i].platform_name);
2010 ret = index;
2011 goto err;
2012 }
2013
2014 np = of_parse_phandle(cdev->of_node, "asoc-platform",
2015 index);
2016 if (!np) {
2017 pr_err("%s: retrieving phandle for platform %s, index %d failed\n",
2018 __func__, dai_link[i].platform_name,
2019 index);
2020 ret = -ENODEV;
2021 goto err;
2022 }
2023 dai_link[i].platform_of_node = np;
2024 dai_link[i].platform_name = NULL;
2025 }
2026
2027 /* populate cpu_of_node for snd card dai links */
2028 if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) {
2029 index = of_property_match_string(cdev->of_node,
2030 "asoc-cpu-names",
2031 dai_link[i].cpu_dai_name);
2032 if (index >= 0) {
2033 np = of_parse_phandle(cdev->of_node,
2034 "asoc-cpu",
2035 index);
2036 if (!np) {
2037 pr_err("%s: retrieving phandle for cpu dai %s failed\n",
2038 __func__,
2039 dai_link[i].cpu_dai_name);
2040 ret = -ENODEV;
2041 goto err;
2042 }
2043 dai_link[i].cpu_of_node = np;
2044 dai_link[i].cpu_dai_name = NULL;
2045 }
2046 }
2047
2048 /* populate codec_of_node for snd card dai links */
2049 if (dai_link[i].codec_name && !dai_link[i].codec_of_node) {
2050 index = of_property_match_string(cdev->of_node,
2051 "asoc-codec-names",
2052 dai_link[i].codec_name);
2053 if (index < 0)
2054 continue;
2055 np = of_parse_phandle(cdev->of_node, "asoc-codec",
2056 index);
2057 if (!np) {
2058 pr_err("%s: retrieving phandle for codec %s failed\n",
2059 __func__, dai_link[i].codec_name);
2060 ret = -ENODEV;
2061 goto err;
2062 }
2063 dai_link[i].codec_of_node = np;
2064 dai_link[i].codec_name = NULL;
2065 }
2066 }
2067
2068err:
2069 return ret;
2070}
2071
2072static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
2073{
2074 struct snd_soc_card *card = NULL;
2075 int len_1, len_2, len_3, len_4;
2076 int total_links;
2077
2078 card = &snd_soc_card_tavil_sdx;
2079 len_1 = ARRAY_SIZE(sdx_common_dai_links);
2080 len_2 = len_1 + ARRAY_SIZE(sdx_common_misc_fe_dai_links);
2081 len_3 = len_2 + ARRAY_SIZE(sdx_common_be_dai_links);
2082 len_4 = len_3 + ARRAY_SIZE(sdx_mi2s_be_dai_links);
2083 total_links = len_4 + ARRAY_SIZE(sdx_auxpcm_be_dai_links);
2084 memcpy(sdx_tavil_snd_card_dai_links,
2085 sdx_common_dai_links,
2086 sizeof(sdx_common_dai_links));
2087 memcpy(sdx_tavil_snd_card_dai_links + len_1,
2088 sdx_common_misc_fe_dai_links,
2089 sizeof(sdx_common_misc_fe_dai_links));
2090 memcpy(sdx_tavil_snd_card_dai_links + len_2,
2091 sdx_common_be_dai_links,
2092 sizeof(sdx_common_be_dai_links));
2093 memcpy(sdx_tavil_snd_card_dai_links + len_3,
2094 sdx_mi2s_be_dai_links,
2095 sizeof(sdx_mi2s_be_dai_links));
2096 memcpy(sdx_tavil_snd_card_dai_links + len_4,
2097 sdx_auxpcm_be_dai_links,
2098 sizeof(sdx_auxpcm_be_dai_links));
2099
2100 if (card) {
2101 card->dai_link = sdx_tavil_snd_card_dai_links;
2102 card->num_links = total_links;
2103 }
2104
2105 return card;
2106}
2107
2108static int sdx_init_wsa_dev(struct platform_device *pdev,
2109 struct snd_soc_card *card)
2110{
2111 struct device_node *wsa_of_node;
2112 u32 wsa_max_devs;
2113 u32 wsa_dev_cnt;
2114 char *dev_name_str = NULL;
2115 struct sdx_wsa881x_dev_info *wsa881x_dev_info;
2116 const char *wsa_auxdev_name_prefix[1];
2117 int found = 0;
2118 int i;
2119 int ret;
2120
2121 /* Get maximum WSA device count for this platform */
2122 ret = of_property_read_u32(pdev->dev.of_node,
2123 "qcom,wsa-max-devs", &wsa_max_devs);
2124 if (ret) {
2125 dev_dbg(&pdev->dev,
2126 "%s: wsa-max-devs property missing in DT %s, ret = %d\n",
2127 __func__, pdev->dev.of_node->full_name, ret);
2128 return 0;
2129 }
2130 if (wsa_max_devs == 0) {
2131 dev_warn(&pdev->dev,
2132 "%s: Max WSA devices is 0 for this target?\n",
2133 __func__);
2134 return 0;
2135 }
2136
2137 /* Get count of WSA device phandles for this platform */
2138 wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node,
2139 "qcom,wsa-devs", NULL);
2140 if (wsa_dev_cnt == -ENOENT) {
2141 dev_dbg(&pdev->dev, "%s: No wsa device defined in DT.\n",
2142 __func__);
2143 return 0;
2144 } else if (wsa_dev_cnt <= 0) {
2145 dev_err(&pdev->dev,
2146 "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n",
2147 __func__, wsa_dev_cnt);
2148 return -EINVAL;
2149 }
2150
2151 /*
2152 * Expect total phandles count to be NOT less than maximum possible
2153 * WSA count. However, if it is less, then assign same value to
2154 * max count as well.
2155 */
2156 if (wsa_dev_cnt < wsa_max_devs) {
2157 dev_dbg(&pdev->dev,
2158 "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n",
2159 __func__, wsa_max_devs, wsa_dev_cnt);
2160 wsa_max_devs = wsa_dev_cnt;
2161 }
2162
2163 /* Make sure prefix string passed for each WSA device */
2164 ret = of_property_count_strings(pdev->dev.of_node,
2165 "qcom,wsa-aux-dev-prefix");
2166 if (ret != wsa_dev_cnt) {
2167 dev_err(&pdev->dev,
2168 "%s: expecting %d wsa prefix. Defined only %d in DT\n",
2169 __func__, wsa_dev_cnt, ret);
2170 return -EINVAL;
2171 }
2172
2173 /*
2174 * Alloc mem to store phandle and index info of WSA device, if already
2175 * registered with ALSA core
2176 */
2177 wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs,
2178 sizeof(struct sdx_wsa881x_dev_info),
2179 GFP_KERNEL);
2180 if (!wsa881x_dev_info)
2181 return -ENOMEM;
2182
2183 /*
2184 * search and check whether all WSA devices are already
2185 * registered with ALSA core or not. If found a node, store
2186 * the node and the index in a local array of struct for later
2187 * use.
2188 */
2189 for (i = 0; i < wsa_dev_cnt; i++) {
2190 wsa_of_node = of_parse_phandle(pdev->dev.of_node,
2191 "qcom,wsa-devs", i);
2192 if (unlikely(!wsa_of_node)) {
2193 /* we should not be here */
2194 dev_err(&pdev->dev,
2195 "%s: wsa dev node is not present\n",
2196 __func__);
2197 return -EINVAL;
2198 }
2199 if (soc_find_component(wsa_of_node, NULL)) {
2200 /* WSA device registered with ALSA core */
2201 wsa881x_dev_info[found].of_node = wsa_of_node;
2202 wsa881x_dev_info[found].index = i;
2203 found++;
2204 if (found == wsa_max_devs)
2205 break;
2206 }
2207 }
2208
2209 if (found < wsa_max_devs) {
2210 dev_dbg(&pdev->dev,
2211 "%s: failed to find %d components. Found only %d\n",
2212 __func__, wsa_max_devs, found);
2213 return -EPROBE_DEFER;
2214 }
2215 dev_info(&pdev->dev,
2216 "%s: found %d wsa881x devices registered with ALSA core\n",
2217 __func__, found);
2218
2219 card->num_aux_devs = wsa_max_devs;
2220 card->num_configs = wsa_max_devs;
2221
2222 /* Alloc array of AUX devs struct */
2223 sdx_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs,
2224 sizeof(struct snd_soc_aux_dev),
2225 GFP_KERNEL);
2226 if (!sdx_aux_dev)
2227 return -ENOMEM;
2228
2229 /* Alloc array of codec conf struct */
2230 sdx_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs,
2231 sizeof(struct snd_soc_codec_conf),
2232 GFP_KERNEL);
2233 if (!sdx_codec_conf)
2234 return -ENOMEM;
2235
2236 for (i = 0; i < card->num_aux_devs; i++) {
2237 dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN,
2238 GFP_KERNEL);
2239 if (!dev_name_str)
2240 return -ENOMEM;
2241
2242 ret = of_property_read_string_index(pdev->dev.of_node,
2243 "qcom,wsa-aux-dev-prefix",
2244 wsa881x_dev_info[i].index,
2245 wsa_auxdev_name_prefix);
2246 if (ret) {
2247 dev_err(&pdev->dev,
2248 "%s: failed to read wsa aux dev prefix, ret = %d\n",
2249 __func__, ret);
2250 return -EINVAL;
2251 }
2252
2253 snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i);
2254 sdx_aux_dev[i].name = dev_name_str;
2255 sdx_aux_dev[i].codec_name = NULL;
2256 sdx_aux_dev[i].codec_of_node = wsa881x_dev_info[i].of_node;
2257 sdx_aux_dev[i].init = sdx_wsa881x_init;
2258 sdx_codec_conf[i].dev_name = NULL;
2259 sdx_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0];
2260 sdx_codec_conf[i].of_node = wsa881x_dev_info[i].of_node;
2261 }
2262 card->codec_conf = sdx_codec_conf;
2263 card->aux_dev = sdx_aux_dev;
2264
2265 return 0;
2266}
2267
2268static int sdx_asoc_machine_probe(struct platform_device *pdev)
2269{
2270 int ret;
2271 struct sdx_machine_data *pdata;
2272 struct snd_soc_card *card;
2273
2274 if (!pdev->dev.of_node) {
2275 dev_err(&pdev->dev,
2276 "%s No platform supplied from device tree\n", __func__);
2277
2278 return -EINVAL;
2279 }
2280
2281 pdata = devm_kzalloc(&pdev->dev, sizeof(struct sdx_machine_data),
2282 GFP_KERNEL);
2283 if (!pdata)
2284 return -ENOMEM;
2285
2286 card = populate_snd_card_dailinks(&pdev->dev);
2287 if (!card) {
2288 dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__);
2289 ret = -EINVAL;
2290 goto err;
2291 }
2292
2293 ret = of_property_read_u32(pdev->dev.of_node,
2294 "qcom,tavil-mclk-clk-freq",
2295 &pdata->mclk_freq);
2296 if (ret) {
2297 dev_err(&pdev->dev,
2298 "%s Looking up %s property in node %s failed",
2299 __func__, "qcom,tavil-mclk-clk-freq",
2300 pdev->dev.of_node->full_name);
2301
2302 goto err;
2303 }
2304 /* At present only 12.288MHz is supported on SDX. */
2305 if (q6afe_check_osr_clk_freq(pdata->mclk_freq)) {
2306 dev_err(&pdev->dev, "%s Unsupported tavil mclk freq %u\n",
2307 __func__, pdata->mclk_freq);
2308
2309 ret = -EINVAL;
2310 goto err;
2311 }
2312
2313 pdata->prim_master_p = of_parse_phandle(pdev->dev.of_node,
2314 "qcom,prim_mi2s_aux_master",
2315 0);
2316 pdata->prim_slave_p = of_parse_phandle(pdev->dev.of_node,
2317 "qcom,prim_mi2s_aux_slave", 0);
2318 pdata->sec_master_p = of_parse_phandle(pdev->dev.of_node,
2319 "qcom,sec_mi2s_aux_master", 0);
2320 pdata->sec_slave_p = of_parse_phandle(pdev->dev.of_node,
2321 "qcom,sec_mi2s_aux_slave", 0);
2322 mutex_init(&cdc_mclk_mutex);
2323 atomic_set(&mi2s_ref_count, 0);
2324 atomic_set(&sec_mi2s_ref_count, 0);
2325 pdata->prim_clk_usrs = 0;
2326
2327 card->dev = &pdev->dev;
2328 platform_set_drvdata(pdev, card);
2329 snd_soc_card_set_drvdata(card, pdata);
2330
2331 ret = snd_soc_of_parse_card_name(card, "qcom,model");
2332 if (ret)
2333 goto err;
2334 ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing");
2335 if (ret)
2336 goto err;
2337 ret = sdx_populate_dai_link_component_of_node(card);
2338 if (ret) {
2339 ret = -EPROBE_DEFER;
2340 goto err;
2341 }
2342
2343 ret = sdx_init_wsa_dev(pdev, card);
2344 if (ret)
2345 goto err;
2346
2347 ret = snd_soc_register_card(card);
2348 if (ret == -EPROBE_DEFER) {
2349 goto err;
2350 } else if (ret) {
2351 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
2352 ret);
2353 goto err;
2354 }
2355
2356 pdata->lpaif_pri_muxsel_virt_addr = ioremap(LPAIF_PRI_MODE_MUXSEL, 4);
2357 if (pdata->lpaif_pri_muxsel_virt_addr == NULL) {
2358 pr_err("%s Pri muxsel virt addr is null\n", __func__);
2359
2360 ret = -EINVAL;
2361 goto err;
2362 }
2363 pdata->lpass_mux_spkr_ctl_virt_addr =
2364 ioremap(LPASS_CSR_GP_IO_MUX_SPKR_CTL, 4);
2365 if (pdata->lpass_mux_spkr_ctl_virt_addr == NULL) {
2366 pr_err("%s lpass spkr ctl virt addr is null\n", __func__);
2367
2368 ret = -EINVAL;
2369 goto err1;
2370 }
2371
2372 pdata->lpaif_sec_muxsel_virt_addr = ioremap(LPAIF_SEC_MODE_MUXSEL, 4);
2373 if (pdata->lpaif_sec_muxsel_virt_addr == NULL) {
2374 pr_err("%s Sec muxsel virt addr is null\n", __func__);
2375 ret = -EINVAL;
2376 goto err2;
2377 }
2378
2379 pdata->lpass_mux_mic_ctl_virt_addr =
2380 ioremap(LPASS_CSR_GP_IO_MUX_MIC_CTL, 4);
2381 if (pdata->lpass_mux_mic_ctl_virt_addr == NULL) {
2382 pr_err("%s lpass_mux_mic_ctl_virt_addr is null\n",
2383 __func__);
2384 ret = -EINVAL;
2385 goto err3;
2386 }
2387
2388 return 0;
2389err3:
2390 iounmap(pdata->lpaif_sec_muxsel_virt_addr);
2391err2:
2392 iounmap(pdata->lpass_mux_spkr_ctl_virt_addr);
2393err1:
2394 iounmap(pdata->lpaif_pri_muxsel_virt_addr);
2395err:
2396 devm_kfree(&pdev->dev, pdata);
2397 return ret;
2398}
2399
2400static int sdx_asoc_machine_remove(struct platform_device *pdev)
2401{
2402 struct snd_soc_card *card = platform_get_drvdata(pdev);
2403 struct sdx_machine_data *pdata = snd_soc_card_get_drvdata(card);
2404
2405 pdata->mclk_freq = 0;
2406 gpio_free(pdata->hph_en1_gpio);
2407 gpio_free(pdata->hph_en0_gpio);
2408 iounmap(pdata->lpaif_pri_muxsel_virt_addr);
2409 iounmap(pdata->lpass_mux_spkr_ctl_virt_addr);
2410 iounmap(pdata->lpaif_sec_muxsel_virt_addr);
2411 iounmap(pdata->lpass_mux_mic_ctl_virt_addr);
2412 snd_soc_unregister_card(card);
2413
2414 return 0;
2415}
2416
2417static const struct of_device_id sdx_asoc_machine_of_match[] = {
2418 { .compatible = "qcom,sdx-asoc-snd-tavil", },
2419 {},
2420};
2421
2422static struct platform_driver sdx_asoc_machine_driver = {
2423 .driver = {
2424 .name = DRV_NAME,
2425 .owner = THIS_MODULE,
2426 .pm = &snd_soc_pm_ops,
2427 .of_match_table = sdx_asoc_machine_of_match,
2428 },
2429 .probe = sdx_asoc_machine_probe,
2430 .remove = sdx_asoc_machine_remove,
2431};
2432
2433static int dummy_machine_probe(struct platform_device *pdev)
2434{
2435 return 0;
2436}
2437
2438static int dummy_machine_remove(struct platform_device *pdev)
2439{
2440 return 0;
2441}
2442
2443static struct platform_device dummy_machine_device = {
2444 .name = "dummymachinedriver",
2445};
2446
2447static struct platform_driver sdx_asoc_machine_dummy_driver = {
2448 .driver = {
2449 .name = "dummymachinedriver",
2450 .owner = THIS_MODULE,
2451 },
2452 .probe = dummy_machine_probe,
2453 .remove = dummy_machine_remove,
2454};
2455
2456static int sdx_adsp_state_callback(struct notifier_block *nb,
2457 unsigned long value, void *priv)
2458{
2459 if (!dummy_device_registered && SUBSYS_AFTER_POWERUP == value) {
2460 platform_driver_register(&sdx_asoc_machine_dummy_driver);
2461 platform_device_register(&dummy_machine_device);
2462 dummy_device_registered = true;
2463 }
2464
2465 return NOTIFY_OK;
2466}
2467
2468static struct notifier_block adsp_state_notifier_block = {
2469 .notifier_call = sdx_adsp_state_callback,
2470 .priority = -INT_MAX,
2471};
2472
2473static int __init sdx_soc_platform_init(void)
2474{
2475 adsp_state_notifier = subsys_notif_register_notifier("modem",
2476 &adsp_state_notifier_block);
2477 return 0;
2478}
2479
2480module_init(sdx_soc_platform_init);
2481
2482module_platform_driver(sdx_asoc_machine_driver);
2483
2484MODULE_DESCRIPTION("ALSA SoC sdx");
2485MODULE_LICENSE("GPL v2");
2486MODULE_ALIAS("platform:" DRV_NAME);
2487MODULE_DEVICE_TABLE(of, sdx_asoc_machine_of_match);