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                .init = mt8183_mt6358_ts3a227_max98357_hdmi_init,
 519                SND_SOC_DAILINK_REG(tdm),
 520        },
 521};
 522
 523static struct snd_soc_card mt8183_mt6358_ts3a227_max98357_card = {
 524        .name = "mt8183_mt6358_ts3a227_max98357",
 525        .owner = THIS_MODULE,
 526        .dai_link = mt8183_mt6358_ts3a227_dai_links,
 527        .num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_dai_links),
 528};
 529
 530static struct snd_soc_card mt8183_mt6358_ts3a227_max98357b_card = {
 531        .name = "mt8183_mt6358_ts3a227_max98357b",
 532        .owner = THIS_MODULE,
 533        .dai_link = mt8183_mt6358_ts3a227_dai_links,
 534        .num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_dai_links),
 535};
 536
 537static struct snd_soc_codec_conf mt8183_mt6358_ts3a227_rt1015_amp_conf[] = {
 538        {
 539                .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME),
 540                .name_prefix = "Left",
 541        },
 542        {
 543                .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME),
 544                .name_prefix = "Right",
 545        },
 546};
 547
 548static struct snd_soc_card mt8183_mt6358_ts3a227_rt1015_card = {
 549        .name = "mt8183_mt6358_ts3a227_rt1015",
 550        .owner = THIS_MODULE,
 551        .dai_link = mt8183_mt6358_ts3a227_dai_links,
 552        .num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_dai_links),
 553        .codec_conf = mt8183_mt6358_ts3a227_rt1015_amp_conf,
 554        .num_configs = ARRAY_SIZE(mt8183_mt6358_ts3a227_rt1015_amp_conf),
 555};
 556
 557static int
 558mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *component)
 559{
 560        int ret;
 561        struct mt8183_mt6358_ts3a227_max98357_priv *priv =
 562                        snd_soc_card_get_drvdata(component->card);
 563
 564        /* Enable Headset and 4 Buttons Jack detection */
 565        ret = snd_soc_card_jack_new(component->card,
 566                                    "Headset Jack",
 567                                    SND_JACK_HEADSET |
 568                                    SND_JACK_BTN_0 | SND_JACK_BTN_1 |
 569                                    SND_JACK_BTN_2 | SND_JACK_BTN_3,
 570                                    &priv->headset_jack,
 571                                    NULL, 0);
 572        if (ret)
 573                return ret;
 574
 575        ret = ts3a227e_enable_jack_detect(component, &priv->headset_jack);
 576
 577        return ret;
 578}
 579
 580static struct snd_soc_aux_dev mt8183_mt6358_ts3a227_max98357_headset_dev = {
 581        .dlc = COMP_EMPTY(),
 582        .init = mt8183_mt6358_ts3a227_max98357_headset_init,
 583};
 584
 585static int
 586mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
 587{
 588        struct snd_soc_card *card;
 589        struct device_node *platform_node, *ec_codec, *hdmi_codec;
 590        struct snd_soc_dai_link *dai_link;
 591        struct mt8183_mt6358_ts3a227_max98357_priv *priv;
 592        const struct of_device_id *match;
 593        int ret, i;
 594
 595        platform_node = of_parse_phandle(pdev->dev.of_node,
 596                                         "mediatek,platform", 0);
 597        if (!platform_node) {
 598                dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
 599                return -EINVAL;
 600        }
 601
 602        match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev);
 603        if (!match || !match->data)
 604                return -EINVAL;
 605
 606        card = (struct snd_soc_card *)match->data;
 607        card->dev = &pdev->dev;
 608
 609        ec_codec = of_parse_phandle(pdev->dev.of_node, "mediatek,ec-codec", 0);
 610        hdmi_codec = of_parse_phandle(pdev->dev.of_node,
 611                                      "mediatek,hdmi-codec", 0);
 612
 613        for_each_card_prelinks(card, i, dai_link) {
 614                if (ec_codec && strcmp(dai_link->name, "Wake on Voice") == 0) {
 615                        dai_link->cpus[0].name = NULL;
 616                        dai_link->cpus[0].of_node = ec_codec;
 617                        dai_link->cpus[0].dai_name = NULL;
 618                        dai_link->codecs[0].name = NULL;
 619                        dai_link->codecs[0].of_node = ec_codec;
 620                        dai_link->codecs[0].dai_name = "Wake on Voice";
 621                        dai_link->platforms[0].of_node = ec_codec;
 622                        dai_link->ignore = 0;
 623                }
 624
 625                if (strcmp(dai_link->name, "I2S3") == 0) {
 626                        if (card == &mt8183_mt6358_ts3a227_max98357_card ||
 627                            card == &mt8183_mt6358_ts3a227_max98357b_card) {
 628                                dai_link->be_hw_params_fixup =
 629                                        mt8183_i2s_hw_params_fixup;
 630                                dai_link->ops = &mt8183_mt6358_i2s_ops;
 631                                dai_link->cpus = i2s3_max98357a_cpus;
 632                                dai_link->num_cpus =
 633                                        ARRAY_SIZE(i2s3_max98357a_cpus);
 634                                dai_link->codecs = i2s3_max98357a_codecs;
 635                                dai_link->num_codecs =
 636                                        ARRAY_SIZE(i2s3_max98357a_codecs);
 637                                dai_link->platforms = i2s3_max98357a_platforms;
 638                                dai_link->num_platforms =
 639                                        ARRAY_SIZE(i2s3_max98357a_platforms);
 640                        } else if (card == &mt8183_mt6358_ts3a227_rt1015_card) {
 641                                dai_link->be_hw_params_fixup =
 642                                        mt8183_rt1015_i2s_hw_params_fixup;
 643                                dai_link->ops = &mt8183_mt6358_rt1015_i2s_ops;
 644                                dai_link->cpus = i2s3_rt1015_cpus;
 645                                dai_link->num_cpus =
 646                                        ARRAY_SIZE(i2s3_rt1015_cpus);
 647                                dai_link->codecs = i2s3_rt1015_codecs;
 648                                dai_link->num_codecs =
 649                                        ARRAY_SIZE(i2s3_rt1015_codecs);
 650                                dai_link->platforms = i2s3_rt1015_platforms;
 651                                dai_link->num_platforms =
 652                                        ARRAY_SIZE(i2s3_rt1015_platforms);
 653                        }
 654                }
 655
 656                if (card == &mt8183_mt6358_ts3a227_max98357b_card) {
 657                        if (strcmp(dai_link->name, "I2S2") == 0 ||
 658                            strcmp(dai_link->name, "I2S3") == 0)
 659                                dai_link->dai_fmt = SND_SOC_DAIFMT_LEFT_J |
 660                                                    SND_SOC_DAIFMT_NB_NF |
 661                                                    SND_SOC_DAIFMT_CBM_CFM;
 662                }
 663
 664                if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0)
 665                        dai_link->codecs->of_node = hdmi_codec;
 666
 667                if (!dai_link->platforms->name)
 668                        dai_link->platforms->of_node = platform_node;
 669        }
 670
 671        mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node =
 672                of_parse_phandle(pdev->dev.of_node,
 673                                 "mediatek,headset-codec", 0);
 674        if (mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node) {
 675                card->aux_dev = &mt8183_mt6358_ts3a227_max98357_headset_dev;
 676                card->num_aux_devs = 1;
 677        }
 678
 679        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 680        if (!priv)
 681                return -ENOMEM;
 682
 683        snd_soc_card_set_drvdata(card, priv);
 684
 685        priv->pinctrl = devm_pinctrl_get(&pdev->dev);
 686        if (IS_ERR(priv->pinctrl)) {
 687                dev_err(&pdev->dev, "%s devm_pinctrl_get failed\n",
 688                        __func__);
 689                return PTR_ERR(priv->pinctrl);
 690        }
 691
 692        for (i = 0; i < PIN_STATE_MAX; i++) {
 693                priv->pin_states[i] = pinctrl_lookup_state(priv->pinctrl,
 694                                                           mt8183_pin_str[i]);
 695                if (IS_ERR(priv->pin_states[i])) {
 696                        ret = PTR_ERR(priv->pin_states[i]);
 697                        dev_info(&pdev->dev, "%s Can't find pin state %s %d\n",
 698                                 __func__, mt8183_pin_str[i], ret);
 699                }
 700        }
 701
 702        if (!IS_ERR(priv->pin_states[PIN_TDM_OUT_OFF])) {
 703                ret = pinctrl_select_state(priv->pinctrl,
 704                                           priv->pin_states[PIN_TDM_OUT_OFF]);
 705                if (ret)
 706                        dev_info(&pdev->dev,
 707                                 "%s failed to select state %d\n",
 708                                 __func__, ret);
 709        }
 710
 711        if (!IS_ERR(priv->pin_states[PIN_STATE_DEFAULT])) {
 712                ret = pinctrl_select_state(priv->pinctrl,
 713                                           priv->pin_states[PIN_STATE_DEFAULT]);
 714                if (ret)
 715                        dev_info(&pdev->dev,
 716                                 "%s failed to select state %d\n",
 717                                 __func__, ret);
 718        }
 719
 720        return devm_snd_soc_register_card(&pdev->dev, card);
 721}
 722
 723#ifdef CONFIG_OF
 724static const struct of_device_id mt8183_mt6358_ts3a227_max98357_dt_match[] = {
 725        {
 726                .compatible = "mediatek,mt8183_mt6358_ts3a227_max98357",
 727                .data = &mt8183_mt6358_ts3a227_max98357_card,
 728        },
 729        {
 730                .compatible = "mediatek,mt8183_mt6358_ts3a227_max98357b",
 731                .data = &mt8183_mt6358_ts3a227_max98357b_card,
 732        },
 733        {
 734                .compatible = "mediatek,mt8183_mt6358_ts3a227_rt1015",
 735                .data = &mt8183_mt6358_ts3a227_rt1015_card,
 736        },
 737        {}
 738};
 739#endif
 740
 741static struct platform_driver mt8183_mt6358_ts3a227_max98357_driver = {
 742        .driver = {
 743                .name = "mt8183_mt6358_ts3a227",
 744#ifdef CONFIG_OF
 745                .of_match_table = mt8183_mt6358_ts3a227_max98357_dt_match,
 746#endif
 747        },
 748        .probe = mt8183_mt6358_ts3a227_max98357_dev_probe,
 749};
 750
 751module_platform_driver(mt8183_mt6358_ts3a227_max98357_driver);
 752
 753/* Module information */
 754MODULE_DESCRIPTION("MT8183-MT6358-TS3A227-MAX98357 ALSA SoC machine driver");
 755MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>");
 756MODULE_LICENSE("GPL v2");
 757MODULE_ALIAS("mt8183_mt6358_ts3a227_max98357 soc card");
 758