1 // SPDX-License-Identifier: GPL-2.0
3 // mt8183-da7219-max98357.c
4 // -- MT8183-DA7219-MAX98357 ALSA SoC machine driver
6 // Copyright (c) 2018 MediaTek Inc.
7 // Author: Shunli Wang <shunli.wang@mediatek.com>
9 #include <linux/input.h>
10 #include <linux/module.h>
11 #include <linux/of_device.h>
12 #include <linux/pinctrl/consumer.h>
13 #include <sound/jack.h>
14 #include <sound/pcm_params.h>
15 #include <sound/soc.h>
17 #include "../../codecs/da7219-aad.h"
18 #include "../../codecs/da7219.h"
19 #include "../../codecs/rt1015.h"
20 #include "mt8183-afe-common.h"
22 #define DA7219_CODEC_DAI "da7219-hifi"
23 #define DA7219_DEV_NAME "da7219.5-001a"
24 #define RT1015_CODEC_DAI "rt1015-aif"
25 #define RT1015_DEV0_NAME "rt1015.6-0028"
26 #define RT1015_DEV1_NAME "rt1015.6-0029"
28 struct mt8183_da7219_max98357_priv {
29 struct snd_soc_jack headset_jack, hdmi_jack;
32 static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream,
33 struct snd_pcm_hw_params *params)
35 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
36 unsigned int rate = params_rate(params);
37 unsigned int mclk_fs_ratio = 128;
38 unsigned int mclk_fs = rate * mclk_fs_ratio;
40 return snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0),
41 0, mclk_fs, SND_SOC_CLOCK_OUT);
44 static const struct snd_soc_ops mt8183_mt6358_i2s_ops = {
45 .hw_params = mt8183_mt6358_i2s_hw_params,
48 static int mt8183_da7219_i2s_hw_params(struct snd_pcm_substream *substream,
49 struct snd_pcm_hw_params *params)
51 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
52 struct snd_soc_dai *codec_dai;
53 unsigned int rate = params_rate(params);
54 unsigned int mclk_fs_ratio = 256;
55 unsigned int mclk_fs = rate * mclk_fs_ratio;
59 ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0,
60 mclk_fs, SND_SOC_CLOCK_OUT);
62 dev_err(rtd->dev, "failed to set cpu dai sysclk\n");
64 for_each_rtd_codec_dais(rtd, j, codec_dai) {
65 if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
66 ret = snd_soc_dai_set_sysclk(codec_dai,
71 dev_err(rtd->dev, "failed to set sysclk\n");
73 if ((rate % 8000) == 0)
74 freq = DA7219_PLL_FREQ_OUT_98304;
76 freq = DA7219_PLL_FREQ_OUT_90316;
78 ret = snd_soc_dai_set_pll(codec_dai, 0,
79 DA7219_SYSCLK_PLL_SRM,
82 dev_err(rtd->dev, "failed to start PLL: %d\n",
90 static int mt8183_da7219_hw_free(struct snd_pcm_substream *substream)
92 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
93 struct snd_soc_dai *codec_dai;
96 for_each_rtd_codec_dais(rtd, j, codec_dai) {
97 if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
98 ret = snd_soc_dai_set_pll(codec_dai,
99 0, DA7219_SYSCLK_MCLK, 0, 0);
101 dev_err(rtd->dev, "failed to stop PLL: %d\n",
111 static const struct snd_soc_ops mt8183_da7219_i2s_ops = {
112 .hw_params = mt8183_da7219_i2s_hw_params,
113 .hw_free = mt8183_da7219_hw_free,
117 mt8183_da7219_rt1015_i2s_hw_params(struct snd_pcm_substream *substream,
118 struct snd_pcm_hw_params *params)
120 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
121 unsigned int rate = params_rate(params);
122 struct snd_soc_dai *codec_dai;
125 for_each_rtd_codec_dais(rtd, i, codec_dai) {
126 if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) ||
127 !strcmp(codec_dai->component->name, RT1015_DEV1_NAME)) {
128 ret = snd_soc_dai_set_pll(codec_dai, 0,
130 rate * 64, rate * 256);
132 dev_err(rtd->dev, "failed to set pll\n");
136 ret = snd_soc_dai_set_sysclk(codec_dai,
141 dev_err(rtd->dev, "failed to set sysclk\n");
147 return mt8183_da7219_i2s_hw_params(substream, params);
150 static const struct snd_soc_ops mt8183_da7219_rt1015_i2s_ops = {
151 .hw_params = mt8183_da7219_rt1015_i2s_hw_params,
152 .hw_free = mt8183_da7219_hw_free,
155 static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
156 struct snd_pcm_hw_params *params)
158 /* fix BE i2s format to S32_LE, clean param mask first */
159 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
160 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
162 params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
167 static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
168 struct snd_pcm_hw_params *params)
170 /* fix BE i2s format to S24_LE, clean param mask first */
171 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
172 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
174 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
180 mt8183_da7219_max98357_startup(
181 struct snd_pcm_substream *substream)
183 static const unsigned int rates[] = {
186 static const struct snd_pcm_hw_constraint_list constraints_rates = {
187 .count = ARRAY_SIZE(rates),
191 static const unsigned int channels[] = {
194 static const struct snd_pcm_hw_constraint_list constraints_channels = {
195 .count = ARRAY_SIZE(channels),
200 struct snd_pcm_runtime *runtime = substream->runtime;
202 snd_pcm_hw_constraint_list(runtime, 0,
203 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
204 runtime->hw.channels_max = 2;
205 snd_pcm_hw_constraint_list(runtime, 0,
206 SNDRV_PCM_HW_PARAM_CHANNELS,
207 &constraints_channels);
209 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
210 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
215 static const struct snd_soc_ops mt8183_da7219_max98357_ops = {
216 .startup = mt8183_da7219_max98357_startup,
220 mt8183_da7219_max98357_bt_sco_startup(
221 struct snd_pcm_substream *substream)
223 static const unsigned int rates[] = {
226 static const struct snd_pcm_hw_constraint_list constraints_rates = {
227 .count = ARRAY_SIZE(rates),
231 static const unsigned int channels[] = {
234 static const struct snd_pcm_hw_constraint_list constraints_channels = {
235 .count = ARRAY_SIZE(channels),
240 struct snd_pcm_runtime *runtime = substream->runtime;
242 snd_pcm_hw_constraint_list(runtime, 0,
243 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
244 runtime->hw.channels_max = 1;
245 snd_pcm_hw_constraint_list(runtime, 0,
246 SNDRV_PCM_HW_PARAM_CHANNELS,
247 &constraints_channels);
249 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
250 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
255 static const struct snd_soc_ops mt8183_da7219_max98357_bt_sco_ops = {
256 .startup = mt8183_da7219_max98357_bt_sco_startup,
260 SND_SOC_DAILINK_DEFS(playback1,
261 DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
262 DAILINK_COMP_ARRAY(COMP_DUMMY()),
263 DAILINK_COMP_ARRAY(COMP_EMPTY()));
265 SND_SOC_DAILINK_DEFS(playback2,
266 DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
267 DAILINK_COMP_ARRAY(COMP_DUMMY()),
268 DAILINK_COMP_ARRAY(COMP_EMPTY()));
270 SND_SOC_DAILINK_DEFS(playback3,
271 DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
272 DAILINK_COMP_ARRAY(COMP_DUMMY()),
273 DAILINK_COMP_ARRAY(COMP_EMPTY()));
275 SND_SOC_DAILINK_DEFS(capture1,
276 DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
277 DAILINK_COMP_ARRAY(COMP_DUMMY()),
278 DAILINK_COMP_ARRAY(COMP_EMPTY()));
280 SND_SOC_DAILINK_DEFS(capture2,
281 DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
282 DAILINK_COMP_ARRAY(COMP_DUMMY()),
283 DAILINK_COMP_ARRAY(COMP_EMPTY()));
285 SND_SOC_DAILINK_DEFS(capture3,
286 DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
287 DAILINK_COMP_ARRAY(COMP_DUMMY()),
288 DAILINK_COMP_ARRAY(COMP_EMPTY()));
290 SND_SOC_DAILINK_DEFS(capture_mono,
291 DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")),
292 DAILINK_COMP_ARRAY(COMP_DUMMY()),
293 DAILINK_COMP_ARRAY(COMP_EMPTY()));
295 SND_SOC_DAILINK_DEFS(playback_hdmi,
296 DAILINK_COMP_ARRAY(COMP_CPU("HDMI")),
297 DAILINK_COMP_ARRAY(COMP_DUMMY()),
298 DAILINK_COMP_ARRAY(COMP_EMPTY()));
301 SND_SOC_DAILINK_DEFS(primary_codec,
302 DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
303 DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")),
304 DAILINK_COMP_ARRAY(COMP_EMPTY()));
306 SND_SOC_DAILINK_DEFS(pcm1,
307 DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
308 DAILINK_COMP_ARRAY(COMP_DUMMY()),
309 DAILINK_COMP_ARRAY(COMP_EMPTY()));
311 SND_SOC_DAILINK_DEFS(pcm2,
312 DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")),
313 DAILINK_COMP_ARRAY(COMP_DUMMY()),
314 DAILINK_COMP_ARRAY(COMP_EMPTY()));
316 SND_SOC_DAILINK_DEFS(i2s0,
317 DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
318 DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
319 DAILINK_COMP_ARRAY(COMP_EMPTY()));
321 SND_SOC_DAILINK_DEFS(i2s1,
322 DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
323 DAILINK_COMP_ARRAY(COMP_DUMMY()),
324 DAILINK_COMP_ARRAY(COMP_EMPTY()));
326 SND_SOC_DAILINK_DEFS(i2s2,
327 DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
328 DAILINK_COMP_ARRAY(COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
329 DAILINK_COMP_ARRAY(COMP_EMPTY()));
331 SND_SOC_DAILINK_DEFS(i2s3_max98357a,
332 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
333 DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi"),
334 COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
335 DAILINK_COMP_ARRAY(COMP_EMPTY()));
337 SND_SOC_DAILINK_DEFS(i2s3_rt1015,
338 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
339 DAILINK_COMP_ARRAY(COMP_CODEC(RT1015_DEV0_NAME, RT1015_CODEC_DAI),
340 COMP_CODEC(RT1015_DEV1_NAME, RT1015_CODEC_DAI),
341 COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
342 DAILINK_COMP_ARRAY(COMP_EMPTY()));
344 SND_SOC_DAILINK_DEFS(i2s3_rt1015p,
345 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
346 DAILINK_COMP_ARRAY(COMP_CODEC("rt1015p", "HiFi"),
347 COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
348 DAILINK_COMP_ARRAY(COMP_EMPTY()));
350 SND_SOC_DAILINK_DEFS(i2s5,
351 DAILINK_COMP_ARRAY(COMP_CPU("I2S5")),
352 DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
353 DAILINK_COMP_ARRAY(COMP_EMPTY()));
355 SND_SOC_DAILINK_DEFS(tdm,
356 DAILINK_COMP_ARRAY(COMP_CPU("TDM")),
357 DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")),
358 DAILINK_COMP_ARRAY(COMP_EMPTY()));
360 static int mt8183_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd)
362 struct mt8183_da7219_max98357_priv *priv =
363 snd_soc_card_get_drvdata(rtd->card);
366 ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
371 return snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component,
372 &priv->hdmi_jack, NULL);
375 static struct snd_soc_dai_link mt8183_da7219_dai_links[] = {
378 .name = "Playback_1",
379 .stream_name = "Playback_1",
380 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
381 SND_SOC_DPCM_TRIGGER_PRE},
384 .ops = &mt8183_da7219_max98357_ops,
385 SND_SOC_DAILINK_REG(playback1),
388 .name = "Playback_2",
389 .stream_name = "Playback_2",
390 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
391 SND_SOC_DPCM_TRIGGER_PRE},
394 .ops = &mt8183_da7219_max98357_bt_sco_ops,
395 SND_SOC_DAILINK_REG(playback2),
398 .name = "Playback_3",
399 .stream_name = "Playback_3",
400 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
401 SND_SOC_DPCM_TRIGGER_PRE},
404 SND_SOC_DAILINK_REG(playback3),
408 .stream_name = "Capture_1",
409 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
410 SND_SOC_DPCM_TRIGGER_PRE},
413 .ops = &mt8183_da7219_max98357_bt_sco_ops,
414 SND_SOC_DAILINK_REG(capture1),
418 .stream_name = "Capture_2",
419 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
420 SND_SOC_DPCM_TRIGGER_PRE},
423 SND_SOC_DAILINK_REG(capture2),
427 .stream_name = "Capture_3",
428 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
429 SND_SOC_DPCM_TRIGGER_PRE},
432 .ops = &mt8183_da7219_max98357_ops,
433 SND_SOC_DAILINK_REG(capture3),
436 .name = "Capture_Mono_1",
437 .stream_name = "Capture_Mono_1",
438 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
439 SND_SOC_DPCM_TRIGGER_PRE},
442 SND_SOC_DAILINK_REG(capture_mono),
445 .name = "Playback_HDMI",
446 .stream_name = "Playback_HDMI",
447 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
448 SND_SOC_DPCM_TRIGGER_PRE},
451 SND_SOC_DAILINK_REG(playback_hdmi),
455 .name = "Primary Codec",
460 SND_SOC_DAILINK_REG(primary_codec),
468 SND_SOC_DAILINK_REG(pcm1),
476 SND_SOC_DAILINK_REG(pcm2),
483 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
484 .ops = &mt8183_mt6358_i2s_ops,
485 SND_SOC_DAILINK_REG(i2s0),
492 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
493 .ops = &mt8183_mt6358_i2s_ops,
494 SND_SOC_DAILINK_REG(i2s1),
501 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
502 .ops = &mt8183_da7219_i2s_ops,
503 SND_SOC_DAILINK_REG(i2s2),
516 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
517 .ops = &mt8183_mt6358_i2s_ops,
518 SND_SOC_DAILINK_REG(i2s5),
523 .dai_fmt = SND_SOC_DAIFMT_I2S |
524 SND_SOC_DAIFMT_IB_IF |
525 SND_SOC_DAIFMT_CBM_CFM,
528 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
530 .init = mt8183_da7219_max98357_hdmi_init,
531 SND_SOC_DAILINK_REG(tdm),
536 mt8183_da7219_max98357_headset_init(struct snd_soc_component *component)
539 struct mt8183_da7219_max98357_priv *priv =
540 snd_soc_card_get_drvdata(component->card);
542 /* Enable Headset and 4 Buttons Jack detection */
543 ret = snd_soc_card_jack_new(component->card,
546 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
547 SND_JACK_BTN_2 | SND_JACK_BTN_3 |
549 &priv->headset_jack);
554 priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
556 priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
558 priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
560 priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
562 da7219_aad_jack_det(component, &priv->headset_jack);
567 static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = {
569 .init = mt8183_da7219_max98357_headset_init,
572 static struct snd_soc_codec_conf mt6358_codec_conf[] = {
574 .dlc = COMP_CODEC_CONF("mt6358-sound"),
575 .name_prefix = "Mt6358",
579 static const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = {
580 SOC_DAPM_PIN_SWITCH("Speakers"),
584 struct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = {
585 SND_SOC_DAPM_SPK("Speakers", NULL),
586 SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
587 "aud_tdm_out_on", "aud_tdm_out_off"),
590 static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = {
591 {"Speakers", NULL, "Speaker"},
592 {"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
595 static struct snd_soc_card mt8183_da7219_max98357_card = {
596 .name = "mt8183_da7219_max98357",
597 .owner = THIS_MODULE,
598 .controls = mt8183_da7219_max98357_snd_controls,
599 .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
600 .dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
601 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
602 .dapm_routes = mt8183_da7219_max98357_dapm_routes,
603 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
604 .dai_link = mt8183_da7219_dai_links,
605 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
606 .aux_dev = &mt8183_da7219_max98357_headset_dev,
608 .codec_conf = mt6358_codec_conf,
609 .num_configs = ARRAY_SIZE(mt6358_codec_conf),
612 static struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = {
614 .dlc = COMP_CODEC_CONF("mt6358-sound"),
615 .name_prefix = "Mt6358",
618 .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME),
619 .name_prefix = "Left",
622 .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME),
623 .name_prefix = "Right",
627 static const struct snd_kcontrol_new mt8183_da7219_rt1015_snd_controls[] = {
628 SOC_DAPM_PIN_SWITCH("Left Spk"),
629 SOC_DAPM_PIN_SWITCH("Right Spk"),
633 struct snd_soc_dapm_widget mt8183_da7219_rt1015_dapm_widgets[] = {
634 SND_SOC_DAPM_SPK("Left Spk", NULL),
635 SND_SOC_DAPM_SPK("Right Spk", NULL),
636 SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
637 "aud_tdm_out_on", "aud_tdm_out_off"),
640 static const struct snd_soc_dapm_route mt8183_da7219_rt1015_dapm_routes[] = {
641 {"Left Spk", NULL, "Left SPO"},
642 {"Right Spk", NULL, "Right SPO"},
643 {"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
646 static struct snd_soc_card mt8183_da7219_rt1015_card = {
647 .name = "mt8183_da7219_rt1015",
648 .owner = THIS_MODULE,
649 .controls = mt8183_da7219_rt1015_snd_controls,
650 .num_controls = ARRAY_SIZE(mt8183_da7219_rt1015_snd_controls),
651 .dapm_widgets = mt8183_da7219_rt1015_dapm_widgets,
652 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_widgets),
653 .dapm_routes = mt8183_da7219_rt1015_dapm_routes,
654 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_routes),
655 .dai_link = mt8183_da7219_dai_links,
656 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
657 .aux_dev = &mt8183_da7219_max98357_headset_dev,
659 .codec_conf = mt8183_da7219_rt1015_codec_conf,
660 .num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf),
663 static struct snd_soc_card mt8183_da7219_rt1015p_card = {
664 .name = "mt8183_da7219_rt1015p",
665 .owner = THIS_MODULE,
666 .controls = mt8183_da7219_max98357_snd_controls,
667 .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
668 .dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
669 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
670 .dapm_routes = mt8183_da7219_max98357_dapm_routes,
671 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
672 .dai_link = mt8183_da7219_dai_links,
673 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
674 .aux_dev = &mt8183_da7219_max98357_headset_dev,
676 .codec_conf = mt6358_codec_conf,
677 .num_configs = ARRAY_SIZE(mt6358_codec_conf),
680 static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
682 struct snd_soc_card *card;
683 struct device_node *platform_node, *hdmi_codec;
684 struct snd_soc_dai_link *dai_link;
685 struct mt8183_da7219_max98357_priv *priv;
686 struct pinctrl *pinctrl;
689 platform_node = of_parse_phandle(pdev->dev.of_node,
690 "mediatek,platform", 0);
691 if (!platform_node) {
692 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
696 card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev);
699 goto put_platform_node;
702 card->dev = &pdev->dev;
704 hdmi_codec = of_parse_phandle(pdev->dev.of_node,
705 "mediatek,hdmi-codec", 0);
707 for_each_card_prelinks(card, i, dai_link) {
708 if (strcmp(dai_link->name, "I2S3") == 0) {
709 if (card == &mt8183_da7219_max98357_card) {
710 dai_link->be_hw_params_fixup =
711 mt8183_i2s_hw_params_fixup;
712 dai_link->ops = &mt8183_da7219_i2s_ops;
713 dai_link->cpus = i2s3_max98357a_cpus;
715 ARRAY_SIZE(i2s3_max98357a_cpus);
716 dai_link->codecs = i2s3_max98357a_codecs;
717 dai_link->num_codecs =
718 ARRAY_SIZE(i2s3_max98357a_codecs);
719 dai_link->platforms = i2s3_max98357a_platforms;
720 dai_link->num_platforms =
721 ARRAY_SIZE(i2s3_max98357a_platforms);
722 } else if (card == &mt8183_da7219_rt1015_card) {
723 dai_link->be_hw_params_fixup =
724 mt8183_rt1015_i2s_hw_params_fixup;
725 dai_link->ops = &mt8183_da7219_rt1015_i2s_ops;
726 dai_link->cpus = i2s3_rt1015_cpus;
728 ARRAY_SIZE(i2s3_rt1015_cpus);
729 dai_link->codecs = i2s3_rt1015_codecs;
730 dai_link->num_codecs =
731 ARRAY_SIZE(i2s3_rt1015_codecs);
732 dai_link->platforms = i2s3_rt1015_platforms;
733 dai_link->num_platforms =
734 ARRAY_SIZE(i2s3_rt1015_platforms);
735 } else if (card == &mt8183_da7219_rt1015p_card) {
736 dai_link->be_hw_params_fixup =
737 mt8183_rt1015_i2s_hw_params_fixup;
738 dai_link->ops = &mt8183_da7219_i2s_ops;
739 dai_link->cpus = i2s3_rt1015p_cpus;
741 ARRAY_SIZE(i2s3_rt1015p_cpus);
742 dai_link->codecs = i2s3_rt1015p_codecs;
743 dai_link->num_codecs =
744 ARRAY_SIZE(i2s3_rt1015p_codecs);
745 dai_link->platforms = i2s3_rt1015p_platforms;
746 dai_link->num_platforms =
747 ARRAY_SIZE(i2s3_rt1015p_platforms);
751 if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) {
752 dai_link->codecs->of_node = hdmi_codec;
753 dai_link->ignore = 0;
756 if (!dai_link->platforms->name)
757 dai_link->platforms->of_node = platform_node;
760 mt8183_da7219_max98357_headset_dev.dlc.of_node =
761 of_parse_phandle(pdev->dev.of_node,
762 "mediatek,headset-codec", 0);
763 if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) {
765 "Property 'mediatek,headset-codec' missing/invalid\n");
770 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
776 snd_soc_card_set_drvdata(card, priv);
778 pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT);
779 if (IS_ERR(pinctrl)) {
780 ret = PTR_ERR(pinctrl);
781 dev_err(&pdev->dev, "%s failed to select default state %d\n",
786 ret = devm_snd_soc_register_card(&pdev->dev, card);
790 of_node_put(hdmi_codec);
792 of_node_put(platform_node);
797 static const struct of_device_id mt8183_da7219_max98357_dt_match[] = {
799 .compatible = "mediatek,mt8183_da7219_max98357",
800 .data = &mt8183_da7219_max98357_card,
803 .compatible = "mediatek,mt8183_da7219_rt1015",
804 .data = &mt8183_da7219_rt1015_card,
807 .compatible = "mediatek,mt8183_da7219_rt1015p",
808 .data = &mt8183_da7219_rt1015p_card,
814 static struct platform_driver mt8183_da7219_max98357_driver = {
816 .name = "mt8183_da7219",
818 .of_match_table = mt8183_da7219_max98357_dt_match,
820 .pm = &snd_soc_pm_ops,
822 .probe = mt8183_da7219_max98357_dev_probe,
825 module_platform_driver(mt8183_da7219_max98357_driver);
827 /* Module information */
828 MODULE_DESCRIPTION("MT8183-DA7219-MAX98357 ALSA SoC machine driver");
829 MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>");
830 MODULE_LICENSE("GPL v2");
831 MODULE_ALIAS("mt8183_da7219_max98357 soc card");