linux/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// mt8183-da7219-max98357.c
   4//      --  MT8183-DA7219-MAX98357 ALSA SoC machine driver
   5//
   6// Copyright (c) 2018 MediaTek Inc.
   7// Author: Shunli Wang <shunli.wang@mediatek.com>
   8
   9#include <linux/input.h>
  10#include <linux/module.h>
  11#include <linux/of_device.h>
  12#include <linux/pinctrl/consumer.h>
  13#include <sound/jack.h>
  14#include <sound/pcm_params.h>
  15#include <sound/soc.h>
  16
  17#include "../../codecs/da7219-aad.h"
  18#include "../../codecs/da7219.h"
  19#include "../../codecs/rt1015.h"
  20#include "mt8183-afe-common.h"
  21
  22#define DA7219_CODEC_DAI "da7219-hifi"
  23#define DA7219_DEV_NAME "da7219.5-001a"
  24#define RT1015_CODEC_DAI "rt1015-aif"
  25#define RT1015_DEV0_NAME "rt1015.6-0028"
  26#define RT1015_DEV1_NAME "rt1015.6-0029"
  27
  28struct mt8183_da7219_max98357_priv {
  29        struct snd_soc_jack headset_jack, hdmi_jack;
  30};
  31
  32static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream,
  33                                       struct snd_pcm_hw_params *params)
  34{
  35        struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  36        unsigned int rate = params_rate(params);
  37        unsigned int mclk_fs_ratio = 128;
  38        unsigned int mclk_fs = rate * mclk_fs_ratio;
  39
  40        return snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0),
  41                                      0, mclk_fs, SND_SOC_CLOCK_OUT);
  42}
  43
  44static const struct snd_soc_ops mt8183_mt6358_i2s_ops = {
  45        .hw_params = mt8183_mt6358_i2s_hw_params,
  46};
  47
  48static int mt8183_da7219_i2s_hw_params(struct snd_pcm_substream *substream,
  49                                       struct snd_pcm_hw_params *params)
  50{
  51        struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  52        struct snd_soc_dai *codec_dai;
  53        unsigned int rate = params_rate(params);
  54        unsigned int mclk_fs_ratio = 256;
  55        unsigned int mclk_fs = rate * mclk_fs_ratio;
  56        unsigned int freq;
  57        int ret = 0, j;
  58
  59        ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0,
  60                                     mclk_fs, SND_SOC_CLOCK_OUT);
  61        if (ret < 0)
  62                dev_err(rtd->dev, "failed to set cpu dai sysclk\n");
  63
  64        for_each_rtd_codec_dais(rtd, j, codec_dai) {
  65                if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
  66                        ret = snd_soc_dai_set_sysclk(codec_dai,
  67                                                     DA7219_CLKSRC_MCLK,
  68                                                     mclk_fs,
  69                                                     SND_SOC_CLOCK_IN);
  70                        if (ret < 0)
  71                                dev_err(rtd->dev, "failed to set sysclk\n");
  72
  73                        if ((rate % 8000) == 0)
  74                                freq = DA7219_PLL_FREQ_OUT_98304;
  75                        else
  76                                freq = DA7219_PLL_FREQ_OUT_90316;
  77
  78                        ret = snd_soc_dai_set_pll(codec_dai, 0,
  79                                                  DA7219_SYSCLK_PLL_SRM,
  80                                                  0, freq);
  81                        if (ret)
  82                                dev_err(rtd->dev, "failed to start PLL: %d\n",
  83                                        ret);
  84                }
  85        }
  86
  87        return ret;
  88}
  89
  90static int mt8183_da7219_hw_free(struct snd_pcm_substream *substream)
  91{
  92        struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  93        struct snd_soc_dai *codec_dai;
  94        int ret = 0, j;
  95
  96        for_each_rtd_codec_dais(rtd, j, codec_dai) {
  97                if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
  98                        ret = snd_soc_dai_set_pll(codec_dai,
  99                                                  0, DA7219_SYSCLK_MCLK, 0, 0);
 100                        if (ret < 0) {
 101                                dev_err(rtd->dev, "failed to stop PLL: %d\n",
 102                                        ret);
 103                                break;
 104                        }
 105                }
 106        }
 107
 108        return ret;
 109}
 110
 111static const struct snd_soc_ops mt8183_da7219_i2s_ops = {
 112        .hw_params = mt8183_da7219_i2s_hw_params,
 113        .hw_free = mt8183_da7219_hw_free,
 114};
 115
 116static int
 117mt8183_da7219_rt1015_i2s_hw_params(struct snd_pcm_substream *substream,
 118                                   struct snd_pcm_hw_params *params)
 119{
 120        struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
 121        unsigned int rate = params_rate(params);
 122        struct snd_soc_dai *codec_dai;
 123        int ret = 0, i;
 124
 125        for_each_rtd_codec_dais(rtd, i, codec_dai) {
 126                if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) ||
 127                    !strcmp(codec_dai->component->name, RT1015_DEV1_NAME)) {
 128                        ret = snd_soc_dai_set_pll(codec_dai, 0,
 129                                                  RT1015_PLL_S_BCLK,
 130                                                  rate * 64, rate * 256);
 131                        if (ret) {
 132                                dev_err(rtd->dev, "failed to set pll\n");
 133                                return ret;
 134                        }
 135
 136                        ret = snd_soc_dai_set_sysclk(codec_dai,
 137                                                     RT1015_SCLK_S_PLL,
 138                                                     rate * 256,
 139                                                     SND_SOC_CLOCK_IN);
 140                        if (ret) {
 141                                dev_err(rtd->dev, "failed to set sysclk\n");
 142                                return ret;
 143                        }
 144                }
 145        }
 146
 147        return mt8183_da7219_i2s_hw_params(substream, params);
 148}
 149
 150static const struct snd_soc_ops mt8183_da7219_rt1015_i2s_ops = {
 151        .hw_params = mt8183_da7219_rt1015_i2s_hw_params,
 152        .hw_free = mt8183_da7219_hw_free,
 153};
 154
 155static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 156                                      struct snd_pcm_hw_params *params)
 157{
 158        /* fix BE i2s format to 32bit, clean param mask first */
 159        snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
 160                             0, SNDRV_PCM_FORMAT_LAST);
 161
 162        params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
 163
 164        return 0;
 165}
 166
 167static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 168                                             struct snd_pcm_hw_params *params)
 169{
 170        /* fix BE i2s format to 32bit, clean param mask first */
 171        snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
 172                             0, SNDRV_PCM_FORMAT_LAST);
 173
 174        params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
 175
 176        return 0;
 177}
 178
 179static int
 180mt8183_da7219_max98357_startup(
 181        struct snd_pcm_substream *substream)
 182{
 183        static const unsigned int rates[] = {
 184                48000,
 185        };
 186        static const struct snd_pcm_hw_constraint_list constraints_rates = {
 187                .count = ARRAY_SIZE(rates),
 188                .list  = rates,
 189                .mask = 0,
 190        };
 191        static const unsigned int channels[] = {
 192                2,
 193        };
 194        static const struct snd_pcm_hw_constraint_list constraints_channels = {
 195                .count = ARRAY_SIZE(channels),
 196                .list = channels,
 197                .mask = 0,
 198        };
 199
 200        struct snd_pcm_runtime *runtime = substream->runtime;
 201
 202        snd_pcm_hw_constraint_list(runtime, 0,
 203                        SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
 204        runtime->hw.channels_max = 2;
 205        snd_pcm_hw_constraint_list(runtime, 0,
 206                        SNDRV_PCM_HW_PARAM_CHANNELS,
 207                        &constraints_channels);
 208
 209        runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
 210        snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
 211
 212        return 0;
 213}
 214
 215static const struct snd_soc_ops mt8183_da7219_max98357_ops = {
 216        .startup = mt8183_da7219_max98357_startup,
 217};
 218
 219static int
 220mt8183_da7219_max98357_bt_sco_startup(
 221        struct snd_pcm_substream *substream)
 222{
 223        static const unsigned int rates[] = {
 224                8000, 16000
 225        };
 226        static const struct snd_pcm_hw_constraint_list constraints_rates = {
 227                .count = ARRAY_SIZE(rates),
 228                .list  = rates,
 229                .mask = 0,
 230        };
 231        static const unsigned int channels[] = {
 232                1,
 233        };
 234        static const struct snd_pcm_hw_constraint_list constraints_channels = {
 235                .count = ARRAY_SIZE(channels),
 236                .list = channels,
 237                .mask = 0,
 238        };
 239
 240        struct snd_pcm_runtime *runtime = substream->runtime;
 241
 242        snd_pcm_hw_constraint_list(runtime, 0,
 243                        SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
 244        runtime->hw.channels_max = 1;
 245        snd_pcm_hw_constraint_list(runtime, 0,
 246                        SNDRV_PCM_HW_PARAM_CHANNELS,
 247                        &constraints_channels);
 248
 249        runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
 250        snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
 251
 252        return 0;
 253}
 254
 255static const struct snd_soc_ops mt8183_da7219_max98357_bt_sco_ops = {
 256        .startup = mt8183_da7219_max98357_bt_sco_startup,
 257};
 258
 259/* FE */
 260SND_SOC_DAILINK_DEFS(playback1,
 261        DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
 262        DAILINK_COMP_ARRAY(COMP_DUMMY()),
 263        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 264
 265SND_SOC_DAILINK_DEFS(playback2,
 266        DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
 267        DAILINK_COMP_ARRAY(COMP_DUMMY()),
 268        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 269
 270SND_SOC_DAILINK_DEFS(playback3,
 271        DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
 272        DAILINK_COMP_ARRAY(COMP_DUMMY()),
 273        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 274
 275SND_SOC_DAILINK_DEFS(capture1,
 276        DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
 277        DAILINK_COMP_ARRAY(COMP_DUMMY()),
 278        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 279
 280SND_SOC_DAILINK_DEFS(capture2,
 281        DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
 282        DAILINK_COMP_ARRAY(COMP_DUMMY()),
 283        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 284
 285SND_SOC_DAILINK_DEFS(capture3,
 286        DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
 287        DAILINK_COMP_ARRAY(COMP_DUMMY()),
 288        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 289
 290SND_SOC_DAILINK_DEFS(capture_mono,
 291        DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")),
 292        DAILINK_COMP_ARRAY(COMP_DUMMY()),
 293        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 294
 295SND_SOC_DAILINK_DEFS(playback_hdmi,
 296        DAILINK_COMP_ARRAY(COMP_CPU("HDMI")),
 297        DAILINK_COMP_ARRAY(COMP_DUMMY()),
 298        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 299
 300/* BE */
 301SND_SOC_DAILINK_DEFS(primary_codec,
 302        DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
 303        DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")),
 304        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 305
 306SND_SOC_DAILINK_DEFS(pcm1,
 307        DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
 308        DAILINK_COMP_ARRAY(COMP_DUMMY()),
 309        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 310
 311SND_SOC_DAILINK_DEFS(pcm2,
 312        DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")),
 313        DAILINK_COMP_ARRAY(COMP_DUMMY()),
 314        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 315
 316SND_SOC_DAILINK_DEFS(i2s0,
 317        DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
 318        DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
 319        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 320
 321SND_SOC_DAILINK_DEFS(i2s1,
 322        DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
 323        DAILINK_COMP_ARRAY(COMP_DUMMY()),
 324        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 325
 326SND_SOC_DAILINK_DEFS(i2s2,
 327        DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
 328        DAILINK_COMP_ARRAY(COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
 329        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 330
 331SND_SOC_DAILINK_DEFS(i2s3_max98357a,
 332        DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
 333        DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi"),
 334                           COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
 335        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 336
 337SND_SOC_DAILINK_DEFS(i2s3_rt1015,
 338        DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
 339        DAILINK_COMP_ARRAY(COMP_CODEC(RT1015_DEV0_NAME, RT1015_CODEC_DAI),
 340                           COMP_CODEC(RT1015_DEV1_NAME, RT1015_CODEC_DAI),
 341                           COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
 342        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 343
 344SND_SOC_DAILINK_DEFS(i2s3_rt1015p,
 345        DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
 346        DAILINK_COMP_ARRAY(COMP_CODEC("rt1015p", "HiFi"),
 347                           COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
 348        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 349
 350SND_SOC_DAILINK_DEFS(i2s5,
 351        DAILINK_COMP_ARRAY(COMP_CPU("I2S5")),
 352        DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
 353        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 354
 355SND_SOC_DAILINK_DEFS(tdm,
 356        DAILINK_COMP_ARRAY(COMP_CPU("TDM")),
 357        DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")),
 358        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 359
 360static int mt8183_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd)
 361{
 362        struct mt8183_da7219_max98357_priv *priv =
 363                snd_soc_card_get_drvdata(rtd->card);
 364        int ret;
 365
 366        ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
 367                                    &priv->hdmi_jack, NULL, 0);
 368        if (ret)
 369                return ret;
 370
 371        return snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component,
 372                                          &priv->hdmi_jack, NULL);
 373}
 374
 375static struct snd_soc_dai_link mt8183_da7219_dai_links[] = {
 376        /* FE */
 377        {
 378                .name = "Playback_1",
 379                .stream_name = "Playback_1",
 380                .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 381                            SND_SOC_DPCM_TRIGGER_PRE},
 382                .dynamic = 1,
 383                .dpcm_playback = 1,
 384                .ops = &mt8183_da7219_max98357_ops,
 385                SND_SOC_DAILINK_REG(playback1),
 386        },
 387        {
 388                .name = "Playback_2",
 389                .stream_name = "Playback_2",
 390                .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 391                            SND_SOC_DPCM_TRIGGER_PRE},
 392                .dynamic = 1,
 393                .dpcm_playback = 1,
 394                .ops = &mt8183_da7219_max98357_bt_sco_ops,
 395                SND_SOC_DAILINK_REG(playback2),
 396        },
 397        {
 398                .name = "Playback_3",
 399                .stream_name = "Playback_3",
 400                .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 401                            SND_SOC_DPCM_TRIGGER_PRE},
 402                .dynamic = 1,
 403                .dpcm_playback = 1,
 404                SND_SOC_DAILINK_REG(playback3),
 405        },
 406        {
 407                .name = "Capture_1",
 408                .stream_name = "Capture_1",
 409                .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 410                            SND_SOC_DPCM_TRIGGER_PRE},
 411                .dynamic = 1,
 412                .dpcm_capture = 1,
 413                .ops = &mt8183_da7219_max98357_bt_sco_ops,
 414                SND_SOC_DAILINK_REG(capture1),
 415        },
 416        {
 417                .name = "Capture_2",
 418                .stream_name = "Capture_2",
 419                .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 420                            SND_SOC_DPCM_TRIGGER_PRE},
 421                .dynamic = 1,
 422                .dpcm_capture = 1,
 423                SND_SOC_DAILINK_REG(capture2),
 424        },
 425        {
 426                .name = "Capture_3",
 427                .stream_name = "Capture_3",
 428                .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 429                            SND_SOC_DPCM_TRIGGER_PRE},
 430                .dynamic = 1,
 431                .dpcm_capture = 1,
 432                .ops = &mt8183_da7219_max98357_ops,
 433                SND_SOC_DAILINK_REG(capture3),
 434        },
 435        {
 436                .name = "Capture_Mono_1",
 437                .stream_name = "Capture_Mono_1",
 438                .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 439                            SND_SOC_DPCM_TRIGGER_PRE},
 440                .dynamic = 1,
 441                .dpcm_capture = 1,
 442                SND_SOC_DAILINK_REG(capture_mono),
 443        },
 444        {
 445                .name = "Playback_HDMI",
 446                .stream_name = "Playback_HDMI",
 447                .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 448                            SND_SOC_DPCM_TRIGGER_PRE},
 449                .dynamic = 1,
 450                .dpcm_playback = 1,
 451                SND_SOC_DAILINK_REG(playback_hdmi),
 452        },
 453        /* BE */
 454        {
 455                .name = "Primary Codec",
 456                .no_pcm = 1,
 457                .dpcm_playback = 1,
 458                .dpcm_capture = 1,
 459                .ignore_suspend = 1,
 460                SND_SOC_DAILINK_REG(primary_codec),
 461        },
 462        {
 463                .name = "PCM 1",
 464                .no_pcm = 1,
 465                .dpcm_playback = 1,
 466                .dpcm_capture = 1,
 467                .ignore_suspend = 1,
 468                SND_SOC_DAILINK_REG(pcm1),
 469        },
 470        {
 471                .name = "PCM 2",
 472                .no_pcm = 1,
 473                .dpcm_playback = 1,
 474                .dpcm_capture = 1,
 475                .ignore_suspend = 1,
 476                SND_SOC_DAILINK_REG(pcm2),
 477        },
 478        {
 479                .name = "I2S0",
 480                .no_pcm = 1,
 481                .dpcm_capture = 1,
 482                .ignore_suspend = 1,
 483                .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
 484                .ops = &mt8183_mt6358_i2s_ops,
 485                SND_SOC_DAILINK_REG(i2s0),
 486        },
 487        {
 488                .name = "I2S1",
 489                .no_pcm = 1,
 490                .dpcm_playback = 1,
 491                .ignore_suspend = 1,
 492                .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
 493                .ops = &mt8183_mt6358_i2s_ops,
 494                SND_SOC_DAILINK_REG(i2s1),
 495        },
 496        {
 497                .name = "I2S2",
 498                .no_pcm = 1,
 499                .dpcm_capture = 1,
 500                .ignore_suspend = 1,
 501                .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
 502                .ops = &mt8183_da7219_i2s_ops,
 503                SND_SOC_DAILINK_REG(i2s2),
 504        },
 505        {
 506                .name = "I2S3",
 507                .no_pcm = 1,
 508                .dpcm_playback = 1,
 509                .ignore_suspend = 1,
 510        },
 511        {
 512                .name = "I2S5",
 513                .no_pcm = 1,
 514                .dpcm_playback = 1,
 515                .ignore_suspend = 1,
 516                .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
 517                .ops = &mt8183_mt6358_i2s_ops,
 518                SND_SOC_DAILINK_REG(i2s5),
 519        },
 520        {
 521                .name = "TDM",
 522                .no_pcm = 1,
 523                .dai_fmt = SND_SOC_DAIFMT_I2S |
 524                           SND_SOC_DAIFMT_IB_IF |
 525                           SND_SOC_DAIFMT_CBM_CFM,
 526                .dpcm_playback = 1,
 527                .ignore_suspend = 1,
 528                .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
 529                .ignore = 1,
 530                .init = mt8183_da7219_max98357_hdmi_init,
 531                SND_SOC_DAILINK_REG(tdm),
 532        },
 533};
 534
 535static int
 536mt8183_da7219_max98357_headset_init(struct snd_soc_component *component)
 537{
 538        int ret;
 539        struct mt8183_da7219_max98357_priv *priv =
 540                        snd_soc_card_get_drvdata(component->card);
 541
 542        /* Enable Headset and 4 Buttons Jack detection */
 543        ret = snd_soc_card_jack_new(component->card,
 544                                    "Headset Jack",
 545                                    SND_JACK_HEADSET |
 546                                    SND_JACK_BTN_0 | SND_JACK_BTN_1 |
 547                                    SND_JACK_BTN_2 | SND_JACK_BTN_3 |
 548                                    SND_JACK_LINEOUT,
 549                                    &priv->headset_jack,
 550                                    NULL, 0);
 551        if (ret)
 552                return ret;
 553
 554        snd_jack_set_key(
 555                priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
 556        snd_jack_set_key(
 557                priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
 558        snd_jack_set_key(
 559                priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
 560        snd_jack_set_key(
 561                priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
 562
 563        da7219_aad_jack_det(component, &priv->headset_jack);
 564
 565        return 0;
 566}
 567
 568static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = {
 569        .dlc = COMP_EMPTY(),
 570        .init = mt8183_da7219_max98357_headset_init,
 571};
 572
 573static struct snd_soc_codec_conf mt6358_codec_conf[] = {
 574        {
 575                .dlc = COMP_CODEC_CONF("mt6358-sound"),
 576                .name_prefix = "Mt6358",
 577        },
 578};
 579
 580static const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = {
 581        SOC_DAPM_PIN_SWITCH("Speakers"),
 582};
 583
 584static const
 585struct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = {
 586        SND_SOC_DAPM_SPK("Speakers", NULL),
 587        SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
 588                             "aud_tdm_out_on", "aud_tdm_out_off"),
 589};
 590
 591static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = {
 592        {"Speakers", NULL, "Speaker"},
 593        {"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
 594};
 595
 596static struct snd_soc_card mt8183_da7219_max98357_card = {
 597        .name = "mt8183_da7219_max98357",
 598        .owner = THIS_MODULE,
 599        .controls = mt8183_da7219_max98357_snd_controls,
 600        .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
 601        .dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
 602        .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
 603        .dapm_routes = mt8183_da7219_max98357_dapm_routes,
 604        .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
 605        .dai_link = mt8183_da7219_dai_links,
 606        .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
 607        .aux_dev = &mt8183_da7219_max98357_headset_dev,
 608        .num_aux_devs = 1,
 609        .codec_conf = mt6358_codec_conf,
 610        .num_configs = ARRAY_SIZE(mt6358_codec_conf),
 611};
 612
 613static struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = {
 614        {
 615                .dlc = COMP_CODEC_CONF("mt6358-sound"),
 616                .name_prefix = "Mt6358",
 617        },
 618        {
 619                .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME),
 620                .name_prefix = "Left",
 621        },
 622        {
 623                .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME),
 624                .name_prefix = "Right",
 625        },
 626};
 627
 628static const struct snd_kcontrol_new mt8183_da7219_rt1015_snd_controls[] = {
 629        SOC_DAPM_PIN_SWITCH("Left Spk"),
 630        SOC_DAPM_PIN_SWITCH("Right Spk"),
 631};
 632
 633static const
 634struct snd_soc_dapm_widget mt8183_da7219_rt1015_dapm_widgets[] = {
 635        SND_SOC_DAPM_SPK("Left Spk", NULL),
 636        SND_SOC_DAPM_SPK("Right Spk", NULL),
 637        SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
 638                             "aud_tdm_out_on", "aud_tdm_out_off"),
 639};
 640
 641static const struct snd_soc_dapm_route mt8183_da7219_rt1015_dapm_routes[] = {
 642        {"Left Spk", NULL, "Left SPO"},
 643        {"Right Spk", NULL, "Right SPO"},
 644        {"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
 645};
 646
 647static struct snd_soc_card mt8183_da7219_rt1015_card = {
 648        .name = "mt8183_da7219_rt1015",
 649        .owner = THIS_MODULE,
 650        .controls = mt8183_da7219_rt1015_snd_controls,
 651        .num_controls = ARRAY_SIZE(mt8183_da7219_rt1015_snd_controls),
 652        .dapm_widgets = mt8183_da7219_rt1015_dapm_widgets,
 653        .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_widgets),
 654        .dapm_routes = mt8183_da7219_rt1015_dapm_routes,
 655        .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_routes),
 656        .dai_link = mt8183_da7219_dai_links,
 657        .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
 658        .aux_dev = &mt8183_da7219_max98357_headset_dev,
 659        .num_aux_devs = 1,
 660        .codec_conf = mt8183_da7219_rt1015_codec_conf,
 661        .num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf),
 662};
 663
 664static struct snd_soc_card mt8183_da7219_rt1015p_card = {
 665        .name = "mt8183_da7219_rt1015p",
 666        .owner = THIS_MODULE,
 667        .controls = mt8183_da7219_max98357_snd_controls,
 668        .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
 669        .dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
 670        .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
 671        .dapm_routes = mt8183_da7219_max98357_dapm_routes,
 672        .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
 673        .dai_link = mt8183_da7219_dai_links,
 674        .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
 675        .aux_dev = &mt8183_da7219_max98357_headset_dev,
 676        .num_aux_devs = 1,
 677        .codec_conf = mt6358_codec_conf,
 678        .num_configs = ARRAY_SIZE(mt6358_codec_conf),
 679};
 680
 681static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
 682{
 683        struct snd_soc_card *card;
 684        struct device_node *platform_node, *hdmi_codec;
 685        struct snd_soc_dai_link *dai_link;
 686        struct mt8183_da7219_max98357_priv *priv;
 687        struct pinctrl *pinctrl;
 688        const struct of_device_id *match;
 689        int ret, i;
 690
 691        platform_node = of_parse_phandle(pdev->dev.of_node,
 692                                         "mediatek,platform", 0);
 693        if (!platform_node) {
 694                dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
 695                return -EINVAL;
 696        }
 697
 698        match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev);
 699        if (!match || !match->data)
 700                return -EINVAL;
 701
 702        card = (struct snd_soc_card *)match->data;
 703        card->dev = &pdev->dev;
 704
 705        hdmi_codec = of_parse_phandle(pdev->dev.of_node,
 706                                      "mediatek,hdmi-codec", 0);
 707
 708        for_each_card_prelinks(card, i, dai_link) {
 709                if (strcmp(dai_link->name, "I2S3") == 0) {
 710                        if (card == &mt8183_da7219_max98357_card) {
 711                                dai_link->be_hw_params_fixup =
 712                                        mt8183_i2s_hw_params_fixup;
 713                                dai_link->ops = &mt8183_da7219_i2s_ops;
 714                                dai_link->cpus = i2s3_max98357a_cpus;
 715                                dai_link->num_cpus =
 716                                        ARRAY_SIZE(i2s3_max98357a_cpus);
 717                                dai_link->codecs = i2s3_max98357a_codecs;
 718                                dai_link->num_codecs =
 719                                        ARRAY_SIZE(i2s3_max98357a_codecs);
 720                                dai_link->platforms = i2s3_max98357a_platforms;
 721                                dai_link->num_platforms =
 722                                        ARRAY_SIZE(i2s3_max98357a_platforms);
 723                        } else if (card == &mt8183_da7219_rt1015_card) {
 724                                dai_link->be_hw_params_fixup =
 725                                        mt8183_rt1015_i2s_hw_params_fixup;
 726                                dai_link->ops = &mt8183_da7219_rt1015_i2s_ops;
 727                                dai_link->cpus = i2s3_rt1015_cpus;
 728                                dai_link->num_cpus =
 729                                        ARRAY_SIZE(i2s3_rt1015_cpus);
 730                                dai_link->codecs = i2s3_rt1015_codecs;
 731                                dai_link->num_codecs =
 732                                        ARRAY_SIZE(i2s3_rt1015_codecs);
 733                                dai_link->platforms = i2s3_rt1015_platforms;
 734                                dai_link->num_platforms =
 735                                        ARRAY_SIZE(i2s3_rt1015_platforms);
 736                        } else if (card == &mt8183_da7219_rt1015p_card) {
 737                                dai_link->be_hw_params_fixup =
 738                                        mt8183_rt1015_i2s_hw_params_fixup;
 739                                dai_link->ops = &mt8183_da7219_i2s_ops;
 740                                dai_link->cpus = i2s3_rt1015p_cpus;
 741                                dai_link->num_cpus =
 742                                        ARRAY_SIZE(i2s3_rt1015p_cpus);
 743                                dai_link->codecs = i2s3_rt1015p_codecs;
 744                                dai_link->num_codecs =
 745                                        ARRAY_SIZE(i2s3_rt1015p_codecs);
 746                                dai_link->platforms = i2s3_rt1015p_platforms;
 747                                dai_link->num_platforms =
 748                                        ARRAY_SIZE(i2s3_rt1015p_platforms);
 749                        }
 750                }
 751
 752                if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) {
 753                        dai_link->codecs->of_node = hdmi_codec;
 754                        dai_link->ignore = 0;
 755                }
 756
 757                if (!dai_link->platforms->name)
 758                        dai_link->platforms->of_node = platform_node;
 759        }
 760
 761        mt8183_da7219_max98357_headset_dev.dlc.of_node =
 762                of_parse_phandle(pdev->dev.of_node,
 763                                 "mediatek,headset-codec", 0);
 764        if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) {
 765                dev_err(&pdev->dev,
 766                        "Property 'mediatek,headset-codec' missing/invalid\n");
 767                return -EINVAL;
 768        }
 769
 770        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 771        if (!priv)
 772                return -ENOMEM;
 773
 774        snd_soc_card_set_drvdata(card, priv);
 775
 776        pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT);
 777        if (IS_ERR(pinctrl)) {
 778                ret = PTR_ERR(pinctrl);
 779                dev_err(&pdev->dev, "%s failed to select default state %d\n",
 780                        __func__, ret);
 781                return ret;
 782        }
 783
 784        return devm_snd_soc_register_card(&pdev->dev, card);
 785}
 786
 787#ifdef CONFIG_OF
 788static const struct of_device_id mt8183_da7219_max98357_dt_match[] = {
 789        {
 790                .compatible = "mediatek,mt8183_da7219_max98357",
 791                .data = &mt8183_da7219_max98357_card,
 792        },
 793        {
 794                .compatible = "mediatek,mt8183_da7219_rt1015",
 795                .data = &mt8183_da7219_rt1015_card,
 796        },
 797        {
 798                .compatible = "mediatek,mt8183_da7219_rt1015p",
 799                .data = &mt8183_da7219_rt1015p_card,
 800        },
 801        {}
 802};
 803#endif
 804
 805static struct platform_driver mt8183_da7219_max98357_driver = {
 806        .driver = {
 807                .name = "mt8183_da7219",
 808#ifdef CONFIG_OF
 809                .of_match_table = mt8183_da7219_max98357_dt_match,
 810#endif
 811                .pm = &snd_soc_pm_ops,
 812        },
 813        .probe = mt8183_da7219_max98357_dev_probe,
 814};
 815
 816module_platform_driver(mt8183_da7219_max98357_driver);
 817
 818/* Module information */
 819MODULE_DESCRIPTION("MT8183-DA7219-MAX98357 ALSA SoC machine driver");
 820MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>");
 821MODULE_LICENSE("GPL v2");
 822MODULE_ALIAS("mt8183_da7219_max98357 soc card");
 823