1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // mt8183-da7219-max98357.c 4 // -- MT8183-DA7219-MAX98357 ALSA SoC machine driver 5 // 6 // Copyright (c) 2018 MediaTek Inc. 7 // Author: Shunli Wang <shunli.wang@mediatek.com> 8 9 #include <linux/input.h> 10 #include <linux/module.h> 11 #include <linux/of_device.h> 12 #include <linux/pinctrl/consumer.h> 13 #include <sound/hdmi-codec.h> 14 #include <sound/jack.h> 15 #include <sound/pcm_params.h> 16 #include <sound/soc.h> 17 18 #include "../../codecs/da7219-aad.h" 19 #include "../../codecs/da7219.h" 20 #include "../../codecs/rt1015.h" 21 #include "mt8183-afe-common.h" 22 23 #define DA7219_CODEC_DAI "da7219-hifi" 24 #define DA7219_DEV_NAME "da7219.5-001a" 25 #define RT1015_CODEC_DAI "rt1015-aif" 26 #define RT1015_DEV0_NAME "rt1015.6-0028" 27 #define RT1015_DEV1_NAME "rt1015.6-0029" 28 29 struct mt8183_da7219_max98357_priv { 30 struct snd_soc_jack headset_jack, hdmi_jack; 31 }; 32 33 static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream, 34 struct snd_pcm_hw_params *params) 35 { 36 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 37 unsigned int rate = params_rate(params); 38 unsigned int mclk_fs_ratio = 128; 39 unsigned int mclk_fs = rate * mclk_fs_ratio; 40 41 return snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 42 0, mclk_fs, SND_SOC_CLOCK_OUT); 43 } 44 45 static const struct snd_soc_ops mt8183_mt6358_i2s_ops = { 46 .hw_params = mt8183_mt6358_i2s_hw_params, 47 }; 48 49 static int mt8183_da7219_i2s_hw_params(struct snd_pcm_substream *substream, 50 struct snd_pcm_hw_params *params) 51 { 52 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 53 struct snd_soc_dai *codec_dai; 54 unsigned int rate = params_rate(params); 55 unsigned int mclk_fs_ratio = 256; 56 unsigned int mclk_fs = rate * mclk_fs_ratio; 57 unsigned int freq; 58 int ret = 0, j; 59 60 ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, 61 mclk_fs, SND_SOC_CLOCK_OUT); 62 if (ret < 0) 63 dev_err(rtd->dev, "failed to set cpu dai sysclk\n"); 64 65 for_each_rtd_codec_dais(rtd, j, codec_dai) { 66 if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) { 67 ret = snd_soc_dai_set_sysclk(codec_dai, 68 DA7219_CLKSRC_MCLK, 69 mclk_fs, 70 SND_SOC_CLOCK_IN); 71 if (ret < 0) 72 dev_err(rtd->dev, "failed to set sysclk\n"); 73 74 if ((rate % 8000) == 0) 75 freq = DA7219_PLL_FREQ_OUT_98304; 76 else 77 freq = DA7219_PLL_FREQ_OUT_90316; 78 79 ret = snd_soc_dai_set_pll(codec_dai, 0, 80 DA7219_SYSCLK_PLL_SRM, 81 0, freq); 82 if (ret) 83 dev_err(rtd->dev, "failed to start PLL: %d\n", 84 ret); 85 } 86 } 87 88 return ret; 89 } 90 91 static int mt8183_da7219_hw_free(struct snd_pcm_substream *substream) 92 { 93 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 94 struct snd_soc_dai *codec_dai; 95 int ret = 0, j; 96 97 for_each_rtd_codec_dais(rtd, j, codec_dai) { 98 if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) { 99 ret = snd_soc_dai_set_pll(codec_dai, 100 0, DA7219_SYSCLK_MCLK, 0, 0); 101 if (ret < 0) { 102 dev_err(rtd->dev, "failed to stop PLL: %d\n", 103 ret); 104 break; 105 } 106 } 107 } 108 109 return ret; 110 } 111 112 static const struct snd_soc_ops mt8183_da7219_i2s_ops = { 113 .hw_params = mt8183_da7219_i2s_hw_params, 114 .hw_free = mt8183_da7219_hw_free, 115 }; 116 117 static int 118 mt8183_da7219_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, 119 struct snd_pcm_hw_params *params) 120 { 121 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 122 unsigned int rate = params_rate(params); 123 struct snd_soc_dai *codec_dai; 124 int ret = 0, i; 125 126 for_each_rtd_codec_dais(rtd, i, codec_dai) { 127 if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) || 128 !strcmp(codec_dai->component->name, RT1015_DEV1_NAME)) { 129 ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64); 130 if (ret) { 131 dev_err(rtd->dev, "failed to set bclk ratio\n"); 132 return ret; 133 } 134 135 ret = snd_soc_dai_set_pll(codec_dai, 0, 136 RT1015_PLL_S_BCLK, 137 rate * 64, rate * 256); 138 if (ret) { 139 dev_err(rtd->dev, "failed to set pll\n"); 140 return ret; 141 } 142 143 ret = snd_soc_dai_set_sysclk(codec_dai, 144 RT1015_SCLK_S_PLL, 145 rate * 256, 146 SND_SOC_CLOCK_IN); 147 if (ret) { 148 dev_err(rtd->dev, "failed to set sysclk\n"); 149 return ret; 150 } 151 } 152 } 153 154 return mt8183_da7219_i2s_hw_params(substream, params); 155 } 156 157 static const struct snd_soc_ops mt8183_da7219_rt1015_i2s_ops = { 158 .hw_params = mt8183_da7219_rt1015_i2s_hw_params, 159 .hw_free = mt8183_da7219_hw_free, 160 }; 161 162 static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 163 struct snd_pcm_hw_params *params) 164 { 165 /* fix BE i2s format to 32bit, clean param mask first */ 166 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), 167 0, SNDRV_PCM_FORMAT_LAST); 168 169 params_set_format(params, SNDRV_PCM_FORMAT_S32_LE); 170 171 return 0; 172 } 173 174 static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 175 struct snd_pcm_hw_params *params) 176 { 177 /* fix BE i2s format to 32bit, clean param mask first */ 178 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), 179 0, SNDRV_PCM_FORMAT_LAST); 180 181 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); 182 183 return 0; 184 } 185 186 static int 187 mt8183_da7219_max98357_startup( 188 struct snd_pcm_substream *substream) 189 { 190 static const unsigned int rates[] = { 191 48000, 192 }; 193 static const struct snd_pcm_hw_constraint_list constraints_rates = { 194 .count = ARRAY_SIZE(rates), 195 .list = rates, 196 .mask = 0, 197 }; 198 static const unsigned int channels[] = { 199 2, 200 }; 201 static const struct snd_pcm_hw_constraint_list constraints_channels = { 202 .count = ARRAY_SIZE(channels), 203 .list = channels, 204 .mask = 0, 205 }; 206 207 struct snd_pcm_runtime *runtime = substream->runtime; 208 209 snd_pcm_hw_constraint_list(runtime, 0, 210 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 211 runtime->hw.channels_max = 2; 212 snd_pcm_hw_constraint_list(runtime, 0, 213 SNDRV_PCM_HW_PARAM_CHANNELS, 214 &constraints_channels); 215 216 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; 217 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); 218 219 return 0; 220 } 221 222 static const struct snd_soc_ops mt8183_da7219_max98357_ops = { 223 .startup = mt8183_da7219_max98357_startup, 224 }; 225 226 static int 227 mt8183_da7219_max98357_bt_sco_startup( 228 struct snd_pcm_substream *substream) 229 { 230 static const unsigned int rates[] = { 231 8000, 16000 232 }; 233 static const struct snd_pcm_hw_constraint_list constraints_rates = { 234 .count = ARRAY_SIZE(rates), 235 .list = rates, 236 .mask = 0, 237 }; 238 static const unsigned int channels[] = { 239 1, 240 }; 241 static const struct snd_pcm_hw_constraint_list constraints_channels = { 242 .count = ARRAY_SIZE(channels), 243 .list = channels, 244 .mask = 0, 245 }; 246 247 struct snd_pcm_runtime *runtime = substream->runtime; 248 249 snd_pcm_hw_constraint_list(runtime, 0, 250 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 251 runtime->hw.channels_max = 1; 252 snd_pcm_hw_constraint_list(runtime, 0, 253 SNDRV_PCM_HW_PARAM_CHANNELS, 254 &constraints_channels); 255 256 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; 257 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); 258 259 return 0; 260 } 261 262 static const struct snd_soc_ops mt8183_da7219_max98357_bt_sco_ops = { 263 .startup = mt8183_da7219_max98357_bt_sco_startup, 264 }; 265 266 /* FE */ 267 SND_SOC_DAILINK_DEFS(playback1, 268 DAILINK_COMP_ARRAY(COMP_CPU("DL1")), 269 DAILINK_COMP_ARRAY(COMP_DUMMY()), 270 DAILINK_COMP_ARRAY(COMP_EMPTY())); 271 272 SND_SOC_DAILINK_DEFS(playback2, 273 DAILINK_COMP_ARRAY(COMP_CPU("DL2")), 274 DAILINK_COMP_ARRAY(COMP_DUMMY()), 275 DAILINK_COMP_ARRAY(COMP_EMPTY())); 276 277 SND_SOC_DAILINK_DEFS(playback3, 278 DAILINK_COMP_ARRAY(COMP_CPU("DL3")), 279 DAILINK_COMP_ARRAY(COMP_DUMMY()), 280 DAILINK_COMP_ARRAY(COMP_EMPTY())); 281 282 SND_SOC_DAILINK_DEFS(capture1, 283 DAILINK_COMP_ARRAY(COMP_CPU("UL1")), 284 DAILINK_COMP_ARRAY(COMP_DUMMY()), 285 DAILINK_COMP_ARRAY(COMP_EMPTY())); 286 287 SND_SOC_DAILINK_DEFS(capture2, 288 DAILINK_COMP_ARRAY(COMP_CPU("UL2")), 289 DAILINK_COMP_ARRAY(COMP_DUMMY()), 290 DAILINK_COMP_ARRAY(COMP_EMPTY())); 291 292 SND_SOC_DAILINK_DEFS(capture3, 293 DAILINK_COMP_ARRAY(COMP_CPU("UL3")), 294 DAILINK_COMP_ARRAY(COMP_DUMMY()), 295 DAILINK_COMP_ARRAY(COMP_EMPTY())); 296 297 SND_SOC_DAILINK_DEFS(capture_mono, 298 DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")), 299 DAILINK_COMP_ARRAY(COMP_DUMMY()), 300 DAILINK_COMP_ARRAY(COMP_EMPTY())); 301 302 SND_SOC_DAILINK_DEFS(playback_hdmi, 303 DAILINK_COMP_ARRAY(COMP_CPU("HDMI")), 304 DAILINK_COMP_ARRAY(COMP_DUMMY()), 305 DAILINK_COMP_ARRAY(COMP_EMPTY())); 306 307 /* BE */ 308 SND_SOC_DAILINK_DEFS(primary_codec, 309 DAILINK_COMP_ARRAY(COMP_CPU("ADDA")), 310 DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")), 311 DAILINK_COMP_ARRAY(COMP_EMPTY())); 312 313 SND_SOC_DAILINK_DEFS(pcm1, 314 DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")), 315 DAILINK_COMP_ARRAY(COMP_DUMMY()), 316 DAILINK_COMP_ARRAY(COMP_EMPTY())); 317 318 SND_SOC_DAILINK_DEFS(pcm2, 319 DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")), 320 DAILINK_COMP_ARRAY(COMP_DUMMY()), 321 DAILINK_COMP_ARRAY(COMP_EMPTY())); 322 323 SND_SOC_DAILINK_DEFS(i2s0, 324 DAILINK_COMP_ARRAY(COMP_CPU("I2S0")), 325 DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")), 326 DAILINK_COMP_ARRAY(COMP_EMPTY())); 327 328 SND_SOC_DAILINK_DEFS(i2s1, 329 DAILINK_COMP_ARRAY(COMP_CPU("I2S1")), 330 DAILINK_COMP_ARRAY(COMP_DUMMY()), 331 DAILINK_COMP_ARRAY(COMP_EMPTY())); 332 333 SND_SOC_DAILINK_DEFS(i2s2, 334 DAILINK_COMP_ARRAY(COMP_CPU("I2S2")), 335 DAILINK_COMP_ARRAY(COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)), 336 DAILINK_COMP_ARRAY(COMP_EMPTY())); 337 338 SND_SOC_DAILINK_DEFS(i2s3_max98357a, 339 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")), 340 DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi"), 341 COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)), 342 DAILINK_COMP_ARRAY(COMP_EMPTY())); 343 344 SND_SOC_DAILINK_DEFS(i2s3_rt1015, 345 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")), 346 DAILINK_COMP_ARRAY(COMP_CODEC(RT1015_DEV0_NAME, RT1015_CODEC_DAI), 347 COMP_CODEC(RT1015_DEV1_NAME, RT1015_CODEC_DAI), 348 COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)), 349 DAILINK_COMP_ARRAY(COMP_EMPTY())); 350 351 SND_SOC_DAILINK_DEFS(i2s5, 352 DAILINK_COMP_ARRAY(COMP_CPU("I2S5")), 353 DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")), 354 DAILINK_COMP_ARRAY(COMP_EMPTY())); 355 356 SND_SOC_DAILINK_DEFS(tdm, 357 DAILINK_COMP_ARRAY(COMP_CPU("TDM")), 358 DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")), 359 DAILINK_COMP_ARRAY(COMP_EMPTY())); 360 361 static int mt8183_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd) 362 { 363 struct mt8183_da7219_max98357_priv *priv = 364 snd_soc_card_get_drvdata(rtd->card); 365 int ret; 366 367 ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, 368 &priv->hdmi_jack, NULL, 0); 369 if (ret) 370 return ret; 371 372 return hdmi_codec_set_jack_detect(asoc_rtd_to_codec(rtd, 0)->component, 373 &priv->hdmi_jack); 374 } 375 376 static struct snd_soc_dai_link mt8183_da7219_dai_links[] = { 377 /* FE */ 378 { 379 .name = "Playback_1", 380 .stream_name = "Playback_1", 381 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 382 SND_SOC_DPCM_TRIGGER_PRE}, 383 .dynamic = 1, 384 .dpcm_playback = 1, 385 .ops = &mt8183_da7219_max98357_ops, 386 SND_SOC_DAILINK_REG(playback1), 387 }, 388 { 389 .name = "Playback_2", 390 .stream_name = "Playback_2", 391 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 392 SND_SOC_DPCM_TRIGGER_PRE}, 393 .dynamic = 1, 394 .dpcm_playback = 1, 395 .ops = &mt8183_da7219_max98357_bt_sco_ops, 396 SND_SOC_DAILINK_REG(playback2), 397 }, 398 { 399 .name = "Playback_3", 400 .stream_name = "Playback_3", 401 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 402 SND_SOC_DPCM_TRIGGER_PRE}, 403 .dynamic = 1, 404 .dpcm_playback = 1, 405 SND_SOC_DAILINK_REG(playback3), 406 }, 407 { 408 .name = "Capture_1", 409 .stream_name = "Capture_1", 410 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 411 SND_SOC_DPCM_TRIGGER_PRE}, 412 .dynamic = 1, 413 .dpcm_capture = 1, 414 .ops = &mt8183_da7219_max98357_bt_sco_ops, 415 SND_SOC_DAILINK_REG(capture1), 416 }, 417 { 418 .name = "Capture_2", 419 .stream_name = "Capture_2", 420 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 421 SND_SOC_DPCM_TRIGGER_PRE}, 422 .dynamic = 1, 423 .dpcm_capture = 1, 424 SND_SOC_DAILINK_REG(capture2), 425 }, 426 { 427 .name = "Capture_3", 428 .stream_name = "Capture_3", 429 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 430 SND_SOC_DPCM_TRIGGER_PRE}, 431 .dynamic = 1, 432 .dpcm_capture = 1, 433 .ops = &mt8183_da7219_max98357_ops, 434 SND_SOC_DAILINK_REG(capture3), 435 }, 436 { 437 .name = "Capture_Mono_1", 438 .stream_name = "Capture_Mono_1", 439 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 440 SND_SOC_DPCM_TRIGGER_PRE}, 441 .dynamic = 1, 442 .dpcm_capture = 1, 443 SND_SOC_DAILINK_REG(capture_mono), 444 }, 445 { 446 .name = "Playback_HDMI", 447 .stream_name = "Playback_HDMI", 448 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 449 SND_SOC_DPCM_TRIGGER_PRE}, 450 .dynamic = 1, 451 .dpcm_playback = 1, 452 SND_SOC_DAILINK_REG(playback_hdmi), 453 }, 454 /* BE */ 455 { 456 .name = "Primary Codec", 457 .no_pcm = 1, 458 .dpcm_playback = 1, 459 .dpcm_capture = 1, 460 .ignore_suspend = 1, 461 SND_SOC_DAILINK_REG(primary_codec), 462 }, 463 { 464 .name = "PCM 1", 465 .no_pcm = 1, 466 .dpcm_playback = 1, 467 .dpcm_capture = 1, 468 .ignore_suspend = 1, 469 SND_SOC_DAILINK_REG(pcm1), 470 }, 471 { 472 .name = "PCM 2", 473 .no_pcm = 1, 474 .dpcm_playback = 1, 475 .dpcm_capture = 1, 476 .ignore_suspend = 1, 477 SND_SOC_DAILINK_REG(pcm2), 478 }, 479 { 480 .name = "I2S0", 481 .no_pcm = 1, 482 .dpcm_capture = 1, 483 .ignore_suspend = 1, 484 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 485 .ops = &mt8183_mt6358_i2s_ops, 486 SND_SOC_DAILINK_REG(i2s0), 487 }, 488 { 489 .name = "I2S1", 490 .no_pcm = 1, 491 .dpcm_playback = 1, 492 .ignore_suspend = 1, 493 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 494 .ops = &mt8183_mt6358_i2s_ops, 495 SND_SOC_DAILINK_REG(i2s1), 496 }, 497 { 498 .name = "I2S2", 499 .no_pcm = 1, 500 .dpcm_capture = 1, 501 .ignore_suspend = 1, 502 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 503 .ops = &mt8183_da7219_i2s_ops, 504 SND_SOC_DAILINK_REG(i2s2), 505 }, 506 { 507 .name = "I2S3", 508 .no_pcm = 1, 509 .dpcm_playback = 1, 510 .ignore_suspend = 1, 511 }, 512 { 513 .name = "I2S5", 514 .no_pcm = 1, 515 .dpcm_playback = 1, 516 .ignore_suspend = 1, 517 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 518 .ops = &mt8183_mt6358_i2s_ops, 519 SND_SOC_DAILINK_REG(i2s5), 520 }, 521 { 522 .name = "TDM", 523 .no_pcm = 1, 524 .dai_fmt = SND_SOC_DAIFMT_I2S | 525 SND_SOC_DAIFMT_IB_IF | 526 SND_SOC_DAIFMT_CBM_CFM, 527 .dpcm_playback = 1, 528 .ignore_suspend = 1, 529 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 530 .init = mt8183_da7219_max98357_hdmi_init, 531 SND_SOC_DAILINK_REG(tdm), 532 }, 533 }; 534 535 static int 536 mt8183_da7219_max98357_headset_init(struct snd_soc_component *component) 537 { 538 int ret; 539 struct mt8183_da7219_max98357_priv *priv = 540 snd_soc_card_get_drvdata(component->card); 541 542 /* Enable Headset and 4 Buttons Jack detection */ 543 ret = snd_soc_card_jack_new(component->card, 544 "Headset Jack", 545 SND_JACK_HEADSET | 546 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 547 SND_JACK_BTN_2 | SND_JACK_BTN_3, 548 &priv->headset_jack, 549 NULL, 0); 550 if (ret) 551 return ret; 552 553 snd_jack_set_key( 554 priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 555 snd_jack_set_key( 556 priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); 557 snd_jack_set_key( 558 priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); 559 snd_jack_set_key( 560 priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); 561 562 da7219_aad_jack_det(component, &priv->headset_jack); 563 564 return 0; 565 } 566 567 static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = { 568 .dlc = COMP_EMPTY(), 569 .init = mt8183_da7219_max98357_headset_init, 570 }; 571 572 static struct snd_soc_codec_conf mt6358_codec_conf[] = { 573 { 574 .dlc = COMP_CODEC_CONF("mt6358-sound"), 575 .name_prefix = "Mt6358", 576 }, 577 }; 578 579 static const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = { 580 SOC_DAPM_PIN_SWITCH("Speakers"), 581 }; 582 583 static const 584 struct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = { 585 SND_SOC_DAPM_SPK("Speakers", NULL), 586 SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL", 587 "aud_tdm_out_on", "aud_tdm_out_off"), 588 }; 589 590 static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = { 591 {"Speakers", NULL, "Speaker"}, 592 {"I2S Playback", NULL, "TDM_OUT_PINCTRL"}, 593 }; 594 595 static struct snd_soc_card mt8183_da7219_max98357_card = { 596 .name = "mt8183_da7219_max98357", 597 .owner = THIS_MODULE, 598 .controls = mt8183_da7219_max98357_snd_controls, 599 .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls), 600 .dapm_widgets = mt8183_da7219_max98357_dapm_widgets, 601 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets), 602 .dapm_routes = mt8183_da7219_max98357_dapm_routes, 603 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes), 604 .dai_link = mt8183_da7219_dai_links, 605 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 606 .aux_dev = &mt8183_da7219_max98357_headset_dev, 607 .num_aux_devs = 1, 608 .codec_conf = mt6358_codec_conf, 609 .num_configs = ARRAY_SIZE(mt6358_codec_conf), 610 }; 611 612 static struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = { 613 { 614 .dlc = COMP_CODEC_CONF("mt6358-sound"), 615 .name_prefix = "Mt6358", 616 }, 617 { 618 .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME), 619 .name_prefix = "Left", 620 }, 621 { 622 .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME), 623 .name_prefix = "Right", 624 }, 625 }; 626 627 static struct snd_soc_card mt8183_da7219_rt1015_card = { 628 .name = "mt8183_da7219_rt1015", 629 .owner = THIS_MODULE, 630 .controls = mt8183_da7219_max98357_snd_controls, 631 .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls), 632 .dapm_widgets = mt8183_da7219_max98357_dapm_widgets, 633 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets), 634 .dapm_routes = mt8183_da7219_max98357_dapm_routes, 635 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes), 636 .dai_link = mt8183_da7219_dai_links, 637 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 638 .aux_dev = &mt8183_da7219_max98357_headset_dev, 639 .num_aux_devs = 1, 640 .codec_conf = mt8183_da7219_rt1015_codec_conf, 641 .num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf), 642 }; 643 644 static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev) 645 { 646 struct snd_soc_card *card; 647 struct device_node *platform_node, *hdmi_codec; 648 struct snd_soc_dai_link *dai_link; 649 struct mt8183_da7219_max98357_priv *priv; 650 struct pinctrl *pinctrl; 651 const struct of_device_id *match; 652 int ret, i; 653 654 platform_node = of_parse_phandle(pdev->dev.of_node, 655 "mediatek,platform", 0); 656 if (!platform_node) { 657 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n"); 658 return -EINVAL; 659 } 660 661 match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev); 662 if (!match || !match->data) 663 return -EINVAL; 664 665 card = (struct snd_soc_card *)match->data; 666 card->dev = &pdev->dev; 667 668 hdmi_codec = of_parse_phandle(pdev->dev.of_node, 669 "mediatek,hdmi-codec", 0); 670 671 for_each_card_prelinks(card, i, dai_link) { 672 if (strcmp(dai_link->name, "I2S3") == 0) { 673 if (card == &mt8183_da7219_max98357_card) { 674 dai_link->be_hw_params_fixup = 675 mt8183_i2s_hw_params_fixup; 676 dai_link->ops = &mt8183_mt6358_i2s_ops; 677 dai_link->cpus = i2s3_max98357a_cpus; 678 dai_link->num_cpus = 679 ARRAY_SIZE(i2s3_max98357a_cpus); 680 dai_link->codecs = i2s3_max98357a_codecs; 681 dai_link->num_codecs = 682 ARRAY_SIZE(i2s3_max98357a_codecs); 683 dai_link->platforms = i2s3_max98357a_platforms; 684 dai_link->num_platforms = 685 ARRAY_SIZE(i2s3_max98357a_platforms); 686 } else if (card == &mt8183_da7219_rt1015_card) { 687 dai_link->be_hw_params_fixup = 688 mt8183_rt1015_i2s_hw_params_fixup; 689 dai_link->ops = &mt8183_da7219_rt1015_i2s_ops; 690 dai_link->cpus = i2s3_rt1015_cpus; 691 dai_link->num_cpus = 692 ARRAY_SIZE(i2s3_rt1015_cpus); 693 dai_link->codecs = i2s3_rt1015_codecs; 694 dai_link->num_codecs = 695 ARRAY_SIZE(i2s3_rt1015_codecs); 696 dai_link->platforms = i2s3_rt1015_platforms; 697 dai_link->num_platforms = 698 ARRAY_SIZE(i2s3_rt1015_platforms); 699 } 700 } 701 702 if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) 703 dai_link->codecs->of_node = hdmi_codec; 704 705 if (!dai_link->platforms->name) 706 dai_link->platforms->of_node = platform_node; 707 } 708 709 mt8183_da7219_max98357_headset_dev.dlc.of_node = 710 of_parse_phandle(pdev->dev.of_node, 711 "mediatek,headset-codec", 0); 712 if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) { 713 dev_err(&pdev->dev, 714 "Property 'mediatek,headset-codec' missing/invalid\n"); 715 return -EINVAL; 716 } 717 718 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 719 if (!priv) 720 return -ENOMEM; 721 722 snd_soc_card_set_drvdata(card, priv); 723 724 pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT); 725 if (IS_ERR(pinctrl)) { 726 ret = PTR_ERR(pinctrl); 727 dev_err(&pdev->dev, "%s failed to select default state %d\n", 728 __func__, ret); 729 return ret; 730 } 731 732 return devm_snd_soc_register_card(&pdev->dev, card); 733 } 734 735 #ifdef CONFIG_OF 736 static const struct of_device_id mt8183_da7219_max98357_dt_match[] = { 737 { 738 .compatible = "mediatek,mt8183_da7219_max98357", 739 .data = &mt8183_da7219_max98357_card, 740 }, 741 { 742 .compatible = "mediatek,mt8183_da7219_rt1015", 743 .data = &mt8183_da7219_rt1015_card, 744 }, 745 {} 746 }; 747 #endif 748 749 static struct platform_driver mt8183_da7219_max98357_driver = { 750 .driver = { 751 .name = "mt8183_da7219", 752 #ifdef CONFIG_OF 753 .of_match_table = mt8183_da7219_max98357_dt_match, 754 #endif 755 }, 756 .probe = mt8183_da7219_max98357_dev_probe, 757 }; 758 759 module_platform_driver(mt8183_da7219_max98357_driver); 760 761 /* Module information */ 762 MODULE_DESCRIPTION("MT8183-DA7219-MAX98357 ALSA SoC machine driver"); 763 MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>"); 764 MODULE_LICENSE("GPL v2"); 765 MODULE_ALIAS("mt8183_da7219_max98357 soc card"); 766