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