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.h" 18 #include "../../codecs/rt1015.h" 19 #include "../common/mtk-afe-platform-driver.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); 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 int mt8183_bt_init(struct snd_soc_pcm_runtime *rtd) 376 { 377 struct snd_soc_component *cmpnt_afe = 378 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 379 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); 380 int ret; 381 382 ret = mt8183_dai_i2s_set_share(afe, "I2S5", "I2S0"); 383 if (ret) { 384 dev_err(rtd->dev, "Failed to set up shared clocks\n"); 385 return ret; 386 } 387 return 0; 388 } 389 390 static int mt8183_da7219_init(struct snd_soc_pcm_runtime *rtd) 391 { 392 struct snd_soc_component *cmpnt_afe = 393 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 394 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); 395 int ret; 396 397 ret = mt8183_dai_i2s_set_share(afe, "I2S2", "I2S3"); 398 if (ret) { 399 dev_err(rtd->dev, "Failed to set up shared clocks\n"); 400 return ret; 401 } 402 return 0; 403 } 404 405 static struct snd_soc_dai_link mt8183_da7219_dai_links[] = { 406 /* FE */ 407 { 408 .name = "Playback_1", 409 .stream_name = "Playback_1", 410 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 411 SND_SOC_DPCM_TRIGGER_PRE}, 412 .dynamic = 1, 413 .dpcm_playback = 1, 414 .ops = &mt8183_da7219_max98357_ops, 415 SND_SOC_DAILINK_REG(playback1), 416 }, 417 { 418 .name = "Playback_2", 419 .stream_name = "Playback_2", 420 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 421 SND_SOC_DPCM_TRIGGER_PRE}, 422 .dynamic = 1, 423 .dpcm_playback = 1, 424 .ops = &mt8183_da7219_max98357_bt_sco_ops, 425 SND_SOC_DAILINK_REG(playback2), 426 }, 427 { 428 .name = "Playback_3", 429 .stream_name = "Playback_3", 430 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 431 SND_SOC_DPCM_TRIGGER_PRE}, 432 .dynamic = 1, 433 .dpcm_playback = 1, 434 SND_SOC_DAILINK_REG(playback3), 435 }, 436 { 437 .name = "Capture_1", 438 .stream_name = "Capture_1", 439 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 440 SND_SOC_DPCM_TRIGGER_PRE}, 441 .dynamic = 1, 442 .dpcm_capture = 1, 443 .ops = &mt8183_da7219_max98357_bt_sco_ops, 444 SND_SOC_DAILINK_REG(capture1), 445 }, 446 { 447 .name = "Capture_2", 448 .stream_name = "Capture_2", 449 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 450 SND_SOC_DPCM_TRIGGER_PRE}, 451 .dynamic = 1, 452 .dpcm_capture = 1, 453 SND_SOC_DAILINK_REG(capture2), 454 }, 455 { 456 .name = "Capture_3", 457 .stream_name = "Capture_3", 458 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 459 SND_SOC_DPCM_TRIGGER_PRE}, 460 .dynamic = 1, 461 .dpcm_capture = 1, 462 .ops = &mt8183_da7219_max98357_ops, 463 SND_SOC_DAILINK_REG(capture3), 464 }, 465 { 466 .name = "Capture_Mono_1", 467 .stream_name = "Capture_Mono_1", 468 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 469 SND_SOC_DPCM_TRIGGER_PRE}, 470 .dynamic = 1, 471 .dpcm_capture = 1, 472 SND_SOC_DAILINK_REG(capture_mono), 473 }, 474 { 475 .name = "Playback_HDMI", 476 .stream_name = "Playback_HDMI", 477 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 478 SND_SOC_DPCM_TRIGGER_PRE}, 479 .dynamic = 1, 480 .dpcm_playback = 1, 481 SND_SOC_DAILINK_REG(playback_hdmi), 482 }, 483 /* BE */ 484 { 485 .name = "Primary Codec", 486 .no_pcm = 1, 487 .dpcm_playback = 1, 488 .dpcm_capture = 1, 489 .ignore_suspend = 1, 490 SND_SOC_DAILINK_REG(primary_codec), 491 }, 492 { 493 .name = "PCM 1", 494 .no_pcm = 1, 495 .dpcm_playback = 1, 496 .dpcm_capture = 1, 497 .ignore_suspend = 1, 498 SND_SOC_DAILINK_REG(pcm1), 499 }, 500 { 501 .name = "PCM 2", 502 .no_pcm = 1, 503 .dpcm_playback = 1, 504 .dpcm_capture = 1, 505 .ignore_suspend = 1, 506 SND_SOC_DAILINK_REG(pcm2), 507 }, 508 { 509 .name = "I2S0", 510 .no_pcm = 1, 511 .dpcm_capture = 1, 512 .ignore_suspend = 1, 513 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 514 .ops = &mt8183_mt6358_i2s_ops, 515 SND_SOC_DAILINK_REG(i2s0), 516 }, 517 { 518 .name = "I2S1", 519 .no_pcm = 1, 520 .dpcm_playback = 1, 521 .ignore_suspend = 1, 522 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 523 .ops = &mt8183_mt6358_i2s_ops, 524 SND_SOC_DAILINK_REG(i2s1), 525 }, 526 { 527 .name = "I2S2", 528 .no_pcm = 1, 529 .dpcm_capture = 1, 530 .ignore_suspend = 1, 531 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 532 .ops = &mt8183_da7219_i2s_ops, 533 .init = &mt8183_da7219_init, 534 SND_SOC_DAILINK_REG(i2s2), 535 }, 536 { 537 .name = "I2S3", 538 .no_pcm = 1, 539 .dpcm_playback = 1, 540 .ignore_suspend = 1, 541 }, 542 { 543 .name = "I2S5", 544 .no_pcm = 1, 545 .dpcm_playback = 1, 546 .ignore_suspend = 1, 547 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 548 .ops = &mt8183_mt6358_i2s_ops, 549 .init = &mt8183_bt_init, 550 SND_SOC_DAILINK_REG(i2s5), 551 }, 552 { 553 .name = "TDM", 554 .no_pcm = 1, 555 .dai_fmt = SND_SOC_DAIFMT_I2S | 556 SND_SOC_DAIFMT_IB_IF | 557 SND_SOC_DAIFMT_CBM_CFM, 558 .dpcm_playback = 1, 559 .ignore_suspend = 1, 560 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 561 .ignore = 1, 562 .init = mt8183_da7219_max98357_hdmi_init, 563 SND_SOC_DAILINK_REG(tdm), 564 }, 565 }; 566 567 static int 568 mt8183_da7219_max98357_headset_init(struct snd_soc_component *component) 569 { 570 int ret; 571 struct mt8183_da7219_max98357_priv *priv = 572 snd_soc_card_get_drvdata(component->card); 573 574 /* Enable Headset and 4 Buttons Jack detection */ 575 ret = snd_soc_card_jack_new(component->card, 576 "Headset Jack", 577 SND_JACK_HEADSET | 578 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 579 SND_JACK_BTN_2 | SND_JACK_BTN_3 | 580 SND_JACK_LINEOUT, 581 &priv->headset_jack); 582 if (ret) 583 return ret; 584 585 snd_jack_set_key( 586 priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 587 snd_jack_set_key( 588 priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); 589 snd_jack_set_key( 590 priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); 591 snd_jack_set_key( 592 priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); 593 594 snd_soc_component_set_jack(component, &priv->headset_jack, NULL); 595 596 return 0; 597 } 598 599 static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = { 600 .dlc = COMP_EMPTY(), 601 .init = mt8183_da7219_max98357_headset_init, 602 }; 603 604 static struct snd_soc_codec_conf mt6358_codec_conf[] = { 605 { 606 .dlc = COMP_CODEC_CONF("mt6358-sound"), 607 .name_prefix = "Mt6358", 608 }, 609 }; 610 611 static const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = { 612 SOC_DAPM_PIN_SWITCH("Speakers"), 613 }; 614 615 static const 616 struct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = { 617 SND_SOC_DAPM_SPK("Speakers", NULL), 618 SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL", 619 "aud_tdm_out_on", "aud_tdm_out_off"), 620 }; 621 622 static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = { 623 {"Speakers", NULL, "Speaker"}, 624 {"I2S Playback", NULL, "TDM_OUT_PINCTRL"}, 625 }; 626 627 static struct snd_soc_card mt8183_da7219_max98357_card = { 628 .name = "mt8183_da7219_max98357", 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 = mt6358_codec_conf, 641 .num_configs = ARRAY_SIZE(mt6358_codec_conf), 642 }; 643 644 static struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = { 645 { 646 .dlc = COMP_CODEC_CONF("mt6358-sound"), 647 .name_prefix = "Mt6358", 648 }, 649 { 650 .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME), 651 .name_prefix = "Left", 652 }, 653 { 654 .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME), 655 .name_prefix = "Right", 656 }, 657 }; 658 659 static const struct snd_kcontrol_new mt8183_da7219_rt1015_snd_controls[] = { 660 SOC_DAPM_PIN_SWITCH("Left Spk"), 661 SOC_DAPM_PIN_SWITCH("Right Spk"), 662 }; 663 664 static const 665 struct snd_soc_dapm_widget mt8183_da7219_rt1015_dapm_widgets[] = { 666 SND_SOC_DAPM_SPK("Left Spk", NULL), 667 SND_SOC_DAPM_SPK("Right Spk", NULL), 668 SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL", 669 "aud_tdm_out_on", "aud_tdm_out_off"), 670 }; 671 672 static const struct snd_soc_dapm_route mt8183_da7219_rt1015_dapm_routes[] = { 673 {"Left Spk", NULL, "Left SPO"}, 674 {"Right Spk", NULL, "Right SPO"}, 675 {"I2S Playback", NULL, "TDM_OUT_PINCTRL"}, 676 }; 677 678 static struct snd_soc_card mt8183_da7219_rt1015_card = { 679 .name = "mt8183_da7219_rt1015", 680 .owner = THIS_MODULE, 681 .controls = mt8183_da7219_rt1015_snd_controls, 682 .num_controls = ARRAY_SIZE(mt8183_da7219_rt1015_snd_controls), 683 .dapm_widgets = mt8183_da7219_rt1015_dapm_widgets, 684 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_widgets), 685 .dapm_routes = mt8183_da7219_rt1015_dapm_routes, 686 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_routes), 687 .dai_link = mt8183_da7219_dai_links, 688 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 689 .aux_dev = &mt8183_da7219_max98357_headset_dev, 690 .num_aux_devs = 1, 691 .codec_conf = mt8183_da7219_rt1015_codec_conf, 692 .num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf), 693 }; 694 695 static struct snd_soc_card mt8183_da7219_rt1015p_card = { 696 .name = "mt8183_da7219_rt1015p", 697 .owner = THIS_MODULE, 698 .controls = mt8183_da7219_max98357_snd_controls, 699 .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls), 700 .dapm_widgets = mt8183_da7219_max98357_dapm_widgets, 701 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets), 702 .dapm_routes = mt8183_da7219_max98357_dapm_routes, 703 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes), 704 .dai_link = mt8183_da7219_dai_links, 705 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 706 .aux_dev = &mt8183_da7219_max98357_headset_dev, 707 .num_aux_devs = 1, 708 .codec_conf = mt6358_codec_conf, 709 .num_configs = ARRAY_SIZE(mt6358_codec_conf), 710 }; 711 712 static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev) 713 { 714 struct snd_soc_card *card; 715 struct device_node *platform_node, *hdmi_codec; 716 struct snd_soc_dai_link *dai_link; 717 struct mt8183_da7219_max98357_priv *priv; 718 struct pinctrl *pinctrl; 719 int ret, i; 720 721 platform_node = of_parse_phandle(pdev->dev.of_node, 722 "mediatek,platform", 0); 723 if (!platform_node) { 724 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n"); 725 return -EINVAL; 726 } 727 728 card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev); 729 if (!card) { 730 ret = -EINVAL; 731 goto put_platform_node; 732 } 733 734 card->dev = &pdev->dev; 735 736 hdmi_codec = of_parse_phandle(pdev->dev.of_node, 737 "mediatek,hdmi-codec", 0); 738 739 for_each_card_prelinks(card, i, dai_link) { 740 if (strcmp(dai_link->name, "I2S3") == 0) { 741 if (card == &mt8183_da7219_max98357_card) { 742 dai_link->be_hw_params_fixup = 743 mt8183_i2s_hw_params_fixup; 744 dai_link->ops = &mt8183_da7219_i2s_ops; 745 dai_link->cpus = i2s3_max98357a_cpus; 746 dai_link->num_cpus = 747 ARRAY_SIZE(i2s3_max98357a_cpus); 748 dai_link->codecs = i2s3_max98357a_codecs; 749 dai_link->num_codecs = 750 ARRAY_SIZE(i2s3_max98357a_codecs); 751 dai_link->platforms = i2s3_max98357a_platforms; 752 dai_link->num_platforms = 753 ARRAY_SIZE(i2s3_max98357a_platforms); 754 } else if (card == &mt8183_da7219_rt1015_card) { 755 dai_link->be_hw_params_fixup = 756 mt8183_rt1015_i2s_hw_params_fixup; 757 dai_link->ops = &mt8183_da7219_rt1015_i2s_ops; 758 dai_link->cpus = i2s3_rt1015_cpus; 759 dai_link->num_cpus = 760 ARRAY_SIZE(i2s3_rt1015_cpus); 761 dai_link->codecs = i2s3_rt1015_codecs; 762 dai_link->num_codecs = 763 ARRAY_SIZE(i2s3_rt1015_codecs); 764 dai_link->platforms = i2s3_rt1015_platforms; 765 dai_link->num_platforms = 766 ARRAY_SIZE(i2s3_rt1015_platforms); 767 } else if (card == &mt8183_da7219_rt1015p_card) { 768 dai_link->be_hw_params_fixup = 769 mt8183_rt1015_i2s_hw_params_fixup; 770 dai_link->ops = &mt8183_da7219_i2s_ops; 771 dai_link->cpus = i2s3_rt1015p_cpus; 772 dai_link->num_cpus = 773 ARRAY_SIZE(i2s3_rt1015p_cpus); 774 dai_link->codecs = i2s3_rt1015p_codecs; 775 dai_link->num_codecs = 776 ARRAY_SIZE(i2s3_rt1015p_codecs); 777 dai_link->platforms = i2s3_rt1015p_platforms; 778 dai_link->num_platforms = 779 ARRAY_SIZE(i2s3_rt1015p_platforms); 780 } 781 } 782 783 if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) { 784 dai_link->codecs->of_node = hdmi_codec; 785 dai_link->ignore = 0; 786 } 787 788 if (!dai_link->platforms->name) 789 dai_link->platforms->of_node = platform_node; 790 } 791 792 mt8183_da7219_max98357_headset_dev.dlc.of_node = 793 of_parse_phandle(pdev->dev.of_node, 794 "mediatek,headset-codec", 0); 795 if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) { 796 dev_err(&pdev->dev, 797 "Property 'mediatek,headset-codec' missing/invalid\n"); 798 ret = -EINVAL; 799 goto put_hdmi_codec; 800 } 801 802 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 803 if (!priv) { 804 ret = -ENOMEM; 805 goto put_hdmi_codec; 806 } 807 808 snd_soc_card_set_drvdata(card, priv); 809 810 pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT); 811 if (IS_ERR(pinctrl)) { 812 ret = PTR_ERR(pinctrl); 813 dev_err(&pdev->dev, "%s failed to select default state %d\n", 814 __func__, ret); 815 goto put_hdmi_codec; 816 } 817 818 ret = devm_snd_soc_register_card(&pdev->dev, card); 819 820 821 put_hdmi_codec: 822 of_node_put(hdmi_codec); 823 put_platform_node: 824 of_node_put(platform_node); 825 return ret; 826 } 827 828 #ifdef CONFIG_OF 829 static const struct of_device_id mt8183_da7219_max98357_dt_match[] = { 830 { 831 .compatible = "mediatek,mt8183_da7219_max98357", 832 .data = &mt8183_da7219_max98357_card, 833 }, 834 { 835 .compatible = "mediatek,mt8183_da7219_rt1015", 836 .data = &mt8183_da7219_rt1015_card, 837 }, 838 { 839 .compatible = "mediatek,mt8183_da7219_rt1015p", 840 .data = &mt8183_da7219_rt1015p_card, 841 }, 842 {} 843 }; 844 MODULE_DEVICE_TABLE(of, mt8183_da7219_max98357_dt_match); 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