xref: /openbmc/linux/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c (revision 2d27a4cf19674ff5c05d84e1037d8793e1090065)
1ebbddc75SShunli Wang // SPDX-License-Identifier: GPL-2.0
2ebbddc75SShunli Wang //
3ebbddc75SShunli Wang // mt8183-da7219-max98357.c
4ebbddc75SShunli Wang //	--  MT8183-DA7219-MAX98357 ALSA SoC machine driver
5ebbddc75SShunli Wang //
6ebbddc75SShunli Wang // Copyright (c) 2018 MediaTek Inc.
7ebbddc75SShunli Wang // Author: Shunli Wang <shunli.wang@mediatek.com>
8ebbddc75SShunli Wang 
9ebbddc75SShunli Wang #include <linux/module.h>
10ebbddc75SShunli Wang #include <sound/pcm_params.h>
11ebbddc75SShunli Wang #include <sound/soc.h>
12ebbddc75SShunli Wang #include <sound/jack.h>
13ebbddc75SShunli Wang #include <linux/pinctrl/consumer.h>
14ebbddc75SShunli Wang 
15ebbddc75SShunli Wang #include "mt8183-afe-common.h"
16ebbddc75SShunli Wang #include "../../codecs/da7219-aad.h"
17ebbddc75SShunli Wang #include "../../codecs/da7219.h"
18ebbddc75SShunli Wang 
19ebbddc75SShunli Wang static struct snd_soc_jack headset_jack;
20ebbddc75SShunli Wang 
21ebbddc75SShunli Wang static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream,
22ebbddc75SShunli Wang 				       struct snd_pcm_hw_params *params)
23ebbddc75SShunli Wang {
24ebbddc75SShunli Wang 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
25ebbddc75SShunli Wang 	unsigned int rate = params_rate(params);
26ebbddc75SShunli Wang 	unsigned int mclk_fs_ratio = 128;
27ebbddc75SShunli Wang 	unsigned int mclk_fs = rate * mclk_fs_ratio;
28ebbddc75SShunli Wang 
29ebbddc75SShunli Wang 	return snd_soc_dai_set_sysclk(rtd->cpu_dai,
30ebbddc75SShunli Wang 				      0, mclk_fs, SND_SOC_CLOCK_OUT);
31ebbddc75SShunli Wang }
32ebbddc75SShunli Wang 
33ebbddc75SShunli Wang static const struct snd_soc_ops mt8183_mt6358_i2s_ops = {
34ebbddc75SShunli Wang 	.hw_params = mt8183_mt6358_i2s_hw_params,
35ebbddc75SShunli Wang };
36ebbddc75SShunli Wang 
37ebbddc75SShunli Wang static int mt8183_da7219_i2s_hw_params(struct snd_pcm_substream *substream,
38ebbddc75SShunli Wang 				       struct snd_pcm_hw_params *params)
39ebbddc75SShunli Wang {
40ebbddc75SShunli Wang 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
41ebbddc75SShunli Wang 	unsigned int rate = params_rate(params);
42ebbddc75SShunli Wang 	unsigned int mclk_fs_ratio = 256;
43ebbddc75SShunli Wang 	unsigned int mclk_fs = rate * mclk_fs_ratio;
44ebbddc75SShunli Wang 	unsigned int freq;
45ebbddc75SShunli Wang 	int ret = 0, j;
46ebbddc75SShunli Wang 
47ebbddc75SShunli Wang 	ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0,
48ebbddc75SShunli Wang 				     mclk_fs, SND_SOC_CLOCK_OUT);
49ebbddc75SShunli Wang 	if (ret < 0)
50ebbddc75SShunli Wang 		dev_err(rtd->dev, "failed to set cpu dai sysclk\n");
51ebbddc75SShunli Wang 
52ebbddc75SShunli Wang 	for (j = 0; j < rtd->num_codecs; j++) {
53ebbddc75SShunli Wang 		struct snd_soc_dai *codec_dai = rtd->codec_dais[j];
54ebbddc75SShunli Wang 
55ebbddc75SShunli Wang 		if (!strcmp(codec_dai->component->name, "da7219.5-001a")) {
56ebbddc75SShunli Wang 			ret = snd_soc_dai_set_sysclk(codec_dai,
57ebbddc75SShunli Wang 						     DA7219_CLKSRC_MCLK,
58ebbddc75SShunli Wang 						     mclk_fs,
59ebbddc75SShunli Wang 						     SND_SOC_CLOCK_IN);
60ebbddc75SShunli Wang 			if (ret < 0)
61ebbddc75SShunli Wang 				dev_err(rtd->dev, "failed to set sysclk\n");
62ebbddc75SShunli Wang 
63ebbddc75SShunli Wang 			if ((rate % 8000) == 0)
64ebbddc75SShunli Wang 				freq = DA7219_PLL_FREQ_OUT_98304;
65ebbddc75SShunli Wang 			else
66ebbddc75SShunli Wang 				freq = DA7219_PLL_FREQ_OUT_90316;
67ebbddc75SShunli Wang 
68ebbddc75SShunli Wang 			ret = snd_soc_dai_set_pll(codec_dai, 0,
69ebbddc75SShunli Wang 						  DA7219_SYSCLK_PLL_SRM,
70ebbddc75SShunli Wang 						  0, freq);
71ebbddc75SShunli Wang 			if (ret)
72ebbddc75SShunli Wang 				dev_err(rtd->dev, "failed to start PLL: %d\n",
73ebbddc75SShunli Wang 					ret);
74ebbddc75SShunli Wang 		}
75ebbddc75SShunli Wang 	}
76ebbddc75SShunli Wang 
77ebbddc75SShunli Wang 	return ret;
78ebbddc75SShunli Wang }
79ebbddc75SShunli Wang 
80ebbddc75SShunli Wang static int mt8183_da7219_hw_free(struct snd_pcm_substream *substream)
81ebbddc75SShunli Wang {
82ebbddc75SShunli Wang 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
83ebbddc75SShunli Wang 	int ret = 0, j;
84ebbddc75SShunli Wang 
85ebbddc75SShunli Wang 	for (j = 0; j < rtd->num_codecs; j++) {
86ebbddc75SShunli Wang 		struct snd_soc_dai *codec_dai = rtd->codec_dais[j];
87ebbddc75SShunli Wang 
88ebbddc75SShunli Wang 		if (!strcmp(codec_dai->component->name, "da7219.5-001a")) {
89ebbddc75SShunli Wang 			ret = snd_soc_dai_set_pll(codec_dai,
90ebbddc75SShunli Wang 						  0, DA7219_SYSCLK_MCLK, 0, 0);
91ebbddc75SShunli Wang 			if (ret < 0) {
92ebbddc75SShunli Wang 				dev_err(rtd->dev, "failed to stop PLL: %d\n",
93ebbddc75SShunli Wang 					ret);
94ebbddc75SShunli Wang 				break;
95ebbddc75SShunli Wang 			}
96ebbddc75SShunli Wang 		}
97ebbddc75SShunli Wang 	}
98ebbddc75SShunli Wang 
99ebbddc75SShunli Wang 	return ret;
100ebbddc75SShunli Wang }
101ebbddc75SShunli Wang 
102ebbddc75SShunli Wang static const struct snd_soc_ops mt8183_da7219_i2s_ops = {
103ebbddc75SShunli Wang 	.hw_params = mt8183_da7219_i2s_hw_params,
104ebbddc75SShunli Wang 	.hw_free = mt8183_da7219_hw_free,
105ebbddc75SShunli Wang };
106ebbddc75SShunli Wang 
107ebbddc75SShunli Wang static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
108ebbddc75SShunli Wang 				      struct snd_pcm_hw_params *params)
109ebbddc75SShunli Wang {
110ebbddc75SShunli Wang 	/* fix BE i2s format to 32bit, clean param mask first */
111ebbddc75SShunli Wang 	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
112ebbddc75SShunli Wang 			     0, SNDRV_PCM_FORMAT_LAST);
113ebbddc75SShunli Wang 
114ebbddc75SShunli Wang 	params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
115ebbddc75SShunli Wang 
116ebbddc75SShunli Wang 	return 0;
117ebbddc75SShunli Wang }
118ebbddc75SShunli Wang 
1194b990642SKuninori Morimoto /* FE */
1204b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(playback1,
1214b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
1224b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
1234b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
1244b990642SKuninori Morimoto 
1254b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(playback2,
1264b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
1274b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
1284b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
1294b990642SKuninori Morimoto 
1304b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(playback3,
1314b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
1324b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
1334b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
1344b990642SKuninori Morimoto 
1354b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(capture1,
1364b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
1374b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
1384b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
1394b990642SKuninori Morimoto 
1404b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(capture2,
1414b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
1424b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
1434b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
1444b990642SKuninori Morimoto 
1454b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(capture3,
1464b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
1474b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
1484b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
1494b990642SKuninori Morimoto 
1504b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(capture_mono,
1514b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")),
1524b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
1534b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
1544b990642SKuninori Morimoto 
1554b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(playback_hdmi,
1564b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("HDMI")),
1574b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
1584b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
1594b990642SKuninori Morimoto 
1604b990642SKuninori Morimoto /* BE */
1614b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(primary_codec,
1624b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
1634b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")),
1644b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
1654b990642SKuninori Morimoto 
1664b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(pcm1,
1674b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
1684b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
1694b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
1704b990642SKuninori Morimoto 
1714b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(pcm2,
1724b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")),
1734b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
1744b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
1754b990642SKuninori Morimoto 
1764b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(i2s0,
1774b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
1784b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
1794b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
1804b990642SKuninori Morimoto 
1814b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(i2s1,
1824b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
1834b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
1844b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
1854b990642SKuninori Morimoto 
1864b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(i2s2,
1874b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
1884b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CODEC("da7219.5-001a", "da7219-hifi")),
1894b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
1904b990642SKuninori Morimoto 
1914b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(i2s3,
1924b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
1934b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi"),
1944b990642SKuninori Morimoto 			 COMP_CODEC("da7219.5-001a", "da7219-hifi")),
1954b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
1964b990642SKuninori Morimoto 
1974b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(i2s5,
1984b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("I2S5")),
1994b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
2004b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
2014b990642SKuninori Morimoto 
2024b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(tdm,
2034b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("TDM")),
2044b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
2054b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
2064b990642SKuninori Morimoto 
207ebbddc75SShunli Wang static struct snd_soc_dai_link mt8183_da7219_max98357_dai_links[] = {
208ebbddc75SShunli Wang 	/* FE */
209ebbddc75SShunli Wang 	{
210ebbddc75SShunli Wang 		.name = "Playback_1",
211ebbddc75SShunli Wang 		.stream_name = "Playback_1",
212ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
213ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
214ebbddc75SShunli Wang 		.dynamic = 1,
215ebbddc75SShunli Wang 		.dpcm_playback = 1,
2164b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(playback1),
217ebbddc75SShunli Wang 	},
218ebbddc75SShunli Wang 	{
219ebbddc75SShunli Wang 		.name = "Playback_2",
220ebbddc75SShunli Wang 		.stream_name = "Playback_2",
221ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
222ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
223ebbddc75SShunli Wang 		.dynamic = 1,
224ebbddc75SShunli Wang 		.dpcm_playback = 1,
2254b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(playback2),
226ebbddc75SShunli Wang 	},
227ebbddc75SShunli Wang 	{
228ebbddc75SShunli Wang 		.name = "Playback_3",
229ebbddc75SShunli Wang 		.stream_name = "Playback_3",
230ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
231ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
232ebbddc75SShunli Wang 		.dynamic = 1,
233ebbddc75SShunli Wang 		.dpcm_playback = 1,
2344b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(playback3),
235ebbddc75SShunli Wang 	},
236ebbddc75SShunli Wang 	{
237ebbddc75SShunli Wang 		.name = "Capture_1",
238ebbddc75SShunli Wang 		.stream_name = "Capture_1",
239ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
240ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
241ebbddc75SShunli Wang 		.dynamic = 1,
242ebbddc75SShunli Wang 		.dpcm_capture = 1,
2434b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(capture1),
244ebbddc75SShunli Wang 	},
245ebbddc75SShunli Wang 	{
246ebbddc75SShunli Wang 		.name = "Capture_2",
247ebbddc75SShunli Wang 		.stream_name = "Capture_2",
248ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
249ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
250ebbddc75SShunli Wang 		.dynamic = 1,
251ebbddc75SShunli Wang 		.dpcm_capture = 1,
2524b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(capture2),
253ebbddc75SShunli Wang 	},
254ebbddc75SShunli Wang 	{
255ebbddc75SShunli Wang 		.name = "Capture_3",
256ebbddc75SShunli Wang 		.stream_name = "Capture_3",
257ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
258ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
259ebbddc75SShunli Wang 		.dynamic = 1,
260ebbddc75SShunli Wang 		.dpcm_capture = 1,
2614b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(capture3),
262ebbddc75SShunli Wang 	},
263ebbddc75SShunli Wang 	{
264ebbddc75SShunli Wang 		.name = "Capture_Mono_1",
265ebbddc75SShunli Wang 		.stream_name = "Capture_Mono_1",
266ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
267ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
268ebbddc75SShunli Wang 		.dynamic = 1,
269ebbddc75SShunli Wang 		.dpcm_capture = 1,
2704b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(capture_mono),
271ebbddc75SShunli Wang 	},
272ebbddc75SShunli Wang 	{
273ebbddc75SShunli Wang 		.name = "Playback_HDMI",
274ebbddc75SShunli Wang 		.stream_name = "Playback_HDMI",
275ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
276ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
277ebbddc75SShunli Wang 		.dynamic = 1,
278ebbddc75SShunli Wang 		.dpcm_playback = 1,
2794b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(playback_hdmi),
280ebbddc75SShunli Wang 	},
281ebbddc75SShunli Wang 	/* BE */
282ebbddc75SShunli Wang 	{
283ebbddc75SShunli Wang 		.name = "Primary Codec",
284ebbddc75SShunli Wang 		.no_pcm = 1,
285ebbddc75SShunli Wang 		.dpcm_playback = 1,
286ebbddc75SShunli Wang 		.dpcm_capture = 1,
287ebbddc75SShunli Wang 		.ignore_suspend = 1,
2884b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(primary_codec),
289ebbddc75SShunli Wang 	},
290ebbddc75SShunli Wang 	{
291ebbddc75SShunli Wang 		.name = "PCM 1",
292ebbddc75SShunli Wang 		.no_pcm = 1,
293ebbddc75SShunli Wang 		.dpcm_playback = 1,
294ebbddc75SShunli Wang 		.dpcm_capture = 1,
295ebbddc75SShunli Wang 		.ignore_suspend = 1,
2964b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(pcm1),
297ebbddc75SShunli Wang 	},
298ebbddc75SShunli Wang 	{
299ebbddc75SShunli Wang 		.name = "PCM 2",
300ebbddc75SShunli Wang 		.no_pcm = 1,
301ebbddc75SShunli Wang 		.dpcm_playback = 1,
302ebbddc75SShunli Wang 		.dpcm_capture = 1,
303ebbddc75SShunli Wang 		.ignore_suspend = 1,
3044b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(pcm2),
305ebbddc75SShunli Wang 	},
306ebbddc75SShunli Wang 	{
307ebbddc75SShunli Wang 		.name = "I2S0",
308ebbddc75SShunli Wang 		.no_pcm = 1,
309ebbddc75SShunli Wang 		.dpcm_capture = 1,
310ebbddc75SShunli Wang 		.ignore_suspend = 1,
311ebbddc75SShunli Wang 		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
312ebbddc75SShunli Wang 		.ops = &mt8183_mt6358_i2s_ops,
3134b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(i2s0),
314ebbddc75SShunli Wang 	},
315ebbddc75SShunli Wang 	{
316ebbddc75SShunli Wang 		.name = "I2S1",
317ebbddc75SShunli Wang 		.no_pcm = 1,
318ebbddc75SShunli Wang 		.dpcm_playback = 1,
319ebbddc75SShunli Wang 		.ignore_suspend = 1,
320ebbddc75SShunli Wang 		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
321ebbddc75SShunli Wang 		.ops = &mt8183_mt6358_i2s_ops,
3224b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(i2s1),
323ebbddc75SShunli Wang 	},
324ebbddc75SShunli Wang 	{
325ebbddc75SShunli Wang 		.name = "I2S2",
326ebbddc75SShunli Wang 		.no_pcm = 1,
327ebbddc75SShunli Wang 		.dpcm_capture = 1,
328ebbddc75SShunli Wang 		.ignore_suspend = 1,
329ebbddc75SShunli Wang 		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
330ebbddc75SShunli Wang 		.ops = &mt8183_da7219_i2s_ops,
3314b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(i2s2),
332ebbddc75SShunli Wang 	},
333ebbddc75SShunli Wang 	{
334ebbddc75SShunli Wang 		.name = "I2S3",
335ebbddc75SShunli Wang 		.no_pcm = 1,
336ebbddc75SShunli Wang 		.dpcm_playback = 1,
337ebbddc75SShunli Wang 		.ignore_suspend = 1,
338ebbddc75SShunli Wang 		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
339ebbddc75SShunli Wang 		.ops = &mt8183_da7219_i2s_ops,
3404b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(i2s3),
341ebbddc75SShunli Wang 	},
342ebbddc75SShunli Wang 	{
343ebbddc75SShunli Wang 		.name = "I2S5",
344ebbddc75SShunli Wang 		.no_pcm = 1,
345ebbddc75SShunli Wang 		.dpcm_playback = 1,
346ebbddc75SShunli Wang 		.ignore_suspend = 1,
347ebbddc75SShunli Wang 		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
348ebbddc75SShunli Wang 		.ops = &mt8183_mt6358_i2s_ops,
3494b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(i2s5),
350ebbddc75SShunli Wang 	},
351ebbddc75SShunli Wang 	{
352ebbddc75SShunli Wang 		.name = "TDM",
353ebbddc75SShunli Wang 		.no_pcm = 1,
354ebbddc75SShunli Wang 		.dpcm_playback = 1,
355ebbddc75SShunli Wang 		.ignore_suspend = 1,
3564b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(tdm),
357ebbddc75SShunli Wang 	},
358ebbddc75SShunli Wang };
359ebbddc75SShunli Wang 
360ebbddc75SShunli Wang static int
361ebbddc75SShunli Wang mt8183_da7219_max98357_headset_init(struct snd_soc_component *component);
362ebbddc75SShunli Wang 
363ebbddc75SShunli Wang static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = {
3645c9e38cbSKuninori Morimoto 	.dlc = COMP_EMPTY(),
365ebbddc75SShunli Wang 	.init = mt8183_da7219_max98357_headset_init,
366ebbddc75SShunli Wang };
367ebbddc75SShunli Wang 
368ebbddc75SShunli Wang static struct snd_soc_codec_conf mt6358_codec_conf[] = {
369ebbddc75SShunli Wang 	{
370*2d27a4cfSKuninori Morimoto 		.dlc = COMP_CODEC_CONF("mt6358-sound"),
371ebbddc75SShunli Wang 		.name_prefix = "Mt6358",
372ebbddc75SShunli Wang 	},
373ebbddc75SShunli Wang };
374ebbddc75SShunli Wang 
375ebbddc75SShunli Wang static struct snd_soc_card mt8183_da7219_max98357_card = {
376ebbddc75SShunli Wang 	.name = "mt8183_da7219_max98357",
377ebbddc75SShunli Wang 	.owner = THIS_MODULE,
378ebbddc75SShunli Wang 	.dai_link = mt8183_da7219_max98357_dai_links,
379ebbddc75SShunli Wang 	.num_links = ARRAY_SIZE(mt8183_da7219_max98357_dai_links),
380ebbddc75SShunli Wang 	.aux_dev = &mt8183_da7219_max98357_headset_dev,
381ebbddc75SShunli Wang 	.num_aux_devs = 1,
382ebbddc75SShunli Wang 	.codec_conf = mt6358_codec_conf,
383ebbddc75SShunli Wang 	.num_configs = ARRAY_SIZE(mt6358_codec_conf),
384ebbddc75SShunli Wang };
385ebbddc75SShunli Wang 
386ebbddc75SShunli Wang static int
387ebbddc75SShunli Wang mt8183_da7219_max98357_headset_init(struct snd_soc_component *component)
388ebbddc75SShunli Wang {
389ebbddc75SShunli Wang 	int ret;
390ebbddc75SShunli Wang 
391ebbddc75SShunli Wang 	/* Enable Headset and 4 Buttons Jack detection */
392ebbddc75SShunli Wang 	ret = snd_soc_card_jack_new(&mt8183_da7219_max98357_card,
393ebbddc75SShunli Wang 				    "Headset Jack",
394ebbddc75SShunli Wang 				    SND_JACK_HEADSET |
395ebbddc75SShunli Wang 				    SND_JACK_BTN_0 | SND_JACK_BTN_1 |
396ebbddc75SShunli Wang 				    SND_JACK_BTN_2 | SND_JACK_BTN_3,
397ebbddc75SShunli Wang 				    &headset_jack,
398108d0d40STzung-Bi Shih 				    NULL, 0);
399ebbddc75SShunli Wang 	if (ret)
400ebbddc75SShunli Wang 		return ret;
401ebbddc75SShunli Wang 
402ebbddc75SShunli Wang 	da7219_aad_jack_det(component, &headset_jack);
403ebbddc75SShunli Wang 
404ebbddc75SShunli Wang 	return ret;
405ebbddc75SShunli Wang }
406ebbddc75SShunli Wang 
407ebbddc75SShunli Wang static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
408ebbddc75SShunli Wang {
409ebbddc75SShunli Wang 	struct snd_soc_card *card = &mt8183_da7219_max98357_card;
410ebbddc75SShunli Wang 	struct device_node *platform_node;
411ebbddc75SShunli Wang 	struct snd_soc_dai_link *dai_link;
412ebbddc75SShunli Wang 	struct pinctrl *default_pins;
413ebbddc75SShunli Wang 	int ret, i;
414ebbddc75SShunli Wang 
415ebbddc75SShunli Wang 	card->dev = &pdev->dev;
416ebbddc75SShunli Wang 
417ebbddc75SShunli Wang 	platform_node = of_parse_phandle(pdev->dev.of_node,
418ebbddc75SShunli Wang 					 "mediatek,platform", 0);
419ebbddc75SShunli Wang 	if (!platform_node) {
420ebbddc75SShunli Wang 		dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
421ebbddc75SShunli Wang 		return -EINVAL;
422ebbddc75SShunli Wang 	}
423ebbddc75SShunli Wang 
424ebbddc75SShunli Wang 	for_each_card_prelinks(card, i, dai_link) {
4254b990642SKuninori Morimoto 		if (dai_link->platforms->name)
426ebbddc75SShunli Wang 			continue;
4274b990642SKuninori Morimoto 		dai_link->platforms->of_node = platform_node;
428ebbddc75SShunli Wang 	}
429ebbddc75SShunli Wang 
4305c9e38cbSKuninori Morimoto 	mt8183_da7219_max98357_headset_dev.dlc.of_node =
431ebbddc75SShunli Wang 		of_parse_phandle(pdev->dev.of_node,
432ebbddc75SShunli Wang 				 "mediatek,headset-codec", 0);
4335c9e38cbSKuninori Morimoto 	if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) {
434ebbddc75SShunli Wang 		dev_err(&pdev->dev,
435ebbddc75SShunli Wang 			"Property 'mediatek,headset-codec' missing/invalid\n");
436ebbddc75SShunli Wang 		return -EINVAL;
437ebbddc75SShunli Wang 	}
438ebbddc75SShunli Wang 
439ebbddc75SShunli Wang 	ret = devm_snd_soc_register_card(&pdev->dev, card);
440ebbddc75SShunli Wang 	if (ret) {
441ebbddc75SShunli Wang 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
442ebbddc75SShunli Wang 			__func__, ret);
443ebbddc75SShunli Wang 		return ret;
444ebbddc75SShunli Wang 	}
445ebbddc75SShunli Wang 
446ebbddc75SShunli Wang 	default_pins =
447ebbddc75SShunli Wang 		devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT);
448ebbddc75SShunli Wang 	if (IS_ERR(default_pins)) {
449ebbddc75SShunli Wang 		dev_err(&pdev->dev, "%s set pins failed\n",
450ebbddc75SShunli Wang 			__func__);
451ebbddc75SShunli Wang 		return PTR_ERR(default_pins);
452ebbddc75SShunli Wang 	}
453ebbddc75SShunli Wang 
454ebbddc75SShunli Wang 	return ret;
455ebbddc75SShunli Wang }
456ebbddc75SShunli Wang 
457ebbddc75SShunli Wang #ifdef CONFIG_OF
458ebbddc75SShunli Wang static const struct of_device_id mt8183_da7219_max98357_dt_match[] = {
459ebbddc75SShunli Wang 	{.compatible = "mediatek,mt8183_da7219_max98357",},
460ebbddc75SShunli Wang 	{}
461ebbddc75SShunli Wang };
462ebbddc75SShunli Wang #endif
463ebbddc75SShunli Wang 
464ebbddc75SShunli Wang static struct platform_driver mt8183_da7219_max98357_driver = {
465ebbddc75SShunli Wang 	.driver = {
466ebbddc75SShunli Wang 		.name = "mt8183_da7219_max98357",
467ebbddc75SShunli Wang #ifdef CONFIG_OF
468ebbddc75SShunli Wang 		.of_match_table = mt8183_da7219_max98357_dt_match,
469ebbddc75SShunli Wang #endif
470ebbddc75SShunli Wang 	},
471ebbddc75SShunli Wang 	.probe = mt8183_da7219_max98357_dev_probe,
472ebbddc75SShunli Wang };
473ebbddc75SShunli Wang 
474ebbddc75SShunli Wang module_platform_driver(mt8183_da7219_max98357_driver);
475ebbddc75SShunli Wang 
476ebbddc75SShunli Wang /* Module information */
477ebbddc75SShunli Wang MODULE_DESCRIPTION("MT8183-DA7219-MAX98357 ALSA SoC machine driver");
478ebbddc75SShunli Wang MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>");
479ebbddc75SShunli Wang MODULE_LICENSE("GPL v2");
480ebbddc75SShunli Wang MODULE_ALIAS("mt8183_da7219_max98357 soc card");
481ebbddc75SShunli Wang 
482