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 "../common/mtk-afe-platform-driver.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_pll(codec_dai, 0, 130 RT1015_PLL_S_BCLK, 131 rate * 64, rate * 256); 132 if (ret) { 133 dev_err(rtd->dev, "failed to set pll\n"); 134 return ret; 135 } 136 137 ret = snd_soc_dai_set_sysclk(codec_dai, 138 RT1015_SCLK_S_PLL, 139 rate * 256, 140 SND_SOC_CLOCK_IN); 141 if (ret) { 142 dev_err(rtd->dev, "failed to set sysclk\n"); 143 return ret; 144 } 145 } 146 } 147 148 return mt8183_da7219_i2s_hw_params(substream, params); 149 } 150 151 static const struct snd_soc_ops mt8183_da7219_rt1015_i2s_ops = { 152 .hw_params = mt8183_da7219_rt1015_i2s_hw_params, 153 .hw_free = mt8183_da7219_hw_free, 154 }; 155 156 static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 157 struct snd_pcm_hw_params *params) 158 { 159 /* fix BE i2s format to S32_LE, clean param mask first */ 160 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), 161 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); 162 163 params_set_format(params, SNDRV_PCM_FORMAT_S32_LE); 164 165 return 0; 166 } 167 168 static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 169 struct snd_pcm_hw_params *params) 170 { 171 /* fix BE i2s format to S24_LE, clean param mask first */ 172 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), 173 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); 174 175 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); 176 177 return 0; 178 } 179 180 static int 181 mt8183_da7219_max98357_startup( 182 struct snd_pcm_substream *substream) 183 { 184 static const unsigned int rates[] = { 185 48000, 186 }; 187 static const struct snd_pcm_hw_constraint_list constraints_rates = { 188 .count = ARRAY_SIZE(rates), 189 .list = rates, 190 .mask = 0, 191 }; 192 static const unsigned int channels[] = { 193 2, 194 }; 195 static const struct snd_pcm_hw_constraint_list constraints_channels = { 196 .count = ARRAY_SIZE(channels), 197 .list = channels, 198 .mask = 0, 199 }; 200 201 struct snd_pcm_runtime *runtime = substream->runtime; 202 203 snd_pcm_hw_constraint_list(runtime, 0, 204 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 205 runtime->hw.channels_max = 2; 206 snd_pcm_hw_constraint_list(runtime, 0, 207 SNDRV_PCM_HW_PARAM_CHANNELS, 208 &constraints_channels); 209 210 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; 211 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); 212 213 return 0; 214 } 215 216 static const struct snd_soc_ops mt8183_da7219_max98357_ops = { 217 .startup = mt8183_da7219_max98357_startup, 218 }; 219 220 static int 221 mt8183_da7219_max98357_bt_sco_startup( 222 struct snd_pcm_substream *substream) 223 { 224 static const unsigned int rates[] = { 225 8000, 16000 226 }; 227 static const struct snd_pcm_hw_constraint_list constraints_rates = { 228 .count = ARRAY_SIZE(rates), 229 .list = rates, 230 .mask = 0, 231 }; 232 static const unsigned int channels[] = { 233 1, 234 }; 235 static const struct snd_pcm_hw_constraint_list constraints_channels = { 236 .count = ARRAY_SIZE(channels), 237 .list = channels, 238 .mask = 0, 239 }; 240 241 struct snd_pcm_runtime *runtime = substream->runtime; 242 243 snd_pcm_hw_constraint_list(runtime, 0, 244 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 245 runtime->hw.channels_max = 1; 246 snd_pcm_hw_constraint_list(runtime, 0, 247 SNDRV_PCM_HW_PARAM_CHANNELS, 248 &constraints_channels); 249 250 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; 251 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); 252 253 return 0; 254 } 255 256 static const struct snd_soc_ops mt8183_da7219_max98357_bt_sco_ops = { 257 .startup = mt8183_da7219_max98357_bt_sco_startup, 258 }; 259 260 /* FE */ 261 SND_SOC_DAILINK_DEFS(playback1, 262 DAILINK_COMP_ARRAY(COMP_CPU("DL1")), 263 DAILINK_COMP_ARRAY(COMP_DUMMY()), 264 DAILINK_COMP_ARRAY(COMP_EMPTY())); 265 266 SND_SOC_DAILINK_DEFS(playback2, 267 DAILINK_COMP_ARRAY(COMP_CPU("DL2")), 268 DAILINK_COMP_ARRAY(COMP_DUMMY()), 269 DAILINK_COMP_ARRAY(COMP_EMPTY())); 270 271 SND_SOC_DAILINK_DEFS(playback3, 272 DAILINK_COMP_ARRAY(COMP_CPU("DL3")), 273 DAILINK_COMP_ARRAY(COMP_DUMMY()), 274 DAILINK_COMP_ARRAY(COMP_EMPTY())); 275 276 SND_SOC_DAILINK_DEFS(capture1, 277 DAILINK_COMP_ARRAY(COMP_CPU("UL1")), 278 DAILINK_COMP_ARRAY(COMP_DUMMY()), 279 DAILINK_COMP_ARRAY(COMP_EMPTY())); 280 281 SND_SOC_DAILINK_DEFS(capture2, 282 DAILINK_COMP_ARRAY(COMP_CPU("UL2")), 283 DAILINK_COMP_ARRAY(COMP_DUMMY()), 284 DAILINK_COMP_ARRAY(COMP_EMPTY())); 285 286 SND_SOC_DAILINK_DEFS(capture3, 287 DAILINK_COMP_ARRAY(COMP_CPU("UL3")), 288 DAILINK_COMP_ARRAY(COMP_DUMMY()), 289 DAILINK_COMP_ARRAY(COMP_EMPTY())); 290 291 SND_SOC_DAILINK_DEFS(capture_mono, 292 DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")), 293 DAILINK_COMP_ARRAY(COMP_DUMMY()), 294 DAILINK_COMP_ARRAY(COMP_EMPTY())); 295 296 SND_SOC_DAILINK_DEFS(playback_hdmi, 297 DAILINK_COMP_ARRAY(COMP_CPU("HDMI")), 298 DAILINK_COMP_ARRAY(COMP_DUMMY()), 299 DAILINK_COMP_ARRAY(COMP_EMPTY())); 300 301 /* BE */ 302 SND_SOC_DAILINK_DEFS(primary_codec, 303 DAILINK_COMP_ARRAY(COMP_CPU("ADDA")), 304 DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")), 305 DAILINK_COMP_ARRAY(COMP_EMPTY())); 306 307 SND_SOC_DAILINK_DEFS(pcm1, 308 DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")), 309 DAILINK_COMP_ARRAY(COMP_DUMMY()), 310 DAILINK_COMP_ARRAY(COMP_EMPTY())); 311 312 SND_SOC_DAILINK_DEFS(pcm2, 313 DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")), 314 DAILINK_COMP_ARRAY(COMP_DUMMY()), 315 DAILINK_COMP_ARRAY(COMP_EMPTY())); 316 317 SND_SOC_DAILINK_DEFS(i2s0, 318 DAILINK_COMP_ARRAY(COMP_CPU("I2S0")), 319 DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")), 320 DAILINK_COMP_ARRAY(COMP_EMPTY())); 321 322 SND_SOC_DAILINK_DEFS(i2s1, 323 DAILINK_COMP_ARRAY(COMP_CPU("I2S1")), 324 DAILINK_COMP_ARRAY(COMP_DUMMY()), 325 DAILINK_COMP_ARRAY(COMP_EMPTY())); 326 327 SND_SOC_DAILINK_DEFS(i2s2, 328 DAILINK_COMP_ARRAY(COMP_CPU("I2S2")), 329 DAILINK_COMP_ARRAY(COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)), 330 DAILINK_COMP_ARRAY(COMP_EMPTY())); 331 332 SND_SOC_DAILINK_DEFS(i2s3_max98357a, 333 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")), 334 DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi"), 335 COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)), 336 DAILINK_COMP_ARRAY(COMP_EMPTY())); 337 338 SND_SOC_DAILINK_DEFS(i2s3_rt1015, 339 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")), 340 DAILINK_COMP_ARRAY(COMP_CODEC(RT1015_DEV0_NAME, RT1015_CODEC_DAI), 341 COMP_CODEC(RT1015_DEV1_NAME, RT1015_CODEC_DAI), 342 COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)), 343 DAILINK_COMP_ARRAY(COMP_EMPTY())); 344 345 SND_SOC_DAILINK_DEFS(i2s3_rt1015p, 346 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")), 347 DAILINK_COMP_ARRAY(COMP_CODEC("rt1015p", "HiFi"), 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); 369 if (ret) 370 return ret; 371 372 return snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, 373 &priv->hdmi_jack, NULL); 374 } 375 376 static int mt8183_bt_init(struct snd_soc_pcm_runtime *rtd) 377 { 378 struct snd_soc_component *cmpnt_afe = 379 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 380 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); 381 int ret; 382 383 ret = mt8183_dai_i2s_set_share(afe, "I2S5", "I2S0"); 384 if (ret) { 385 dev_err(rtd->dev, "Failed to set up shared clocks\n"); 386 return ret; 387 } 388 return 0; 389 } 390 391 static int mt8183_da7219_init(struct snd_soc_pcm_runtime *rtd) 392 { 393 struct snd_soc_component *cmpnt_afe = 394 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 395 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); 396 int ret; 397 398 ret = mt8183_dai_i2s_set_share(afe, "I2S2", "I2S3"); 399 if (ret) { 400 dev_err(rtd->dev, "Failed to set up shared clocks\n"); 401 return ret; 402 } 403 return 0; 404 } 405 406 static struct snd_soc_dai_link mt8183_da7219_dai_links[] = { 407 /* FE */ 408 { 409 .name = "Playback_1", 410 .stream_name = "Playback_1", 411 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 412 SND_SOC_DPCM_TRIGGER_PRE}, 413 .dynamic = 1, 414 .dpcm_playback = 1, 415 .ops = &mt8183_da7219_max98357_ops, 416 SND_SOC_DAILINK_REG(playback1), 417 }, 418 { 419 .name = "Playback_2", 420 .stream_name = "Playback_2", 421 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 422 SND_SOC_DPCM_TRIGGER_PRE}, 423 .dynamic = 1, 424 .dpcm_playback = 1, 425 .ops = &mt8183_da7219_max98357_bt_sco_ops, 426 SND_SOC_DAILINK_REG(playback2), 427 }, 428 { 429 .name = "Playback_3", 430 .stream_name = "Playback_3", 431 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 432 SND_SOC_DPCM_TRIGGER_PRE}, 433 .dynamic = 1, 434 .dpcm_playback = 1, 435 SND_SOC_DAILINK_REG(playback3), 436 }, 437 { 438 .name = "Capture_1", 439 .stream_name = "Capture_1", 440 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 441 SND_SOC_DPCM_TRIGGER_PRE}, 442 .dynamic = 1, 443 .dpcm_capture = 1, 444 .ops = &mt8183_da7219_max98357_bt_sco_ops, 445 SND_SOC_DAILINK_REG(capture1), 446 }, 447 { 448 .name = "Capture_2", 449 .stream_name = "Capture_2", 450 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 451 SND_SOC_DPCM_TRIGGER_PRE}, 452 .dynamic = 1, 453 .dpcm_capture = 1, 454 SND_SOC_DAILINK_REG(capture2), 455 }, 456 { 457 .name = "Capture_3", 458 .stream_name = "Capture_3", 459 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 460 SND_SOC_DPCM_TRIGGER_PRE}, 461 .dynamic = 1, 462 .dpcm_capture = 1, 463 .ops = &mt8183_da7219_max98357_ops, 464 SND_SOC_DAILINK_REG(capture3), 465 }, 466 { 467 .name = "Capture_Mono_1", 468 .stream_name = "Capture_Mono_1", 469 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 470 SND_SOC_DPCM_TRIGGER_PRE}, 471 .dynamic = 1, 472 .dpcm_capture = 1, 473 SND_SOC_DAILINK_REG(capture_mono), 474 }, 475 { 476 .name = "Playback_HDMI", 477 .stream_name = "Playback_HDMI", 478 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 479 SND_SOC_DPCM_TRIGGER_PRE}, 480 .dynamic = 1, 481 .dpcm_playback = 1, 482 SND_SOC_DAILINK_REG(playback_hdmi), 483 }, 484 /* BE */ 485 { 486 .name = "Primary Codec", 487 .no_pcm = 1, 488 .dpcm_playback = 1, 489 .dpcm_capture = 1, 490 .ignore_suspend = 1, 491 SND_SOC_DAILINK_REG(primary_codec), 492 }, 493 { 494 .name = "PCM 1", 495 .no_pcm = 1, 496 .dpcm_playback = 1, 497 .dpcm_capture = 1, 498 .ignore_suspend = 1, 499 SND_SOC_DAILINK_REG(pcm1), 500 }, 501 { 502 .name = "PCM 2", 503 .no_pcm = 1, 504 .dpcm_playback = 1, 505 .dpcm_capture = 1, 506 .ignore_suspend = 1, 507 SND_SOC_DAILINK_REG(pcm2), 508 }, 509 { 510 .name = "I2S0", 511 .no_pcm = 1, 512 .dpcm_capture = 1, 513 .ignore_suspend = 1, 514 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 515 .ops = &mt8183_mt6358_i2s_ops, 516 SND_SOC_DAILINK_REG(i2s0), 517 }, 518 { 519 .name = "I2S1", 520 .no_pcm = 1, 521 .dpcm_playback = 1, 522 .ignore_suspend = 1, 523 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 524 .ops = &mt8183_mt6358_i2s_ops, 525 SND_SOC_DAILINK_REG(i2s1), 526 }, 527 { 528 .name = "I2S2", 529 .no_pcm = 1, 530 .dpcm_capture = 1, 531 .ignore_suspend = 1, 532 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 533 .ops = &mt8183_da7219_i2s_ops, 534 .init = &mt8183_da7219_init, 535 SND_SOC_DAILINK_REG(i2s2), 536 }, 537 { 538 .name = "I2S3", 539 .no_pcm = 1, 540 .dpcm_playback = 1, 541 .ignore_suspend = 1, 542 }, 543 { 544 .name = "I2S5", 545 .no_pcm = 1, 546 .dpcm_playback = 1, 547 .ignore_suspend = 1, 548 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 549 .ops = &mt8183_mt6358_i2s_ops, 550 .init = &mt8183_bt_init, 551 SND_SOC_DAILINK_REG(i2s5), 552 }, 553 { 554 .name = "TDM", 555 .no_pcm = 1, 556 .dai_fmt = SND_SOC_DAIFMT_I2S | 557 SND_SOC_DAIFMT_IB_IF | 558 SND_SOC_DAIFMT_CBM_CFM, 559 .dpcm_playback = 1, 560 .ignore_suspend = 1, 561 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 562 .ignore = 1, 563 .init = mt8183_da7219_max98357_hdmi_init, 564 SND_SOC_DAILINK_REG(tdm), 565 }, 566 }; 567 568 static int 569 mt8183_da7219_max98357_headset_init(struct snd_soc_component *component) 570 { 571 int ret; 572 struct mt8183_da7219_max98357_priv *priv = 573 snd_soc_card_get_drvdata(component->card); 574 575 /* Enable Headset and 4 Buttons Jack detection */ 576 ret = snd_soc_card_jack_new(component->card, 577 "Headset Jack", 578 SND_JACK_HEADSET | 579 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 580 SND_JACK_BTN_2 | SND_JACK_BTN_3 | 581 SND_JACK_LINEOUT, 582 &priv->headset_jack); 583 if (ret) 584 return ret; 585 586 snd_jack_set_key( 587 priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 588 snd_jack_set_key( 589 priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); 590 snd_jack_set_key( 591 priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); 592 snd_jack_set_key( 593 priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); 594 595 da7219_aad_jack_det(component, &priv->headset_jack); 596 597 return 0; 598 } 599 600 static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = { 601 .dlc = COMP_EMPTY(), 602 .init = mt8183_da7219_max98357_headset_init, 603 }; 604 605 static struct snd_soc_codec_conf mt6358_codec_conf[] = { 606 { 607 .dlc = COMP_CODEC_CONF("mt6358-sound"), 608 .name_prefix = "Mt6358", 609 }, 610 }; 611 612 static const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = { 613 SOC_DAPM_PIN_SWITCH("Speakers"), 614 }; 615 616 static const 617 struct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = { 618 SND_SOC_DAPM_SPK("Speakers", NULL), 619 SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL", 620 "aud_tdm_out_on", "aud_tdm_out_off"), 621 }; 622 623 static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = { 624 {"Speakers", NULL, "Speaker"}, 625 {"I2S Playback", NULL, "TDM_OUT_PINCTRL"}, 626 }; 627 628 static struct snd_soc_card mt8183_da7219_max98357_card = { 629 .name = "mt8183_da7219_max98357", 630 .owner = THIS_MODULE, 631 .controls = mt8183_da7219_max98357_snd_controls, 632 .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls), 633 .dapm_widgets = mt8183_da7219_max98357_dapm_widgets, 634 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets), 635 .dapm_routes = mt8183_da7219_max98357_dapm_routes, 636 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes), 637 .dai_link = mt8183_da7219_dai_links, 638 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 639 .aux_dev = &mt8183_da7219_max98357_headset_dev, 640 .num_aux_devs = 1, 641 .codec_conf = mt6358_codec_conf, 642 .num_configs = ARRAY_SIZE(mt6358_codec_conf), 643 }; 644 645 static struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = { 646 { 647 .dlc = COMP_CODEC_CONF("mt6358-sound"), 648 .name_prefix = "Mt6358", 649 }, 650 { 651 .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME), 652 .name_prefix = "Left", 653 }, 654 { 655 .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME), 656 .name_prefix = "Right", 657 }, 658 }; 659 660 static const struct snd_kcontrol_new mt8183_da7219_rt1015_snd_controls[] = { 661 SOC_DAPM_PIN_SWITCH("Left Spk"), 662 SOC_DAPM_PIN_SWITCH("Right Spk"), 663 }; 664 665 static const 666 struct snd_soc_dapm_widget mt8183_da7219_rt1015_dapm_widgets[] = { 667 SND_SOC_DAPM_SPK("Left Spk", NULL), 668 SND_SOC_DAPM_SPK("Right Spk", NULL), 669 SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL", 670 "aud_tdm_out_on", "aud_tdm_out_off"), 671 }; 672 673 static const struct snd_soc_dapm_route mt8183_da7219_rt1015_dapm_routes[] = { 674 {"Left Spk", NULL, "Left SPO"}, 675 {"Right Spk", NULL, "Right SPO"}, 676 {"I2S Playback", NULL, "TDM_OUT_PINCTRL"}, 677 }; 678 679 static struct snd_soc_card mt8183_da7219_rt1015_card = { 680 .name = "mt8183_da7219_rt1015", 681 .owner = THIS_MODULE, 682 .controls = mt8183_da7219_rt1015_snd_controls, 683 .num_controls = ARRAY_SIZE(mt8183_da7219_rt1015_snd_controls), 684 .dapm_widgets = mt8183_da7219_rt1015_dapm_widgets, 685 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_widgets), 686 .dapm_routes = mt8183_da7219_rt1015_dapm_routes, 687 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_routes), 688 .dai_link = mt8183_da7219_dai_links, 689 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 690 .aux_dev = &mt8183_da7219_max98357_headset_dev, 691 .num_aux_devs = 1, 692 .codec_conf = mt8183_da7219_rt1015_codec_conf, 693 .num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf), 694 }; 695 696 static struct snd_soc_card mt8183_da7219_rt1015p_card = { 697 .name = "mt8183_da7219_rt1015p", 698 .owner = THIS_MODULE, 699 .controls = mt8183_da7219_max98357_snd_controls, 700 .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls), 701 .dapm_widgets = mt8183_da7219_max98357_dapm_widgets, 702 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets), 703 .dapm_routes = mt8183_da7219_max98357_dapm_routes, 704 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes), 705 .dai_link = mt8183_da7219_dai_links, 706 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 707 .aux_dev = &mt8183_da7219_max98357_headset_dev, 708 .num_aux_devs = 1, 709 .codec_conf = mt6358_codec_conf, 710 .num_configs = ARRAY_SIZE(mt6358_codec_conf), 711 }; 712 713 static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev) 714 { 715 struct snd_soc_card *card; 716 struct device_node *platform_node, *hdmi_codec; 717 struct snd_soc_dai_link *dai_link; 718 struct mt8183_da7219_max98357_priv *priv; 719 struct pinctrl *pinctrl; 720 int ret, i; 721 722 platform_node = of_parse_phandle(pdev->dev.of_node, 723 "mediatek,platform", 0); 724 if (!platform_node) { 725 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n"); 726 return -EINVAL; 727 } 728 729 card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev); 730 if (!card) { 731 ret = -EINVAL; 732 goto put_platform_node; 733 } 734 735 card->dev = &pdev->dev; 736 737 hdmi_codec = of_parse_phandle(pdev->dev.of_node, 738 "mediatek,hdmi-codec", 0); 739 740 for_each_card_prelinks(card, i, dai_link) { 741 if (strcmp(dai_link->name, "I2S3") == 0) { 742 if (card == &mt8183_da7219_max98357_card) { 743 dai_link->be_hw_params_fixup = 744 mt8183_i2s_hw_params_fixup; 745 dai_link->ops = &mt8183_da7219_i2s_ops; 746 dai_link->cpus = i2s3_max98357a_cpus; 747 dai_link->num_cpus = 748 ARRAY_SIZE(i2s3_max98357a_cpus); 749 dai_link->codecs = i2s3_max98357a_codecs; 750 dai_link->num_codecs = 751 ARRAY_SIZE(i2s3_max98357a_codecs); 752 dai_link->platforms = i2s3_max98357a_platforms; 753 dai_link->num_platforms = 754 ARRAY_SIZE(i2s3_max98357a_platforms); 755 } else if (card == &mt8183_da7219_rt1015_card) { 756 dai_link->be_hw_params_fixup = 757 mt8183_rt1015_i2s_hw_params_fixup; 758 dai_link->ops = &mt8183_da7219_rt1015_i2s_ops; 759 dai_link->cpus = i2s3_rt1015_cpus; 760 dai_link->num_cpus = 761 ARRAY_SIZE(i2s3_rt1015_cpus); 762 dai_link->codecs = i2s3_rt1015_codecs; 763 dai_link->num_codecs = 764 ARRAY_SIZE(i2s3_rt1015_codecs); 765 dai_link->platforms = i2s3_rt1015_platforms; 766 dai_link->num_platforms = 767 ARRAY_SIZE(i2s3_rt1015_platforms); 768 } else if (card == &mt8183_da7219_rt1015p_card) { 769 dai_link->be_hw_params_fixup = 770 mt8183_rt1015_i2s_hw_params_fixup; 771 dai_link->ops = &mt8183_da7219_i2s_ops; 772 dai_link->cpus = i2s3_rt1015p_cpus; 773 dai_link->num_cpus = 774 ARRAY_SIZE(i2s3_rt1015p_cpus); 775 dai_link->codecs = i2s3_rt1015p_codecs; 776 dai_link->num_codecs = 777 ARRAY_SIZE(i2s3_rt1015p_codecs); 778 dai_link->platforms = i2s3_rt1015p_platforms; 779 dai_link->num_platforms = 780 ARRAY_SIZE(i2s3_rt1015p_platforms); 781 } 782 } 783 784 if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) { 785 dai_link->codecs->of_node = hdmi_codec; 786 dai_link->ignore = 0; 787 } 788 789 if (!dai_link->platforms->name) 790 dai_link->platforms->of_node = platform_node; 791 } 792 793 mt8183_da7219_max98357_headset_dev.dlc.of_node = 794 of_parse_phandle(pdev->dev.of_node, 795 "mediatek,headset-codec", 0); 796 if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) { 797 dev_err(&pdev->dev, 798 "Property 'mediatek,headset-codec' missing/invalid\n"); 799 ret = -EINVAL; 800 goto put_hdmi_codec; 801 } 802 803 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 804 if (!priv) { 805 ret = -ENOMEM; 806 goto put_hdmi_codec; 807 } 808 809 snd_soc_card_set_drvdata(card, priv); 810 811 pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT); 812 if (IS_ERR(pinctrl)) { 813 ret = PTR_ERR(pinctrl); 814 dev_err(&pdev->dev, "%s failed to select default state %d\n", 815 __func__, ret); 816 goto put_hdmi_codec; 817 } 818 819 ret = devm_snd_soc_register_card(&pdev->dev, card); 820 821 822 put_hdmi_codec: 823 of_node_put(hdmi_codec); 824 put_platform_node: 825 of_node_put(platform_node); 826 return ret; 827 } 828 829 #ifdef CONFIG_OF 830 static const struct of_device_id mt8183_da7219_max98357_dt_match[] = { 831 { 832 .compatible = "mediatek,mt8183_da7219_max98357", 833 .data = &mt8183_da7219_max98357_card, 834 }, 835 { 836 .compatible = "mediatek,mt8183_da7219_rt1015", 837 .data = &mt8183_da7219_rt1015_card, 838 }, 839 { 840 .compatible = "mediatek,mt8183_da7219_rt1015p", 841 .data = &mt8183_da7219_rt1015p_card, 842 }, 843 {} 844 }; 845 #endif 846 847 static struct platform_driver mt8183_da7219_max98357_driver = { 848 .driver = { 849 .name = "mt8183_da7219", 850 #ifdef CONFIG_OF 851 .of_match_table = mt8183_da7219_max98357_dt_match, 852 #endif 853 .pm = &snd_soc_pm_ops, 854 }, 855 .probe = mt8183_da7219_max98357_dev_probe, 856 }; 857 858 module_platform_driver(mt8183_da7219_max98357_driver); 859 860 /* Module information */ 861 MODULE_DESCRIPTION("MT8183-DA7219-MAX98357 ALSA SoC machine driver"); 862 MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>"); 863 MODULE_LICENSE("GPL v2"); 864 MODULE_ALIAS("mt8183_da7219_max98357 soc card"); 865