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.h"
189e30251fSTzung-Bi Shih #include "../../codecs/rt1015.h"
194583392aSNícolas F. R. A. Prado #include "../common/mtk-afe-platform-driver.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
329c7388baSAlper Nebi Yasak static struct snd_soc_jack_pin mt8183_da7219_max98357_jack_pins[] = {
339c7388baSAlper Nebi Yasak {
34*2886b30bSHsin-Te Yuan .pin = "Headphones",
359c7388baSAlper Nebi Yasak .mask = SND_JACK_HEADPHONE,
369c7388baSAlper Nebi Yasak },
379c7388baSAlper Nebi Yasak {
389c7388baSAlper Nebi Yasak .pin = "Headset Mic",
399c7388baSAlper Nebi Yasak .mask = SND_JACK_MICROPHONE,
409c7388baSAlper Nebi Yasak },
419c7388baSAlper Nebi Yasak {
429c7388baSAlper Nebi Yasak .pin = "Line Out",
439c7388baSAlper Nebi Yasak .mask = SND_JACK_LINEOUT,
449c7388baSAlper Nebi Yasak },
459c7388baSAlper Nebi Yasak };
469c7388baSAlper Nebi Yasak
mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)47ebbddc75SShunli Wang static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream,
48ebbddc75SShunli Wang struct snd_pcm_hw_params *params)
49ebbddc75SShunli Wang {
500cd08b10SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
51ebbddc75SShunli Wang unsigned int rate = params_rate(params);
52ebbddc75SShunli Wang unsigned int mclk_fs_ratio = 128;
53ebbddc75SShunli Wang unsigned int mclk_fs = rate * mclk_fs_ratio;
54ebbddc75SShunli Wang
55c8ac8212SKuninori Morimoto return snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0),
56ebbddc75SShunli Wang 0, mclk_fs, SND_SOC_CLOCK_OUT);
57ebbddc75SShunli Wang }
58ebbddc75SShunli Wang
59ebbddc75SShunli Wang static const struct snd_soc_ops mt8183_mt6358_i2s_ops = {
60ebbddc75SShunli Wang .hw_params = mt8183_mt6358_i2s_hw_params,
61ebbddc75SShunli Wang };
62ebbddc75SShunli Wang
mt8183_da7219_i2s_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)63ebbddc75SShunli Wang static int mt8183_da7219_i2s_hw_params(struct snd_pcm_substream *substream,
64ebbddc75SShunli Wang struct snd_pcm_hw_params *params)
65ebbddc75SShunli Wang {
660cd08b10SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
6756f1003fSKuninori Morimoto struct snd_soc_dai *codec_dai;
68ebbddc75SShunli Wang unsigned int rate = params_rate(params);
69ebbddc75SShunli Wang unsigned int mclk_fs_ratio = 256;
70ebbddc75SShunli Wang unsigned int mclk_fs = rate * mclk_fs_ratio;
71ebbddc75SShunli Wang unsigned int freq;
72ebbddc75SShunli Wang int ret = 0, j;
73ebbddc75SShunli Wang
74c8ac8212SKuninori Morimoto ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0,
75ebbddc75SShunli Wang mclk_fs, SND_SOC_CLOCK_OUT);
76ebbddc75SShunli Wang if (ret < 0)
77ebbddc75SShunli Wang dev_err(rtd->dev, "failed to set cpu dai sysclk\n");
78ebbddc75SShunli Wang
79c8654520SKuninori Morimoto for_each_rtd_codec_dais(rtd, j, codec_dai) {
80e5d4bdffSTzung-Bi Shih if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
81ebbddc75SShunli Wang ret = snd_soc_dai_set_sysclk(codec_dai,
82ebbddc75SShunli Wang DA7219_CLKSRC_MCLK,
83ebbddc75SShunli Wang mclk_fs,
84ebbddc75SShunli Wang SND_SOC_CLOCK_IN);
85ebbddc75SShunli Wang if (ret < 0)
86ebbddc75SShunli Wang dev_err(rtd->dev, "failed to set sysclk\n");
87ebbddc75SShunli Wang
88ebbddc75SShunli Wang if ((rate % 8000) == 0)
89ebbddc75SShunli Wang freq = DA7219_PLL_FREQ_OUT_98304;
90ebbddc75SShunli Wang else
91ebbddc75SShunli Wang freq = DA7219_PLL_FREQ_OUT_90316;
92ebbddc75SShunli Wang
93ebbddc75SShunli Wang ret = snd_soc_dai_set_pll(codec_dai, 0,
94ebbddc75SShunli Wang DA7219_SYSCLK_PLL_SRM,
95ebbddc75SShunli Wang 0, freq);
96ebbddc75SShunli Wang if (ret)
97ebbddc75SShunli Wang dev_err(rtd->dev, "failed to start PLL: %d\n",
98ebbddc75SShunli Wang ret);
99ebbddc75SShunli Wang }
100ebbddc75SShunli Wang }
101ebbddc75SShunli Wang
102ebbddc75SShunli Wang return ret;
103ebbddc75SShunli Wang }
104ebbddc75SShunli Wang
mt8183_da7219_hw_free(struct snd_pcm_substream * substream)105ebbddc75SShunli Wang static int mt8183_da7219_hw_free(struct snd_pcm_substream *substream)
106ebbddc75SShunli Wang {
1070cd08b10SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
10856f1003fSKuninori Morimoto struct snd_soc_dai *codec_dai;
109ebbddc75SShunli Wang int ret = 0, j;
110ebbddc75SShunli Wang
111c8654520SKuninori Morimoto for_each_rtd_codec_dais(rtd, j, codec_dai) {
112e5d4bdffSTzung-Bi Shih if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
113ebbddc75SShunli Wang ret = snd_soc_dai_set_pll(codec_dai,
114ebbddc75SShunli Wang 0, DA7219_SYSCLK_MCLK, 0, 0);
115ebbddc75SShunli Wang if (ret < 0) {
116ebbddc75SShunli Wang dev_err(rtd->dev, "failed to stop PLL: %d\n",
117ebbddc75SShunli Wang ret);
118ebbddc75SShunli Wang break;
119ebbddc75SShunli Wang }
120ebbddc75SShunli Wang }
121ebbddc75SShunli Wang }
122ebbddc75SShunli Wang
123ebbddc75SShunli Wang return ret;
124ebbddc75SShunli Wang }
125ebbddc75SShunli Wang
126ebbddc75SShunli Wang static const struct snd_soc_ops mt8183_da7219_i2s_ops = {
127ebbddc75SShunli Wang .hw_params = mt8183_da7219_i2s_hw_params,
128ebbddc75SShunli Wang .hw_free = mt8183_da7219_hw_free,
129ebbddc75SShunli Wang };
130ebbddc75SShunli Wang
1319e30251fSTzung-Bi Shih static int
mt8183_da7219_rt1015_i2s_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)1329e30251fSTzung-Bi Shih mt8183_da7219_rt1015_i2s_hw_params(struct snd_pcm_substream *substream,
1339e30251fSTzung-Bi Shih struct snd_pcm_hw_params *params)
1349e30251fSTzung-Bi Shih {
1350cd08b10SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
1369e30251fSTzung-Bi Shih unsigned int rate = params_rate(params);
1379e30251fSTzung-Bi Shih struct snd_soc_dai *codec_dai;
1389e30251fSTzung-Bi Shih int ret = 0, i;
1399e30251fSTzung-Bi Shih
1409e30251fSTzung-Bi Shih for_each_rtd_codec_dais(rtd, i, codec_dai) {
1419e30251fSTzung-Bi Shih if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) ||
1429e30251fSTzung-Bi Shih !strcmp(codec_dai->component->name, RT1015_DEV1_NAME)) {
1439e30251fSTzung-Bi Shih ret = snd_soc_dai_set_pll(codec_dai, 0,
1449e30251fSTzung-Bi Shih RT1015_PLL_S_BCLK,
1459e30251fSTzung-Bi Shih rate * 64, rate * 256);
1469e30251fSTzung-Bi Shih if (ret) {
1479e30251fSTzung-Bi Shih dev_err(rtd->dev, "failed to set pll\n");
1489e30251fSTzung-Bi Shih return ret;
1499e30251fSTzung-Bi Shih }
1509e30251fSTzung-Bi Shih
1519e30251fSTzung-Bi Shih ret = snd_soc_dai_set_sysclk(codec_dai,
1529e30251fSTzung-Bi Shih RT1015_SCLK_S_PLL,
1539e30251fSTzung-Bi Shih rate * 256,
1549e30251fSTzung-Bi Shih SND_SOC_CLOCK_IN);
1559e30251fSTzung-Bi Shih if (ret) {
1569e30251fSTzung-Bi Shih dev_err(rtd->dev, "failed to set sysclk\n");
1579e30251fSTzung-Bi Shih return ret;
1589e30251fSTzung-Bi Shih }
1599e30251fSTzung-Bi Shih }
1609e30251fSTzung-Bi Shih }
1619e30251fSTzung-Bi Shih
1629e30251fSTzung-Bi Shih return mt8183_da7219_i2s_hw_params(substream, params);
1639e30251fSTzung-Bi Shih }
1649e30251fSTzung-Bi Shih
1659e30251fSTzung-Bi Shih static const struct snd_soc_ops mt8183_da7219_rt1015_i2s_ops = {
1669e30251fSTzung-Bi Shih .hw_params = mt8183_da7219_rt1015_i2s_hw_params,
1679e30251fSTzung-Bi Shih .hw_free = mt8183_da7219_hw_free,
1689e30251fSTzung-Bi Shih };
1699e30251fSTzung-Bi Shih
mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime * rtd,struct snd_pcm_hw_params * params)170ebbddc75SShunli Wang static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
171ebbddc75SShunli Wang struct snd_pcm_hw_params *params)
172ebbddc75SShunli Wang {
17303c2192aSJiaxin Yu /* fix BE i2s format to S32_LE, clean param mask first */
174ebbddc75SShunli Wang snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
17503c2192aSJiaxin Yu 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
176ebbddc75SShunli Wang
177ebbddc75SShunli Wang params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
178ebbddc75SShunli Wang
179ebbddc75SShunli Wang return 0;
180ebbddc75SShunli Wang }
181ebbddc75SShunli Wang
mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime * rtd,struct snd_pcm_hw_params * params)1829e30251fSTzung-Bi Shih static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
1839e30251fSTzung-Bi Shih struct snd_pcm_hw_params *params)
1849e30251fSTzung-Bi Shih {
18503c2192aSJiaxin Yu /* fix BE i2s format to S24_LE, clean param mask first */
1869e30251fSTzung-Bi Shih snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
18703c2192aSJiaxin Yu 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
1889e30251fSTzung-Bi Shih
1899e30251fSTzung-Bi Shih params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
1909e30251fSTzung-Bi Shih
1919e30251fSTzung-Bi Shih return 0;
1929e30251fSTzung-Bi Shih }
1939e30251fSTzung-Bi Shih
194ec7ba9e1STzung-Bi Shih static int
mt8183_da7219_max98357_startup(struct snd_pcm_substream * substream)195b1647f9fSTzung-Bi Shih mt8183_da7219_max98357_startup(
196b1647f9fSTzung-Bi Shih struct snd_pcm_substream *substream)
197b1647f9fSTzung-Bi Shih {
198b1647f9fSTzung-Bi Shih static const unsigned int rates[] = {
199b1647f9fSTzung-Bi Shih 48000,
200b1647f9fSTzung-Bi Shih };
201b1647f9fSTzung-Bi Shih static const struct snd_pcm_hw_constraint_list constraints_rates = {
202b1647f9fSTzung-Bi Shih .count = ARRAY_SIZE(rates),
203b1647f9fSTzung-Bi Shih .list = rates,
204b1647f9fSTzung-Bi Shih .mask = 0,
205b1647f9fSTzung-Bi Shih };
206b1647f9fSTzung-Bi Shih static const unsigned int channels[] = {
207b1647f9fSTzung-Bi Shih 2,
208b1647f9fSTzung-Bi Shih };
209b1647f9fSTzung-Bi Shih static const struct snd_pcm_hw_constraint_list constraints_channels = {
210b1647f9fSTzung-Bi Shih .count = ARRAY_SIZE(channels),
211b1647f9fSTzung-Bi Shih .list = channels,
212b1647f9fSTzung-Bi Shih .mask = 0,
213b1647f9fSTzung-Bi Shih };
214b1647f9fSTzung-Bi Shih
215b1647f9fSTzung-Bi Shih struct snd_pcm_runtime *runtime = substream->runtime;
216b1647f9fSTzung-Bi Shih
217b1647f9fSTzung-Bi Shih snd_pcm_hw_constraint_list(runtime, 0,
218b1647f9fSTzung-Bi Shih SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
219b1647f9fSTzung-Bi Shih runtime->hw.channels_max = 2;
220b1647f9fSTzung-Bi Shih snd_pcm_hw_constraint_list(runtime, 0,
221b1647f9fSTzung-Bi Shih SNDRV_PCM_HW_PARAM_CHANNELS,
222b1647f9fSTzung-Bi Shih &constraints_channels);
223b1647f9fSTzung-Bi Shih
224b1647f9fSTzung-Bi Shih runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
225b1647f9fSTzung-Bi Shih snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
226b1647f9fSTzung-Bi Shih
227b1647f9fSTzung-Bi Shih return 0;
228b1647f9fSTzung-Bi Shih }
229b1647f9fSTzung-Bi Shih
230b1647f9fSTzung-Bi Shih static const struct snd_soc_ops mt8183_da7219_max98357_ops = {
231b1647f9fSTzung-Bi Shih .startup = mt8183_da7219_max98357_startup,
232b1647f9fSTzung-Bi Shih };
233b1647f9fSTzung-Bi Shih
234b1647f9fSTzung-Bi Shih static int
mt8183_da7219_max98357_bt_sco_startup(struct snd_pcm_substream * substream)235ec7ba9e1STzung-Bi Shih mt8183_da7219_max98357_bt_sco_startup(
236ec7ba9e1STzung-Bi Shih struct snd_pcm_substream *substream)
237ec7ba9e1STzung-Bi Shih {
238ec7ba9e1STzung-Bi Shih static const unsigned int rates[] = {
239ec7ba9e1STzung-Bi Shih 8000, 16000
240ec7ba9e1STzung-Bi Shih };
241ec7ba9e1STzung-Bi Shih static const struct snd_pcm_hw_constraint_list constraints_rates = {
242ec7ba9e1STzung-Bi Shih .count = ARRAY_SIZE(rates),
243ec7ba9e1STzung-Bi Shih .list = rates,
244ec7ba9e1STzung-Bi Shih .mask = 0,
245ec7ba9e1STzung-Bi Shih };
246ec7ba9e1STzung-Bi Shih static const unsigned int channels[] = {
247ec7ba9e1STzung-Bi Shih 1,
248ec7ba9e1STzung-Bi Shih };
249ec7ba9e1STzung-Bi Shih static const struct snd_pcm_hw_constraint_list constraints_channels = {
250ec7ba9e1STzung-Bi Shih .count = ARRAY_SIZE(channels),
251ec7ba9e1STzung-Bi Shih .list = channels,
252ec7ba9e1STzung-Bi Shih .mask = 0,
253ec7ba9e1STzung-Bi Shih };
254ec7ba9e1STzung-Bi Shih
255ec7ba9e1STzung-Bi Shih struct snd_pcm_runtime *runtime = substream->runtime;
256ec7ba9e1STzung-Bi Shih
257ec7ba9e1STzung-Bi Shih snd_pcm_hw_constraint_list(runtime, 0,
258ec7ba9e1STzung-Bi Shih SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
259ec7ba9e1STzung-Bi Shih runtime->hw.channels_max = 1;
260ec7ba9e1STzung-Bi Shih snd_pcm_hw_constraint_list(runtime, 0,
261ec7ba9e1STzung-Bi Shih SNDRV_PCM_HW_PARAM_CHANNELS,
262ec7ba9e1STzung-Bi Shih &constraints_channels);
263ec7ba9e1STzung-Bi Shih
264ec7ba9e1STzung-Bi Shih runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
265ec7ba9e1STzung-Bi Shih snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
266ec7ba9e1STzung-Bi Shih
267ec7ba9e1STzung-Bi Shih return 0;
268ec7ba9e1STzung-Bi Shih }
269ec7ba9e1STzung-Bi Shih
270ec7ba9e1STzung-Bi Shih static const struct snd_soc_ops mt8183_da7219_max98357_bt_sco_ops = {
271ec7ba9e1STzung-Bi Shih .startup = mt8183_da7219_max98357_bt_sco_startup,
272ec7ba9e1STzung-Bi Shih };
273ec7ba9e1STzung-Bi Shih
2744b990642SKuninori Morimoto /* FE */
2754b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(playback1,
2764b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
2774b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY()),
2784b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
2794b990642SKuninori Morimoto
2804b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(playback2,
2814b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
2824b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY()),
2834b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
2844b990642SKuninori Morimoto
2854b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(playback3,
2864b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
2874b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY()),
2884b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
2894b990642SKuninori Morimoto
2904b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(capture1,
2914b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
2924b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY()),
2934b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
2944b990642SKuninori Morimoto
2954b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(capture2,
2964b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
2974b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY()),
2984b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
2994b990642SKuninori Morimoto
3004b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(capture3,
3014b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
3024b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY()),
3034b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
3044b990642SKuninori Morimoto
3054b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(capture_mono,
3064b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")),
3074b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY()),
3084b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
3094b990642SKuninori Morimoto
3104b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(playback_hdmi,
3114b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("HDMI")),
3124b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY()),
3134b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
3144b990642SKuninori Morimoto
3154b990642SKuninori Morimoto /* BE */
3164b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(primary_codec,
3174b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
3184b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")),
3194b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
3204b990642SKuninori Morimoto
3214b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(pcm1,
3224b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
3234b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY()),
3244b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
3254b990642SKuninori Morimoto
3264b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(pcm2,
3274b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")),
3284b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY()),
3294b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
3304b990642SKuninori Morimoto
3314b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(i2s0,
3324b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
3334b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
3344b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
3354b990642SKuninori Morimoto
3364b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(i2s1,
3374b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
3384b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY()),
3394b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
3404b990642SKuninori Morimoto
3414b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(i2s2,
3424b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
343e5d4bdffSTzung-Bi Shih DAILINK_COMP_ARRAY(COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
3444b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
3454b990642SKuninori Morimoto
3469e30251fSTzung-Bi Shih SND_SOC_DAILINK_DEFS(i2s3_max98357a,
3474b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
3484b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi"),
349e5d4bdffSTzung-Bi Shih COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
3504b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
3514b990642SKuninori Morimoto
3529e30251fSTzung-Bi Shih SND_SOC_DAILINK_DEFS(i2s3_rt1015,
3539e30251fSTzung-Bi Shih DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
3549e30251fSTzung-Bi Shih DAILINK_COMP_ARRAY(COMP_CODEC(RT1015_DEV0_NAME, RT1015_CODEC_DAI),
3559e30251fSTzung-Bi Shih COMP_CODEC(RT1015_DEV1_NAME, RT1015_CODEC_DAI),
3569e30251fSTzung-Bi Shih COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
3579e30251fSTzung-Bi Shih DAILINK_COMP_ARRAY(COMP_EMPTY()));
3589e30251fSTzung-Bi Shih
3597e5bfdddSTzung-Bi Shih SND_SOC_DAILINK_DEFS(i2s3_rt1015p,
3607e5bfdddSTzung-Bi Shih DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
3617e5bfdddSTzung-Bi Shih DAILINK_COMP_ARRAY(COMP_CODEC("rt1015p", "HiFi"),
3627e5bfdddSTzung-Bi Shih COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
3637e5bfdddSTzung-Bi Shih DAILINK_COMP_ARRAY(COMP_EMPTY()));
3647e5bfdddSTzung-Bi Shih
3654b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(i2s5,
3664b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("I2S5")),
3674b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
3684b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
3694b990642SKuninori Morimoto
3704b990642SKuninori Morimoto SND_SOC_DAILINK_DEFS(tdm,
3714b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("TDM")),
3725bdbe977STzung-Bi Shih DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")),
3734b990642SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()));
3744b990642SKuninori Morimoto
mt8183_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime * rtd)375e25f8afdSTzung-Bi Shih static int mt8183_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd)
376e25f8afdSTzung-Bi Shih {
377e25f8afdSTzung-Bi Shih struct mt8183_da7219_max98357_priv *priv =
378e25f8afdSTzung-Bi Shih snd_soc_card_get_drvdata(rtd->card);
379e25f8afdSTzung-Bi Shih int ret;
380e25f8afdSTzung-Bi Shih
381e25f8afdSTzung-Bi Shih ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
38219aed2d6SAkihiko Odaki &priv->hdmi_jack);
383e25f8afdSTzung-Bi Shih if (ret)
384e25f8afdSTzung-Bi Shih return ret;
385e25f8afdSTzung-Bi Shih
38655c5cc63SCheng-Yi Chiang return snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component,
38755c5cc63SCheng-Yi Chiang &priv->hdmi_jack, NULL);
388e25f8afdSTzung-Bi Shih }
389e25f8afdSTzung-Bi Shih
mt8183_bt_init(struct snd_soc_pcm_runtime * rtd)3904583392aSNícolas F. R. A. Prado static int mt8183_bt_init(struct snd_soc_pcm_runtime *rtd)
3914583392aSNícolas F. R. A. Prado {
3924583392aSNícolas F. R. A. Prado struct snd_soc_component *cmpnt_afe =
3934583392aSNícolas F. R. A. Prado snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
3944583392aSNícolas F. R. A. Prado struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
3954583392aSNícolas F. R. A. Prado int ret;
3964583392aSNícolas F. R. A. Prado
3974583392aSNícolas F. R. A. Prado ret = mt8183_dai_i2s_set_share(afe, "I2S5", "I2S0");
3984583392aSNícolas F. R. A. Prado if (ret) {
3994583392aSNícolas F. R. A. Prado dev_err(rtd->dev, "Failed to set up shared clocks\n");
4004583392aSNícolas F. R. A. Prado return ret;
4014583392aSNícolas F. R. A. Prado }
4024583392aSNícolas F. R. A. Prado return 0;
4034583392aSNícolas F. R. A. Prado }
4044583392aSNícolas F. R. A. Prado
mt8183_da7219_init(struct snd_soc_pcm_runtime * rtd)4054583392aSNícolas F. R. A. Prado static int mt8183_da7219_init(struct snd_soc_pcm_runtime *rtd)
4064583392aSNícolas F. R. A. Prado {
4074583392aSNícolas F. R. A. Prado struct snd_soc_component *cmpnt_afe =
4084583392aSNícolas F. R. A. Prado snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
4094583392aSNícolas F. R. A. Prado struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
4104583392aSNícolas F. R. A. Prado int ret;
4114583392aSNícolas F. R. A. Prado
4124583392aSNícolas F. R. A. Prado ret = mt8183_dai_i2s_set_share(afe, "I2S2", "I2S3");
4134583392aSNícolas F. R. A. Prado if (ret) {
4144583392aSNícolas F. R. A. Prado dev_err(rtd->dev, "Failed to set up shared clocks\n");
4154583392aSNícolas F. R. A. Prado return ret;
4164583392aSNícolas F. R. A. Prado }
4174583392aSNícolas F. R. A. Prado return 0;
4184583392aSNícolas F. R. A. Prado }
4194583392aSNícolas F. R. A. Prado
4209e30251fSTzung-Bi Shih static struct snd_soc_dai_link mt8183_da7219_dai_links[] = {
421ebbddc75SShunli Wang /* FE */
422ebbddc75SShunli Wang {
423ebbddc75SShunli Wang .name = "Playback_1",
424ebbddc75SShunli Wang .stream_name = "Playback_1",
425ebbddc75SShunli Wang .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
426ebbddc75SShunli Wang SND_SOC_DPCM_TRIGGER_PRE},
427ebbddc75SShunli Wang .dynamic = 1,
428ebbddc75SShunli Wang .dpcm_playback = 1,
429b1647f9fSTzung-Bi Shih .ops = &mt8183_da7219_max98357_ops,
4304b990642SKuninori Morimoto SND_SOC_DAILINK_REG(playback1),
431ebbddc75SShunli Wang },
432ebbddc75SShunli Wang {
433ebbddc75SShunli Wang .name = "Playback_2",
434ebbddc75SShunli Wang .stream_name = "Playback_2",
435ebbddc75SShunli Wang .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
436ebbddc75SShunli Wang SND_SOC_DPCM_TRIGGER_PRE},
437ebbddc75SShunli Wang .dynamic = 1,
438ebbddc75SShunli Wang .dpcm_playback = 1,
439ec7ba9e1STzung-Bi Shih .ops = &mt8183_da7219_max98357_bt_sco_ops,
4404b990642SKuninori Morimoto SND_SOC_DAILINK_REG(playback2),
441ebbddc75SShunli Wang },
442ebbddc75SShunli Wang {
443ebbddc75SShunli Wang .name = "Playback_3",
444ebbddc75SShunli Wang .stream_name = "Playback_3",
445ebbddc75SShunli Wang .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
446ebbddc75SShunli Wang SND_SOC_DPCM_TRIGGER_PRE},
447ebbddc75SShunli Wang .dynamic = 1,
448ebbddc75SShunli Wang .dpcm_playback = 1,
4494b990642SKuninori Morimoto SND_SOC_DAILINK_REG(playback3),
450ebbddc75SShunli Wang },
451ebbddc75SShunli Wang {
452ebbddc75SShunli Wang .name = "Capture_1",
453ebbddc75SShunli Wang .stream_name = "Capture_1",
454ebbddc75SShunli Wang .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
455ebbddc75SShunli Wang SND_SOC_DPCM_TRIGGER_PRE},
456ebbddc75SShunli Wang .dynamic = 1,
457ebbddc75SShunli Wang .dpcm_capture = 1,
458ec7ba9e1STzung-Bi Shih .ops = &mt8183_da7219_max98357_bt_sco_ops,
4594b990642SKuninori Morimoto SND_SOC_DAILINK_REG(capture1),
460ebbddc75SShunli Wang },
461ebbddc75SShunli Wang {
462ebbddc75SShunli Wang .name = "Capture_2",
463ebbddc75SShunli Wang .stream_name = "Capture_2",
464ebbddc75SShunli Wang .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
465ebbddc75SShunli Wang SND_SOC_DPCM_TRIGGER_PRE},
466ebbddc75SShunli Wang .dynamic = 1,
467ebbddc75SShunli Wang .dpcm_capture = 1,
4684b990642SKuninori Morimoto SND_SOC_DAILINK_REG(capture2),
469ebbddc75SShunli Wang },
470ebbddc75SShunli Wang {
471ebbddc75SShunli Wang .name = "Capture_3",
472ebbddc75SShunli Wang .stream_name = "Capture_3",
473ebbddc75SShunli Wang .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
474ebbddc75SShunli Wang SND_SOC_DPCM_TRIGGER_PRE},
475ebbddc75SShunli Wang .dynamic = 1,
476ebbddc75SShunli Wang .dpcm_capture = 1,
477b1647f9fSTzung-Bi Shih .ops = &mt8183_da7219_max98357_ops,
4784b990642SKuninori Morimoto SND_SOC_DAILINK_REG(capture3),
479ebbddc75SShunli Wang },
480ebbddc75SShunli Wang {
481ebbddc75SShunli Wang .name = "Capture_Mono_1",
482ebbddc75SShunli Wang .stream_name = "Capture_Mono_1",
483ebbddc75SShunli Wang .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
484ebbddc75SShunli Wang SND_SOC_DPCM_TRIGGER_PRE},
485ebbddc75SShunli Wang .dynamic = 1,
486ebbddc75SShunli Wang .dpcm_capture = 1,
4874b990642SKuninori Morimoto SND_SOC_DAILINK_REG(capture_mono),
488ebbddc75SShunli Wang },
489ebbddc75SShunli Wang {
490ebbddc75SShunli Wang .name = "Playback_HDMI",
491ebbddc75SShunli Wang .stream_name = "Playback_HDMI",
492ebbddc75SShunli Wang .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
493ebbddc75SShunli Wang SND_SOC_DPCM_TRIGGER_PRE},
494ebbddc75SShunli Wang .dynamic = 1,
495ebbddc75SShunli Wang .dpcm_playback = 1,
4964b990642SKuninori Morimoto SND_SOC_DAILINK_REG(playback_hdmi),
497ebbddc75SShunli Wang },
498ebbddc75SShunli Wang /* BE */
499ebbddc75SShunli Wang {
500ebbddc75SShunli Wang .name = "Primary Codec",
501ebbddc75SShunli Wang .no_pcm = 1,
502ebbddc75SShunli Wang .dpcm_playback = 1,
503ebbddc75SShunli Wang .dpcm_capture = 1,
504ebbddc75SShunli Wang .ignore_suspend = 1,
5054b990642SKuninori Morimoto SND_SOC_DAILINK_REG(primary_codec),
506ebbddc75SShunli Wang },
507ebbddc75SShunli Wang {
508ebbddc75SShunli Wang .name = "PCM 1",
509ebbddc75SShunli Wang .no_pcm = 1,
510ebbddc75SShunli Wang .dpcm_playback = 1,
511ebbddc75SShunli Wang .dpcm_capture = 1,
512ebbddc75SShunli Wang .ignore_suspend = 1,
5134b990642SKuninori Morimoto SND_SOC_DAILINK_REG(pcm1),
514ebbddc75SShunli Wang },
515ebbddc75SShunli Wang {
516ebbddc75SShunli Wang .name = "PCM 2",
517ebbddc75SShunli Wang .no_pcm = 1,
518ebbddc75SShunli Wang .dpcm_playback = 1,
519ebbddc75SShunli Wang .dpcm_capture = 1,
520ebbddc75SShunli Wang .ignore_suspend = 1,
5214b990642SKuninori Morimoto SND_SOC_DAILINK_REG(pcm2),
522ebbddc75SShunli Wang },
523ebbddc75SShunli Wang {
524ebbddc75SShunli Wang .name = "I2S0",
525ebbddc75SShunli Wang .no_pcm = 1,
526ebbddc75SShunli Wang .dpcm_capture = 1,
527ebbddc75SShunli Wang .ignore_suspend = 1,
528ebbddc75SShunli Wang .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
529ebbddc75SShunli Wang .ops = &mt8183_mt6358_i2s_ops,
5304b990642SKuninori Morimoto SND_SOC_DAILINK_REG(i2s0),
531ebbddc75SShunli Wang },
532ebbddc75SShunli Wang {
533ebbddc75SShunli Wang .name = "I2S1",
534ebbddc75SShunli Wang .no_pcm = 1,
535ebbddc75SShunli Wang .dpcm_playback = 1,
536ebbddc75SShunli Wang .ignore_suspend = 1,
537ebbddc75SShunli Wang .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
538ebbddc75SShunli Wang .ops = &mt8183_mt6358_i2s_ops,
5394b990642SKuninori Morimoto SND_SOC_DAILINK_REG(i2s1),
540ebbddc75SShunli Wang },
541ebbddc75SShunli Wang {
542ebbddc75SShunli Wang .name = "I2S2",
543ebbddc75SShunli Wang .no_pcm = 1,
544ebbddc75SShunli Wang .dpcm_capture = 1,
545ebbddc75SShunli Wang .ignore_suspend = 1,
546ebbddc75SShunli Wang .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
547ebbddc75SShunli Wang .ops = &mt8183_da7219_i2s_ops,
5484583392aSNícolas F. R. A. Prado .init = &mt8183_da7219_init,
5494b990642SKuninori Morimoto SND_SOC_DAILINK_REG(i2s2),
550ebbddc75SShunli Wang },
551ebbddc75SShunli Wang {
552ebbddc75SShunli Wang .name = "I2S3",
553ebbddc75SShunli Wang .no_pcm = 1,
554ebbddc75SShunli Wang .dpcm_playback = 1,
555ebbddc75SShunli Wang .ignore_suspend = 1,
556ebbddc75SShunli Wang },
557ebbddc75SShunli Wang {
558ebbddc75SShunli Wang .name = "I2S5",
559ebbddc75SShunli Wang .no_pcm = 1,
560ebbddc75SShunli Wang .dpcm_playback = 1,
561ebbddc75SShunli Wang .ignore_suspend = 1,
562ebbddc75SShunli Wang .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
563ebbddc75SShunli Wang .ops = &mt8183_mt6358_i2s_ops,
5644583392aSNícolas F. R. A. Prado .init = &mt8183_bt_init,
5654b990642SKuninori Morimoto SND_SOC_DAILINK_REG(i2s5),
566ebbddc75SShunli Wang },
567ebbddc75SShunli Wang {
568ebbddc75SShunli Wang .name = "TDM",
569ebbddc75SShunli Wang .no_pcm = 1,
570195a6431STzung-Bi Shih .dai_fmt = SND_SOC_DAIFMT_I2S |
571195a6431STzung-Bi Shih SND_SOC_DAIFMT_IB_IF |
572195a6431STzung-Bi Shih SND_SOC_DAIFMT_CBM_CFM,
573ebbddc75SShunli Wang .dpcm_playback = 1,
574ebbddc75SShunli Wang .ignore_suspend = 1,
5758726ee61STzung-Bi Shih .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
5764d36ed8eSTzung-Bi Shih .ignore = 1,
577e25f8afdSTzung-Bi Shih .init = mt8183_da7219_max98357_hdmi_init,
5784b990642SKuninori Morimoto SND_SOC_DAILINK_REG(tdm),
579ebbddc75SShunli Wang },
580ebbddc75SShunli Wang };
581ebbddc75SShunli Wang
582ebbddc75SShunli Wang static int
mt8183_da7219_max98357_headset_init(struct snd_soc_component * component)583cbafb2ccSTzung-Bi Shih mt8183_da7219_max98357_headset_init(struct snd_soc_component *component)
584cbafb2ccSTzung-Bi Shih {
585cbafb2ccSTzung-Bi Shih int ret;
586cbafb2ccSTzung-Bi Shih struct mt8183_da7219_max98357_priv *priv =
587cbafb2ccSTzung-Bi Shih snd_soc_card_get_drvdata(component->card);
588cbafb2ccSTzung-Bi Shih
589cbafb2ccSTzung-Bi Shih /* Enable Headset and 4 Buttons Jack detection */
5909c7388baSAlper Nebi Yasak ret = snd_soc_card_jack_new_pins(component->card,
591cbafb2ccSTzung-Bi Shih "Headset Jack",
592cbafb2ccSTzung-Bi Shih SND_JACK_HEADSET |
593cbafb2ccSTzung-Bi Shih SND_JACK_BTN_0 | SND_JACK_BTN_1 |
594859ffd0aSTzung-Bi Shih SND_JACK_BTN_2 | SND_JACK_BTN_3 |
595859ffd0aSTzung-Bi Shih SND_JACK_LINEOUT,
5969c7388baSAlper Nebi Yasak &priv->headset_jack,
5979c7388baSAlper Nebi Yasak mt8183_da7219_max98357_jack_pins,
5989c7388baSAlper Nebi Yasak ARRAY_SIZE(mt8183_da7219_max98357_jack_pins));
599cbafb2ccSTzung-Bi Shih if (ret)
600cbafb2ccSTzung-Bi Shih return ret;
601cbafb2ccSTzung-Bi Shih
602cbafb2ccSTzung-Bi Shih snd_jack_set_key(
603cbafb2ccSTzung-Bi Shih priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
604cbafb2ccSTzung-Bi Shih snd_jack_set_key(
605cbafb2ccSTzung-Bi Shih priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
606cbafb2ccSTzung-Bi Shih snd_jack_set_key(
607cbafb2ccSTzung-Bi Shih priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
608cbafb2ccSTzung-Bi Shih snd_jack_set_key(
609cbafb2ccSTzung-Bi Shih priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
610cbafb2ccSTzung-Bi Shih
611922a5e5aSCezary Rojewski snd_soc_component_set_jack(component, &priv->headset_jack, NULL);
612cbafb2ccSTzung-Bi Shih
613cbafb2ccSTzung-Bi Shih return 0;
614cbafb2ccSTzung-Bi Shih }
615ebbddc75SShunli Wang
616ebbddc75SShunli Wang static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = {
6175c9e38cbSKuninori Morimoto .dlc = COMP_EMPTY(),
618ebbddc75SShunli Wang .init = mt8183_da7219_max98357_headset_init,
619ebbddc75SShunli Wang };
620ebbddc75SShunli Wang
621ebbddc75SShunli Wang static struct snd_soc_codec_conf mt6358_codec_conf[] = {
622ebbddc75SShunli Wang {
6232d27a4cfSKuninori Morimoto .dlc = COMP_CODEC_CONF("mt6358-sound"),
624ebbddc75SShunli Wang .name_prefix = "Mt6358",
625ebbddc75SShunli Wang },
626ebbddc75SShunli Wang };
627ebbddc75SShunli Wang
628514de1c9STzung-Bi Shih static const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = {
629*2886b30bSHsin-Te Yuan SOC_DAPM_PIN_SWITCH("Headphones"),
6309c7388baSAlper Nebi Yasak SOC_DAPM_PIN_SWITCH("Headset Mic"),
631514de1c9STzung-Bi Shih SOC_DAPM_PIN_SWITCH("Speakers"),
6329c7388baSAlper Nebi Yasak SOC_DAPM_PIN_SWITCH("Line Out"),
633514de1c9STzung-Bi Shih };
634514de1c9STzung-Bi Shih
635514de1c9STzung-Bi Shih static const
636514de1c9STzung-Bi Shih struct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = {
637*2886b30bSHsin-Te Yuan SND_SOC_DAPM_HP("Headphones", NULL),
6389c7388baSAlper Nebi Yasak SND_SOC_DAPM_MIC("Headset Mic", NULL),
639514de1c9STzung-Bi Shih SND_SOC_DAPM_SPK("Speakers", NULL),
6409c7388baSAlper Nebi Yasak SND_SOC_DAPM_SPK("Line Out", NULL),
641c77b8317STzung-Bi Shih SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
642c77b8317STzung-Bi Shih "aud_tdm_out_on", "aud_tdm_out_off"),
643514de1c9STzung-Bi Shih };
644514de1c9STzung-Bi Shih
645514de1c9STzung-Bi Shih static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = {
646514de1c9STzung-Bi Shih {"Speakers", NULL, "Speaker"},
647c77b8317STzung-Bi Shih {"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
648514de1c9STzung-Bi Shih };
649514de1c9STzung-Bi Shih
650ebbddc75SShunli Wang static struct snd_soc_card mt8183_da7219_max98357_card = {
651ebbddc75SShunli Wang .name = "mt8183_da7219_max98357",
652ebbddc75SShunli Wang .owner = THIS_MODULE,
653514de1c9STzung-Bi Shih .controls = mt8183_da7219_max98357_snd_controls,
654514de1c9STzung-Bi Shih .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
655514de1c9STzung-Bi Shih .dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
656514de1c9STzung-Bi Shih .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
657514de1c9STzung-Bi Shih .dapm_routes = mt8183_da7219_max98357_dapm_routes,
658514de1c9STzung-Bi Shih .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
6599e30251fSTzung-Bi Shih .dai_link = mt8183_da7219_dai_links,
6609e30251fSTzung-Bi Shih .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
661ebbddc75SShunli Wang .aux_dev = &mt8183_da7219_max98357_headset_dev,
662ebbddc75SShunli Wang .num_aux_devs = 1,
663ebbddc75SShunli Wang .codec_conf = mt6358_codec_conf,
664ebbddc75SShunli Wang .num_configs = ARRAY_SIZE(mt6358_codec_conf),
665ebbddc75SShunli Wang };
666ebbddc75SShunli Wang
6679e30251fSTzung-Bi Shih static struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = {
6689e30251fSTzung-Bi Shih {
6699e30251fSTzung-Bi Shih .dlc = COMP_CODEC_CONF("mt6358-sound"),
6709e30251fSTzung-Bi Shih .name_prefix = "Mt6358",
6719e30251fSTzung-Bi Shih },
6729e30251fSTzung-Bi Shih {
6739e30251fSTzung-Bi Shih .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME),
6749e30251fSTzung-Bi Shih .name_prefix = "Left",
6759e30251fSTzung-Bi Shih },
6769e30251fSTzung-Bi Shih {
6779e30251fSTzung-Bi Shih .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME),
6789e30251fSTzung-Bi Shih .name_prefix = "Right",
6799e30251fSTzung-Bi Shih },
6809e30251fSTzung-Bi Shih };
6819e30251fSTzung-Bi Shih
682eb5a5587STzung-Bi Shih static const struct snd_kcontrol_new mt8183_da7219_rt1015_snd_controls[] = {
683*2886b30bSHsin-Te Yuan SOC_DAPM_PIN_SWITCH("Headphones"),
6849c7388baSAlper Nebi Yasak SOC_DAPM_PIN_SWITCH("Headset Mic"),
685eb5a5587STzung-Bi Shih SOC_DAPM_PIN_SWITCH("Left Spk"),
686eb5a5587STzung-Bi Shih SOC_DAPM_PIN_SWITCH("Right Spk"),
6879c7388baSAlper Nebi Yasak SOC_DAPM_PIN_SWITCH("Line Out"),
688eb5a5587STzung-Bi Shih };
689eb5a5587STzung-Bi Shih
690eb5a5587STzung-Bi Shih static const
691eb5a5587STzung-Bi Shih struct snd_soc_dapm_widget mt8183_da7219_rt1015_dapm_widgets[] = {
692*2886b30bSHsin-Te Yuan SND_SOC_DAPM_HP("Headphones", NULL),
6939c7388baSAlper Nebi Yasak SND_SOC_DAPM_MIC("Headset Mic", NULL),
694eb5a5587STzung-Bi Shih SND_SOC_DAPM_SPK("Left Spk", NULL),
695eb5a5587STzung-Bi Shih SND_SOC_DAPM_SPK("Right Spk", NULL),
6969c7388baSAlper Nebi Yasak SND_SOC_DAPM_LINE("Line Out", NULL),
697eb5a5587STzung-Bi Shih SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
698eb5a5587STzung-Bi Shih "aud_tdm_out_on", "aud_tdm_out_off"),
699eb5a5587STzung-Bi Shih };
700eb5a5587STzung-Bi Shih
701eb5a5587STzung-Bi Shih static const struct snd_soc_dapm_route mt8183_da7219_rt1015_dapm_routes[] = {
702eb5a5587STzung-Bi Shih {"Left Spk", NULL, "Left SPO"},
703eb5a5587STzung-Bi Shih {"Right Spk", NULL, "Right SPO"},
704eb5a5587STzung-Bi Shih {"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
705eb5a5587STzung-Bi Shih };
706eb5a5587STzung-Bi Shih
7079e30251fSTzung-Bi Shih static struct snd_soc_card mt8183_da7219_rt1015_card = {
7089e30251fSTzung-Bi Shih .name = "mt8183_da7219_rt1015",
7099e30251fSTzung-Bi Shih .owner = THIS_MODULE,
710eb5a5587STzung-Bi Shih .controls = mt8183_da7219_rt1015_snd_controls,
711eb5a5587STzung-Bi Shih .num_controls = ARRAY_SIZE(mt8183_da7219_rt1015_snd_controls),
712eb5a5587STzung-Bi Shih .dapm_widgets = mt8183_da7219_rt1015_dapm_widgets,
713eb5a5587STzung-Bi Shih .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_widgets),
714eb5a5587STzung-Bi Shih .dapm_routes = mt8183_da7219_rt1015_dapm_routes,
715eb5a5587STzung-Bi Shih .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_routes),
7169e30251fSTzung-Bi Shih .dai_link = mt8183_da7219_dai_links,
7179e30251fSTzung-Bi Shih .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
7189e30251fSTzung-Bi Shih .aux_dev = &mt8183_da7219_max98357_headset_dev,
7199e30251fSTzung-Bi Shih .num_aux_devs = 1,
7209e30251fSTzung-Bi Shih .codec_conf = mt8183_da7219_rt1015_codec_conf,
7219e30251fSTzung-Bi Shih .num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf),
7229e30251fSTzung-Bi Shih };
7239e30251fSTzung-Bi Shih
7247e5bfdddSTzung-Bi Shih static struct snd_soc_card mt8183_da7219_rt1015p_card = {
7257e5bfdddSTzung-Bi Shih .name = "mt8183_da7219_rt1015p",
7267e5bfdddSTzung-Bi Shih .owner = THIS_MODULE,
7277e5bfdddSTzung-Bi Shih .controls = mt8183_da7219_max98357_snd_controls,
7287e5bfdddSTzung-Bi Shih .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
7297e5bfdddSTzung-Bi Shih .dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
7307e5bfdddSTzung-Bi Shih .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
7317e5bfdddSTzung-Bi Shih .dapm_routes = mt8183_da7219_max98357_dapm_routes,
7327e5bfdddSTzung-Bi Shih .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
7337e5bfdddSTzung-Bi Shih .dai_link = mt8183_da7219_dai_links,
7347e5bfdddSTzung-Bi Shih .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
7357e5bfdddSTzung-Bi Shih .aux_dev = &mt8183_da7219_max98357_headset_dev,
7367e5bfdddSTzung-Bi Shih .num_aux_devs = 1,
7377e5bfdddSTzung-Bi Shih .codec_conf = mt6358_codec_conf,
7387e5bfdddSTzung-Bi Shih .num_configs = ARRAY_SIZE(mt6358_codec_conf),
7397e5bfdddSTzung-Bi Shih };
7407e5bfdddSTzung-Bi Shih
mt8183_da7219_max98357_dev_probe(struct platform_device * pdev)741ebbddc75SShunli Wang static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
742ebbddc75SShunli Wang {
7439e30251fSTzung-Bi Shih struct snd_soc_card *card;
7445bdbe977STzung-Bi Shih struct device_node *platform_node, *hdmi_codec;
745ebbddc75SShunli Wang struct snd_soc_dai_link *dai_link;
7468726ee61STzung-Bi Shih struct mt8183_da7219_max98357_priv *priv;
747c77b8317STzung-Bi Shih struct pinctrl *pinctrl;
748ebbddc75SShunli Wang int ret, i;
749ebbddc75SShunli Wang
750ebbddc75SShunli Wang platform_node = of_parse_phandle(pdev->dev.of_node,
751ebbddc75SShunli Wang "mediatek,platform", 0);
752ebbddc75SShunli Wang if (!platform_node) {
753ebbddc75SShunli Wang dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
754ebbddc75SShunli Wang return -EINVAL;
755ebbddc75SShunli Wang }
756ebbddc75SShunli Wang
7573667a037STzung-Bi Shih card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev);
75828a265a1SMiaoqian Lin if (!card) {
75928a265a1SMiaoqian Lin ret = -EINVAL;
76028a265a1SMiaoqian Lin goto put_platform_node;
76128a265a1SMiaoqian Lin }
76228a265a1SMiaoqian Lin
7639e30251fSTzung-Bi Shih card->dev = &pdev->dev;
7649e30251fSTzung-Bi Shih
7655bdbe977STzung-Bi Shih hdmi_codec = of_parse_phandle(pdev->dev.of_node,
7665bdbe977STzung-Bi Shih "mediatek,hdmi-codec", 0);
7675bdbe977STzung-Bi Shih
768ebbddc75SShunli Wang for_each_card_prelinks(card, i, dai_link) {
7699e30251fSTzung-Bi Shih if (strcmp(dai_link->name, "I2S3") == 0) {
7709e30251fSTzung-Bi Shih if (card == &mt8183_da7219_max98357_card) {
7719e30251fSTzung-Bi Shih dai_link->be_hw_params_fixup =
7729e30251fSTzung-Bi Shih mt8183_i2s_hw_params_fixup;
773ebb11d1dSTzung-Bi Shih dai_link->ops = &mt8183_da7219_i2s_ops;
7749e30251fSTzung-Bi Shih dai_link->cpus = i2s3_max98357a_cpus;
7759e30251fSTzung-Bi Shih dai_link->num_cpus =
7769e30251fSTzung-Bi Shih ARRAY_SIZE(i2s3_max98357a_cpus);
7779e30251fSTzung-Bi Shih dai_link->codecs = i2s3_max98357a_codecs;
7789e30251fSTzung-Bi Shih dai_link->num_codecs =
7799e30251fSTzung-Bi Shih ARRAY_SIZE(i2s3_max98357a_codecs);
7809e30251fSTzung-Bi Shih dai_link->platforms = i2s3_max98357a_platforms;
7819e30251fSTzung-Bi Shih dai_link->num_platforms =
7829e30251fSTzung-Bi Shih ARRAY_SIZE(i2s3_max98357a_platforms);
7839e30251fSTzung-Bi Shih } else if (card == &mt8183_da7219_rt1015_card) {
7849e30251fSTzung-Bi Shih dai_link->be_hw_params_fixup =
7859e30251fSTzung-Bi Shih mt8183_rt1015_i2s_hw_params_fixup;
7869e30251fSTzung-Bi Shih dai_link->ops = &mt8183_da7219_rt1015_i2s_ops;
7879e30251fSTzung-Bi Shih dai_link->cpus = i2s3_rt1015_cpus;
7889e30251fSTzung-Bi Shih dai_link->num_cpus =
7899e30251fSTzung-Bi Shih ARRAY_SIZE(i2s3_rt1015_cpus);
7909e30251fSTzung-Bi Shih dai_link->codecs = i2s3_rt1015_codecs;
7919e30251fSTzung-Bi Shih dai_link->num_codecs =
7929e30251fSTzung-Bi Shih ARRAY_SIZE(i2s3_rt1015_codecs);
7939e30251fSTzung-Bi Shih dai_link->platforms = i2s3_rt1015_platforms;
7949e30251fSTzung-Bi Shih dai_link->num_platforms =
7959e30251fSTzung-Bi Shih ARRAY_SIZE(i2s3_rt1015_platforms);
7967e5bfdddSTzung-Bi Shih } else if (card == &mt8183_da7219_rt1015p_card) {
7977e5bfdddSTzung-Bi Shih dai_link->be_hw_params_fixup =
7987e5bfdddSTzung-Bi Shih mt8183_rt1015_i2s_hw_params_fixup;
7997e5bfdddSTzung-Bi Shih dai_link->ops = &mt8183_da7219_i2s_ops;
8007e5bfdddSTzung-Bi Shih dai_link->cpus = i2s3_rt1015p_cpus;
8017e5bfdddSTzung-Bi Shih dai_link->num_cpus =
8027e5bfdddSTzung-Bi Shih ARRAY_SIZE(i2s3_rt1015p_cpus);
8037e5bfdddSTzung-Bi Shih dai_link->codecs = i2s3_rt1015p_codecs;
8047e5bfdddSTzung-Bi Shih dai_link->num_codecs =
8057e5bfdddSTzung-Bi Shih ARRAY_SIZE(i2s3_rt1015p_codecs);
8067e5bfdddSTzung-Bi Shih dai_link->platforms = i2s3_rt1015p_platforms;
8077e5bfdddSTzung-Bi Shih dai_link->num_platforms =
8087e5bfdddSTzung-Bi Shih ARRAY_SIZE(i2s3_rt1015p_platforms);
8099e30251fSTzung-Bi Shih }
8109e30251fSTzung-Bi Shih }
8119e30251fSTzung-Bi Shih
8124d36ed8eSTzung-Bi Shih if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) {
8135bdbe977STzung-Bi Shih dai_link->codecs->of_node = hdmi_codec;
8144d36ed8eSTzung-Bi Shih dai_link->ignore = 0;
8154d36ed8eSTzung-Bi Shih }
8165bdbe977STzung-Bi Shih
8179e30251fSTzung-Bi Shih if (!dai_link->platforms->name)
8184b990642SKuninori Morimoto dai_link->platforms->of_node = platform_node;
819ebbddc75SShunli Wang }
820ebbddc75SShunli Wang
8215c9e38cbSKuninori Morimoto mt8183_da7219_max98357_headset_dev.dlc.of_node =
822ebbddc75SShunli Wang of_parse_phandle(pdev->dev.of_node,
823ebbddc75SShunli Wang "mediatek,headset-codec", 0);
8245c9e38cbSKuninori Morimoto if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) {
825ebbddc75SShunli Wang dev_err(&pdev->dev,
826ebbddc75SShunli Wang "Property 'mediatek,headset-codec' missing/invalid\n");
82728a265a1SMiaoqian Lin ret = -EINVAL;
82828a265a1SMiaoqian Lin goto put_hdmi_codec;
829ebbddc75SShunli Wang }
830ebbddc75SShunli Wang
8318726ee61STzung-Bi Shih priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
83228a265a1SMiaoqian Lin if (!priv) {
83328a265a1SMiaoqian Lin ret = -ENOMEM;
83428a265a1SMiaoqian Lin goto put_hdmi_codec;
83528a265a1SMiaoqian Lin }
8368726ee61STzung-Bi Shih
8378726ee61STzung-Bi Shih snd_soc_card_set_drvdata(card, priv);
8388726ee61STzung-Bi Shih
839c77b8317STzung-Bi Shih pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT);
840c77b8317STzung-Bi Shih if (IS_ERR(pinctrl)) {
841c77b8317STzung-Bi Shih ret = PTR_ERR(pinctrl);
842c77b8317STzung-Bi Shih dev_err(&pdev->dev, "%s failed to select default state %d\n",
8438726ee61STzung-Bi Shih __func__, ret);
84428a265a1SMiaoqian Lin goto put_hdmi_codec;
845ebbddc75SShunli Wang }
846ebbddc75SShunli Wang
847cb006006STzung-Bi Shih ret = devm_snd_soc_register_card(&pdev->dev, card);
848cb006006STzung-Bi Shih
84928a265a1SMiaoqian Lin
85028a265a1SMiaoqian Lin put_hdmi_codec:
851cb006006STzung-Bi Shih of_node_put(hdmi_codec);
85228a265a1SMiaoqian Lin put_platform_node:
85328a265a1SMiaoqian Lin of_node_put(platform_node);
854cb006006STzung-Bi Shih return ret;
855ebbddc75SShunli Wang }
856ebbddc75SShunli Wang
857ebbddc75SShunli Wang #ifdef CONFIG_OF
858ebbddc75SShunli Wang static const struct of_device_id mt8183_da7219_max98357_dt_match[] = {
8599e30251fSTzung-Bi Shih {
8609e30251fSTzung-Bi Shih .compatible = "mediatek,mt8183_da7219_max98357",
8619e30251fSTzung-Bi Shih .data = &mt8183_da7219_max98357_card,
8629e30251fSTzung-Bi Shih },
8639e30251fSTzung-Bi Shih {
8649e30251fSTzung-Bi Shih .compatible = "mediatek,mt8183_da7219_rt1015",
8659e30251fSTzung-Bi Shih .data = &mt8183_da7219_rt1015_card,
8669e30251fSTzung-Bi Shih },
8677e5bfdddSTzung-Bi Shih {
8687e5bfdddSTzung-Bi Shih .compatible = "mediatek,mt8183_da7219_rt1015p",
8697e5bfdddSTzung-Bi Shih .data = &mt8183_da7219_rt1015p_card,
8707e5bfdddSTzung-Bi Shih },
871ebbddc75SShunli Wang {}
872ebbddc75SShunli Wang };
873b5e004b0SNícolas F. R. A. Prado MODULE_DEVICE_TABLE(of, mt8183_da7219_max98357_dt_match);
874ebbddc75SShunli Wang #endif
875ebbddc75SShunli Wang
876ebbddc75SShunli Wang static struct platform_driver mt8183_da7219_max98357_driver = {
877ebbddc75SShunli Wang .driver = {
8789e30251fSTzung-Bi Shih .name = "mt8183_da7219",
879ebbddc75SShunli Wang #ifdef CONFIG_OF
880ebbddc75SShunli Wang .of_match_table = mt8183_da7219_max98357_dt_match,
881ebbddc75SShunli Wang #endif
882de96bd7bSTzung-Bi Shih .pm = &snd_soc_pm_ops,
883ebbddc75SShunli Wang },
884ebbddc75SShunli Wang .probe = mt8183_da7219_max98357_dev_probe,
885ebbddc75SShunli Wang };
886ebbddc75SShunli Wang
887ebbddc75SShunli Wang module_platform_driver(mt8183_da7219_max98357_driver);
888ebbddc75SShunli Wang
889ebbddc75SShunli Wang /* Module information */
890ebbddc75SShunli Wang MODULE_DESCRIPTION("MT8183-DA7219-MAX98357 ALSA SoC machine driver");
891ebbddc75SShunli Wang MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>");
892ebbddc75SShunli Wang MODULE_LICENSE("GPL v2");
893ebbddc75SShunli Wang MODULE_ALIAS("mt8183_da7219_max98357 soc card");
894