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