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