root/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mt8183_mt6358_i2s_hw_params
  2. mt8183_i2s_hw_params_fixup
  3. mt8183_mt6358_ts3a227_max98357_bt_sco_startup
  4. mt8183_mt6358_tdm_startup
  5. mt8183_mt6358_tdm_shutdown
  6. mt8183_mt6358_ts3a227_max98357_headset_init
  7. mt8183_mt6358_ts3a227_max98357_dev_probe

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

/* [<][>][^][v][top][bottom][index][help] */