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