xref: /openbmc/linux/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c (revision 3667a037e50a31555276a7989435126e501f0f15)
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 
9d9a2d100STzung-Bi Shih #include <linux/input.h>
10ebbddc75SShunli Wang #include <linux/module.h>
119e30251fSTzung-Bi Shih #include <linux/of_device.h>
12d9a2d100STzung-Bi Shih #include <linux/pinctrl/consumer.h>
13d9a2d100STzung-Bi Shih #include <sound/jack.h>
14ebbddc75SShunli Wang #include <sound/pcm_params.h>
15ebbddc75SShunli Wang #include <sound/soc.h>
16ebbddc75SShunli Wang 
17ebbddc75SShunli Wang #include "../../codecs/da7219-aad.h"
18ebbddc75SShunli Wang #include "../../codecs/da7219.h"
199e30251fSTzung-Bi Shih #include "../../codecs/rt1015.h"
2031add0d5STzung-Bi Shih #include "mt8183-afe-common.h"
21ebbddc75SShunli Wang 
22e5d4bdffSTzung-Bi Shih #define DA7219_CODEC_DAI "da7219-hifi"
23e5d4bdffSTzung-Bi Shih #define DA7219_DEV_NAME "da7219.5-001a"
249e30251fSTzung-Bi Shih #define RT1015_CODEC_DAI "rt1015-aif"
259e30251fSTzung-Bi Shih #define RT1015_DEV0_NAME "rt1015.6-0028"
269e30251fSTzung-Bi Shih #define RT1015_DEV1_NAME "rt1015.6-0029"
27e5d4bdffSTzung-Bi Shih 
288726ee61STzung-Bi Shih struct mt8183_da7219_max98357_priv {
29e25f8afdSTzung-Bi Shih 	struct snd_soc_jack headset_jack, hdmi_jack;
308726ee61STzung-Bi Shih };
318726ee61STzung-Bi Shih 
32ebbddc75SShunli Wang static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream,
33ebbddc75SShunli Wang 				       struct snd_pcm_hw_params *params)
34ebbddc75SShunli Wang {
350cd08b10SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
36ebbddc75SShunli Wang 	unsigned int rate = params_rate(params);
37ebbddc75SShunli Wang 	unsigned int mclk_fs_ratio = 128;
38ebbddc75SShunli Wang 	unsigned int mclk_fs = rate * mclk_fs_ratio;
39ebbddc75SShunli Wang 
40c8ac8212SKuninori Morimoto 	return snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0),
41ebbddc75SShunli Wang 				      0, mclk_fs, SND_SOC_CLOCK_OUT);
42ebbddc75SShunli Wang }
43ebbddc75SShunli Wang 
44ebbddc75SShunli Wang static const struct snd_soc_ops mt8183_mt6358_i2s_ops = {
45ebbddc75SShunli Wang 	.hw_params = mt8183_mt6358_i2s_hw_params,
46ebbddc75SShunli Wang };
47ebbddc75SShunli Wang 
48ebbddc75SShunli Wang static int mt8183_da7219_i2s_hw_params(struct snd_pcm_substream *substream,
49ebbddc75SShunli Wang 				       struct snd_pcm_hw_params *params)
50ebbddc75SShunli Wang {
510cd08b10SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
5256f1003fSKuninori Morimoto 	struct snd_soc_dai *codec_dai;
53ebbddc75SShunli Wang 	unsigned int rate = params_rate(params);
54ebbddc75SShunli Wang 	unsigned int mclk_fs_ratio = 256;
55ebbddc75SShunli Wang 	unsigned int mclk_fs = rate * mclk_fs_ratio;
56ebbddc75SShunli Wang 	unsigned int freq;
57ebbddc75SShunli Wang 	int ret = 0, j;
58ebbddc75SShunli Wang 
59c8ac8212SKuninori Morimoto 	ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0,
60ebbddc75SShunli Wang 				     mclk_fs, SND_SOC_CLOCK_OUT);
61ebbddc75SShunli Wang 	if (ret < 0)
62ebbddc75SShunli Wang 		dev_err(rtd->dev, "failed to set cpu dai sysclk\n");
63ebbddc75SShunli Wang 
64c8654520SKuninori Morimoto 	for_each_rtd_codec_dais(rtd, j, codec_dai) {
65e5d4bdffSTzung-Bi Shih 		if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
66ebbddc75SShunli Wang 			ret = snd_soc_dai_set_sysclk(codec_dai,
67ebbddc75SShunli Wang 						     DA7219_CLKSRC_MCLK,
68ebbddc75SShunli Wang 						     mclk_fs,
69ebbddc75SShunli Wang 						     SND_SOC_CLOCK_IN);
70ebbddc75SShunli Wang 			if (ret < 0)
71ebbddc75SShunli Wang 				dev_err(rtd->dev, "failed to set sysclk\n");
72ebbddc75SShunli Wang 
73ebbddc75SShunli Wang 			if ((rate % 8000) == 0)
74ebbddc75SShunli Wang 				freq = DA7219_PLL_FREQ_OUT_98304;
75ebbddc75SShunli Wang 			else
76ebbddc75SShunli Wang 				freq = DA7219_PLL_FREQ_OUT_90316;
77ebbddc75SShunli Wang 
78ebbddc75SShunli Wang 			ret = snd_soc_dai_set_pll(codec_dai, 0,
79ebbddc75SShunli Wang 						  DA7219_SYSCLK_PLL_SRM,
80ebbddc75SShunli Wang 						  0, freq);
81ebbddc75SShunli Wang 			if (ret)
82ebbddc75SShunli Wang 				dev_err(rtd->dev, "failed to start PLL: %d\n",
83ebbddc75SShunli Wang 					ret);
84ebbddc75SShunli Wang 		}
85ebbddc75SShunli Wang 	}
86ebbddc75SShunli Wang 
87ebbddc75SShunli Wang 	return ret;
88ebbddc75SShunli Wang }
89ebbddc75SShunli Wang 
90ebbddc75SShunli Wang static int mt8183_da7219_hw_free(struct snd_pcm_substream *substream)
91ebbddc75SShunli Wang {
920cd08b10SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
9356f1003fSKuninori Morimoto 	struct snd_soc_dai *codec_dai;
94ebbddc75SShunli Wang 	int ret = 0, j;
95ebbddc75SShunli Wang 
96c8654520SKuninori Morimoto 	for_each_rtd_codec_dais(rtd, j, codec_dai) {
97e5d4bdffSTzung-Bi Shih 		if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
98ebbddc75SShunli Wang 			ret = snd_soc_dai_set_pll(codec_dai,
99ebbddc75SShunli Wang 						  0, DA7219_SYSCLK_MCLK, 0, 0);
100ebbddc75SShunli Wang 			if (ret < 0) {
101ebbddc75SShunli Wang 				dev_err(rtd->dev, "failed to stop PLL: %d\n",
102ebbddc75SShunli Wang 					ret);
103ebbddc75SShunli Wang 				break;
104ebbddc75SShunli Wang 			}
105ebbddc75SShunli Wang 		}
106ebbddc75SShunli Wang 	}
107ebbddc75SShunli Wang 
108ebbddc75SShunli Wang 	return ret;
109ebbddc75SShunli Wang }
110ebbddc75SShunli Wang 
111ebbddc75SShunli Wang static const struct snd_soc_ops mt8183_da7219_i2s_ops = {
112ebbddc75SShunli Wang 	.hw_params = mt8183_da7219_i2s_hw_params,
113ebbddc75SShunli Wang 	.hw_free = mt8183_da7219_hw_free,
114ebbddc75SShunli Wang };
115ebbddc75SShunli Wang 
1169e30251fSTzung-Bi Shih static int
1179e30251fSTzung-Bi Shih mt8183_da7219_rt1015_i2s_hw_params(struct snd_pcm_substream *substream,
1189e30251fSTzung-Bi Shih 				   struct snd_pcm_hw_params *params)
1199e30251fSTzung-Bi Shih {
1200cd08b10SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
1219e30251fSTzung-Bi Shih 	unsigned int rate = params_rate(params);
1229e30251fSTzung-Bi Shih 	struct snd_soc_dai *codec_dai;
1239e30251fSTzung-Bi Shih 	int ret = 0, i;
1249e30251fSTzung-Bi Shih 
1259e30251fSTzung-Bi Shih 	for_each_rtd_codec_dais(rtd, i, codec_dai) {
1269e30251fSTzung-Bi Shih 		if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) ||
1279e30251fSTzung-Bi Shih 		    !strcmp(codec_dai->component->name, RT1015_DEV1_NAME)) {
1289e30251fSTzung-Bi Shih 			ret = snd_soc_dai_set_pll(codec_dai, 0,
1299e30251fSTzung-Bi Shih 						  RT1015_PLL_S_BCLK,
1309e30251fSTzung-Bi Shih 						  rate * 64, rate * 256);
1319e30251fSTzung-Bi Shih 			if (ret) {
1329e30251fSTzung-Bi Shih 				dev_err(rtd->dev, "failed to set pll\n");
1339e30251fSTzung-Bi Shih 				return ret;
1349e30251fSTzung-Bi Shih 			}
1359e30251fSTzung-Bi Shih 
1369e30251fSTzung-Bi Shih 			ret = snd_soc_dai_set_sysclk(codec_dai,
1379e30251fSTzung-Bi Shih 						     RT1015_SCLK_S_PLL,
1389e30251fSTzung-Bi Shih 						     rate * 256,
1399e30251fSTzung-Bi Shih 						     SND_SOC_CLOCK_IN);
1409e30251fSTzung-Bi Shih 			if (ret) {
1419e30251fSTzung-Bi Shih 				dev_err(rtd->dev, "failed to set sysclk\n");
1429e30251fSTzung-Bi Shih 				return ret;
1439e30251fSTzung-Bi Shih 			}
1449e30251fSTzung-Bi Shih 		}
1459e30251fSTzung-Bi Shih 	}
1469e30251fSTzung-Bi Shih 
1479e30251fSTzung-Bi Shih 	return mt8183_da7219_i2s_hw_params(substream, params);
1489e30251fSTzung-Bi Shih }
1499e30251fSTzung-Bi Shih 
1509e30251fSTzung-Bi Shih static const struct snd_soc_ops mt8183_da7219_rt1015_i2s_ops = {
1519e30251fSTzung-Bi Shih 	.hw_params = mt8183_da7219_rt1015_i2s_hw_params,
1529e30251fSTzung-Bi Shih 	.hw_free = mt8183_da7219_hw_free,
1539e30251fSTzung-Bi Shih };
1549e30251fSTzung-Bi Shih 
155ebbddc75SShunli Wang static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
156ebbddc75SShunli Wang 				      struct snd_pcm_hw_params *params)
157ebbddc75SShunli Wang {
15803c2192aSJiaxin Yu 	/* fix BE i2s format to S32_LE, clean param mask first */
159ebbddc75SShunli Wang 	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
16003c2192aSJiaxin Yu 			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
161ebbddc75SShunli Wang 
162ebbddc75SShunli Wang 	params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
163ebbddc75SShunli Wang 
164ebbddc75SShunli Wang 	return 0;
165ebbddc75SShunli Wang }
166ebbddc75SShunli Wang 
1679e30251fSTzung-Bi Shih static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
1689e30251fSTzung-Bi Shih 					     struct snd_pcm_hw_params *params)
1699e30251fSTzung-Bi Shih {
17003c2192aSJiaxin Yu 	/* fix BE i2s format to S24_LE, clean param mask first */
1719e30251fSTzung-Bi Shih 	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
17203c2192aSJiaxin Yu 			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
1739e30251fSTzung-Bi Shih 
1749e30251fSTzung-Bi Shih 	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
1759e30251fSTzung-Bi Shih 
1769e30251fSTzung-Bi Shih 	return 0;
1779e30251fSTzung-Bi Shih }
1789e30251fSTzung-Bi Shih 
179ec7ba9e1STzung-Bi Shih static int
180b1647f9fSTzung-Bi Shih mt8183_da7219_max98357_startup(
181b1647f9fSTzung-Bi Shih 	struct snd_pcm_substream *substream)
182b1647f9fSTzung-Bi Shih {
183b1647f9fSTzung-Bi Shih 	static const unsigned int rates[] = {
184b1647f9fSTzung-Bi Shih 		48000,
185b1647f9fSTzung-Bi Shih 	};
186b1647f9fSTzung-Bi Shih 	static const struct snd_pcm_hw_constraint_list constraints_rates = {
187b1647f9fSTzung-Bi Shih 		.count = ARRAY_SIZE(rates),
188b1647f9fSTzung-Bi Shih 		.list  = rates,
189b1647f9fSTzung-Bi Shih 		.mask = 0,
190b1647f9fSTzung-Bi Shih 	};
191b1647f9fSTzung-Bi Shih 	static const unsigned int channels[] = {
192b1647f9fSTzung-Bi Shih 		2,
193b1647f9fSTzung-Bi Shih 	};
194b1647f9fSTzung-Bi Shih 	static const struct snd_pcm_hw_constraint_list constraints_channels = {
195b1647f9fSTzung-Bi Shih 		.count = ARRAY_SIZE(channels),
196b1647f9fSTzung-Bi Shih 		.list = channels,
197b1647f9fSTzung-Bi Shih 		.mask = 0,
198b1647f9fSTzung-Bi Shih 	};
199b1647f9fSTzung-Bi Shih 
200b1647f9fSTzung-Bi Shih 	struct snd_pcm_runtime *runtime = substream->runtime;
201b1647f9fSTzung-Bi Shih 
202b1647f9fSTzung-Bi Shih 	snd_pcm_hw_constraint_list(runtime, 0,
203b1647f9fSTzung-Bi Shih 			SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
204b1647f9fSTzung-Bi Shih 	runtime->hw.channels_max = 2;
205b1647f9fSTzung-Bi Shih 	snd_pcm_hw_constraint_list(runtime, 0,
206b1647f9fSTzung-Bi Shih 			SNDRV_PCM_HW_PARAM_CHANNELS,
207b1647f9fSTzung-Bi Shih 			&constraints_channels);
208b1647f9fSTzung-Bi Shih 
209b1647f9fSTzung-Bi Shih 	runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
210b1647f9fSTzung-Bi Shih 	snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
211b1647f9fSTzung-Bi Shih 
212b1647f9fSTzung-Bi Shih 	return 0;
213b1647f9fSTzung-Bi Shih }
214b1647f9fSTzung-Bi Shih 
215b1647f9fSTzung-Bi Shih static const struct snd_soc_ops mt8183_da7219_max98357_ops = {
216b1647f9fSTzung-Bi Shih 	.startup = mt8183_da7219_max98357_startup,
217b1647f9fSTzung-Bi Shih };
218b1647f9fSTzung-Bi Shih 
219b1647f9fSTzung-Bi Shih static int
220ec7ba9e1STzung-Bi Shih mt8183_da7219_max98357_bt_sco_startup(
221ec7ba9e1STzung-Bi Shih 	struct snd_pcm_substream *substream)
222ec7ba9e1STzung-Bi Shih {
223ec7ba9e1STzung-Bi Shih 	static const unsigned int rates[] = {
224ec7ba9e1STzung-Bi Shih 		8000, 16000
225ec7ba9e1STzung-Bi Shih 	};
226ec7ba9e1STzung-Bi Shih 	static const struct snd_pcm_hw_constraint_list constraints_rates = {
227ec7ba9e1STzung-Bi Shih 		.count = ARRAY_SIZE(rates),
228ec7ba9e1STzung-Bi Shih 		.list  = rates,
229ec7ba9e1STzung-Bi Shih 		.mask = 0,
230ec7ba9e1STzung-Bi Shih 	};
231ec7ba9e1STzung-Bi Shih 	static const unsigned int channels[] = {
232ec7ba9e1STzung-Bi Shih 		1,
233ec7ba9e1STzung-Bi Shih 	};
234ec7ba9e1STzung-Bi Shih 	static const struct snd_pcm_hw_constraint_list constraints_channels = {
235ec7ba9e1STzung-Bi Shih 		.count = ARRAY_SIZE(channels),
236ec7ba9e1STzung-Bi Shih 		.list = channels,
237ec7ba9e1STzung-Bi Shih 		.mask = 0,
238ec7ba9e1STzung-Bi Shih 	};
239ec7ba9e1STzung-Bi Shih 
240ec7ba9e1STzung-Bi Shih 	struct snd_pcm_runtime *runtime = substream->runtime;
241ec7ba9e1STzung-Bi Shih 
242ec7ba9e1STzung-Bi Shih 	snd_pcm_hw_constraint_list(runtime, 0,
243ec7ba9e1STzung-Bi Shih 			SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
244ec7ba9e1STzung-Bi Shih 	runtime->hw.channels_max = 1;
245ec7ba9e1STzung-Bi Shih 	snd_pcm_hw_constraint_list(runtime, 0,
246ec7ba9e1STzung-Bi Shih 			SNDRV_PCM_HW_PARAM_CHANNELS,
247ec7ba9e1STzung-Bi Shih 			&constraints_channels);
248ec7ba9e1STzung-Bi Shih 
249ec7ba9e1STzung-Bi Shih 	runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
250ec7ba9e1STzung-Bi Shih 	snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
251ec7ba9e1STzung-Bi Shih 
252ec7ba9e1STzung-Bi Shih 	return 0;
253ec7ba9e1STzung-Bi Shih }
254ec7ba9e1STzung-Bi Shih 
255ec7ba9e1STzung-Bi Shih static const struct snd_soc_ops mt8183_da7219_max98357_bt_sco_ops = {
256ec7ba9e1STzung-Bi Shih 	.startup = mt8183_da7219_max98357_bt_sco_startup,
257ec7ba9e1STzung-Bi Shih };
258ec7ba9e1STzung-Bi Shih 
2594b990642SKuninori Morimoto /* FE */
2604b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(playback1,
2614b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
2624b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
2634b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
2644b990642SKuninori Morimoto 
2654b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(playback2,
2664b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
2674b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
2684b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
2694b990642SKuninori Morimoto 
2704b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(playback3,
2714b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
2724b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
2734b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
2744b990642SKuninori Morimoto 
2754b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(capture1,
2764b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
2774b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
2784b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
2794b990642SKuninori Morimoto 
2804b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(capture2,
2814b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
2824b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
2834b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
2844b990642SKuninori Morimoto 
2854b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(capture3,
2864b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
2874b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
2884b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
2894b990642SKuninori Morimoto 
2904b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(capture_mono,
2914b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")),
2924b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
2934b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
2944b990642SKuninori Morimoto 
2954b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(playback_hdmi,
2964b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("HDMI")),
2974b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
2984b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
2994b990642SKuninori Morimoto 
3004b990642SKuninori Morimoto /* BE */
3014b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(primary_codec,
3024b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
3034b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")),
3044b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
3054b990642SKuninori Morimoto 
3064b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(pcm1,
3074b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
3084b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
3094b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
3104b990642SKuninori Morimoto 
3114b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(pcm2,
3124b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")),
3134b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
3144b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
3154b990642SKuninori Morimoto 
3164b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(i2s0,
3174b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
3184b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
3194b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
3204b990642SKuninori Morimoto 
3214b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(i2s1,
3224b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
3234b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
3244b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
3254b990642SKuninori Morimoto 
3264b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(i2s2,
3274b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
328e5d4bdffSTzung-Bi Shih 	DAILINK_COMP_ARRAY(COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
3294b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
3304b990642SKuninori Morimoto 
3319e30251fSTzung-Bi Shih SND_SOC_DAILINK_DEFS(i2s3_max98357a,
3324b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
3334b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi"),
334e5d4bdffSTzung-Bi Shih 			   COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
3354b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
3364b990642SKuninori Morimoto 
3379e30251fSTzung-Bi Shih SND_SOC_DAILINK_DEFS(i2s3_rt1015,
3389e30251fSTzung-Bi Shih 	DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
3399e30251fSTzung-Bi Shih 	DAILINK_COMP_ARRAY(COMP_CODEC(RT1015_DEV0_NAME, RT1015_CODEC_DAI),
3409e30251fSTzung-Bi Shih 			   COMP_CODEC(RT1015_DEV1_NAME, RT1015_CODEC_DAI),
3419e30251fSTzung-Bi Shih 			   COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
3429e30251fSTzung-Bi Shih 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
3439e30251fSTzung-Bi Shih 
3447e5bfdddSTzung-Bi Shih SND_SOC_DAILINK_DEFS(i2s3_rt1015p,
3457e5bfdddSTzung-Bi Shih 	DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
3467e5bfdddSTzung-Bi Shih 	DAILINK_COMP_ARRAY(COMP_CODEC("rt1015p", "HiFi"),
3477e5bfdddSTzung-Bi Shih 			   COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
3487e5bfdddSTzung-Bi Shih 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
3497e5bfdddSTzung-Bi Shih 
3504b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(i2s5,
3514b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("I2S5")),
3524b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
3534b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
3544b990642SKuninori Morimoto 
3554b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(tdm,
3564b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("TDM")),
3575bdbe977STzung-Bi Shih 	DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")),
3584b990642SKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
3594b990642SKuninori Morimoto 
360e25f8afdSTzung-Bi Shih static int mt8183_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd)
361e25f8afdSTzung-Bi Shih {
362e25f8afdSTzung-Bi Shih 	struct mt8183_da7219_max98357_priv *priv =
363e25f8afdSTzung-Bi Shih 		snd_soc_card_get_drvdata(rtd->card);
364e25f8afdSTzung-Bi Shih 	int ret;
365e25f8afdSTzung-Bi Shih 
366e25f8afdSTzung-Bi Shih 	ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
367e25f8afdSTzung-Bi Shih 				    &priv->hdmi_jack, NULL, 0);
368e25f8afdSTzung-Bi Shih 	if (ret)
369e25f8afdSTzung-Bi Shih 		return ret;
370e25f8afdSTzung-Bi Shih 
37155c5cc63SCheng-Yi Chiang 	return snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component,
37255c5cc63SCheng-Yi Chiang 					  &priv->hdmi_jack, NULL);
373e25f8afdSTzung-Bi Shih }
374e25f8afdSTzung-Bi Shih 
3759e30251fSTzung-Bi Shih static struct snd_soc_dai_link mt8183_da7219_dai_links[] = {
376ebbddc75SShunli Wang 	/* FE */
377ebbddc75SShunli Wang 	{
378ebbddc75SShunli Wang 		.name = "Playback_1",
379ebbddc75SShunli Wang 		.stream_name = "Playback_1",
380ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
381ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
382ebbddc75SShunli Wang 		.dynamic = 1,
383ebbddc75SShunli Wang 		.dpcm_playback = 1,
384b1647f9fSTzung-Bi Shih 		.ops = &mt8183_da7219_max98357_ops,
3854b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(playback1),
386ebbddc75SShunli Wang 	},
387ebbddc75SShunli Wang 	{
388ebbddc75SShunli Wang 		.name = "Playback_2",
389ebbddc75SShunli Wang 		.stream_name = "Playback_2",
390ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
391ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
392ebbddc75SShunli Wang 		.dynamic = 1,
393ebbddc75SShunli Wang 		.dpcm_playback = 1,
394ec7ba9e1STzung-Bi Shih 		.ops = &mt8183_da7219_max98357_bt_sco_ops,
3954b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(playback2),
396ebbddc75SShunli Wang 	},
397ebbddc75SShunli Wang 	{
398ebbddc75SShunli Wang 		.name = "Playback_3",
399ebbddc75SShunli Wang 		.stream_name = "Playback_3",
400ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
401ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
402ebbddc75SShunli Wang 		.dynamic = 1,
403ebbddc75SShunli Wang 		.dpcm_playback = 1,
4044b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(playback3),
405ebbddc75SShunli Wang 	},
406ebbddc75SShunli Wang 	{
407ebbddc75SShunli Wang 		.name = "Capture_1",
408ebbddc75SShunli Wang 		.stream_name = "Capture_1",
409ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
410ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
411ebbddc75SShunli Wang 		.dynamic = 1,
412ebbddc75SShunli Wang 		.dpcm_capture = 1,
413ec7ba9e1STzung-Bi Shih 		.ops = &mt8183_da7219_max98357_bt_sco_ops,
4144b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(capture1),
415ebbddc75SShunli Wang 	},
416ebbddc75SShunli Wang 	{
417ebbddc75SShunli Wang 		.name = "Capture_2",
418ebbddc75SShunli Wang 		.stream_name = "Capture_2",
419ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
420ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
421ebbddc75SShunli Wang 		.dynamic = 1,
422ebbddc75SShunli Wang 		.dpcm_capture = 1,
4234b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(capture2),
424ebbddc75SShunli Wang 	},
425ebbddc75SShunli Wang 	{
426ebbddc75SShunli Wang 		.name = "Capture_3",
427ebbddc75SShunli Wang 		.stream_name = "Capture_3",
428ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
429ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
430ebbddc75SShunli Wang 		.dynamic = 1,
431ebbddc75SShunli Wang 		.dpcm_capture = 1,
432b1647f9fSTzung-Bi Shih 		.ops = &mt8183_da7219_max98357_ops,
4334b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(capture3),
434ebbddc75SShunli Wang 	},
435ebbddc75SShunli Wang 	{
436ebbddc75SShunli Wang 		.name = "Capture_Mono_1",
437ebbddc75SShunli Wang 		.stream_name = "Capture_Mono_1",
438ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
439ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
440ebbddc75SShunli Wang 		.dynamic = 1,
441ebbddc75SShunli Wang 		.dpcm_capture = 1,
4424b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(capture_mono),
443ebbddc75SShunli Wang 	},
444ebbddc75SShunli Wang 	{
445ebbddc75SShunli Wang 		.name = "Playback_HDMI",
446ebbddc75SShunli Wang 		.stream_name = "Playback_HDMI",
447ebbddc75SShunli Wang 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
448ebbddc75SShunli Wang 			    SND_SOC_DPCM_TRIGGER_PRE},
449ebbddc75SShunli Wang 		.dynamic = 1,
450ebbddc75SShunli Wang 		.dpcm_playback = 1,
4514b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(playback_hdmi),
452ebbddc75SShunli Wang 	},
453ebbddc75SShunli Wang 	/* BE */
454ebbddc75SShunli Wang 	{
455ebbddc75SShunli Wang 		.name = "Primary Codec",
456ebbddc75SShunli Wang 		.no_pcm = 1,
457ebbddc75SShunli Wang 		.dpcm_playback = 1,
458ebbddc75SShunli Wang 		.dpcm_capture = 1,
459ebbddc75SShunli Wang 		.ignore_suspend = 1,
4604b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(primary_codec),
461ebbddc75SShunli Wang 	},
462ebbddc75SShunli Wang 	{
463ebbddc75SShunli Wang 		.name = "PCM 1",
464ebbddc75SShunli Wang 		.no_pcm = 1,
465ebbddc75SShunli Wang 		.dpcm_playback = 1,
466ebbddc75SShunli Wang 		.dpcm_capture = 1,
467ebbddc75SShunli Wang 		.ignore_suspend = 1,
4684b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(pcm1),
469ebbddc75SShunli Wang 	},
470ebbddc75SShunli Wang 	{
471ebbddc75SShunli Wang 		.name = "PCM 2",
472ebbddc75SShunli Wang 		.no_pcm = 1,
473ebbddc75SShunli Wang 		.dpcm_playback = 1,
474ebbddc75SShunli Wang 		.dpcm_capture = 1,
475ebbddc75SShunli Wang 		.ignore_suspend = 1,
4764b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(pcm2),
477ebbddc75SShunli Wang 	},
478ebbddc75SShunli Wang 	{
479ebbddc75SShunli Wang 		.name = "I2S0",
480ebbddc75SShunli Wang 		.no_pcm = 1,
481ebbddc75SShunli Wang 		.dpcm_capture = 1,
482ebbddc75SShunli Wang 		.ignore_suspend = 1,
483ebbddc75SShunli Wang 		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
484ebbddc75SShunli Wang 		.ops = &mt8183_mt6358_i2s_ops,
4854b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(i2s0),
486ebbddc75SShunli Wang 	},
487ebbddc75SShunli Wang 	{
488ebbddc75SShunli Wang 		.name = "I2S1",
489ebbddc75SShunli Wang 		.no_pcm = 1,
490ebbddc75SShunli Wang 		.dpcm_playback = 1,
491ebbddc75SShunli Wang 		.ignore_suspend = 1,
492ebbddc75SShunli Wang 		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
493ebbddc75SShunli Wang 		.ops = &mt8183_mt6358_i2s_ops,
4944b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(i2s1),
495ebbddc75SShunli Wang 	},
496ebbddc75SShunli Wang 	{
497ebbddc75SShunli Wang 		.name = "I2S2",
498ebbddc75SShunli Wang 		.no_pcm = 1,
499ebbddc75SShunli Wang 		.dpcm_capture = 1,
500ebbddc75SShunli Wang 		.ignore_suspend = 1,
501ebbddc75SShunli Wang 		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
502ebbddc75SShunli Wang 		.ops = &mt8183_da7219_i2s_ops,
5034b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(i2s2),
504ebbddc75SShunli Wang 	},
505ebbddc75SShunli Wang 	{
506ebbddc75SShunli Wang 		.name = "I2S3",
507ebbddc75SShunli Wang 		.no_pcm = 1,
508ebbddc75SShunli Wang 		.dpcm_playback = 1,
509ebbddc75SShunli Wang 		.ignore_suspend = 1,
510ebbddc75SShunli Wang 	},
511ebbddc75SShunli Wang 	{
512ebbddc75SShunli Wang 		.name = "I2S5",
513ebbddc75SShunli Wang 		.no_pcm = 1,
514ebbddc75SShunli Wang 		.dpcm_playback = 1,
515ebbddc75SShunli Wang 		.ignore_suspend = 1,
516ebbddc75SShunli Wang 		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
517ebbddc75SShunli Wang 		.ops = &mt8183_mt6358_i2s_ops,
5184b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(i2s5),
519ebbddc75SShunli Wang 	},
520ebbddc75SShunli Wang 	{
521ebbddc75SShunli Wang 		.name = "TDM",
522ebbddc75SShunli Wang 		.no_pcm = 1,
523195a6431STzung-Bi Shih 		.dai_fmt = SND_SOC_DAIFMT_I2S |
524195a6431STzung-Bi Shih 			   SND_SOC_DAIFMT_IB_IF |
525195a6431STzung-Bi Shih 			   SND_SOC_DAIFMT_CBM_CFM,
526ebbddc75SShunli Wang 		.dpcm_playback = 1,
527ebbddc75SShunli Wang 		.ignore_suspend = 1,
5288726ee61STzung-Bi Shih 		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
5294d36ed8eSTzung-Bi Shih 		.ignore = 1,
530e25f8afdSTzung-Bi Shih 		.init = mt8183_da7219_max98357_hdmi_init,
5314b990642SKuninori Morimoto 		SND_SOC_DAILINK_REG(tdm),
532ebbddc75SShunli Wang 	},
533ebbddc75SShunli Wang };
534ebbddc75SShunli Wang 
535ebbddc75SShunli Wang static int
536cbafb2ccSTzung-Bi Shih mt8183_da7219_max98357_headset_init(struct snd_soc_component *component)
537cbafb2ccSTzung-Bi Shih {
538cbafb2ccSTzung-Bi Shih 	int ret;
539cbafb2ccSTzung-Bi Shih 	struct mt8183_da7219_max98357_priv *priv =
540cbafb2ccSTzung-Bi Shih 			snd_soc_card_get_drvdata(component->card);
541cbafb2ccSTzung-Bi Shih 
542cbafb2ccSTzung-Bi Shih 	/* Enable Headset and 4 Buttons Jack detection */
543cbafb2ccSTzung-Bi Shih 	ret = snd_soc_card_jack_new(component->card,
544cbafb2ccSTzung-Bi Shih 				    "Headset Jack",
545cbafb2ccSTzung-Bi Shih 				    SND_JACK_HEADSET |
546cbafb2ccSTzung-Bi Shih 				    SND_JACK_BTN_0 | SND_JACK_BTN_1 |
547859ffd0aSTzung-Bi Shih 				    SND_JACK_BTN_2 | SND_JACK_BTN_3 |
548859ffd0aSTzung-Bi Shih 				    SND_JACK_LINEOUT,
549cbafb2ccSTzung-Bi Shih 				    &priv->headset_jack,
550cbafb2ccSTzung-Bi Shih 				    NULL, 0);
551cbafb2ccSTzung-Bi Shih 	if (ret)
552cbafb2ccSTzung-Bi Shih 		return ret;
553cbafb2ccSTzung-Bi Shih 
554cbafb2ccSTzung-Bi Shih 	snd_jack_set_key(
555cbafb2ccSTzung-Bi Shih 		priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
556cbafb2ccSTzung-Bi Shih 	snd_jack_set_key(
557cbafb2ccSTzung-Bi Shih 		priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
558cbafb2ccSTzung-Bi Shih 	snd_jack_set_key(
559cbafb2ccSTzung-Bi Shih 		priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
560cbafb2ccSTzung-Bi Shih 	snd_jack_set_key(
561cbafb2ccSTzung-Bi Shih 		priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
562cbafb2ccSTzung-Bi Shih 
563cbafb2ccSTzung-Bi Shih 	da7219_aad_jack_det(component, &priv->headset_jack);
564cbafb2ccSTzung-Bi Shih 
565cbafb2ccSTzung-Bi Shih 	return 0;
566cbafb2ccSTzung-Bi Shih }
567ebbddc75SShunli Wang 
568ebbddc75SShunli Wang static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = {
5695c9e38cbSKuninori Morimoto 	.dlc = COMP_EMPTY(),
570ebbddc75SShunli Wang 	.init = mt8183_da7219_max98357_headset_init,
571ebbddc75SShunli Wang };
572ebbddc75SShunli Wang 
573ebbddc75SShunli Wang static struct snd_soc_codec_conf mt6358_codec_conf[] = {
574ebbddc75SShunli Wang 	{
5752d27a4cfSKuninori Morimoto 		.dlc = COMP_CODEC_CONF("mt6358-sound"),
576ebbddc75SShunli Wang 		.name_prefix = "Mt6358",
577ebbddc75SShunli Wang 	},
578ebbddc75SShunli Wang };
579ebbddc75SShunli Wang 
580514de1c9STzung-Bi Shih static const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = {
581514de1c9STzung-Bi Shih 	SOC_DAPM_PIN_SWITCH("Speakers"),
582514de1c9STzung-Bi Shih };
583514de1c9STzung-Bi Shih 
584514de1c9STzung-Bi Shih static const
585514de1c9STzung-Bi Shih struct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = {
586514de1c9STzung-Bi Shih 	SND_SOC_DAPM_SPK("Speakers", NULL),
587c77b8317STzung-Bi Shih 	SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
588c77b8317STzung-Bi Shih 			     "aud_tdm_out_on", "aud_tdm_out_off"),
589514de1c9STzung-Bi Shih };
590514de1c9STzung-Bi Shih 
591514de1c9STzung-Bi Shih static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = {
592514de1c9STzung-Bi Shih 	{"Speakers", NULL, "Speaker"},
593c77b8317STzung-Bi Shih 	{"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
594514de1c9STzung-Bi Shih };
595514de1c9STzung-Bi Shih 
596ebbddc75SShunli Wang static struct snd_soc_card mt8183_da7219_max98357_card = {
597ebbddc75SShunli Wang 	.name = "mt8183_da7219_max98357",
598ebbddc75SShunli Wang 	.owner = THIS_MODULE,
599514de1c9STzung-Bi Shih 	.controls = mt8183_da7219_max98357_snd_controls,
600514de1c9STzung-Bi Shih 	.num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
601514de1c9STzung-Bi Shih 	.dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
602514de1c9STzung-Bi Shih 	.num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
603514de1c9STzung-Bi Shih 	.dapm_routes = mt8183_da7219_max98357_dapm_routes,
604514de1c9STzung-Bi Shih 	.num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
6059e30251fSTzung-Bi Shih 	.dai_link = mt8183_da7219_dai_links,
6069e30251fSTzung-Bi Shih 	.num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
607ebbddc75SShunli Wang 	.aux_dev = &mt8183_da7219_max98357_headset_dev,
608ebbddc75SShunli Wang 	.num_aux_devs = 1,
609ebbddc75SShunli Wang 	.codec_conf = mt6358_codec_conf,
610ebbddc75SShunli Wang 	.num_configs = ARRAY_SIZE(mt6358_codec_conf),
611ebbddc75SShunli Wang };
612ebbddc75SShunli Wang 
6139e30251fSTzung-Bi Shih static struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = {
6149e30251fSTzung-Bi Shih 	{
6159e30251fSTzung-Bi Shih 		.dlc = COMP_CODEC_CONF("mt6358-sound"),
6169e30251fSTzung-Bi Shih 		.name_prefix = "Mt6358",
6179e30251fSTzung-Bi Shih 	},
6189e30251fSTzung-Bi Shih 	{
6199e30251fSTzung-Bi Shih 		.dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME),
6209e30251fSTzung-Bi Shih 		.name_prefix = "Left",
6219e30251fSTzung-Bi Shih 	},
6229e30251fSTzung-Bi Shih 	{
6239e30251fSTzung-Bi Shih 		.dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME),
6249e30251fSTzung-Bi Shih 		.name_prefix = "Right",
6259e30251fSTzung-Bi Shih 	},
6269e30251fSTzung-Bi Shih };
6279e30251fSTzung-Bi Shih 
628eb5a5587STzung-Bi Shih static const struct snd_kcontrol_new mt8183_da7219_rt1015_snd_controls[] = {
629eb5a5587STzung-Bi Shih 	SOC_DAPM_PIN_SWITCH("Left Spk"),
630eb5a5587STzung-Bi Shih 	SOC_DAPM_PIN_SWITCH("Right Spk"),
631eb5a5587STzung-Bi Shih };
632eb5a5587STzung-Bi Shih 
633eb5a5587STzung-Bi Shih static const
634eb5a5587STzung-Bi Shih struct snd_soc_dapm_widget mt8183_da7219_rt1015_dapm_widgets[] = {
635eb5a5587STzung-Bi Shih 	SND_SOC_DAPM_SPK("Left Spk", NULL),
636eb5a5587STzung-Bi Shih 	SND_SOC_DAPM_SPK("Right Spk", NULL),
637eb5a5587STzung-Bi Shih 	SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
638eb5a5587STzung-Bi Shih 			     "aud_tdm_out_on", "aud_tdm_out_off"),
639eb5a5587STzung-Bi Shih };
640eb5a5587STzung-Bi Shih 
641eb5a5587STzung-Bi Shih static const struct snd_soc_dapm_route mt8183_da7219_rt1015_dapm_routes[] = {
642eb5a5587STzung-Bi Shih 	{"Left Spk", NULL, "Left SPO"},
643eb5a5587STzung-Bi Shih 	{"Right Spk", NULL, "Right SPO"},
644eb5a5587STzung-Bi Shih 	{"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
645eb5a5587STzung-Bi Shih };
646eb5a5587STzung-Bi Shih 
6479e30251fSTzung-Bi Shih static struct snd_soc_card mt8183_da7219_rt1015_card = {
6489e30251fSTzung-Bi Shih 	.name = "mt8183_da7219_rt1015",
6499e30251fSTzung-Bi Shih 	.owner = THIS_MODULE,
650eb5a5587STzung-Bi Shih 	.controls = mt8183_da7219_rt1015_snd_controls,
651eb5a5587STzung-Bi Shih 	.num_controls = ARRAY_SIZE(mt8183_da7219_rt1015_snd_controls),
652eb5a5587STzung-Bi Shih 	.dapm_widgets = mt8183_da7219_rt1015_dapm_widgets,
653eb5a5587STzung-Bi Shih 	.num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_widgets),
654eb5a5587STzung-Bi Shih 	.dapm_routes = mt8183_da7219_rt1015_dapm_routes,
655eb5a5587STzung-Bi Shih 	.num_dapm_routes = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_routes),
6569e30251fSTzung-Bi Shih 	.dai_link = mt8183_da7219_dai_links,
6579e30251fSTzung-Bi Shih 	.num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
6589e30251fSTzung-Bi Shih 	.aux_dev = &mt8183_da7219_max98357_headset_dev,
6599e30251fSTzung-Bi Shih 	.num_aux_devs = 1,
6609e30251fSTzung-Bi Shih 	.codec_conf = mt8183_da7219_rt1015_codec_conf,
6619e30251fSTzung-Bi Shih 	.num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf),
6629e30251fSTzung-Bi Shih };
6639e30251fSTzung-Bi Shih 
6647e5bfdddSTzung-Bi Shih static struct snd_soc_card mt8183_da7219_rt1015p_card = {
6657e5bfdddSTzung-Bi Shih 	.name = "mt8183_da7219_rt1015p",
6667e5bfdddSTzung-Bi Shih 	.owner = THIS_MODULE,
6677e5bfdddSTzung-Bi Shih 	.controls = mt8183_da7219_max98357_snd_controls,
6687e5bfdddSTzung-Bi Shih 	.num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
6697e5bfdddSTzung-Bi Shih 	.dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
6707e5bfdddSTzung-Bi Shih 	.num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
6717e5bfdddSTzung-Bi Shih 	.dapm_routes = mt8183_da7219_max98357_dapm_routes,
6727e5bfdddSTzung-Bi Shih 	.num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
6737e5bfdddSTzung-Bi Shih 	.dai_link = mt8183_da7219_dai_links,
6747e5bfdddSTzung-Bi Shih 	.num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
6757e5bfdddSTzung-Bi Shih 	.aux_dev = &mt8183_da7219_max98357_headset_dev,
6767e5bfdddSTzung-Bi Shih 	.num_aux_devs = 1,
6777e5bfdddSTzung-Bi Shih 	.codec_conf = mt6358_codec_conf,
6787e5bfdddSTzung-Bi Shih 	.num_configs = ARRAY_SIZE(mt6358_codec_conf),
6797e5bfdddSTzung-Bi Shih };
6807e5bfdddSTzung-Bi Shih 
681ebbddc75SShunli Wang static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
682ebbddc75SShunli Wang {
6839e30251fSTzung-Bi Shih 	struct snd_soc_card *card;
6845bdbe977STzung-Bi Shih 	struct device_node *platform_node, *hdmi_codec;
685ebbddc75SShunli Wang 	struct snd_soc_dai_link *dai_link;
6868726ee61STzung-Bi Shih 	struct mt8183_da7219_max98357_priv *priv;
687c77b8317STzung-Bi Shih 	struct pinctrl *pinctrl;
688ebbddc75SShunli Wang 	int ret, i;
689ebbddc75SShunli Wang 
690ebbddc75SShunli Wang 	platform_node = of_parse_phandle(pdev->dev.of_node,
691ebbddc75SShunli Wang 					 "mediatek,platform", 0);
692ebbddc75SShunli Wang 	if (!platform_node) {
693ebbddc75SShunli Wang 		dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
694ebbddc75SShunli Wang 		return -EINVAL;
695ebbddc75SShunli Wang 	}
696ebbddc75SShunli Wang 
697*3667a037STzung-Bi Shih 	card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev);
698*3667a037STzung-Bi Shih 	if (!card)
6999e30251fSTzung-Bi Shih 		return -EINVAL;
7009e30251fSTzung-Bi Shih 	card->dev = &pdev->dev;
7019e30251fSTzung-Bi Shih 
7025bdbe977STzung-Bi Shih 	hdmi_codec = of_parse_phandle(pdev->dev.of_node,
7035bdbe977STzung-Bi Shih 				      "mediatek,hdmi-codec", 0);
7045bdbe977STzung-Bi Shih 
705ebbddc75SShunli Wang 	for_each_card_prelinks(card, i, dai_link) {
7069e30251fSTzung-Bi Shih 		if (strcmp(dai_link->name, "I2S3") == 0) {
7079e30251fSTzung-Bi Shih 			if (card == &mt8183_da7219_max98357_card) {
7089e30251fSTzung-Bi Shih 				dai_link->be_hw_params_fixup =
7099e30251fSTzung-Bi Shih 					mt8183_i2s_hw_params_fixup;
710ebb11d1dSTzung-Bi Shih 				dai_link->ops = &mt8183_da7219_i2s_ops;
7119e30251fSTzung-Bi Shih 				dai_link->cpus = i2s3_max98357a_cpus;
7129e30251fSTzung-Bi Shih 				dai_link->num_cpus =
7139e30251fSTzung-Bi Shih 					ARRAY_SIZE(i2s3_max98357a_cpus);
7149e30251fSTzung-Bi Shih 				dai_link->codecs = i2s3_max98357a_codecs;
7159e30251fSTzung-Bi Shih 				dai_link->num_codecs =
7169e30251fSTzung-Bi Shih 					ARRAY_SIZE(i2s3_max98357a_codecs);
7179e30251fSTzung-Bi Shih 				dai_link->platforms = i2s3_max98357a_platforms;
7189e30251fSTzung-Bi Shih 				dai_link->num_platforms =
7199e30251fSTzung-Bi Shih 					ARRAY_SIZE(i2s3_max98357a_platforms);
7209e30251fSTzung-Bi Shih 			} else if (card == &mt8183_da7219_rt1015_card) {
7219e30251fSTzung-Bi Shih 				dai_link->be_hw_params_fixup =
7229e30251fSTzung-Bi Shih 					mt8183_rt1015_i2s_hw_params_fixup;
7239e30251fSTzung-Bi Shih 				dai_link->ops = &mt8183_da7219_rt1015_i2s_ops;
7249e30251fSTzung-Bi Shih 				dai_link->cpus = i2s3_rt1015_cpus;
7259e30251fSTzung-Bi Shih 				dai_link->num_cpus =
7269e30251fSTzung-Bi Shih 					ARRAY_SIZE(i2s3_rt1015_cpus);
7279e30251fSTzung-Bi Shih 				dai_link->codecs = i2s3_rt1015_codecs;
7289e30251fSTzung-Bi Shih 				dai_link->num_codecs =
7299e30251fSTzung-Bi Shih 					ARRAY_SIZE(i2s3_rt1015_codecs);
7309e30251fSTzung-Bi Shih 				dai_link->platforms = i2s3_rt1015_platforms;
7319e30251fSTzung-Bi Shih 				dai_link->num_platforms =
7329e30251fSTzung-Bi Shih 					ARRAY_SIZE(i2s3_rt1015_platforms);
7337e5bfdddSTzung-Bi Shih 			} else if (card == &mt8183_da7219_rt1015p_card) {
7347e5bfdddSTzung-Bi Shih 				dai_link->be_hw_params_fixup =
7357e5bfdddSTzung-Bi Shih 					mt8183_rt1015_i2s_hw_params_fixup;
7367e5bfdddSTzung-Bi Shih 				dai_link->ops = &mt8183_da7219_i2s_ops;
7377e5bfdddSTzung-Bi Shih 				dai_link->cpus = i2s3_rt1015p_cpus;
7387e5bfdddSTzung-Bi Shih 				dai_link->num_cpus =
7397e5bfdddSTzung-Bi Shih 					ARRAY_SIZE(i2s3_rt1015p_cpus);
7407e5bfdddSTzung-Bi Shih 				dai_link->codecs = i2s3_rt1015p_codecs;
7417e5bfdddSTzung-Bi Shih 				dai_link->num_codecs =
7427e5bfdddSTzung-Bi Shih 					ARRAY_SIZE(i2s3_rt1015p_codecs);
7437e5bfdddSTzung-Bi Shih 				dai_link->platforms = i2s3_rt1015p_platforms;
7447e5bfdddSTzung-Bi Shih 				dai_link->num_platforms =
7457e5bfdddSTzung-Bi Shih 					ARRAY_SIZE(i2s3_rt1015p_platforms);
7469e30251fSTzung-Bi Shih 			}
7479e30251fSTzung-Bi Shih 		}
7489e30251fSTzung-Bi Shih 
7494d36ed8eSTzung-Bi Shih 		if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) {
7505bdbe977STzung-Bi Shih 			dai_link->codecs->of_node = hdmi_codec;
7514d36ed8eSTzung-Bi Shih 			dai_link->ignore = 0;
7524d36ed8eSTzung-Bi Shih 		}
7535bdbe977STzung-Bi Shih 
7549e30251fSTzung-Bi Shih 		if (!dai_link->platforms->name)
7554b990642SKuninori Morimoto 			dai_link->platforms->of_node = platform_node;
756ebbddc75SShunli Wang 	}
757ebbddc75SShunli Wang 
7585c9e38cbSKuninori Morimoto 	mt8183_da7219_max98357_headset_dev.dlc.of_node =
759ebbddc75SShunli Wang 		of_parse_phandle(pdev->dev.of_node,
760ebbddc75SShunli Wang 				 "mediatek,headset-codec", 0);
7615c9e38cbSKuninori Morimoto 	if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) {
762ebbddc75SShunli Wang 		dev_err(&pdev->dev,
763ebbddc75SShunli Wang 			"Property 'mediatek,headset-codec' missing/invalid\n");
764ebbddc75SShunli Wang 		return -EINVAL;
765ebbddc75SShunli Wang 	}
766ebbddc75SShunli Wang 
7678726ee61STzung-Bi Shih 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
7688726ee61STzung-Bi Shih 	if (!priv)
7698726ee61STzung-Bi Shih 		return -ENOMEM;
7708726ee61STzung-Bi Shih 
7718726ee61STzung-Bi Shih 	snd_soc_card_set_drvdata(card, priv);
7728726ee61STzung-Bi Shih 
773c77b8317STzung-Bi Shih 	pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT);
774c77b8317STzung-Bi Shih 	if (IS_ERR(pinctrl)) {
775c77b8317STzung-Bi Shih 		ret = PTR_ERR(pinctrl);
776c77b8317STzung-Bi Shih 		dev_err(&pdev->dev, "%s failed to select default state %d\n",
7778726ee61STzung-Bi Shih 			__func__, ret);
778c77b8317STzung-Bi Shih 		return ret;
779ebbddc75SShunli Wang 	}
780ebbddc75SShunli Wang 
781cb006006STzung-Bi Shih 	ret = devm_snd_soc_register_card(&pdev->dev, card);
782cb006006STzung-Bi Shih 
783cb006006STzung-Bi Shih 	of_node_put(platform_node);
784cb006006STzung-Bi Shih 	of_node_put(hdmi_codec);
785cb006006STzung-Bi Shih 	return ret;
786ebbddc75SShunli Wang }
787ebbddc75SShunli Wang 
788ebbddc75SShunli Wang #ifdef CONFIG_OF
789ebbddc75SShunli Wang static const struct of_device_id mt8183_da7219_max98357_dt_match[] = {
7909e30251fSTzung-Bi Shih 	{
7919e30251fSTzung-Bi Shih 		.compatible = "mediatek,mt8183_da7219_max98357",
7929e30251fSTzung-Bi Shih 		.data = &mt8183_da7219_max98357_card,
7939e30251fSTzung-Bi Shih 	},
7949e30251fSTzung-Bi Shih 	{
7959e30251fSTzung-Bi Shih 		.compatible = "mediatek,mt8183_da7219_rt1015",
7969e30251fSTzung-Bi Shih 		.data = &mt8183_da7219_rt1015_card,
7979e30251fSTzung-Bi Shih 	},
7987e5bfdddSTzung-Bi Shih 	{
7997e5bfdddSTzung-Bi Shih 		.compatible = "mediatek,mt8183_da7219_rt1015p",
8007e5bfdddSTzung-Bi Shih 		.data = &mt8183_da7219_rt1015p_card,
8017e5bfdddSTzung-Bi Shih 	},
802ebbddc75SShunli Wang 	{}
803ebbddc75SShunli Wang };
804ebbddc75SShunli Wang #endif
805ebbddc75SShunli Wang 
806ebbddc75SShunli Wang static struct platform_driver mt8183_da7219_max98357_driver = {
807ebbddc75SShunli Wang 	.driver = {
8089e30251fSTzung-Bi Shih 		.name = "mt8183_da7219",
809ebbddc75SShunli Wang #ifdef CONFIG_OF
810ebbddc75SShunli Wang 		.of_match_table = mt8183_da7219_max98357_dt_match,
811ebbddc75SShunli Wang #endif
812de96bd7bSTzung-Bi Shih 		.pm = &snd_soc_pm_ops,
813ebbddc75SShunli Wang 	},
814ebbddc75SShunli Wang 	.probe = mt8183_da7219_max98357_dev_probe,
815ebbddc75SShunli Wang };
816ebbddc75SShunli Wang 
817ebbddc75SShunli Wang module_platform_driver(mt8183_da7219_max98357_driver);
818ebbddc75SShunli Wang 
819ebbddc75SShunli Wang /* Module information */
820ebbddc75SShunli Wang MODULE_DESCRIPTION("MT8183-DA7219-MAX98357 ALSA SoC machine driver");
821ebbddc75SShunli Wang MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>");
822ebbddc75SShunli Wang MODULE_LICENSE("GPL v2");
823ebbddc75SShunli Wang MODULE_ALIAS("mt8183_da7219_max98357 soc card");
824