0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/input.h>
0011 #include <linux/module.h>
0012 #include <linux/of_device.h>
0013 #include <linux/pm_runtime.h>
0014 #include <sound/jack.h>
0015 #include <sound/pcm_params.h>
0016 #include <sound/rt5682.h>
0017 #include <sound/soc.h>
0018
0019 #include "../../codecs/mt6358.h"
0020 #include "../../codecs/rt5682.h"
0021 #include "../common/mtk-afe-platform-driver.h"
0022 #include "mt8186-afe-common.h"
0023 #include "mt8186-afe-clk.h"
0024 #include "mt8186-afe-gpio.h"
0025 #include "mt8186-mt6366-common.h"
0026
0027 #define RT1019_CODEC_DAI "HiFi"
0028 #define RT1019_DEV0_NAME "rt1019p"
0029
0030 #define RT5682S_CODEC_DAI "rt5682s-aif1"
0031 #define RT5682S_DEV0_NAME "rt5682s.5-001a"
0032
0033 struct mt8186_mt6366_rt1019_rt5682s_priv {
0034 struct snd_soc_jack headset_jack, hdmi_jack;
0035 };
0036
0037 static struct snd_soc_codec_conf mt8186_mt6366_rt1019_rt5682s_codec_conf[] = {
0038 {
0039 .dlc = COMP_CODEC_CONF("mt6358-sound"),
0040 .name_prefix = "Mt6366",
0041 },
0042 {
0043 .dlc = COMP_CODEC_CONF("bt-sco"),
0044 .name_prefix = "Mt8186 bt",
0045 },
0046 {
0047 .dlc = COMP_CODEC_CONF("hdmi-audio-codec"),
0048 .name_prefix = "Mt8186 hdmi",
0049 },
0050 };
0051
0052 static int mt8186_rt5682s_init(struct snd_soc_pcm_runtime *rtd)
0053 {
0054 struct mt8186_mt6366_rt1019_rt5682s_priv *priv =
0055 snd_soc_card_get_drvdata(rtd->card);
0056 struct snd_soc_jack *jack = &priv->headset_jack;
0057 struct snd_soc_component *cmpnt_codec =
0058 asoc_rtd_to_codec(rtd, 0)->component;
0059 int ret;
0060
0061 ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
0062 SND_JACK_HEADSET | SND_JACK_BTN_0 |
0063 SND_JACK_BTN_1 | SND_JACK_BTN_2 |
0064 SND_JACK_BTN_3,
0065 jack);
0066 if (ret) {
0067 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
0068 return ret;
0069 }
0070
0071 snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
0072 snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
0073 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
0074 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
0075
0076 return snd_soc_component_set_jack(cmpnt_codec, jack, NULL);
0077 }
0078
0079 static int mt8186_rt5682s_i2s_hw_params(struct snd_pcm_substream *substream,
0080 struct snd_pcm_hw_params *params)
0081 {
0082 struct snd_soc_pcm_runtime *rtd = substream->private_data;
0083 struct snd_soc_card *card = rtd->card;
0084 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0085 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0086 unsigned int rate = params_rate(params);
0087 unsigned int mclk_fs_ratio = 128;
0088 unsigned int mclk_fs = rate * mclk_fs_ratio;
0089 int bitwidth;
0090 int ret;
0091
0092 bitwidth = snd_pcm_format_width(params_format(params));
0093 if (bitwidth < 0) {
0094 dev_err(card->dev, "invalid bit width: %d\n", bitwidth);
0095 return bitwidth;
0096 }
0097
0098 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth);
0099 if (ret) {
0100 dev_err(card->dev, "failed to set tdm slot\n");
0101 return ret;
0102 }
0103
0104 ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1,
0105 RT5682_PLL1_S_BCLK1,
0106 params_rate(params) * 64,
0107 params_rate(params) * 512);
0108 if (ret) {
0109 dev_err(card->dev, "failed to set pll\n");
0110 return ret;
0111 }
0112
0113 ret = snd_soc_dai_set_sysclk(codec_dai,
0114 RT5682_SCLK_S_PLL1,
0115 params_rate(params) * 512,
0116 SND_SOC_CLOCK_IN);
0117 if (ret) {
0118 dev_err(card->dev, "failed to set sysclk\n");
0119 return ret;
0120 }
0121
0122 return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);
0123 }
0124
0125 static const struct snd_soc_ops mt8186_rt5682s_i2s_ops = {
0126 .hw_params = mt8186_rt5682s_i2s_hw_params,
0127 };
0128
0129 static int mt8186_mt6366_rt1019_rt5682s_hdmi_init(struct snd_soc_pcm_runtime *rtd)
0130 {
0131 struct snd_soc_component *cmpnt_codec =
0132 asoc_rtd_to_codec(rtd, 0)->component;
0133 struct mt8186_mt6366_rt1019_rt5682s_priv *priv =
0134 snd_soc_card_get_drvdata(rtd->card);
0135 int ret;
0136
0137 ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, &priv->hdmi_jack);
0138 if (ret) {
0139 dev_err(rtd->dev, "HDMI Jack creation failed: %d\n", ret);
0140 return ret;
0141 }
0142
0143 return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL);
0144 }
0145
0146 static int mt8186_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
0147 struct snd_pcm_hw_params *params,
0148 snd_pcm_format_t fmt)
0149 {
0150 struct snd_interval *channels = hw_param_interval(params,
0151 SNDRV_PCM_HW_PARAM_CHANNELS);
0152
0153 dev_dbg(rtd->dev, "%s(), fix format to %d\n", __func__, fmt);
0154
0155
0156 channels->min = 2;
0157 channels->max = 2;
0158
0159
0160 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
0161 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
0162
0163 params_set_format(params, fmt);
0164
0165 return 0;
0166 }
0167
0168 static int mt8186_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
0169 struct snd_pcm_hw_params *params)
0170 {
0171 return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S24_LE);
0172 }
0173
0174 static int mt8186_it6505_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
0175 struct snd_pcm_hw_params *params)
0176 {
0177 return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S32_LE);
0178 }
0179
0180 static int mt8186_mt6366_rt1019_rt5682s_playback_startup(struct snd_pcm_substream *substream)
0181 {
0182 static const unsigned int rates[] = {
0183 48000
0184 };
0185 static const unsigned int channels[] = {
0186 2
0187 };
0188 static const struct snd_pcm_hw_constraint_list constraints_rates = {
0189 .count = ARRAY_SIZE(rates),
0190 .list = rates,
0191 .mask = 0,
0192 };
0193 static const struct snd_pcm_hw_constraint_list constraints_channels = {
0194 .count = ARRAY_SIZE(channels),
0195 .list = channels,
0196 .mask = 0,
0197 };
0198
0199 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0200 struct snd_pcm_runtime *runtime = substream->runtime;
0201 int ret;
0202
0203 ret = snd_pcm_hw_constraint_list(runtime, 0,
0204 SNDRV_PCM_HW_PARAM_RATE,
0205 &constraints_rates);
0206 if (ret < 0) {
0207 dev_err(rtd->dev, "hw_constraint_list rate failed\n");
0208 return ret;
0209 }
0210
0211 ret = snd_pcm_hw_constraint_list(runtime, 0,
0212 SNDRV_PCM_HW_PARAM_CHANNELS,
0213 &constraints_channels);
0214 if (ret < 0) {
0215 dev_err(rtd->dev, "hw_constraint_list channel failed\n");
0216 return ret;
0217 }
0218
0219 return 0;
0220 }
0221
0222 static const struct snd_soc_ops mt8186_mt6366_rt1019_rt5682s_playback_ops = {
0223 .startup = mt8186_mt6366_rt1019_rt5682s_playback_startup,
0224 };
0225
0226 static int mt8186_mt6366_rt1019_rt5682s_capture_startup(struct snd_pcm_substream *substream)
0227 {
0228 static const unsigned int rates[] = {
0229 48000
0230 };
0231 static const unsigned int channels[] = {
0232 1, 2
0233 };
0234 static const struct snd_pcm_hw_constraint_list constraints_rates = {
0235 .count = ARRAY_SIZE(rates),
0236 .list = rates,
0237 .mask = 0,
0238 };
0239 static const struct snd_pcm_hw_constraint_list constraints_channels = {
0240 .count = ARRAY_SIZE(channels),
0241 .list = channels,
0242 .mask = 0,
0243 };
0244
0245 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0246 struct snd_pcm_runtime *runtime = substream->runtime;
0247 int ret;
0248
0249 ret = snd_pcm_hw_constraint_list(runtime, 0,
0250 SNDRV_PCM_HW_PARAM_RATE,
0251 &constraints_rates);
0252 if (ret < 0) {
0253 dev_err(rtd->dev, "hw_constraint_list rate failed\n");
0254 return ret;
0255 }
0256
0257 ret = snd_pcm_hw_constraint_list(runtime, 0,
0258 SNDRV_PCM_HW_PARAM_CHANNELS,
0259 &constraints_channels);
0260 if (ret < 0) {
0261 dev_err(rtd->dev, "hw_constraint_list channel failed\n");
0262 return ret;
0263 }
0264
0265 return 0;
0266 }
0267
0268 static const struct snd_soc_ops mt8186_mt6366_rt1019_rt5682s_capture_ops = {
0269 .startup = mt8186_mt6366_rt1019_rt5682s_capture_startup,
0270 };
0271
0272
0273 SND_SOC_DAILINK_DEFS(playback1,
0274 DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
0275 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0276 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0277
0278 SND_SOC_DAILINK_DEFS(playback12,
0279 DAILINK_COMP_ARRAY(COMP_CPU("DL12")),
0280 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0281 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0282
0283 SND_SOC_DAILINK_DEFS(playback2,
0284 DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
0285 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0286 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0287
0288 SND_SOC_DAILINK_DEFS(playback3,
0289 DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
0290 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0291 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0292
0293 SND_SOC_DAILINK_DEFS(playback4,
0294 DAILINK_COMP_ARRAY(COMP_CPU("DL4")),
0295 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0296 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0297
0298 SND_SOC_DAILINK_DEFS(playback5,
0299 DAILINK_COMP_ARRAY(COMP_CPU("DL5")),
0300 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0301 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0302
0303 SND_SOC_DAILINK_DEFS(playback6,
0304 DAILINK_COMP_ARRAY(COMP_CPU("DL6")),
0305 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0306 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0307
0308 SND_SOC_DAILINK_DEFS(playback7,
0309 DAILINK_COMP_ARRAY(COMP_CPU("DL7")),
0310 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0311 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0312
0313 SND_SOC_DAILINK_DEFS(playback8,
0314 DAILINK_COMP_ARRAY(COMP_CPU("DL8")),
0315 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0316 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0317
0318 SND_SOC_DAILINK_DEFS(capture1,
0319 DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
0320 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0321 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0322
0323 SND_SOC_DAILINK_DEFS(capture2,
0324 DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
0325 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0326 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0327
0328 SND_SOC_DAILINK_DEFS(capture3,
0329 DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
0330 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0331 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0332
0333 SND_SOC_DAILINK_DEFS(capture4,
0334 DAILINK_COMP_ARRAY(COMP_CPU("UL4")),
0335 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0336 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0337
0338 SND_SOC_DAILINK_DEFS(capture5,
0339 DAILINK_COMP_ARRAY(COMP_CPU("UL5")),
0340 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0341 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0342
0343 SND_SOC_DAILINK_DEFS(capture6,
0344 DAILINK_COMP_ARRAY(COMP_CPU("UL6")),
0345 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0346 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0347
0348 SND_SOC_DAILINK_DEFS(capture7,
0349 DAILINK_COMP_ARRAY(COMP_CPU("UL7")),
0350 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0351 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0352
0353
0354 SND_SOC_DAILINK_DEFS(hostless_lpbk,
0355 DAILINK_COMP_ARRAY(COMP_CPU("Hostless LPBK DAI")),
0356 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0357 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0358 SND_SOC_DAILINK_DEFS(hostless_fm,
0359 DAILINK_COMP_ARRAY(COMP_CPU("Hostless FM DAI")),
0360 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0361 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0362 SND_SOC_DAILINK_DEFS(hostless_src1,
0363 DAILINK_COMP_ARRAY(COMP_CPU("Hostless_SRC_1_DAI")),
0364 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0365 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0366 SND_SOC_DAILINK_DEFS(hostless_src_bargein,
0367 DAILINK_COMP_ARRAY(COMP_CPU("Hostless_SRC_Bargein_DAI")),
0368 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0369 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0370
0371
0372 SND_SOC_DAILINK_DEFS(adda,
0373 DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
0374 DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound",
0375 "mt6358-snd-codec-aif1"),
0376 COMP_CODEC("dmic-codec",
0377 "dmic-hifi")),
0378 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0379 SND_SOC_DAILINK_DEFS(i2s0,
0380 DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
0381 DAILINK_COMP_ARRAY(COMP_EMPTY()),
0382 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0383 SND_SOC_DAILINK_DEFS(i2s1,
0384 DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
0385 DAILINK_COMP_ARRAY(COMP_EMPTY()),
0386 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0387 SND_SOC_DAILINK_DEFS(i2s2,
0388 DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
0389 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0390 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0391 SND_SOC_DAILINK_DEFS(i2s3,
0392 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
0393 DAILINK_COMP_ARRAY(COMP_EMPTY()),
0394 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0395 SND_SOC_DAILINK_DEFS(hw_gain1,
0396 DAILINK_COMP_ARRAY(COMP_CPU("HW Gain 1")),
0397 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0398 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0399 SND_SOC_DAILINK_DEFS(hw_gain2,
0400 DAILINK_COMP_ARRAY(COMP_CPU("HW Gain 2")),
0401 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0402 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0403 SND_SOC_DAILINK_DEFS(hw_src1,
0404 DAILINK_COMP_ARRAY(COMP_CPU("HW_SRC_1")),
0405 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0406 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0407 SND_SOC_DAILINK_DEFS(hw_src2,
0408 DAILINK_COMP_ARRAY(COMP_CPU("HW_SRC_2")),
0409 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0410 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0411 SND_SOC_DAILINK_DEFS(connsys_i2s,
0412 DAILINK_COMP_ARRAY(COMP_CPU("CONNSYS_I2S")),
0413 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0414 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0415 SND_SOC_DAILINK_DEFS(pcm1,
0416 DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
0417 DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm-wb")),
0418 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0419 SND_SOC_DAILINK_DEFS(tdm_in,
0420 DAILINK_COMP_ARRAY(COMP_CPU("TDM IN")),
0421 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0422 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0423
0424
0425 SND_SOC_DAILINK_DEFS(hostless_ul1,
0426 DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL1 DAI")),
0427 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0428 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0429 SND_SOC_DAILINK_DEFS(hostless_ul2,
0430 DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL2 DAI")),
0431 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0432 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0433 SND_SOC_DAILINK_DEFS(hostless_ul3,
0434 DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL3 DAI")),
0435 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0436 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0437 SND_SOC_DAILINK_DEFS(hostless_ul5,
0438 DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL5 DAI")),
0439 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0440 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0441 SND_SOC_DAILINK_DEFS(hostless_ul6,
0442 DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL6 DAI")),
0443 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0444 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0445 SND_SOC_DAILINK_DEFS(hostless_hw_gain_aaudio,
0446 DAILINK_COMP_ARRAY(COMP_CPU("Hostless HW Gain AAudio DAI")),
0447 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0448 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0449 SND_SOC_DAILINK_DEFS(hostless_src_aaudio,
0450 DAILINK_COMP_ARRAY(COMP_CPU("Hostless SRC AAudio DAI")),
0451 DAILINK_COMP_ARRAY(COMP_DUMMY()),
0452 DAILINK_COMP_ARRAY(COMP_EMPTY()));
0453 static struct snd_soc_dai_link mt8186_mt6366_rt1019_rt5682s_dai_links[] = {
0454
0455 {
0456 .name = "Playback_1",
0457 .stream_name = "Playback_1",
0458 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0459 SND_SOC_DPCM_TRIGGER_PRE},
0460 .dynamic = 1,
0461 .dpcm_playback = 1,
0462 .dpcm_merged_format = 1,
0463 .dpcm_merged_chan = 1,
0464 .dpcm_merged_rate = 1,
0465 .ops = &mt8186_mt6366_rt1019_rt5682s_playback_ops,
0466 SND_SOC_DAILINK_REG(playback1),
0467 },
0468 {
0469 .name = "Playback_12",
0470 .stream_name = "Playback_12",
0471 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0472 SND_SOC_DPCM_TRIGGER_PRE},
0473 .dynamic = 1,
0474 .dpcm_playback = 1,
0475 SND_SOC_DAILINK_REG(playback12),
0476 },
0477 {
0478 .name = "Playback_2",
0479 .stream_name = "Playback_2",
0480 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0481 SND_SOC_DPCM_TRIGGER_PRE},
0482 .dynamic = 1,
0483 .dpcm_playback = 1,
0484 .dpcm_merged_format = 1,
0485 .dpcm_merged_chan = 1,
0486 .dpcm_merged_rate = 1,
0487 SND_SOC_DAILINK_REG(playback2),
0488 },
0489 {
0490 .name = "Playback_3",
0491 .stream_name = "Playback_3",
0492 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0493 SND_SOC_DPCM_TRIGGER_PRE},
0494 .dynamic = 1,
0495 .dpcm_playback = 1,
0496 .dpcm_merged_format = 1,
0497 .dpcm_merged_chan = 1,
0498 .dpcm_merged_rate = 1,
0499 .ops = &mt8186_mt6366_rt1019_rt5682s_playback_ops,
0500 SND_SOC_DAILINK_REG(playback3),
0501 },
0502 {
0503 .name = "Playback_4",
0504 .stream_name = "Playback_4",
0505 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0506 SND_SOC_DPCM_TRIGGER_PRE},
0507 .dynamic = 1,
0508 .dpcm_playback = 1,
0509 SND_SOC_DAILINK_REG(playback4),
0510 },
0511 {
0512 .name = "Playback_5",
0513 .stream_name = "Playback_5",
0514 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0515 SND_SOC_DPCM_TRIGGER_PRE},
0516 .dynamic = 1,
0517 .dpcm_playback = 1,
0518 SND_SOC_DAILINK_REG(playback5),
0519 },
0520 {
0521 .name = "Playback_6",
0522 .stream_name = "Playback_6",
0523 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0524 SND_SOC_DPCM_TRIGGER_PRE},
0525 .dynamic = 1,
0526 .dpcm_playback = 1,
0527 SND_SOC_DAILINK_REG(playback6),
0528 },
0529 {
0530 .name = "Playback_7",
0531 .stream_name = "Playback_7",
0532 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0533 SND_SOC_DPCM_TRIGGER_PRE},
0534 .dynamic = 1,
0535 .dpcm_playback = 1,
0536 SND_SOC_DAILINK_REG(playback7),
0537 },
0538 {
0539 .name = "Playback_8",
0540 .stream_name = "Playback_8",
0541 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0542 SND_SOC_DPCM_TRIGGER_PRE},
0543 .dynamic = 1,
0544 .dpcm_playback = 1,
0545 SND_SOC_DAILINK_REG(playback8),
0546 },
0547 {
0548 .name = "Capture_1",
0549 .stream_name = "Capture_1",
0550 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0551 SND_SOC_DPCM_TRIGGER_PRE},
0552 .dynamic = 1,
0553 .dpcm_capture = 1,
0554 SND_SOC_DAILINK_REG(capture1),
0555 },
0556 {
0557 .name = "Capture_2",
0558 .stream_name = "Capture_2",
0559 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0560 SND_SOC_DPCM_TRIGGER_PRE},
0561 .dynamic = 1,
0562 .dpcm_capture = 1,
0563 .dpcm_merged_format = 1,
0564 .dpcm_merged_chan = 1,
0565 .dpcm_merged_rate = 1,
0566 .ops = &mt8186_mt6366_rt1019_rt5682s_capture_ops,
0567 SND_SOC_DAILINK_REG(capture2),
0568 },
0569 {
0570 .name = "Capture_3",
0571 .stream_name = "Capture_3",
0572 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0573 SND_SOC_DPCM_TRIGGER_PRE},
0574 .dynamic = 1,
0575 .dpcm_capture = 1,
0576 SND_SOC_DAILINK_REG(capture3),
0577 },
0578 {
0579 .name = "Capture_4",
0580 .stream_name = "Capture_4",
0581 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0582 SND_SOC_DPCM_TRIGGER_PRE},
0583 .dynamic = 1,
0584 .dpcm_capture = 1,
0585 .dpcm_merged_format = 1,
0586 .dpcm_merged_chan = 1,
0587 .dpcm_merged_rate = 1,
0588 .ops = &mt8186_mt6366_rt1019_rt5682s_capture_ops,
0589 SND_SOC_DAILINK_REG(capture4),
0590 },
0591 {
0592 .name = "Capture_5",
0593 .stream_name = "Capture_5",
0594 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0595 SND_SOC_DPCM_TRIGGER_PRE},
0596 .dynamic = 1,
0597 .dpcm_capture = 1,
0598 SND_SOC_DAILINK_REG(capture5),
0599 },
0600 {
0601 .name = "Capture_6",
0602 .stream_name = "Capture_6",
0603 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0604 SND_SOC_DPCM_TRIGGER_PRE},
0605 .dynamic = 1,
0606 .dpcm_capture = 1,
0607 .dpcm_merged_format = 1,
0608 .dpcm_merged_chan = 1,
0609 .dpcm_merged_rate = 1,
0610 SND_SOC_DAILINK_REG(capture6),
0611 },
0612 {
0613 .name = "Capture_7",
0614 .stream_name = "Capture_7",
0615 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0616 SND_SOC_DPCM_TRIGGER_PRE},
0617 .dynamic = 1,
0618 .dpcm_capture = 1,
0619 SND_SOC_DAILINK_REG(capture7),
0620 },
0621 {
0622 .name = "Hostless_LPBK",
0623 .stream_name = "Hostless_LPBK",
0624 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0625 SND_SOC_DPCM_TRIGGER_PRE},
0626 .dynamic = 1,
0627 .dpcm_playback = 1,
0628 .dpcm_capture = 1,
0629 .ignore_suspend = 1,
0630 SND_SOC_DAILINK_REG(hostless_lpbk),
0631 },
0632 {
0633 .name = "Hostless_FM",
0634 .stream_name = "Hostless_FM",
0635 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0636 SND_SOC_DPCM_TRIGGER_PRE},
0637 .dynamic = 1,
0638 .dpcm_playback = 1,
0639 .dpcm_capture = 1,
0640 .ignore_suspend = 1,
0641 SND_SOC_DAILINK_REG(hostless_fm),
0642 },
0643 {
0644 .name = "Hostless_SRC_1",
0645 .stream_name = "Hostless_SRC_1",
0646 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0647 SND_SOC_DPCM_TRIGGER_PRE},
0648 .dynamic = 1,
0649 .dpcm_playback = 1,
0650 .dpcm_capture = 1,
0651 .ignore_suspend = 1,
0652 SND_SOC_DAILINK_REG(hostless_src1),
0653 },
0654 {
0655 .name = "Hostless_SRC_Bargein",
0656 .stream_name = "Hostless_SRC_Bargein",
0657 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0658 SND_SOC_DPCM_TRIGGER_PRE},
0659 .dynamic = 1,
0660 .dpcm_playback = 1,
0661 .dpcm_capture = 1,
0662 .ignore_suspend = 1,
0663 SND_SOC_DAILINK_REG(hostless_src_bargein),
0664 },
0665 {
0666 .name = "Hostless_HW_Gain_AAudio",
0667 .stream_name = "Hostless_HW_Gain_AAudio",
0668 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0669 SND_SOC_DPCM_TRIGGER_PRE},
0670 .dynamic = 1,
0671 .dpcm_capture = 1,
0672 .ignore_suspend = 1,
0673 SND_SOC_DAILINK_REG(hostless_hw_gain_aaudio),
0674 },
0675 {
0676 .name = "Hostless_SRC_AAudio",
0677 .stream_name = "Hostless_SRC_AAudio",
0678 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0679 SND_SOC_DPCM_TRIGGER_PRE},
0680 .dynamic = 1,
0681 .dpcm_playback = 1,
0682 .dpcm_capture = 1,
0683 .ignore_suspend = 1,
0684 SND_SOC_DAILINK_REG(hostless_src_aaudio),
0685 },
0686
0687 {
0688 .name = "Primary Codec",
0689 .no_pcm = 1,
0690 .dpcm_playback = 1,
0691 .dpcm_capture = 1,
0692 .ignore_suspend = 1,
0693 .init = mt8186_mt6366_init,
0694 SND_SOC_DAILINK_REG(adda),
0695 },
0696 {
0697 .name = "I2S3",
0698 .no_pcm = 1,
0699 .dai_fmt = SND_SOC_DAIFMT_I2S |
0700 SND_SOC_DAIFMT_IB_IF |
0701 SND_SOC_DAIFMT_CBM_CFM,
0702 .dpcm_playback = 1,
0703 .ignore_suspend = 1,
0704 .init = mt8186_mt6366_rt1019_rt5682s_hdmi_init,
0705 .be_hw_params_fixup = mt8186_it6505_i2s_hw_params_fixup,
0706 SND_SOC_DAILINK_REG(i2s3),
0707 },
0708 {
0709 .name = "I2S0",
0710 .no_pcm = 1,
0711 .dpcm_capture = 1,
0712 .ignore_suspend = 1,
0713 .be_hw_params_fixup = mt8186_i2s_hw_params_fixup,
0714 .ops = &mt8186_rt5682s_i2s_ops,
0715 SND_SOC_DAILINK_REG(i2s0),
0716 },
0717 {
0718 .name = "I2S1",
0719 .no_pcm = 1,
0720 .dpcm_playback = 1,
0721 .ignore_suspend = 1,
0722 .be_hw_params_fixup = mt8186_i2s_hw_params_fixup,
0723 .init = mt8186_rt5682s_init,
0724 .ops = &mt8186_rt5682s_i2s_ops,
0725 SND_SOC_DAILINK_REG(i2s1),
0726 },
0727 {
0728 .name = "I2S2",
0729 .no_pcm = 1,
0730 .dpcm_capture = 1,
0731 .ignore_suspend = 1,
0732 .be_hw_params_fixup = mt8186_i2s_hw_params_fixup,
0733 SND_SOC_DAILINK_REG(i2s2),
0734 },
0735 {
0736 .name = "HW Gain 1",
0737 .no_pcm = 1,
0738 .dpcm_playback = 1,
0739 .dpcm_capture = 1,
0740 .ignore_suspend = 1,
0741 SND_SOC_DAILINK_REG(hw_gain1),
0742 },
0743 {
0744 .name = "HW Gain 2",
0745 .no_pcm = 1,
0746 .dpcm_playback = 1,
0747 .dpcm_capture = 1,
0748 .ignore_suspend = 1,
0749 SND_SOC_DAILINK_REG(hw_gain2),
0750 },
0751 {
0752 .name = "HW_SRC_1",
0753 .no_pcm = 1,
0754 .dpcm_playback = 1,
0755 .dpcm_capture = 1,
0756 .ignore_suspend = 1,
0757 SND_SOC_DAILINK_REG(hw_src1),
0758 },
0759 {
0760 .name = "HW_SRC_2",
0761 .no_pcm = 1,
0762 .dpcm_playback = 1,
0763 .dpcm_capture = 1,
0764 .ignore_suspend = 1,
0765 SND_SOC_DAILINK_REG(hw_src2),
0766 },
0767 {
0768 .name = "CONNSYS_I2S",
0769 .no_pcm = 1,
0770 .dpcm_capture = 1,
0771 .ignore_suspend = 1,
0772 SND_SOC_DAILINK_REG(connsys_i2s),
0773 },
0774 {
0775 .name = "PCM 1",
0776 .dai_fmt = SND_SOC_DAIFMT_I2S |
0777 SND_SOC_DAIFMT_NB_IF,
0778 .no_pcm = 1,
0779 .dpcm_playback = 1,
0780 .dpcm_capture = 1,
0781 .ignore_suspend = 1,
0782 SND_SOC_DAILINK_REG(pcm1),
0783 },
0784 {
0785 .name = "TDM IN",
0786 .no_pcm = 1,
0787 .dpcm_capture = 1,
0788 .ignore_suspend = 1,
0789 SND_SOC_DAILINK_REG(tdm_in),
0790 },
0791
0792 {
0793 .name = "Hostless_UL1",
0794 .no_pcm = 1,
0795 .dpcm_capture = 1,
0796 .ignore_suspend = 1,
0797 SND_SOC_DAILINK_REG(hostless_ul1),
0798 },
0799 {
0800 .name = "Hostless_UL2",
0801 .no_pcm = 1,
0802 .dpcm_capture = 1,
0803 .ignore_suspend = 1,
0804 SND_SOC_DAILINK_REG(hostless_ul2),
0805 },
0806 {
0807 .name = "Hostless_UL3",
0808 .no_pcm = 1,
0809 .dpcm_capture = 1,
0810 .ignore_suspend = 1,
0811 SND_SOC_DAILINK_REG(hostless_ul3),
0812 },
0813 {
0814 .name = "Hostless_UL5",
0815 .no_pcm = 1,
0816 .dpcm_capture = 1,
0817 .ignore_suspend = 1,
0818 SND_SOC_DAILINK_REG(hostless_ul5),
0819 },
0820 {
0821 .name = "Hostless_UL6",
0822 .no_pcm = 1,
0823 .dpcm_capture = 1,
0824 .ignore_suspend = 1,
0825 SND_SOC_DAILINK_REG(hostless_ul6),
0826 },
0827 };
0828
0829 static const struct snd_soc_dapm_widget
0830 mt8186_mt6366_rt1019_rt5682s_widgets[] = {
0831 SND_SOC_DAPM_SPK("Speakers", NULL),
0832 SND_SOC_DAPM_OUTPUT("HDMI1"),
0833 };
0834
0835 static const struct snd_soc_dapm_route
0836 mt8186_mt6366_rt1019_rt5682s_routes[] = {
0837
0838 { "Speakers", NULL, "Speaker" },
0839
0840 { "HDMI1", NULL, "TX" },
0841 };
0842
0843 static const struct snd_kcontrol_new
0844 mt8186_mt6366_rt1019_rt5682s_controls[] = {
0845 SOC_DAPM_PIN_SWITCH("Speakers"),
0846 SOC_DAPM_PIN_SWITCH("HDMI1"),
0847 };
0848
0849 static struct snd_soc_card mt8186_mt6366_rt1019_rt5682s_soc_card = {
0850 .name = "mt8186_mt6366_rt1019_rt5682s",
0851 .owner = THIS_MODULE,
0852 .dai_link = mt8186_mt6366_rt1019_rt5682s_dai_links,
0853 .num_links = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_dai_links),
0854 .controls = mt8186_mt6366_rt1019_rt5682s_controls,
0855 .num_controls = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_controls),
0856 .dapm_widgets = mt8186_mt6366_rt1019_rt5682s_widgets,
0857 .num_dapm_widgets = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_widgets),
0858 .dapm_routes = mt8186_mt6366_rt1019_rt5682s_routes,
0859 .num_dapm_routes = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_routes),
0860 .codec_conf = mt8186_mt6366_rt1019_rt5682s_codec_conf,
0861 .num_configs = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_codec_conf),
0862 };
0863
0864 static int mt8186_mt6366_rt1019_rt5682s_dev_probe(struct platform_device *pdev)
0865 {
0866 struct snd_soc_card *card;
0867 struct snd_soc_dai_link *dai_link;
0868 struct mt8186_mt6366_rt1019_rt5682s_priv *priv;
0869 struct device_node *platform_node, *headset_codec, *playback_codec;
0870 int ret, i;
0871
0872 card = (struct snd_soc_card *)device_get_match_data(&pdev->dev);
0873 if (!card)
0874 return -EINVAL;
0875 card->dev = &pdev->dev;
0876
0877 platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0);
0878 if (!platform_node) {
0879 ret = -EINVAL;
0880 dev_err_probe(&pdev->dev, ret, "Property 'platform' missing or invalid\n");
0881 return ret;
0882 }
0883
0884 playback_codec = of_get_child_by_name(pdev->dev.of_node, "playback-codecs");
0885 if (!playback_codec) {
0886 ret = -EINVAL;
0887 dev_err_probe(&pdev->dev, ret, "Property 'speaker-codecs' missing or invalid\n");
0888 goto err_playback_codec;
0889 }
0890
0891 headset_codec = of_get_child_by_name(pdev->dev.of_node, "headset-codec");
0892 if (!headset_codec) {
0893 ret = -EINVAL;
0894 dev_err_probe(&pdev->dev, ret, "Property 'headset-codec' missing or invalid\n");
0895 goto err_headset_codec;
0896 }
0897
0898 for_each_card_prelinks(card, i, dai_link) {
0899 ret = mt8186_mt6366_card_set_be_link(card, dai_link, playback_codec, "I2S3");
0900 if (ret) {
0901 dev_err_probe(&pdev->dev, ret, "%s set speaker_codec fail\n",
0902 dai_link->name);
0903 goto err_probe;
0904 }
0905
0906 ret = mt8186_mt6366_card_set_be_link(card, dai_link, headset_codec, "I2S0");
0907 if (ret) {
0908 dev_err_probe(&pdev->dev, ret, "%s set headset_codec fail\n",
0909 dai_link->name);
0910 goto err_probe;
0911 }
0912
0913 ret = mt8186_mt6366_card_set_be_link(card, dai_link, headset_codec, "I2S1");
0914 if (ret) {
0915 dev_err_probe(&pdev->dev, ret, "%s set headset_codec fail\n",
0916 dai_link->name);
0917 goto err_probe;
0918 }
0919
0920 if (!dai_link->platforms->name)
0921 dai_link->platforms->of_node = platform_node;
0922 }
0923
0924 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
0925 if (!priv) {
0926 ret = -ENOMEM;
0927 goto err_probe;
0928 }
0929
0930 snd_soc_card_set_drvdata(card, priv);
0931
0932 ret = mt8186_afe_gpio_init(&pdev->dev);
0933 if (ret) {
0934 dev_err_probe(&pdev->dev, ret, "%s init gpio error\n", __func__);
0935 goto err_probe;
0936 }
0937
0938 ret = devm_snd_soc_register_card(&pdev->dev, card);
0939 if (ret)
0940 dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n", __func__);
0941
0942 err_probe:
0943 of_node_put(headset_codec);
0944 err_headset_codec:
0945 of_node_put(playback_codec);
0946 err_playback_codec:
0947 of_node_put(platform_node);
0948
0949 return ret;
0950 }
0951
0952 #if IS_ENABLED(CONFIG_OF)
0953 static const struct of_device_id mt8186_mt6366_rt1019_rt5682s_dt_match[] = {
0954 { .compatible = "mediatek,mt8186-mt6366-rt1019-rt5682s-sound",
0955 .data = &mt8186_mt6366_rt1019_rt5682s_soc_card,
0956 },
0957 {}
0958 };
0959 #endif
0960
0961 static struct platform_driver mt8186_mt6366_rt1019_rt5682s_driver = {
0962 .driver = {
0963 .name = "mt8186_mt6366_rt1019_rt5682s",
0964 #if IS_ENABLED(CONFIG_OF)
0965 .of_match_table = mt8186_mt6366_rt1019_rt5682s_dt_match,
0966 #endif
0967 .pm = &snd_soc_pm_ops,
0968 },
0969 .probe = mt8186_mt6366_rt1019_rt5682s_dev_probe,
0970 };
0971
0972 module_platform_driver(mt8186_mt6366_rt1019_rt5682s_driver);
0973
0974
0975 MODULE_DESCRIPTION("MT8186-MT6366-RT1019-RT5682S ALSA SoC machine driver");
0976 MODULE_AUTHOR("Jiaxin Yu <jiaxin.yu@mediatek.com>");
0977 MODULE_LICENSE("GPL v2");
0978 MODULE_ALIAS("mt8186_mt6366_rt1019_rt5682s soc card");