Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // mt8183-da7219-max98357.c
0004 //  --  MT8183-DA7219-MAX98357 ALSA SoC machine driver
0005 //
0006 // Copyright (c) 2018 MediaTek Inc.
0007 // Author: Shunli Wang <shunli.wang@mediatek.com>
0008 
0009 #include <linux/input.h>
0010 #include <linux/module.h>
0011 #include <linux/of_device.h>
0012 #include <linux/pinctrl/consumer.h>
0013 #include <sound/jack.h>
0014 #include <sound/pcm_params.h>
0015 #include <sound/soc.h>
0016 
0017 #include "../../codecs/da7219-aad.h"
0018 #include "../../codecs/da7219.h"
0019 #include "../../codecs/rt1015.h"
0020 #include "mt8183-afe-common.h"
0021 
0022 #define DA7219_CODEC_DAI "da7219-hifi"
0023 #define DA7219_DEV_NAME "da7219.5-001a"
0024 #define RT1015_CODEC_DAI "rt1015-aif"
0025 #define RT1015_DEV0_NAME "rt1015.6-0028"
0026 #define RT1015_DEV1_NAME "rt1015.6-0029"
0027 
0028 struct mt8183_da7219_max98357_priv {
0029     struct snd_soc_jack headset_jack, hdmi_jack;
0030 };
0031 
0032 static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream,
0033                        struct snd_pcm_hw_params *params)
0034 {
0035     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0036     unsigned int rate = params_rate(params);
0037     unsigned int mclk_fs_ratio = 128;
0038     unsigned int mclk_fs = rate * mclk_fs_ratio;
0039 
0040     return snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0),
0041                       0, mclk_fs, SND_SOC_CLOCK_OUT);
0042 }
0043 
0044 static const struct snd_soc_ops mt8183_mt6358_i2s_ops = {
0045     .hw_params = mt8183_mt6358_i2s_hw_params,
0046 };
0047 
0048 static int mt8183_da7219_i2s_hw_params(struct snd_pcm_substream *substream,
0049                        struct snd_pcm_hw_params *params)
0050 {
0051     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0052     struct snd_soc_dai *codec_dai;
0053     unsigned int rate = params_rate(params);
0054     unsigned int mclk_fs_ratio = 256;
0055     unsigned int mclk_fs = rate * mclk_fs_ratio;
0056     unsigned int freq;
0057     int ret = 0, j;
0058 
0059     ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0,
0060                      mclk_fs, SND_SOC_CLOCK_OUT);
0061     if (ret < 0)
0062         dev_err(rtd->dev, "failed to set cpu dai sysclk\n");
0063 
0064     for_each_rtd_codec_dais(rtd, j, codec_dai) {
0065         if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
0066             ret = snd_soc_dai_set_sysclk(codec_dai,
0067                              DA7219_CLKSRC_MCLK,
0068                              mclk_fs,
0069                              SND_SOC_CLOCK_IN);
0070             if (ret < 0)
0071                 dev_err(rtd->dev, "failed to set sysclk\n");
0072 
0073             if ((rate % 8000) == 0)
0074                 freq = DA7219_PLL_FREQ_OUT_98304;
0075             else
0076                 freq = DA7219_PLL_FREQ_OUT_90316;
0077 
0078             ret = snd_soc_dai_set_pll(codec_dai, 0,
0079                           DA7219_SYSCLK_PLL_SRM,
0080                           0, freq);
0081             if (ret)
0082                 dev_err(rtd->dev, "failed to start PLL: %d\n",
0083                     ret);
0084         }
0085     }
0086 
0087     return ret;
0088 }
0089 
0090 static int mt8183_da7219_hw_free(struct snd_pcm_substream *substream)
0091 {
0092     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0093     struct snd_soc_dai *codec_dai;
0094     int ret = 0, j;
0095 
0096     for_each_rtd_codec_dais(rtd, j, codec_dai) {
0097         if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
0098             ret = snd_soc_dai_set_pll(codec_dai,
0099                           0, DA7219_SYSCLK_MCLK, 0, 0);
0100             if (ret < 0) {
0101                 dev_err(rtd->dev, "failed to stop PLL: %d\n",
0102                     ret);
0103                 break;
0104             }
0105         }
0106     }
0107 
0108     return ret;
0109 }
0110 
0111 static const struct snd_soc_ops mt8183_da7219_i2s_ops = {
0112     .hw_params = mt8183_da7219_i2s_hw_params,
0113     .hw_free = mt8183_da7219_hw_free,
0114 };
0115 
0116 static int
0117 mt8183_da7219_rt1015_i2s_hw_params(struct snd_pcm_substream *substream,
0118                    struct snd_pcm_hw_params *params)
0119 {
0120     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0121     unsigned int rate = params_rate(params);
0122     struct snd_soc_dai *codec_dai;
0123     int ret = 0, i;
0124 
0125     for_each_rtd_codec_dais(rtd, i, codec_dai) {
0126         if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) ||
0127             !strcmp(codec_dai->component->name, RT1015_DEV1_NAME)) {
0128             ret = snd_soc_dai_set_pll(codec_dai, 0,
0129                           RT1015_PLL_S_BCLK,
0130                           rate * 64, rate * 256);
0131             if (ret) {
0132                 dev_err(rtd->dev, "failed to set pll\n");
0133                 return ret;
0134             }
0135 
0136             ret = snd_soc_dai_set_sysclk(codec_dai,
0137                              RT1015_SCLK_S_PLL,
0138                              rate * 256,
0139                              SND_SOC_CLOCK_IN);
0140             if (ret) {
0141                 dev_err(rtd->dev, "failed to set sysclk\n");
0142                 return ret;
0143             }
0144         }
0145     }
0146 
0147     return mt8183_da7219_i2s_hw_params(substream, params);
0148 }
0149 
0150 static const struct snd_soc_ops mt8183_da7219_rt1015_i2s_ops = {
0151     .hw_params = mt8183_da7219_rt1015_i2s_hw_params,
0152     .hw_free = mt8183_da7219_hw_free,
0153 };
0154 
0155 static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
0156                       struct snd_pcm_hw_params *params)
0157 {
0158     /* fix BE i2s format to S32_LE, clean param mask first */
0159     snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
0160                  0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
0161 
0162     params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
0163 
0164     return 0;
0165 }
0166 
0167 static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
0168                          struct snd_pcm_hw_params *params)
0169 {
0170     /* fix BE i2s format to S24_LE, clean param mask first */
0171     snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
0172                  0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
0173 
0174     params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
0175 
0176     return 0;
0177 }
0178 
0179 static int
0180 mt8183_da7219_max98357_startup(
0181     struct snd_pcm_substream *substream)
0182 {
0183     static const unsigned int rates[] = {
0184         48000,
0185     };
0186     static const struct snd_pcm_hw_constraint_list constraints_rates = {
0187         .count = ARRAY_SIZE(rates),
0188         .list  = rates,
0189         .mask = 0,
0190     };
0191     static const unsigned int channels[] = {
0192         2,
0193     };
0194     static const struct snd_pcm_hw_constraint_list constraints_channels = {
0195         .count = ARRAY_SIZE(channels),
0196         .list = channels,
0197         .mask = 0,
0198     };
0199 
0200     struct snd_pcm_runtime *runtime = substream->runtime;
0201 
0202     snd_pcm_hw_constraint_list(runtime, 0,
0203             SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
0204     runtime->hw.channels_max = 2;
0205     snd_pcm_hw_constraint_list(runtime, 0,
0206             SNDRV_PCM_HW_PARAM_CHANNELS,
0207             &constraints_channels);
0208 
0209     runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
0210     snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
0211 
0212     return 0;
0213 }
0214 
0215 static const struct snd_soc_ops mt8183_da7219_max98357_ops = {
0216     .startup = mt8183_da7219_max98357_startup,
0217 };
0218 
0219 static int
0220 mt8183_da7219_max98357_bt_sco_startup(
0221     struct snd_pcm_substream *substream)
0222 {
0223     static const unsigned int rates[] = {
0224         8000, 16000
0225     };
0226     static const struct snd_pcm_hw_constraint_list constraints_rates = {
0227         .count = ARRAY_SIZE(rates),
0228         .list  = rates,
0229         .mask = 0,
0230     };
0231     static const unsigned int channels[] = {
0232         1,
0233     };
0234     static const struct snd_pcm_hw_constraint_list constraints_channels = {
0235         .count = ARRAY_SIZE(channels),
0236         .list = channels,
0237         .mask = 0,
0238     };
0239 
0240     struct snd_pcm_runtime *runtime = substream->runtime;
0241 
0242     snd_pcm_hw_constraint_list(runtime, 0,
0243             SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
0244     runtime->hw.channels_max = 1;
0245     snd_pcm_hw_constraint_list(runtime, 0,
0246             SNDRV_PCM_HW_PARAM_CHANNELS,
0247             &constraints_channels);
0248 
0249     runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
0250     snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
0251 
0252     return 0;
0253 }
0254 
0255 static const struct snd_soc_ops mt8183_da7219_max98357_bt_sco_ops = {
0256     .startup = mt8183_da7219_max98357_bt_sco_startup,
0257 };
0258 
0259 /* FE */
0260 SND_SOC_DAILINK_DEFS(playback1,
0261     DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
0262     DAILINK_COMP_ARRAY(COMP_DUMMY()),
0263     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0264 
0265 SND_SOC_DAILINK_DEFS(playback2,
0266     DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
0267     DAILINK_COMP_ARRAY(COMP_DUMMY()),
0268     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0269 
0270 SND_SOC_DAILINK_DEFS(playback3,
0271     DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
0272     DAILINK_COMP_ARRAY(COMP_DUMMY()),
0273     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0274 
0275 SND_SOC_DAILINK_DEFS(capture1,
0276     DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
0277     DAILINK_COMP_ARRAY(COMP_DUMMY()),
0278     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0279 
0280 SND_SOC_DAILINK_DEFS(capture2,
0281     DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
0282     DAILINK_COMP_ARRAY(COMP_DUMMY()),
0283     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0284 
0285 SND_SOC_DAILINK_DEFS(capture3,
0286     DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
0287     DAILINK_COMP_ARRAY(COMP_DUMMY()),
0288     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0289 
0290 SND_SOC_DAILINK_DEFS(capture_mono,
0291     DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")),
0292     DAILINK_COMP_ARRAY(COMP_DUMMY()),
0293     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0294 
0295 SND_SOC_DAILINK_DEFS(playback_hdmi,
0296     DAILINK_COMP_ARRAY(COMP_CPU("HDMI")),
0297     DAILINK_COMP_ARRAY(COMP_DUMMY()),
0298     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0299 
0300 /* BE */
0301 SND_SOC_DAILINK_DEFS(primary_codec,
0302     DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
0303     DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")),
0304     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0305 
0306 SND_SOC_DAILINK_DEFS(pcm1,
0307     DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
0308     DAILINK_COMP_ARRAY(COMP_DUMMY()),
0309     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0310 
0311 SND_SOC_DAILINK_DEFS(pcm2,
0312     DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")),
0313     DAILINK_COMP_ARRAY(COMP_DUMMY()),
0314     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0315 
0316 SND_SOC_DAILINK_DEFS(i2s0,
0317     DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
0318     DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
0319     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0320 
0321 SND_SOC_DAILINK_DEFS(i2s1,
0322     DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
0323     DAILINK_COMP_ARRAY(COMP_DUMMY()),
0324     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0325 
0326 SND_SOC_DAILINK_DEFS(i2s2,
0327     DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
0328     DAILINK_COMP_ARRAY(COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
0329     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0330 
0331 SND_SOC_DAILINK_DEFS(i2s3_max98357a,
0332     DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
0333     DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi"),
0334                COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
0335     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0336 
0337 SND_SOC_DAILINK_DEFS(i2s3_rt1015,
0338     DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
0339     DAILINK_COMP_ARRAY(COMP_CODEC(RT1015_DEV0_NAME, RT1015_CODEC_DAI),
0340                COMP_CODEC(RT1015_DEV1_NAME, RT1015_CODEC_DAI),
0341                COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
0342     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0343 
0344 SND_SOC_DAILINK_DEFS(i2s3_rt1015p,
0345     DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
0346     DAILINK_COMP_ARRAY(COMP_CODEC("rt1015p", "HiFi"),
0347                COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
0348     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0349 
0350 SND_SOC_DAILINK_DEFS(i2s5,
0351     DAILINK_COMP_ARRAY(COMP_CPU("I2S5")),
0352     DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
0353     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0354 
0355 SND_SOC_DAILINK_DEFS(tdm,
0356     DAILINK_COMP_ARRAY(COMP_CPU("TDM")),
0357     DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")),
0358     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0359 
0360 static int mt8183_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd)
0361 {
0362     struct mt8183_da7219_max98357_priv *priv =
0363         snd_soc_card_get_drvdata(rtd->card);
0364     int ret;
0365 
0366     ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
0367                     &priv->hdmi_jack);
0368     if (ret)
0369         return ret;
0370 
0371     return snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component,
0372                       &priv->hdmi_jack, NULL);
0373 }
0374 
0375 static struct snd_soc_dai_link mt8183_da7219_dai_links[] = {
0376     /* FE */
0377     {
0378         .name = "Playback_1",
0379         .stream_name = "Playback_1",
0380         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0381                 SND_SOC_DPCM_TRIGGER_PRE},
0382         .dynamic = 1,
0383         .dpcm_playback = 1,
0384         .ops = &mt8183_da7219_max98357_ops,
0385         SND_SOC_DAILINK_REG(playback1),
0386     },
0387     {
0388         .name = "Playback_2",
0389         .stream_name = "Playback_2",
0390         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0391                 SND_SOC_DPCM_TRIGGER_PRE},
0392         .dynamic = 1,
0393         .dpcm_playback = 1,
0394         .ops = &mt8183_da7219_max98357_bt_sco_ops,
0395         SND_SOC_DAILINK_REG(playback2),
0396     },
0397     {
0398         .name = "Playback_3",
0399         .stream_name = "Playback_3",
0400         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0401                 SND_SOC_DPCM_TRIGGER_PRE},
0402         .dynamic = 1,
0403         .dpcm_playback = 1,
0404         SND_SOC_DAILINK_REG(playback3),
0405     },
0406     {
0407         .name = "Capture_1",
0408         .stream_name = "Capture_1",
0409         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0410                 SND_SOC_DPCM_TRIGGER_PRE},
0411         .dynamic = 1,
0412         .dpcm_capture = 1,
0413         .ops = &mt8183_da7219_max98357_bt_sco_ops,
0414         SND_SOC_DAILINK_REG(capture1),
0415     },
0416     {
0417         .name = "Capture_2",
0418         .stream_name = "Capture_2",
0419         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0420                 SND_SOC_DPCM_TRIGGER_PRE},
0421         .dynamic = 1,
0422         .dpcm_capture = 1,
0423         SND_SOC_DAILINK_REG(capture2),
0424     },
0425     {
0426         .name = "Capture_3",
0427         .stream_name = "Capture_3",
0428         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0429                 SND_SOC_DPCM_TRIGGER_PRE},
0430         .dynamic = 1,
0431         .dpcm_capture = 1,
0432         .ops = &mt8183_da7219_max98357_ops,
0433         SND_SOC_DAILINK_REG(capture3),
0434     },
0435     {
0436         .name = "Capture_Mono_1",
0437         .stream_name = "Capture_Mono_1",
0438         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0439                 SND_SOC_DPCM_TRIGGER_PRE},
0440         .dynamic = 1,
0441         .dpcm_capture = 1,
0442         SND_SOC_DAILINK_REG(capture_mono),
0443     },
0444     {
0445         .name = "Playback_HDMI",
0446         .stream_name = "Playback_HDMI",
0447         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0448                 SND_SOC_DPCM_TRIGGER_PRE},
0449         .dynamic = 1,
0450         .dpcm_playback = 1,
0451         SND_SOC_DAILINK_REG(playback_hdmi),
0452     },
0453     /* BE */
0454     {
0455         .name = "Primary Codec",
0456         .no_pcm = 1,
0457         .dpcm_playback = 1,
0458         .dpcm_capture = 1,
0459         .ignore_suspend = 1,
0460         SND_SOC_DAILINK_REG(primary_codec),
0461     },
0462     {
0463         .name = "PCM 1",
0464         .no_pcm = 1,
0465         .dpcm_playback = 1,
0466         .dpcm_capture = 1,
0467         .ignore_suspend = 1,
0468         SND_SOC_DAILINK_REG(pcm1),
0469     },
0470     {
0471         .name = "PCM 2",
0472         .no_pcm = 1,
0473         .dpcm_playback = 1,
0474         .dpcm_capture = 1,
0475         .ignore_suspend = 1,
0476         SND_SOC_DAILINK_REG(pcm2),
0477     },
0478     {
0479         .name = "I2S0",
0480         .no_pcm = 1,
0481         .dpcm_capture = 1,
0482         .ignore_suspend = 1,
0483         .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
0484         .ops = &mt8183_mt6358_i2s_ops,
0485         SND_SOC_DAILINK_REG(i2s0),
0486     },
0487     {
0488         .name = "I2S1",
0489         .no_pcm = 1,
0490         .dpcm_playback = 1,
0491         .ignore_suspend = 1,
0492         .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
0493         .ops = &mt8183_mt6358_i2s_ops,
0494         SND_SOC_DAILINK_REG(i2s1),
0495     },
0496     {
0497         .name = "I2S2",
0498         .no_pcm = 1,
0499         .dpcm_capture = 1,
0500         .ignore_suspend = 1,
0501         .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
0502         .ops = &mt8183_da7219_i2s_ops,
0503         SND_SOC_DAILINK_REG(i2s2),
0504     },
0505     {
0506         .name = "I2S3",
0507         .no_pcm = 1,
0508         .dpcm_playback = 1,
0509         .ignore_suspend = 1,
0510     },
0511     {
0512         .name = "I2S5",
0513         .no_pcm = 1,
0514         .dpcm_playback = 1,
0515         .ignore_suspend = 1,
0516         .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
0517         .ops = &mt8183_mt6358_i2s_ops,
0518         SND_SOC_DAILINK_REG(i2s5),
0519     },
0520     {
0521         .name = "TDM",
0522         .no_pcm = 1,
0523         .dai_fmt = SND_SOC_DAIFMT_I2S |
0524                SND_SOC_DAIFMT_IB_IF |
0525                SND_SOC_DAIFMT_CBM_CFM,
0526         .dpcm_playback = 1,
0527         .ignore_suspend = 1,
0528         .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
0529         .ignore = 1,
0530         .init = mt8183_da7219_max98357_hdmi_init,
0531         SND_SOC_DAILINK_REG(tdm),
0532     },
0533 };
0534 
0535 static int
0536 mt8183_da7219_max98357_headset_init(struct snd_soc_component *component)
0537 {
0538     int ret;
0539     struct mt8183_da7219_max98357_priv *priv =
0540             snd_soc_card_get_drvdata(component->card);
0541 
0542     /* Enable Headset and 4 Buttons Jack detection */
0543     ret = snd_soc_card_jack_new(component->card,
0544                     "Headset Jack",
0545                     SND_JACK_HEADSET |
0546                     SND_JACK_BTN_0 | SND_JACK_BTN_1 |
0547                     SND_JACK_BTN_2 | SND_JACK_BTN_3 |
0548                     SND_JACK_LINEOUT,
0549                     &priv->headset_jack);
0550     if (ret)
0551         return ret;
0552 
0553     snd_jack_set_key(
0554         priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
0555     snd_jack_set_key(
0556         priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
0557     snd_jack_set_key(
0558         priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
0559     snd_jack_set_key(
0560         priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
0561 
0562     da7219_aad_jack_det(component, &priv->headset_jack);
0563 
0564     return 0;
0565 }
0566 
0567 static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = {
0568     .dlc = COMP_EMPTY(),
0569     .init = mt8183_da7219_max98357_headset_init,
0570 };
0571 
0572 static struct snd_soc_codec_conf mt6358_codec_conf[] = {
0573     {
0574         .dlc = COMP_CODEC_CONF("mt6358-sound"),
0575         .name_prefix = "Mt6358",
0576     },
0577 };
0578 
0579 static const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = {
0580     SOC_DAPM_PIN_SWITCH("Speakers"),
0581 };
0582 
0583 static const
0584 struct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = {
0585     SND_SOC_DAPM_SPK("Speakers", NULL),
0586     SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
0587                  "aud_tdm_out_on", "aud_tdm_out_off"),
0588 };
0589 
0590 static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = {
0591     {"Speakers", NULL, "Speaker"},
0592     {"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
0593 };
0594 
0595 static struct snd_soc_card mt8183_da7219_max98357_card = {
0596     .name = "mt8183_da7219_max98357",
0597     .owner = THIS_MODULE,
0598     .controls = mt8183_da7219_max98357_snd_controls,
0599     .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
0600     .dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
0601     .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
0602     .dapm_routes = mt8183_da7219_max98357_dapm_routes,
0603     .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
0604     .dai_link = mt8183_da7219_dai_links,
0605     .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
0606     .aux_dev = &mt8183_da7219_max98357_headset_dev,
0607     .num_aux_devs = 1,
0608     .codec_conf = mt6358_codec_conf,
0609     .num_configs = ARRAY_SIZE(mt6358_codec_conf),
0610 };
0611 
0612 static struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = {
0613     {
0614         .dlc = COMP_CODEC_CONF("mt6358-sound"),
0615         .name_prefix = "Mt6358",
0616     },
0617     {
0618         .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME),
0619         .name_prefix = "Left",
0620     },
0621     {
0622         .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME),
0623         .name_prefix = "Right",
0624     },
0625 };
0626 
0627 static const struct snd_kcontrol_new mt8183_da7219_rt1015_snd_controls[] = {
0628     SOC_DAPM_PIN_SWITCH("Left Spk"),
0629     SOC_DAPM_PIN_SWITCH("Right Spk"),
0630 };
0631 
0632 static const
0633 struct snd_soc_dapm_widget mt8183_da7219_rt1015_dapm_widgets[] = {
0634     SND_SOC_DAPM_SPK("Left Spk", NULL),
0635     SND_SOC_DAPM_SPK("Right Spk", NULL),
0636     SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
0637                  "aud_tdm_out_on", "aud_tdm_out_off"),
0638 };
0639 
0640 static const struct snd_soc_dapm_route mt8183_da7219_rt1015_dapm_routes[] = {
0641     {"Left Spk", NULL, "Left SPO"},
0642     {"Right Spk", NULL, "Right SPO"},
0643     {"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
0644 };
0645 
0646 static struct snd_soc_card mt8183_da7219_rt1015_card = {
0647     .name = "mt8183_da7219_rt1015",
0648     .owner = THIS_MODULE,
0649     .controls = mt8183_da7219_rt1015_snd_controls,
0650     .num_controls = ARRAY_SIZE(mt8183_da7219_rt1015_snd_controls),
0651     .dapm_widgets = mt8183_da7219_rt1015_dapm_widgets,
0652     .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_widgets),
0653     .dapm_routes = mt8183_da7219_rt1015_dapm_routes,
0654     .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_routes),
0655     .dai_link = mt8183_da7219_dai_links,
0656     .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
0657     .aux_dev = &mt8183_da7219_max98357_headset_dev,
0658     .num_aux_devs = 1,
0659     .codec_conf = mt8183_da7219_rt1015_codec_conf,
0660     .num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf),
0661 };
0662 
0663 static struct snd_soc_card mt8183_da7219_rt1015p_card = {
0664     .name = "mt8183_da7219_rt1015p",
0665     .owner = THIS_MODULE,
0666     .controls = mt8183_da7219_max98357_snd_controls,
0667     .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
0668     .dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
0669     .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
0670     .dapm_routes = mt8183_da7219_max98357_dapm_routes,
0671     .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
0672     .dai_link = mt8183_da7219_dai_links,
0673     .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
0674     .aux_dev = &mt8183_da7219_max98357_headset_dev,
0675     .num_aux_devs = 1,
0676     .codec_conf = mt6358_codec_conf,
0677     .num_configs = ARRAY_SIZE(mt6358_codec_conf),
0678 };
0679 
0680 static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
0681 {
0682     struct snd_soc_card *card;
0683     struct device_node *platform_node, *hdmi_codec;
0684     struct snd_soc_dai_link *dai_link;
0685     struct mt8183_da7219_max98357_priv *priv;
0686     struct pinctrl *pinctrl;
0687     int ret, i;
0688 
0689     platform_node = of_parse_phandle(pdev->dev.of_node,
0690                      "mediatek,platform", 0);
0691     if (!platform_node) {
0692         dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
0693         return -EINVAL;
0694     }
0695 
0696     card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev);
0697     if (!card) {
0698         ret = -EINVAL;
0699         goto put_platform_node;
0700     }
0701 
0702     card->dev = &pdev->dev;
0703 
0704     hdmi_codec = of_parse_phandle(pdev->dev.of_node,
0705                       "mediatek,hdmi-codec", 0);
0706 
0707     for_each_card_prelinks(card, i, dai_link) {
0708         if (strcmp(dai_link->name, "I2S3") == 0) {
0709             if (card == &mt8183_da7219_max98357_card) {
0710                 dai_link->be_hw_params_fixup =
0711                     mt8183_i2s_hw_params_fixup;
0712                 dai_link->ops = &mt8183_da7219_i2s_ops;
0713                 dai_link->cpus = i2s3_max98357a_cpus;
0714                 dai_link->num_cpus =
0715                     ARRAY_SIZE(i2s3_max98357a_cpus);
0716                 dai_link->codecs = i2s3_max98357a_codecs;
0717                 dai_link->num_codecs =
0718                     ARRAY_SIZE(i2s3_max98357a_codecs);
0719                 dai_link->platforms = i2s3_max98357a_platforms;
0720                 dai_link->num_platforms =
0721                     ARRAY_SIZE(i2s3_max98357a_platforms);
0722             } else if (card == &mt8183_da7219_rt1015_card) {
0723                 dai_link->be_hw_params_fixup =
0724                     mt8183_rt1015_i2s_hw_params_fixup;
0725                 dai_link->ops = &mt8183_da7219_rt1015_i2s_ops;
0726                 dai_link->cpus = i2s3_rt1015_cpus;
0727                 dai_link->num_cpus =
0728                     ARRAY_SIZE(i2s3_rt1015_cpus);
0729                 dai_link->codecs = i2s3_rt1015_codecs;
0730                 dai_link->num_codecs =
0731                     ARRAY_SIZE(i2s3_rt1015_codecs);
0732                 dai_link->platforms = i2s3_rt1015_platforms;
0733                 dai_link->num_platforms =
0734                     ARRAY_SIZE(i2s3_rt1015_platforms);
0735             } else if (card == &mt8183_da7219_rt1015p_card) {
0736                 dai_link->be_hw_params_fixup =
0737                     mt8183_rt1015_i2s_hw_params_fixup;
0738                 dai_link->ops = &mt8183_da7219_i2s_ops;
0739                 dai_link->cpus = i2s3_rt1015p_cpus;
0740                 dai_link->num_cpus =
0741                     ARRAY_SIZE(i2s3_rt1015p_cpus);
0742                 dai_link->codecs = i2s3_rt1015p_codecs;
0743                 dai_link->num_codecs =
0744                     ARRAY_SIZE(i2s3_rt1015p_codecs);
0745                 dai_link->platforms = i2s3_rt1015p_platforms;
0746                 dai_link->num_platforms =
0747                     ARRAY_SIZE(i2s3_rt1015p_platforms);
0748             }
0749         }
0750 
0751         if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) {
0752             dai_link->codecs->of_node = hdmi_codec;
0753             dai_link->ignore = 0;
0754         }
0755 
0756         if (!dai_link->platforms->name)
0757             dai_link->platforms->of_node = platform_node;
0758     }
0759 
0760     mt8183_da7219_max98357_headset_dev.dlc.of_node =
0761         of_parse_phandle(pdev->dev.of_node,
0762                  "mediatek,headset-codec", 0);
0763     if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) {
0764         dev_err(&pdev->dev,
0765             "Property 'mediatek,headset-codec' missing/invalid\n");
0766         ret = -EINVAL;
0767         goto put_hdmi_codec;
0768     }
0769 
0770     priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
0771     if (!priv) {
0772         ret = -ENOMEM;
0773         goto put_hdmi_codec;
0774     }
0775 
0776     snd_soc_card_set_drvdata(card, priv);
0777 
0778     pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT);
0779     if (IS_ERR(pinctrl)) {
0780         ret = PTR_ERR(pinctrl);
0781         dev_err(&pdev->dev, "%s failed to select default state %d\n",
0782             __func__, ret);
0783         goto put_hdmi_codec;
0784     }
0785 
0786     ret = devm_snd_soc_register_card(&pdev->dev, card);
0787 
0788 
0789 put_hdmi_codec:
0790     of_node_put(hdmi_codec);
0791 put_platform_node:
0792     of_node_put(platform_node);
0793     return ret;
0794 }
0795 
0796 #ifdef CONFIG_OF
0797 static const struct of_device_id mt8183_da7219_max98357_dt_match[] = {
0798     {
0799         .compatible = "mediatek,mt8183_da7219_max98357",
0800         .data = &mt8183_da7219_max98357_card,
0801     },
0802     {
0803         .compatible = "mediatek,mt8183_da7219_rt1015",
0804         .data = &mt8183_da7219_rt1015_card,
0805     },
0806     {
0807         .compatible = "mediatek,mt8183_da7219_rt1015p",
0808         .data = &mt8183_da7219_rt1015p_card,
0809     },
0810     {}
0811 };
0812 #endif
0813 
0814 static struct platform_driver mt8183_da7219_max98357_driver = {
0815     .driver = {
0816         .name = "mt8183_da7219",
0817 #ifdef CONFIG_OF
0818         .of_match_table = mt8183_da7219_max98357_dt_match,
0819 #endif
0820         .pm = &snd_soc_pm_ops,
0821     },
0822     .probe = mt8183_da7219_max98357_dev_probe,
0823 };
0824 
0825 module_platform_driver(mt8183_da7219_max98357_driver);
0826 
0827 /* Module information */
0828 MODULE_DESCRIPTION("MT8183-DA7219-MAX98357 ALSA SoC machine driver");
0829 MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>");
0830 MODULE_LICENSE("GPL v2");
0831 MODULE_ALIAS("mt8183_da7219_max98357 soc card");