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