mt8183-da7219-max98357.c (23041B)
1// SPDX-License-Identifier: GPL-2.0 2// 3// mt8183-da7219-max98357.c 4// -- MT8183-DA7219-MAX98357 ALSA SoC machine driver 5// 6// Copyright (c) 2018 MediaTek Inc. 7// Author: Shunli Wang <shunli.wang@mediatek.com> 8 9#include <linux/input.h> 10#include <linux/module.h> 11#include <linux/of_device.h> 12#include <linux/pinctrl/consumer.h> 13#include <sound/jack.h> 14#include <sound/pcm_params.h> 15#include <sound/soc.h> 16 17#include "../../codecs/da7219-aad.h" 18#include "../../codecs/da7219.h" 19#include "../../codecs/rt1015.h" 20#include "mt8183-afe-common.h" 21 22#define DA7219_CODEC_DAI "da7219-hifi" 23#define DA7219_DEV_NAME "da7219.5-001a" 24#define RT1015_CODEC_DAI "rt1015-aif" 25#define RT1015_DEV0_NAME "rt1015.6-0028" 26#define RT1015_DEV1_NAME "rt1015.6-0029" 27 28struct mt8183_da7219_max98357_priv { 29 struct snd_soc_jack headset_jack, hdmi_jack; 30}; 31 32static 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 44static const struct snd_soc_ops mt8183_mt6358_i2s_ops = { 45 .hw_params = mt8183_mt6358_i2s_hw_params, 46}; 47 48static 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 90static 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 111static 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 116static int 117mt8183_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 150static 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 155static 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 167static 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 179static int 180mt8183_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 215static const struct snd_soc_ops mt8183_da7219_max98357_ops = { 216 .startup = mt8183_da7219_max98357_startup, 217}; 218 219static int 220mt8183_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 255static const struct snd_soc_ops mt8183_da7219_max98357_bt_sco_ops = { 256 .startup = mt8183_da7219_max98357_bt_sco_startup, 257}; 258 259/* FE */ 260SND_SOC_DAILINK_DEFS(playback1, 261 DAILINK_COMP_ARRAY(COMP_CPU("DL1")), 262 DAILINK_COMP_ARRAY(COMP_DUMMY()), 263 DAILINK_COMP_ARRAY(COMP_EMPTY())); 264 265SND_SOC_DAILINK_DEFS(playback2, 266 DAILINK_COMP_ARRAY(COMP_CPU("DL2")), 267 DAILINK_COMP_ARRAY(COMP_DUMMY()), 268 DAILINK_COMP_ARRAY(COMP_EMPTY())); 269 270SND_SOC_DAILINK_DEFS(playback3, 271 DAILINK_COMP_ARRAY(COMP_CPU("DL3")), 272 DAILINK_COMP_ARRAY(COMP_DUMMY()), 273 DAILINK_COMP_ARRAY(COMP_EMPTY())); 274 275SND_SOC_DAILINK_DEFS(capture1, 276 DAILINK_COMP_ARRAY(COMP_CPU("UL1")), 277 DAILINK_COMP_ARRAY(COMP_DUMMY()), 278 DAILINK_COMP_ARRAY(COMP_EMPTY())); 279 280SND_SOC_DAILINK_DEFS(capture2, 281 DAILINK_COMP_ARRAY(COMP_CPU("UL2")), 282 DAILINK_COMP_ARRAY(COMP_DUMMY()), 283 DAILINK_COMP_ARRAY(COMP_EMPTY())); 284 285SND_SOC_DAILINK_DEFS(capture3, 286 DAILINK_COMP_ARRAY(COMP_CPU("UL3")), 287 DAILINK_COMP_ARRAY(COMP_DUMMY()), 288 DAILINK_COMP_ARRAY(COMP_EMPTY())); 289 290SND_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 295SND_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 */ 301SND_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 306SND_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 311SND_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 316SND_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 321SND_SOC_DAILINK_DEFS(i2s1, 322 DAILINK_COMP_ARRAY(COMP_CPU("I2S1")), 323 DAILINK_COMP_ARRAY(COMP_DUMMY()), 324 DAILINK_COMP_ARRAY(COMP_EMPTY())); 325 326SND_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 331SND_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 337SND_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 344SND_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 350SND_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 355SND_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 360static 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 375static struct snd_soc_dai_link mt8183_da7219_dai_links[] = { 376 /* FE */ 377 { 378 .name = "Playback_1", 379 .stream_name = "Playback_1", 380 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 381 SND_SOC_DPCM_TRIGGER_PRE}, 382 .dynamic = 1, 383 .dpcm_playback = 1, 384 .ops = &mt8183_da7219_max98357_ops, 385 SND_SOC_DAILINK_REG(playback1), 386 }, 387 { 388 .name = "Playback_2", 389 .stream_name = "Playback_2", 390 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 391 SND_SOC_DPCM_TRIGGER_PRE}, 392 .dynamic = 1, 393 .dpcm_playback = 1, 394 .ops = &mt8183_da7219_max98357_bt_sco_ops, 395 SND_SOC_DAILINK_REG(playback2), 396 }, 397 { 398 .name = "Playback_3", 399 .stream_name = "Playback_3", 400 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 401 SND_SOC_DPCM_TRIGGER_PRE}, 402 .dynamic = 1, 403 .dpcm_playback = 1, 404 SND_SOC_DAILINK_REG(playback3), 405 }, 406 { 407 .name = "Capture_1", 408 .stream_name = "Capture_1", 409 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 410 SND_SOC_DPCM_TRIGGER_PRE}, 411 .dynamic = 1, 412 .dpcm_capture = 1, 413 .ops = &mt8183_da7219_max98357_bt_sco_ops, 414 SND_SOC_DAILINK_REG(capture1), 415 }, 416 { 417 .name = "Capture_2", 418 .stream_name = "Capture_2", 419 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 420 SND_SOC_DPCM_TRIGGER_PRE}, 421 .dynamic = 1, 422 .dpcm_capture = 1, 423 SND_SOC_DAILINK_REG(capture2), 424 }, 425 { 426 .name = "Capture_3", 427 .stream_name = "Capture_3", 428 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 429 SND_SOC_DPCM_TRIGGER_PRE}, 430 .dynamic = 1, 431 .dpcm_capture = 1, 432 .ops = &mt8183_da7219_max98357_ops, 433 SND_SOC_DAILINK_REG(capture3), 434 }, 435 { 436 .name = "Capture_Mono_1", 437 .stream_name = "Capture_Mono_1", 438 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 439 SND_SOC_DPCM_TRIGGER_PRE}, 440 .dynamic = 1, 441 .dpcm_capture = 1, 442 SND_SOC_DAILINK_REG(capture_mono), 443 }, 444 { 445 .name = "Playback_HDMI", 446 .stream_name = "Playback_HDMI", 447 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 448 SND_SOC_DPCM_TRIGGER_PRE}, 449 .dynamic = 1, 450 .dpcm_playback = 1, 451 SND_SOC_DAILINK_REG(playback_hdmi), 452 }, 453 /* BE */ 454 { 455 .name = "Primary Codec", 456 .no_pcm = 1, 457 .dpcm_playback = 1, 458 .dpcm_capture = 1, 459 .ignore_suspend = 1, 460 SND_SOC_DAILINK_REG(primary_codec), 461 }, 462 { 463 .name = "PCM 1", 464 .no_pcm = 1, 465 .dpcm_playback = 1, 466 .dpcm_capture = 1, 467 .ignore_suspend = 1, 468 SND_SOC_DAILINK_REG(pcm1), 469 }, 470 { 471 .name = "PCM 2", 472 .no_pcm = 1, 473 .dpcm_playback = 1, 474 .dpcm_capture = 1, 475 .ignore_suspend = 1, 476 SND_SOC_DAILINK_REG(pcm2), 477 }, 478 { 479 .name = "I2S0", 480 .no_pcm = 1, 481 .dpcm_capture = 1, 482 .ignore_suspend = 1, 483 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 484 .ops = &mt8183_mt6358_i2s_ops, 485 SND_SOC_DAILINK_REG(i2s0), 486 }, 487 { 488 .name = "I2S1", 489 .no_pcm = 1, 490 .dpcm_playback = 1, 491 .ignore_suspend = 1, 492 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 493 .ops = &mt8183_mt6358_i2s_ops, 494 SND_SOC_DAILINK_REG(i2s1), 495 }, 496 { 497 .name = "I2S2", 498 .no_pcm = 1, 499 .dpcm_capture = 1, 500 .ignore_suspend = 1, 501 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 502 .ops = &mt8183_da7219_i2s_ops, 503 SND_SOC_DAILINK_REG(i2s2), 504 }, 505 { 506 .name = "I2S3", 507 .no_pcm = 1, 508 .dpcm_playback = 1, 509 .ignore_suspend = 1, 510 }, 511 { 512 .name = "I2S5", 513 .no_pcm = 1, 514 .dpcm_playback = 1, 515 .ignore_suspend = 1, 516 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 517 .ops = &mt8183_mt6358_i2s_ops, 518 SND_SOC_DAILINK_REG(i2s5), 519 }, 520 { 521 .name = "TDM", 522 .no_pcm = 1, 523 .dai_fmt = SND_SOC_DAIFMT_I2S | 524 SND_SOC_DAIFMT_IB_IF | 525 SND_SOC_DAIFMT_CBM_CFM, 526 .dpcm_playback = 1, 527 .ignore_suspend = 1, 528 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 529 .ignore = 1, 530 .init = mt8183_da7219_max98357_hdmi_init, 531 SND_SOC_DAILINK_REG(tdm), 532 }, 533}; 534 535static int 536mt8183_da7219_max98357_headset_init(struct snd_soc_component *component) 537{ 538 int ret; 539 struct mt8183_da7219_max98357_priv *priv = 540 snd_soc_card_get_drvdata(component->card); 541 542 /* Enable Headset and 4 Buttons Jack detection */ 543 ret = snd_soc_card_jack_new(component->card, 544 "Headset Jack", 545 SND_JACK_HEADSET | 546 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 547 SND_JACK_BTN_2 | SND_JACK_BTN_3 | 548 SND_JACK_LINEOUT, 549 &priv->headset_jack); 550 if (ret) 551 return ret; 552 553 snd_jack_set_key( 554 priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 555 snd_jack_set_key( 556 priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); 557 snd_jack_set_key( 558 priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); 559 snd_jack_set_key( 560 priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); 561 562 da7219_aad_jack_det(component, &priv->headset_jack); 563 564 return 0; 565} 566 567static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = { 568 .dlc = COMP_EMPTY(), 569 .init = mt8183_da7219_max98357_headset_init, 570}; 571 572static struct snd_soc_codec_conf mt6358_codec_conf[] = { 573 { 574 .dlc = COMP_CODEC_CONF("mt6358-sound"), 575 .name_prefix = "Mt6358", 576 }, 577}; 578 579static const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = { 580 SOC_DAPM_PIN_SWITCH("Speakers"), 581}; 582 583static const 584struct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = { 585 SND_SOC_DAPM_SPK("Speakers", NULL), 586 SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL", 587 "aud_tdm_out_on", "aud_tdm_out_off"), 588}; 589 590static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = { 591 {"Speakers", NULL, "Speaker"}, 592 {"I2S Playback", NULL, "TDM_OUT_PINCTRL"}, 593}; 594 595static struct snd_soc_card mt8183_da7219_max98357_card = { 596 .name = "mt8183_da7219_max98357", 597 .owner = THIS_MODULE, 598 .controls = mt8183_da7219_max98357_snd_controls, 599 .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls), 600 .dapm_widgets = mt8183_da7219_max98357_dapm_widgets, 601 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets), 602 .dapm_routes = mt8183_da7219_max98357_dapm_routes, 603 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes), 604 .dai_link = mt8183_da7219_dai_links, 605 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 606 .aux_dev = &mt8183_da7219_max98357_headset_dev, 607 .num_aux_devs = 1, 608 .codec_conf = mt6358_codec_conf, 609 .num_configs = ARRAY_SIZE(mt6358_codec_conf), 610}; 611 612static struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = { 613 { 614 .dlc = COMP_CODEC_CONF("mt6358-sound"), 615 .name_prefix = "Mt6358", 616 }, 617 { 618 .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME), 619 .name_prefix = "Left", 620 }, 621 { 622 .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME), 623 .name_prefix = "Right", 624 }, 625}; 626 627static const struct snd_kcontrol_new mt8183_da7219_rt1015_snd_controls[] = { 628 SOC_DAPM_PIN_SWITCH("Left Spk"), 629 SOC_DAPM_PIN_SWITCH("Right Spk"), 630}; 631 632static const 633struct snd_soc_dapm_widget mt8183_da7219_rt1015_dapm_widgets[] = { 634 SND_SOC_DAPM_SPK("Left Spk", NULL), 635 SND_SOC_DAPM_SPK("Right Spk", NULL), 636 SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL", 637 "aud_tdm_out_on", "aud_tdm_out_off"), 638}; 639 640static const struct snd_soc_dapm_route mt8183_da7219_rt1015_dapm_routes[] = { 641 {"Left Spk", NULL, "Left SPO"}, 642 {"Right Spk", NULL, "Right SPO"}, 643 {"I2S Playback", NULL, "TDM_OUT_PINCTRL"}, 644}; 645 646static struct snd_soc_card mt8183_da7219_rt1015_card = { 647 .name = "mt8183_da7219_rt1015", 648 .owner = THIS_MODULE, 649 .controls = mt8183_da7219_rt1015_snd_controls, 650 .num_controls = ARRAY_SIZE(mt8183_da7219_rt1015_snd_controls), 651 .dapm_widgets = mt8183_da7219_rt1015_dapm_widgets, 652 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_widgets), 653 .dapm_routes = mt8183_da7219_rt1015_dapm_routes, 654 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_routes), 655 .dai_link = mt8183_da7219_dai_links, 656 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 657 .aux_dev = &mt8183_da7219_max98357_headset_dev, 658 .num_aux_devs = 1, 659 .codec_conf = mt8183_da7219_rt1015_codec_conf, 660 .num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf), 661}; 662 663static struct snd_soc_card mt8183_da7219_rt1015p_card = { 664 .name = "mt8183_da7219_rt1015p", 665 .owner = THIS_MODULE, 666 .controls = mt8183_da7219_max98357_snd_controls, 667 .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls), 668 .dapm_widgets = mt8183_da7219_max98357_dapm_widgets, 669 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets), 670 .dapm_routes = mt8183_da7219_max98357_dapm_routes, 671 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes), 672 .dai_link = mt8183_da7219_dai_links, 673 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 674 .aux_dev = &mt8183_da7219_max98357_headset_dev, 675 .num_aux_devs = 1, 676 .codec_conf = mt6358_codec_conf, 677 .num_configs = ARRAY_SIZE(mt6358_codec_conf), 678}; 679 680static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev) 681{ 682 struct snd_soc_card *card; 683 struct device_node *platform_node, *hdmi_codec; 684 struct snd_soc_dai_link *dai_link; 685 struct mt8183_da7219_max98357_priv *priv; 686 struct pinctrl *pinctrl; 687 int ret, i; 688 689 platform_node = of_parse_phandle(pdev->dev.of_node, 690 "mediatek,platform", 0); 691 if (!platform_node) { 692 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n"); 693 return -EINVAL; 694 } 695 696 card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev); 697 if (!card) { 698 ret = -EINVAL; 699 goto put_platform_node; 700 } 701 702 card->dev = &pdev->dev; 703 704 hdmi_codec = of_parse_phandle(pdev->dev.of_node, 705 "mediatek,hdmi-codec", 0); 706 707 for_each_card_prelinks(card, i, dai_link) { 708 if (strcmp(dai_link->name, "I2S3") == 0) { 709 if (card == &mt8183_da7219_max98357_card) { 710 dai_link->be_hw_params_fixup = 711 mt8183_i2s_hw_params_fixup; 712 dai_link->ops = &mt8183_da7219_i2s_ops; 713 dai_link->cpus = i2s3_max98357a_cpus; 714 dai_link->num_cpus = 715 ARRAY_SIZE(i2s3_max98357a_cpus); 716 dai_link->codecs = i2s3_max98357a_codecs; 717 dai_link->num_codecs = 718 ARRAY_SIZE(i2s3_max98357a_codecs); 719 dai_link->platforms = i2s3_max98357a_platforms; 720 dai_link->num_platforms = 721 ARRAY_SIZE(i2s3_max98357a_platforms); 722 } else if (card == &mt8183_da7219_rt1015_card) { 723 dai_link->be_hw_params_fixup = 724 mt8183_rt1015_i2s_hw_params_fixup; 725 dai_link->ops = &mt8183_da7219_rt1015_i2s_ops; 726 dai_link->cpus = i2s3_rt1015_cpus; 727 dai_link->num_cpus = 728 ARRAY_SIZE(i2s3_rt1015_cpus); 729 dai_link->codecs = i2s3_rt1015_codecs; 730 dai_link->num_codecs = 731 ARRAY_SIZE(i2s3_rt1015_codecs); 732 dai_link->platforms = i2s3_rt1015_platforms; 733 dai_link->num_platforms = 734 ARRAY_SIZE(i2s3_rt1015_platforms); 735 } else if (card == &mt8183_da7219_rt1015p_card) { 736 dai_link->be_hw_params_fixup = 737 mt8183_rt1015_i2s_hw_params_fixup; 738 dai_link->ops = &mt8183_da7219_i2s_ops; 739 dai_link->cpus = i2s3_rt1015p_cpus; 740 dai_link->num_cpus = 741 ARRAY_SIZE(i2s3_rt1015p_cpus); 742 dai_link->codecs = i2s3_rt1015p_codecs; 743 dai_link->num_codecs = 744 ARRAY_SIZE(i2s3_rt1015p_codecs); 745 dai_link->platforms = i2s3_rt1015p_platforms; 746 dai_link->num_platforms = 747 ARRAY_SIZE(i2s3_rt1015p_platforms); 748 } 749 } 750 751 if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) { 752 dai_link->codecs->of_node = hdmi_codec; 753 dai_link->ignore = 0; 754 } 755 756 if (!dai_link->platforms->name) 757 dai_link->platforms->of_node = platform_node; 758 } 759 760 mt8183_da7219_max98357_headset_dev.dlc.of_node = 761 of_parse_phandle(pdev->dev.of_node, 762 "mediatek,headset-codec", 0); 763 if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) { 764 dev_err(&pdev->dev, 765 "Property 'mediatek,headset-codec' missing/invalid\n"); 766 ret = -EINVAL; 767 goto put_hdmi_codec; 768 } 769 770 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 771 if (!priv) { 772 ret = -ENOMEM; 773 goto put_hdmi_codec; 774 } 775 776 snd_soc_card_set_drvdata(card, priv); 777 778 pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT); 779 if (IS_ERR(pinctrl)) { 780 ret = PTR_ERR(pinctrl); 781 dev_err(&pdev->dev, "%s failed to select default state %d\n", 782 __func__, ret); 783 goto put_hdmi_codec; 784 } 785 786 ret = devm_snd_soc_register_card(&pdev->dev, card); 787 788 789put_hdmi_codec: 790 of_node_put(hdmi_codec); 791put_platform_node: 792 of_node_put(platform_node); 793 return ret; 794} 795 796#ifdef CONFIG_OF 797static const struct of_device_id mt8183_da7219_max98357_dt_match[] = { 798 { 799 .compatible = "mediatek,mt8183_da7219_max98357", 800 .data = &mt8183_da7219_max98357_card, 801 }, 802 { 803 .compatible = "mediatek,mt8183_da7219_rt1015", 804 .data = &mt8183_da7219_rt1015_card, 805 }, 806 { 807 .compatible = "mediatek,mt8183_da7219_rt1015p", 808 .data = &mt8183_da7219_rt1015p_card, 809 }, 810 {} 811}; 812#endif 813 814static struct platform_driver mt8183_da7219_max98357_driver = { 815 .driver = { 816 .name = "mt8183_da7219", 817#ifdef CONFIG_OF 818 .of_match_table = mt8183_da7219_max98357_dt_match, 819#endif 820 .pm = &snd_soc_pm_ops, 821 }, 822 .probe = mt8183_da7219_max98357_dev_probe, 823}; 824 825module_platform_driver(mt8183_da7219_max98357_driver); 826 827/* Module information */ 828MODULE_DESCRIPTION("MT8183-DA7219-MAX98357 ALSA SoC machine driver"); 829MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>"); 830MODULE_LICENSE("GPL v2"); 831MODULE_ALIAS("mt8183_da7219_max98357 soc card");