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