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 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 = asoc_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(asoc_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 = asoc_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(asoc_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 = asoc_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 = asoc_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(asoc_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 .dpcm_playback = 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 .dpcm_playback = 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 .dpcm_playback = 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 .dpcm_capture = 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 .dpcm_capture = 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 .dpcm_capture = 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 .dpcm_capture = 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 .dpcm_playback = 1, 496 SND_SOC_DAILINK_REG(playback_hdmi), 497 }, 498 /* BE */ 499 { 500 .name = "Primary Codec", 501 .no_pcm = 1, 502 .dpcm_playback = 1, 503 .dpcm_capture = 1, 504 .ignore_suspend = 1, 505 SND_SOC_DAILINK_REG(primary_codec), 506 }, 507 { 508 .name = "PCM 1", 509 .no_pcm = 1, 510 .dpcm_playback = 1, 511 .dpcm_capture = 1, 512 .ignore_suspend = 1, 513 SND_SOC_DAILINK_REG(pcm1), 514 }, 515 { 516 .name = "PCM 2", 517 .no_pcm = 1, 518 .dpcm_playback = 1, 519 .dpcm_capture = 1, 520 .ignore_suspend = 1, 521 SND_SOC_DAILINK_REG(pcm2), 522 }, 523 { 524 .name = "I2S0", 525 .no_pcm = 1, 526 .dpcm_capture = 1, 527 .ignore_suspend = 1, 528 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 529 .ops = &mt8183_mt6358_i2s_ops, 530 SND_SOC_DAILINK_REG(i2s0), 531 }, 532 { 533 .name = "I2S1", 534 .no_pcm = 1, 535 .dpcm_playback = 1, 536 .ignore_suspend = 1, 537 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 538 .ops = &mt8183_mt6358_i2s_ops, 539 SND_SOC_DAILINK_REG(i2s1), 540 }, 541 { 542 .name = "I2S2", 543 .no_pcm = 1, 544 .dpcm_capture = 1, 545 .ignore_suspend = 1, 546 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 547 .ops = &mt8183_da7219_i2s_ops, 548 .init = &mt8183_da7219_init, 549 SND_SOC_DAILINK_REG(i2s2), 550 }, 551 { 552 .name = "I2S3", 553 .no_pcm = 1, 554 .dpcm_playback = 1, 555 .ignore_suspend = 1, 556 }, 557 { 558 .name = "I2S5", 559 .no_pcm = 1, 560 .dpcm_playback = 1, 561 .ignore_suspend = 1, 562 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 563 .ops = &mt8183_mt6358_i2s_ops, 564 .init = &mt8183_bt_init, 565 SND_SOC_DAILINK_REG(i2s5), 566 }, 567 { 568 .name = "TDM", 569 .no_pcm = 1, 570 .dai_fmt = SND_SOC_DAIFMT_I2S | 571 SND_SOC_DAIFMT_IB_IF | 572 SND_SOC_DAIFMT_CBM_CFM, 573 .dpcm_playback = 1, 574 .ignore_suspend = 1, 575 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 576 .ignore = 1, 577 .init = mt8183_da7219_max98357_hdmi_init, 578 SND_SOC_DAILINK_REG(tdm), 579 }, 580 }; 581 582 static int 583 mt8183_da7219_max98357_headset_init(struct snd_soc_component *component) 584 { 585 int ret; 586 struct mt8183_da7219_max98357_priv *priv = 587 snd_soc_card_get_drvdata(component->card); 588 589 /* Enable Headset and 4 Buttons Jack detection */ 590 ret = snd_soc_card_jack_new_pins(component->card, 591 "Headset Jack", 592 SND_JACK_HEADSET | 593 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 594 SND_JACK_BTN_2 | SND_JACK_BTN_3 | 595 SND_JACK_LINEOUT, 596 &priv->headset_jack, 597 mt8183_da7219_max98357_jack_pins, 598 ARRAY_SIZE(mt8183_da7219_max98357_jack_pins)); 599 if (ret) 600 return ret; 601 602 snd_jack_set_key( 603 priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 604 snd_jack_set_key( 605 priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); 606 snd_jack_set_key( 607 priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); 608 snd_jack_set_key( 609 priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); 610 611 snd_soc_component_set_jack(component, &priv->headset_jack, NULL); 612 613 return 0; 614 } 615 616 static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = { 617 .dlc = COMP_EMPTY(), 618 .init = mt8183_da7219_max98357_headset_init, 619 }; 620 621 static struct snd_soc_codec_conf mt6358_codec_conf[] = { 622 { 623 .dlc = COMP_CODEC_CONF("mt6358-sound"), 624 .name_prefix = "Mt6358", 625 }, 626 }; 627 628 static const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = { 629 SOC_DAPM_PIN_SWITCH("Headphones"), 630 SOC_DAPM_PIN_SWITCH("Headset Mic"), 631 SOC_DAPM_PIN_SWITCH("Speakers"), 632 SOC_DAPM_PIN_SWITCH("Line Out"), 633 }; 634 635 static const 636 struct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = { 637 SND_SOC_DAPM_HP("Headphones", NULL), 638 SND_SOC_DAPM_MIC("Headset Mic", NULL), 639 SND_SOC_DAPM_SPK("Speakers", NULL), 640 SND_SOC_DAPM_SPK("Line Out", NULL), 641 SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL", 642 "aud_tdm_out_on", "aud_tdm_out_off"), 643 }; 644 645 static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = { 646 {"Speakers", NULL, "Speaker"}, 647 {"I2S Playback", NULL, "TDM_OUT_PINCTRL"}, 648 }; 649 650 static struct snd_soc_card mt8183_da7219_max98357_card = { 651 .name = "mt8183_da7219_max98357", 652 .owner = THIS_MODULE, 653 .controls = mt8183_da7219_max98357_snd_controls, 654 .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls), 655 .dapm_widgets = mt8183_da7219_max98357_dapm_widgets, 656 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets), 657 .dapm_routes = mt8183_da7219_max98357_dapm_routes, 658 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes), 659 .dai_link = mt8183_da7219_dai_links, 660 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 661 .aux_dev = &mt8183_da7219_max98357_headset_dev, 662 .num_aux_devs = 1, 663 .codec_conf = mt6358_codec_conf, 664 .num_configs = ARRAY_SIZE(mt6358_codec_conf), 665 }; 666 667 static struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = { 668 { 669 .dlc = COMP_CODEC_CONF("mt6358-sound"), 670 .name_prefix = "Mt6358", 671 }, 672 { 673 .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME), 674 .name_prefix = "Left", 675 }, 676 { 677 .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME), 678 .name_prefix = "Right", 679 }, 680 }; 681 682 static const struct snd_kcontrol_new mt8183_da7219_rt1015_snd_controls[] = { 683 SOC_DAPM_PIN_SWITCH("Headphones"), 684 SOC_DAPM_PIN_SWITCH("Headset Mic"), 685 SOC_DAPM_PIN_SWITCH("Left Spk"), 686 SOC_DAPM_PIN_SWITCH("Right Spk"), 687 SOC_DAPM_PIN_SWITCH("Line Out"), 688 }; 689 690 static const 691 struct snd_soc_dapm_widget mt8183_da7219_rt1015_dapm_widgets[] = { 692 SND_SOC_DAPM_HP("Headphones", NULL), 693 SND_SOC_DAPM_MIC("Headset Mic", NULL), 694 SND_SOC_DAPM_SPK("Left Spk", NULL), 695 SND_SOC_DAPM_SPK("Right Spk", NULL), 696 SND_SOC_DAPM_LINE("Line Out", NULL), 697 SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL", 698 "aud_tdm_out_on", "aud_tdm_out_off"), 699 }; 700 701 static const struct snd_soc_dapm_route mt8183_da7219_rt1015_dapm_routes[] = { 702 {"Left Spk", NULL, "Left SPO"}, 703 {"Right Spk", NULL, "Right SPO"}, 704 {"I2S Playback", NULL, "TDM_OUT_PINCTRL"}, 705 }; 706 707 static struct snd_soc_card mt8183_da7219_rt1015_card = { 708 .name = "mt8183_da7219_rt1015", 709 .owner = THIS_MODULE, 710 .controls = mt8183_da7219_rt1015_snd_controls, 711 .num_controls = ARRAY_SIZE(mt8183_da7219_rt1015_snd_controls), 712 .dapm_widgets = mt8183_da7219_rt1015_dapm_widgets, 713 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_widgets), 714 .dapm_routes = mt8183_da7219_rt1015_dapm_routes, 715 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_routes), 716 .dai_link = mt8183_da7219_dai_links, 717 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 718 .aux_dev = &mt8183_da7219_max98357_headset_dev, 719 .num_aux_devs = 1, 720 .codec_conf = mt8183_da7219_rt1015_codec_conf, 721 .num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf), 722 }; 723 724 static struct snd_soc_card mt8183_da7219_rt1015p_card = { 725 .name = "mt8183_da7219_rt1015p", 726 .owner = THIS_MODULE, 727 .controls = mt8183_da7219_max98357_snd_controls, 728 .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls), 729 .dapm_widgets = mt8183_da7219_max98357_dapm_widgets, 730 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets), 731 .dapm_routes = mt8183_da7219_max98357_dapm_routes, 732 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes), 733 .dai_link = mt8183_da7219_dai_links, 734 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 735 .aux_dev = &mt8183_da7219_max98357_headset_dev, 736 .num_aux_devs = 1, 737 .codec_conf = mt6358_codec_conf, 738 .num_configs = ARRAY_SIZE(mt6358_codec_conf), 739 }; 740 741 static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev) 742 { 743 struct snd_soc_card *card; 744 struct device_node *platform_node, *hdmi_codec; 745 struct snd_soc_dai_link *dai_link; 746 struct mt8183_da7219_max98357_priv *priv; 747 struct pinctrl *pinctrl; 748 int ret, i; 749 750 platform_node = of_parse_phandle(pdev->dev.of_node, 751 "mediatek,platform", 0); 752 if (!platform_node) { 753 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n"); 754 return -EINVAL; 755 } 756 757 card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev); 758 if (!card) { 759 ret = -EINVAL; 760 goto put_platform_node; 761 } 762 763 card->dev = &pdev->dev; 764 765 hdmi_codec = of_parse_phandle(pdev->dev.of_node, 766 "mediatek,hdmi-codec", 0); 767 768 for_each_card_prelinks(card, i, dai_link) { 769 if (strcmp(dai_link->name, "I2S3") == 0) { 770 if (card == &mt8183_da7219_max98357_card) { 771 dai_link->be_hw_params_fixup = 772 mt8183_i2s_hw_params_fixup; 773 dai_link->ops = &mt8183_da7219_i2s_ops; 774 dai_link->cpus = i2s3_max98357a_cpus; 775 dai_link->num_cpus = 776 ARRAY_SIZE(i2s3_max98357a_cpus); 777 dai_link->codecs = i2s3_max98357a_codecs; 778 dai_link->num_codecs = 779 ARRAY_SIZE(i2s3_max98357a_codecs); 780 dai_link->platforms = i2s3_max98357a_platforms; 781 dai_link->num_platforms = 782 ARRAY_SIZE(i2s3_max98357a_platforms); 783 } else if (card == &mt8183_da7219_rt1015_card) { 784 dai_link->be_hw_params_fixup = 785 mt8183_rt1015_i2s_hw_params_fixup; 786 dai_link->ops = &mt8183_da7219_rt1015_i2s_ops; 787 dai_link->cpus = i2s3_rt1015_cpus; 788 dai_link->num_cpus = 789 ARRAY_SIZE(i2s3_rt1015_cpus); 790 dai_link->codecs = i2s3_rt1015_codecs; 791 dai_link->num_codecs = 792 ARRAY_SIZE(i2s3_rt1015_codecs); 793 dai_link->platforms = i2s3_rt1015_platforms; 794 dai_link->num_platforms = 795 ARRAY_SIZE(i2s3_rt1015_platforms); 796 } else if (card == &mt8183_da7219_rt1015p_card) { 797 dai_link->be_hw_params_fixup = 798 mt8183_rt1015_i2s_hw_params_fixup; 799 dai_link->ops = &mt8183_da7219_i2s_ops; 800 dai_link->cpus = i2s3_rt1015p_cpus; 801 dai_link->num_cpus = 802 ARRAY_SIZE(i2s3_rt1015p_cpus); 803 dai_link->codecs = i2s3_rt1015p_codecs; 804 dai_link->num_codecs = 805 ARRAY_SIZE(i2s3_rt1015p_codecs); 806 dai_link->platforms = i2s3_rt1015p_platforms; 807 dai_link->num_platforms = 808 ARRAY_SIZE(i2s3_rt1015p_platforms); 809 } 810 } 811 812 if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) { 813 dai_link->codecs->of_node = hdmi_codec; 814 dai_link->ignore = 0; 815 } 816 817 if (!dai_link->platforms->name) 818 dai_link->platforms->of_node = platform_node; 819 } 820 821 mt8183_da7219_max98357_headset_dev.dlc.of_node = 822 of_parse_phandle(pdev->dev.of_node, 823 "mediatek,headset-codec", 0); 824 if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) { 825 dev_err(&pdev->dev, 826 "Property 'mediatek,headset-codec' missing/invalid\n"); 827 ret = -EINVAL; 828 goto put_hdmi_codec; 829 } 830 831 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 832 if (!priv) { 833 ret = -ENOMEM; 834 goto put_hdmi_codec; 835 } 836 837 snd_soc_card_set_drvdata(card, priv); 838 839 pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT); 840 if (IS_ERR(pinctrl)) { 841 ret = PTR_ERR(pinctrl); 842 dev_err(&pdev->dev, "%s failed to select default state %d\n", 843 __func__, ret); 844 goto put_hdmi_codec; 845 } 846 847 ret = devm_snd_soc_register_card(&pdev->dev, card); 848 849 850 put_hdmi_codec: 851 of_node_put(hdmi_codec); 852 put_platform_node: 853 of_node_put(platform_node); 854 return ret; 855 } 856 857 #ifdef CONFIG_OF 858 static const struct of_device_id mt8183_da7219_max98357_dt_match[] = { 859 { 860 .compatible = "mediatek,mt8183_da7219_max98357", 861 .data = &mt8183_da7219_max98357_card, 862 }, 863 { 864 .compatible = "mediatek,mt8183_da7219_rt1015", 865 .data = &mt8183_da7219_rt1015_card, 866 }, 867 { 868 .compatible = "mediatek,mt8183_da7219_rt1015p", 869 .data = &mt8183_da7219_rt1015p_card, 870 }, 871 {} 872 }; 873 MODULE_DEVICE_TABLE(of, mt8183_da7219_max98357_dt_match); 874 #endif 875 876 static struct platform_driver mt8183_da7219_max98357_driver = { 877 .driver = { 878 .name = "mt8183_da7219", 879 #ifdef CONFIG_OF 880 .of_match_table = mt8183_da7219_max98357_dt_match, 881 #endif 882 .pm = &snd_soc_pm_ops, 883 }, 884 .probe = mt8183_da7219_max98357_dev_probe, 885 }; 886 887 module_platform_driver(mt8183_da7219_max98357_driver); 888 889 /* Module information */ 890 MODULE_DESCRIPTION("MT8183-DA7219-MAX98357 ALSA SoC machine driver"); 891 MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>"); 892 MODULE_LICENSE("GPL v2"); 893 MODULE_ALIAS("mt8183_da7219_max98357 soc card"); 894