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