1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // mt8183-mt6358.c -- 4 // MT8183-MT6358-TS3A227-MAX98357 ALSA SoC machine driver 5 // 6 // Copyright (c) 2018 MediaTek Inc. 7 // Author: Shunli Wang <shunli.wang@mediatek.com> 8 9 #include <linux/module.h> 10 #include <sound/pcm_params.h> 11 #include <sound/soc.h> 12 #include <sound/jack.h> 13 #include <linux/pinctrl/consumer.h> 14 15 #include "mt8183-afe-common.h" 16 #include "../../codecs/ts3a227e.h" 17 18 enum PINCTRL_PIN_STATE { 19 PIN_STATE_DEFAULT = 0, 20 PIN_TDM_OUT_ON, 21 PIN_TDM_OUT_OFF, 22 PIN_WOV, 23 PIN_STATE_MAX 24 }; 25 26 static const char * const mt8183_pin_str[PIN_STATE_MAX] = { 27 "default", "aud_tdm_out_on", "aud_tdm_out_off", "wov", 28 }; 29 30 struct mt8183_mt6358_ts3a227_max98357_priv { 31 struct pinctrl *pinctrl; 32 struct pinctrl_state *pin_states[PIN_STATE_MAX]; 33 struct snd_soc_jack headset_jack; 34 }; 35 36 static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream, 37 struct snd_pcm_hw_params *params) 38 { 39 struct snd_soc_pcm_runtime *rtd = substream->private_data; 40 unsigned int rate = params_rate(params); 41 unsigned int mclk_fs_ratio = 128; 42 unsigned int mclk_fs = rate * mclk_fs_ratio; 43 44 return snd_soc_dai_set_sysclk(rtd->cpu_dai, 45 0, mclk_fs, SND_SOC_CLOCK_OUT); 46 } 47 48 static const struct snd_soc_ops mt8183_mt6358_i2s_ops = { 49 .hw_params = mt8183_mt6358_i2s_hw_params, 50 }; 51 52 static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 53 struct snd_pcm_hw_params *params) 54 { 55 dev_dbg(rtd->dev, "%s(), fix format to 32bit\n", __func__); 56 57 /* fix BE i2s format to 32bit, clean param mask first */ 58 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), 59 0, SNDRV_PCM_FORMAT_LAST); 60 61 params_set_format(params, SNDRV_PCM_FORMAT_S32_LE); 62 return 0; 63 } 64 65 static int 66 mt8183_mt6358_ts3a227_max98357_bt_sco_startup( 67 struct snd_pcm_substream *substream) 68 { 69 static const unsigned int rates[] = { 70 8000, 16000 71 }; 72 static const struct snd_pcm_hw_constraint_list constraints_rates = { 73 .count = ARRAY_SIZE(rates), 74 .list = rates, 75 .mask = 0, 76 }; 77 static const unsigned int channels[] = { 78 1, 79 }; 80 static const struct snd_pcm_hw_constraint_list constraints_channels = { 81 .count = ARRAY_SIZE(channels), 82 .list = channels, 83 .mask = 0, 84 }; 85 86 struct snd_pcm_runtime *runtime = substream->runtime; 87 88 snd_pcm_hw_constraint_list(runtime, 0, 89 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 90 runtime->hw.channels_max = 1; 91 snd_pcm_hw_constraint_list(runtime, 0, 92 SNDRV_PCM_HW_PARAM_CHANNELS, 93 &constraints_channels); 94 95 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; 96 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); 97 98 return 0; 99 } 100 101 static const struct snd_soc_ops mt8183_mt6358_ts3a227_max98357_bt_sco_ops = { 102 .startup = mt8183_mt6358_ts3a227_max98357_bt_sco_startup, 103 }; 104 105 /* FE */ 106 SND_SOC_DAILINK_DEFS(playback1, 107 DAILINK_COMP_ARRAY(COMP_CPU("DL1")), 108 DAILINK_COMP_ARRAY(COMP_DUMMY()), 109 DAILINK_COMP_ARRAY(COMP_EMPTY())); 110 111 SND_SOC_DAILINK_DEFS(playback2, 112 DAILINK_COMP_ARRAY(COMP_CPU("DL2")), 113 DAILINK_COMP_ARRAY(COMP_DUMMY()), 114 DAILINK_COMP_ARRAY(COMP_EMPTY())); 115 116 SND_SOC_DAILINK_DEFS(playback3, 117 DAILINK_COMP_ARRAY(COMP_CPU("DL3")), 118 DAILINK_COMP_ARRAY(COMP_DUMMY()), 119 DAILINK_COMP_ARRAY(COMP_EMPTY())); 120 121 SND_SOC_DAILINK_DEFS(capture1, 122 DAILINK_COMP_ARRAY(COMP_CPU("UL1")), 123 DAILINK_COMP_ARRAY(COMP_DUMMY()), 124 DAILINK_COMP_ARRAY(COMP_EMPTY())); 125 126 SND_SOC_DAILINK_DEFS(capture2, 127 DAILINK_COMP_ARRAY(COMP_CPU("UL2")), 128 DAILINK_COMP_ARRAY(COMP_DUMMY()), 129 DAILINK_COMP_ARRAY(COMP_EMPTY())); 130 131 SND_SOC_DAILINK_DEFS(capture3, 132 DAILINK_COMP_ARRAY(COMP_CPU("UL3")), 133 DAILINK_COMP_ARRAY(COMP_DUMMY()), 134 DAILINK_COMP_ARRAY(COMP_EMPTY())); 135 136 SND_SOC_DAILINK_DEFS(capture_mono, 137 DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")), 138 DAILINK_COMP_ARRAY(COMP_DUMMY()), 139 DAILINK_COMP_ARRAY(COMP_EMPTY())); 140 141 SND_SOC_DAILINK_DEFS(playback_hdmi, 142 DAILINK_COMP_ARRAY(COMP_CPU("HDMI")), 143 DAILINK_COMP_ARRAY(COMP_DUMMY()), 144 DAILINK_COMP_ARRAY(COMP_EMPTY())); 145 146 SND_SOC_DAILINK_DEFS(wake_on_voice, 147 DAILINK_COMP_ARRAY(COMP_DUMMY()), 148 DAILINK_COMP_ARRAY(COMP_DUMMY()), 149 DAILINK_COMP_ARRAY(COMP_EMPTY())); 150 151 /* BE */ 152 SND_SOC_DAILINK_DEFS(primary_codec, 153 DAILINK_COMP_ARRAY(COMP_CPU("ADDA")), 154 DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")), 155 DAILINK_COMP_ARRAY(COMP_EMPTY())); 156 157 SND_SOC_DAILINK_DEFS(pcm1, 158 DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")), 159 DAILINK_COMP_ARRAY(COMP_DUMMY()), 160 DAILINK_COMP_ARRAY(COMP_EMPTY())); 161 162 SND_SOC_DAILINK_DEFS(pcm2, 163 DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")), 164 DAILINK_COMP_ARRAY(COMP_DUMMY()), 165 DAILINK_COMP_ARRAY(COMP_EMPTY())); 166 167 SND_SOC_DAILINK_DEFS(i2s0, 168 DAILINK_COMP_ARRAY(COMP_CPU("I2S0")), 169 DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")), 170 DAILINK_COMP_ARRAY(COMP_EMPTY())); 171 172 SND_SOC_DAILINK_DEFS(i2s1, 173 DAILINK_COMP_ARRAY(COMP_CPU("I2S1")), 174 DAILINK_COMP_ARRAY(COMP_DUMMY()), 175 DAILINK_COMP_ARRAY(COMP_EMPTY())); 176 177 SND_SOC_DAILINK_DEFS(i2s2, 178 DAILINK_COMP_ARRAY(COMP_CPU("I2S2")), 179 DAILINK_COMP_ARRAY(COMP_DUMMY()), 180 DAILINK_COMP_ARRAY(COMP_EMPTY())); 181 182 SND_SOC_DAILINK_DEFS(i2s3, 183 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")), 184 DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi")), 185 DAILINK_COMP_ARRAY(COMP_EMPTY())); 186 187 SND_SOC_DAILINK_DEFS(i2s5, 188 DAILINK_COMP_ARRAY(COMP_CPU("I2S5")), 189 DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")), 190 DAILINK_COMP_ARRAY(COMP_EMPTY())); 191 192 SND_SOC_DAILINK_DEFS(tdm, 193 DAILINK_COMP_ARRAY(COMP_CPU("TDM")), 194 DAILINK_COMP_ARRAY(COMP_DUMMY()), 195 DAILINK_COMP_ARRAY(COMP_EMPTY())); 196 197 static int mt8183_mt6358_tdm_startup(struct snd_pcm_substream *substream) 198 { 199 struct snd_soc_pcm_runtime *rtd = substream->private_data; 200 struct mt8183_mt6358_ts3a227_max98357_priv *priv = 201 snd_soc_card_get_drvdata(rtd->card); 202 int ret; 203 204 if (IS_ERR(priv->pin_states[PIN_TDM_OUT_ON])) 205 return PTR_ERR(priv->pin_states[PIN_TDM_OUT_ON]); 206 207 ret = pinctrl_select_state(priv->pinctrl, 208 priv->pin_states[PIN_TDM_OUT_ON]); 209 if (ret) 210 dev_err(rtd->card->dev, "%s failed to select state %d\n", 211 __func__, ret); 212 213 return ret; 214 } 215 216 static void mt8183_mt6358_tdm_shutdown(struct snd_pcm_substream *substream) 217 { 218 struct snd_soc_pcm_runtime *rtd = substream->private_data; 219 struct mt8183_mt6358_ts3a227_max98357_priv *priv = 220 snd_soc_card_get_drvdata(rtd->card); 221 int ret; 222 223 if (IS_ERR(priv->pin_states[PIN_TDM_OUT_OFF])) 224 return; 225 226 ret = pinctrl_select_state(priv->pinctrl, 227 priv->pin_states[PIN_TDM_OUT_OFF]); 228 if (ret) 229 dev_err(rtd->card->dev, "%s failed to select state %d\n", 230 __func__, ret); 231 } 232 233 static struct snd_soc_ops mt8183_mt6358_tdm_ops = { 234 .startup = mt8183_mt6358_tdm_startup, 235 .shutdown = mt8183_mt6358_tdm_shutdown, 236 }; 237 238 static int 239 mt8183_mt6358_ts3a227_max98357_wov_startup( 240 struct snd_pcm_substream *substream) 241 { 242 struct snd_soc_pcm_runtime *rtd = substream->private_data; 243 struct snd_soc_card *card = rtd->card; 244 struct mt8183_mt6358_ts3a227_max98357_priv *priv = 245 snd_soc_card_get_drvdata(card); 246 247 return pinctrl_select_state(priv->pinctrl, 248 priv->pin_states[PIN_WOV]); 249 } 250 251 static void 252 mt8183_mt6358_ts3a227_max98357_wov_shutdown( 253 struct snd_pcm_substream *substream) 254 { 255 struct snd_soc_pcm_runtime *rtd = substream->private_data; 256 struct snd_soc_card *card = rtd->card; 257 struct mt8183_mt6358_ts3a227_max98357_priv *priv = 258 snd_soc_card_get_drvdata(card); 259 int ret; 260 261 ret = pinctrl_select_state(priv->pinctrl, 262 priv->pin_states[PIN_STATE_DEFAULT]); 263 if (ret) 264 dev_err(card->dev, "%s failed to select state %d\n", 265 __func__, ret); 266 } 267 268 static const struct snd_soc_ops mt8183_mt6358_ts3a227_max98357_wov_ops = { 269 .startup = mt8183_mt6358_ts3a227_max98357_wov_startup, 270 .shutdown = mt8183_mt6358_ts3a227_max98357_wov_shutdown, 271 }; 272 273 static struct snd_soc_dai_link 274 mt8183_mt6358_ts3a227_max98357_dai_links[] = { 275 /* FE */ 276 { 277 .name = "Playback_1", 278 .stream_name = "Playback_1", 279 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 280 SND_SOC_DPCM_TRIGGER_PRE}, 281 .dynamic = 1, 282 .dpcm_playback = 1, 283 SND_SOC_DAILINK_REG(playback1), 284 }, 285 { 286 .name = "Playback_2", 287 .stream_name = "Playback_2", 288 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 289 SND_SOC_DPCM_TRIGGER_PRE}, 290 .dynamic = 1, 291 .dpcm_playback = 1, 292 .ops = &mt8183_mt6358_ts3a227_max98357_bt_sco_ops, 293 SND_SOC_DAILINK_REG(playback2), 294 }, 295 { 296 .name = "Playback_3", 297 .stream_name = "Playback_3", 298 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 299 SND_SOC_DPCM_TRIGGER_PRE}, 300 .dynamic = 1, 301 .dpcm_playback = 1, 302 SND_SOC_DAILINK_REG(playback3), 303 }, 304 { 305 .name = "Capture_1", 306 .stream_name = "Capture_1", 307 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 308 SND_SOC_DPCM_TRIGGER_PRE}, 309 .dynamic = 1, 310 .dpcm_capture = 1, 311 .ops = &mt8183_mt6358_ts3a227_max98357_bt_sco_ops, 312 SND_SOC_DAILINK_REG(capture1), 313 }, 314 { 315 .name = "Capture_2", 316 .stream_name = "Capture_2", 317 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 318 SND_SOC_DPCM_TRIGGER_PRE}, 319 .dynamic = 1, 320 .dpcm_capture = 1, 321 SND_SOC_DAILINK_REG(capture2), 322 }, 323 { 324 .name = "Capture_3", 325 .stream_name = "Capture_3", 326 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 327 SND_SOC_DPCM_TRIGGER_PRE}, 328 .dynamic = 1, 329 .dpcm_capture = 1, 330 SND_SOC_DAILINK_REG(capture3), 331 }, 332 { 333 .name = "Capture_Mono_1", 334 .stream_name = "Capture_Mono_1", 335 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 336 SND_SOC_DPCM_TRIGGER_PRE}, 337 .dynamic = 1, 338 .dpcm_capture = 1, 339 SND_SOC_DAILINK_REG(capture_mono), 340 }, 341 { 342 .name = "Playback_HDMI", 343 .stream_name = "Playback_HDMI", 344 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 345 SND_SOC_DPCM_TRIGGER_PRE}, 346 .dynamic = 1, 347 .dpcm_playback = 1, 348 SND_SOC_DAILINK_REG(playback_hdmi), 349 }, 350 { 351 .name = "Wake on Voice", 352 .stream_name = "Wake on Voice", 353 .ignore_suspend = 1, 354 .ignore = 1, 355 SND_SOC_DAILINK_REG(wake_on_voice), 356 .ops = &mt8183_mt6358_ts3a227_max98357_wov_ops, 357 }, 358 359 /* BE */ 360 { 361 .name = "Primary Codec", 362 .no_pcm = 1, 363 .dpcm_playback = 1, 364 .dpcm_capture = 1, 365 .ignore_suspend = 1, 366 SND_SOC_DAILINK_REG(primary_codec), 367 }, 368 { 369 .name = "PCM 1", 370 .no_pcm = 1, 371 .dpcm_playback = 1, 372 .dpcm_capture = 1, 373 .ignore_suspend = 1, 374 SND_SOC_DAILINK_REG(pcm1), 375 }, 376 { 377 .name = "PCM 2", 378 .no_pcm = 1, 379 .dpcm_playback = 1, 380 .dpcm_capture = 1, 381 .ignore_suspend = 1, 382 SND_SOC_DAILINK_REG(pcm2), 383 }, 384 { 385 .name = "I2S0", 386 .no_pcm = 1, 387 .dpcm_capture = 1, 388 .ignore_suspend = 1, 389 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 390 .ops = &mt8183_mt6358_i2s_ops, 391 SND_SOC_DAILINK_REG(i2s0), 392 }, 393 { 394 .name = "I2S1", 395 .no_pcm = 1, 396 .dpcm_playback = 1, 397 .ignore_suspend = 1, 398 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 399 .ops = &mt8183_mt6358_i2s_ops, 400 SND_SOC_DAILINK_REG(i2s1), 401 }, 402 { 403 .name = "I2S2", 404 .no_pcm = 1, 405 .dpcm_capture = 1, 406 .ignore_suspend = 1, 407 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 408 .ops = &mt8183_mt6358_i2s_ops, 409 SND_SOC_DAILINK_REG(i2s2), 410 }, 411 { 412 .name = "I2S3", 413 .no_pcm = 1, 414 .dpcm_playback = 1, 415 .ignore_suspend = 1, 416 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 417 .ops = &mt8183_mt6358_i2s_ops, 418 SND_SOC_DAILINK_REG(i2s3), 419 }, 420 { 421 .name = "I2S5", 422 .no_pcm = 1, 423 .dpcm_playback = 1, 424 .ignore_suspend = 1, 425 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 426 .ops = &mt8183_mt6358_i2s_ops, 427 SND_SOC_DAILINK_REG(i2s5), 428 }, 429 { 430 .name = "TDM", 431 .no_pcm = 1, 432 .dai_fmt = SND_SOC_DAIFMT_I2S | 433 SND_SOC_DAIFMT_IB_IF | 434 SND_SOC_DAIFMT_CBM_CFM, 435 .dpcm_playback = 1, 436 .ignore_suspend = 1, 437 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 438 .ops = &mt8183_mt6358_tdm_ops, 439 SND_SOC_DAILINK_REG(tdm), 440 }, 441 }; 442 443 static struct snd_soc_card mt8183_mt6358_ts3a227_max98357_card = { 444 .name = "mt8183_mt6358_ts3a227_max98357", 445 .owner = THIS_MODULE, 446 .dai_link = mt8183_mt6358_ts3a227_max98357_dai_links, 447 .num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_dai_links), 448 }; 449 450 static int 451 mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *component) 452 { 453 int ret; 454 struct mt8183_mt6358_ts3a227_max98357_priv *priv = 455 snd_soc_card_get_drvdata(component->card); 456 457 /* Enable Headset and 4 Buttons Jack detection */ 458 ret = snd_soc_card_jack_new(&mt8183_mt6358_ts3a227_max98357_card, 459 "Headset Jack", 460 SND_JACK_HEADSET | 461 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 462 SND_JACK_BTN_2 | SND_JACK_BTN_3, 463 &priv->headset_jack, 464 NULL, 0); 465 if (ret) 466 return ret; 467 468 ret = ts3a227e_enable_jack_detect(component, &priv->headset_jack); 469 470 return ret; 471 } 472 473 static struct snd_soc_aux_dev mt8183_mt6358_ts3a227_max98357_headset_dev = { 474 .dlc = COMP_EMPTY(), 475 .init = mt8183_mt6358_ts3a227_max98357_headset_init, 476 }; 477 478 static int 479 mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) 480 { 481 struct snd_soc_card *card = &mt8183_mt6358_ts3a227_max98357_card; 482 struct device_node *platform_node, *ec_codec; 483 struct snd_soc_dai_link *dai_link; 484 struct mt8183_mt6358_ts3a227_max98357_priv *priv; 485 int ret; 486 int i; 487 488 card->dev = &pdev->dev; 489 490 platform_node = of_parse_phandle(pdev->dev.of_node, 491 "mediatek,platform", 0); 492 if (!platform_node) { 493 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n"); 494 return -EINVAL; 495 } 496 497 ec_codec = of_parse_phandle(pdev->dev.of_node, "mediatek,ec-codec", 0); 498 499 for_each_card_prelinks(card, i, dai_link) { 500 if (dai_link->platforms->name) 501 continue; 502 503 if (ec_codec && strcmp(dai_link->name, "Wake on Voice") == 0) { 504 dai_link->cpus[0].name = NULL; 505 dai_link->cpus[0].of_node = ec_codec; 506 dai_link->cpus[0].dai_name = NULL; 507 dai_link->codecs[0].name = NULL; 508 dai_link->codecs[0].of_node = ec_codec; 509 dai_link->codecs[0].dai_name = "Wake on Voice"; 510 dai_link->platforms[0].of_node = ec_codec; 511 dai_link->ignore = 0; 512 } else { 513 dai_link->platforms->of_node = platform_node; 514 } 515 } 516 517 mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node = 518 of_parse_phandle(pdev->dev.of_node, 519 "mediatek,headset-codec", 0); 520 if (mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node) { 521 card->aux_dev = &mt8183_mt6358_ts3a227_max98357_headset_dev; 522 card->num_aux_devs = 1; 523 } 524 525 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 526 if (!priv) 527 return -ENOMEM; 528 529 snd_soc_card_set_drvdata(card, priv); 530 531 priv->pinctrl = devm_pinctrl_get(&pdev->dev); 532 if (IS_ERR(priv->pinctrl)) { 533 dev_err(&pdev->dev, "%s devm_pinctrl_get failed\n", 534 __func__); 535 return PTR_ERR(priv->pinctrl); 536 } 537 538 for (i = 0; i < PIN_STATE_MAX; i++) { 539 priv->pin_states[i] = pinctrl_lookup_state(priv->pinctrl, 540 mt8183_pin_str[i]); 541 if (IS_ERR(priv->pin_states[i])) { 542 ret = PTR_ERR(priv->pin_states[i]); 543 dev_info(&pdev->dev, "%s Can't find pin state %s %d\n", 544 __func__, mt8183_pin_str[i], ret); 545 } 546 } 547 548 if (!IS_ERR(priv->pin_states[PIN_TDM_OUT_OFF])) { 549 ret = pinctrl_select_state(priv->pinctrl, 550 priv->pin_states[PIN_TDM_OUT_OFF]); 551 if (ret) 552 dev_info(&pdev->dev, 553 "%s failed to select state %d\n", 554 __func__, ret); 555 } 556 557 if (!IS_ERR(priv->pin_states[PIN_STATE_DEFAULT])) { 558 ret = pinctrl_select_state(priv->pinctrl, 559 priv->pin_states[PIN_STATE_DEFAULT]); 560 if (ret) 561 dev_info(&pdev->dev, 562 "%s failed to select state %d\n", 563 __func__, ret); 564 } 565 566 return devm_snd_soc_register_card(&pdev->dev, card); 567 } 568 569 #ifdef CONFIG_OF 570 static const struct of_device_id mt8183_mt6358_ts3a227_max98357_dt_match[] = { 571 {.compatible = "mediatek,mt8183_mt6358_ts3a227_max98357",}, 572 {} 573 }; 574 #endif 575 576 static struct platform_driver mt8183_mt6358_ts3a227_max98357_driver = { 577 .driver = { 578 .name = "mt8183_mt6358_ts3a227_max98357", 579 #ifdef CONFIG_OF 580 .of_match_table = mt8183_mt6358_ts3a227_max98357_dt_match, 581 #endif 582 }, 583 .probe = mt8183_mt6358_ts3a227_max98357_dev_probe, 584 }; 585 586 module_platform_driver(mt8183_mt6358_ts3a227_max98357_driver); 587 588 /* Module information */ 589 MODULE_DESCRIPTION("MT8183-MT6358-TS3A227-MAX98357 ALSA SoC machine driver"); 590 MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>"); 591 MODULE_LICENSE("GPL v2"); 592 MODULE_ALIAS("mt8183_mt6358_ts3a227_max98357 soc card"); 593