linux/sound/soc/intel/boards/sof_rt5682.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2// Copyright(c) 2019-2020 Intel Corporation.
   3
   4/*
   5 * Intel SOF Machine Driver with Realtek rt5682 Codec
   6 * and speaker codec MAX98357A or RT1015.
   7 */
   8#include <linux/i2c.h>
   9#include <linux/input.h>
  10#include <linux/module.h>
  11#include <linux/platform_device.h>
  12#include <linux/clk.h>
  13#include <linux/dmi.h>
  14#include <sound/core.h>
  15#include <sound/jack.h>
  16#include <sound/pcm.h>
  17#include <sound/pcm_params.h>
  18#include <sound/soc.h>
  19#include <sound/sof.h>
  20#include <sound/rt5682.h>
  21#include <sound/soc-acpi.h>
  22#include "../../codecs/rt1015.h"
  23#include "../../codecs/rt5682.h"
  24#include "../../codecs/hdac_hdmi.h"
  25#include "../common/soc-intel-quirks.h"
  26#include "hda_dsp_common.h"
  27#include "sof_maxim_common.h"
  28#include "sof_realtek_common.h"
  29
  30#define NAME_SIZE 32
  31
  32#define SOF_RT5682_SSP_CODEC(quirk)             ((quirk) & GENMASK(2, 0))
  33#define SOF_RT5682_SSP_CODEC_MASK                       (GENMASK(2, 0))
  34#define SOF_RT5682_MCLK_EN                      BIT(3)
  35#define SOF_RT5682_MCLK_24MHZ                   BIT(4)
  36#define SOF_SPEAKER_AMP_PRESENT         BIT(5)
  37#define SOF_RT5682_SSP_AMP_SHIFT                6
  38#define SOF_RT5682_SSP_AMP_MASK                 (GENMASK(8, 6))
  39#define SOF_RT5682_SSP_AMP(quirk)       \
  40        (((quirk) << SOF_RT5682_SSP_AMP_SHIFT) & SOF_RT5682_SSP_AMP_MASK)
  41#define SOF_RT5682_MCLK_BYTCHT_EN               BIT(9)
  42#define SOF_RT5682_NUM_HDMIDEV_SHIFT            10
  43#define SOF_RT5682_NUM_HDMIDEV_MASK             (GENMASK(12, 10))
  44#define SOF_RT5682_NUM_HDMIDEV(quirk)   \
  45        ((quirk << SOF_RT5682_NUM_HDMIDEV_SHIFT) & SOF_RT5682_NUM_HDMIDEV_MASK)
  46#define SOF_RT1011_SPEAKER_AMP_PRESENT          BIT(13)
  47#define SOF_RT1015_SPEAKER_AMP_PRESENT          BIT(14)
  48#define SOF_RT1015_SPEAKER_AMP_100FS            BIT(15)
  49#define SOF_RT1015P_SPEAKER_AMP_PRESENT         BIT(16)
  50#define SOF_MAX98373_SPEAKER_AMP_PRESENT        BIT(17)
  51#define SOF_MAX98360A_SPEAKER_AMP_PRESENT       BIT(18)
  52
  53/* BT audio offload: reserve 3 bits for future */
  54#define SOF_BT_OFFLOAD_SSP_SHIFT                19
  55#define SOF_BT_OFFLOAD_SSP_MASK         (GENMASK(21, 19))
  56#define SOF_BT_OFFLOAD_SSP(quirk)       \
  57        (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK)
  58#define SOF_SSP_BT_OFFLOAD_PRESENT              BIT(22)
  59
  60/* Default: MCLK on, MCLK 19.2M, SSP0  */
  61static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
  62                                        SOF_RT5682_SSP_CODEC(0);
  63
  64static int is_legacy_cpu;
  65
  66static struct snd_soc_jack sof_hdmi[3];
  67
  68struct sof_hdmi_pcm {
  69        struct list_head head;
  70        struct snd_soc_dai *codec_dai;
  71        int device;
  72};
  73
  74struct sof_card_private {
  75        struct clk *mclk;
  76        struct snd_soc_jack sof_headset;
  77        struct list_head hdmi_pcm_list;
  78        bool common_hdmi_codec_drv;
  79};
  80
  81static int sof_rt5682_quirk_cb(const struct dmi_system_id *id)
  82{
  83        sof_rt5682_quirk = (unsigned long)id->driver_data;
  84        return 1;
  85}
  86
  87static const struct dmi_system_id sof_rt5682_quirk_table[] = {
  88        {
  89                .callback = sof_rt5682_quirk_cb,
  90                .matches = {
  91                        DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
  92                        DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max"),
  93                },
  94                .driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)),
  95        },
  96        {
  97                .callback = sof_rt5682_quirk_cb,
  98                .matches = {
  99                        DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
 100                        DMI_MATCH(DMI_PRODUCT_NAME, "UP-CHT01"),
 101                },
 102                .driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)),
 103        },
 104        {
 105                .callback = sof_rt5682_quirk_cb,
 106                .matches = {
 107                        DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
 108                        DMI_MATCH(DMI_PRODUCT_NAME, "WhiskeyLake Client"),
 109                },
 110                .driver_data = (void *)(SOF_RT5682_MCLK_EN |
 111                                        SOF_RT5682_MCLK_24MHZ |
 112                                        SOF_RT5682_SSP_CODEC(1)),
 113        },
 114        {
 115                /*
 116                 * Dooly is hatch family but using rt1015 amp so it
 117                 * requires a quirk before "Google_Hatch".
 118                 */
 119                .callback = sof_rt5682_quirk_cb,
 120                .matches = {
 121                        DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 122                        DMI_MATCH(DMI_PRODUCT_NAME, "Dooly"),
 123                },
 124                .driver_data = (void *)(SOF_RT5682_MCLK_EN |
 125                                        SOF_RT5682_MCLK_24MHZ |
 126                                        SOF_RT5682_SSP_CODEC(0) |
 127                                        SOF_SPEAKER_AMP_PRESENT |
 128                                        SOF_RT1015_SPEAKER_AMP_PRESENT |
 129                                        SOF_RT1015_SPEAKER_AMP_100FS |
 130                                        SOF_RT5682_SSP_AMP(1)),
 131        },
 132        {
 133                .callback = sof_rt5682_quirk_cb,
 134                .matches = {
 135                        DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Hatch"),
 136                },
 137                .driver_data = (void *)(SOF_RT5682_MCLK_EN |
 138                                        SOF_RT5682_MCLK_24MHZ |
 139                                        SOF_RT5682_SSP_CODEC(0) |
 140                                        SOF_SPEAKER_AMP_PRESENT |
 141                                        SOF_RT5682_SSP_AMP(1)),
 142        },
 143        {
 144                .callback = sof_rt5682_quirk_cb,
 145                .matches = {
 146                        DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
 147                        DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"),
 148                },
 149                .driver_data = (void *)(SOF_RT5682_MCLK_EN |
 150                                        SOF_RT5682_SSP_CODEC(0)),
 151        },
 152        {
 153                .callback = sof_rt5682_quirk_cb,
 154                .matches = {
 155                        DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Volteer"),
 156                        DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98373_ALC5682I_I2S_UP4"),
 157                },
 158                .driver_data = (void *)(SOF_RT5682_MCLK_EN |
 159                                        SOF_RT5682_SSP_CODEC(0) |
 160                                        SOF_SPEAKER_AMP_PRESENT |
 161                                        SOF_MAX98373_SPEAKER_AMP_PRESENT |
 162                                        SOF_RT5682_SSP_AMP(2) |
 163                                        SOF_RT5682_NUM_HDMIDEV(4)),
 164        },
 165        {
 166                .callback = sof_rt5682_quirk_cb,
 167                .matches = {
 168                        DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
 169                        DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"),
 170                        DMI_MATCH(DMI_OEM_STRING, "AUDIO-ADL_MAX98373_ALC5682I_I2S"),
 171                },
 172                .driver_data = (void *)(SOF_RT5682_MCLK_EN |
 173                                        SOF_RT5682_SSP_CODEC(0) |
 174                                        SOF_SPEAKER_AMP_PRESENT |
 175                                        SOF_MAX98373_SPEAKER_AMP_PRESENT |
 176                                        SOF_RT5682_SSP_AMP(2) |
 177                                        SOF_RT5682_NUM_HDMIDEV(4)),
 178        },
 179        {}
 180};
 181
 182static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd)
 183{
 184        struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
 185        struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
 186        struct sof_hdmi_pcm *pcm;
 187
 188        pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
 189        if (!pcm)
 190                return -ENOMEM;
 191
 192        /* dai_link id is 1:1 mapped to the PCM device */
 193        pcm->device = rtd->dai_link->id;
 194        pcm->codec_dai = dai;
 195
 196        list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
 197
 198        return 0;
 199}
 200
 201static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
 202{
 203        struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
 204        struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
 205        struct snd_soc_jack *jack;
 206        int ret;
 207
 208        /* need to enable ASRC function for 24MHz mclk rate */
 209        if ((sof_rt5682_quirk & SOF_RT5682_MCLK_EN) &&
 210            (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ)) {
 211                rt5682_sel_asrc_clk_src(component, RT5682_DA_STEREO1_FILTER |
 212                                        RT5682_AD_STEREO1_FILTER,
 213                                        RT5682_CLK_SEL_I2S1_ASRC);
 214        }
 215
 216        if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
 217                /*
 218                 * The firmware might enable the clock at
 219                 * boot (this information may or may not
 220                 * be reflected in the enable clock register).
 221                 * To change the rate we must disable the clock
 222                 * first to cover these cases. Due to common
 223                 * clock framework restrictions that do not allow
 224                 * to disable a clock that has not been enabled,
 225                 * we need to enable the clock first.
 226                 */
 227                ret = clk_prepare_enable(ctx->mclk);
 228                if (!ret)
 229                        clk_disable_unprepare(ctx->mclk);
 230
 231                ret = clk_set_rate(ctx->mclk, 19200000);
 232
 233                if (ret)
 234                        dev_err(rtd->dev, "unable to set MCLK rate\n");
 235        }
 236
 237        /*
 238         * Headset buttons map to the google Reference headset.
 239         * These can be configured by userspace.
 240         */
 241        ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
 242                                    SND_JACK_HEADSET | SND_JACK_BTN_0 |
 243                                    SND_JACK_BTN_1 | SND_JACK_BTN_2 |
 244                                    SND_JACK_BTN_3,
 245                                    &ctx->sof_headset, NULL, 0);
 246        if (ret) {
 247                dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
 248                return ret;
 249        }
 250
 251        jack = &ctx->sof_headset;
 252
 253        snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
 254        snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
 255        snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
 256        snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
 257        ret = snd_soc_component_set_jack(component, jack, NULL);
 258
 259        if (ret) {
 260                dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
 261                return ret;
 262        }
 263
 264        return ret;
 265};
 266
 267static void sof_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd)
 268{
 269        struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
 270
 271        snd_soc_component_set_jack(component, NULL, NULL);
 272}
 273
 274static int sof_rt5682_hw_params(struct snd_pcm_substream *substream,
 275                                struct snd_pcm_hw_params *params)
 276{
 277        struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
 278        struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
 279        struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
 280        int clk_id, clk_freq, pll_out, ret;
 281
 282        if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) {
 283                if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
 284                        ret = clk_prepare_enable(ctx->mclk);
 285                        if (ret < 0) {
 286                                dev_err(rtd->dev,
 287                                        "could not configure MCLK state");
 288                                return ret;
 289                        }
 290                }
 291
 292                clk_id = RT5682_PLL1_S_MCLK;
 293
 294                /* get the tplg configured mclk. */
 295                clk_freq = sof_dai_get_mclk(rtd);
 296
 297                /* mclk from the quirk is the first choice */
 298                if (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ) {
 299                        if (clk_freq != 24000000)
 300                                dev_warn(rtd->dev, "configure wrong mclk in tplg, please use 24MHz.\n");
 301                        clk_freq = 24000000;
 302                } else if (clk_freq == 0) {
 303                        /* use default mclk if not specified correct in topology */
 304                        clk_freq = 19200000;
 305                } else if (clk_freq < 0) {
 306                        return clk_freq;
 307                }
 308        } else {
 309                clk_id = RT5682_PLL1_S_BCLK1;
 310                clk_freq = params_rate(params) * 50;
 311        }
 312
 313        pll_out = params_rate(params) * 512;
 314
 315        ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out);
 316        if (ret < 0)
 317                dev_err(rtd->dev, "snd_soc_dai_set_pll err = %d\n", ret);
 318
 319        /* Configure sysclk for codec */
 320        ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1,
 321                                     pll_out, SND_SOC_CLOCK_IN);
 322        if (ret < 0)
 323                dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
 324
 325        /*
 326         * slot_width should equal or large than data length, set them
 327         * be the same
 328         */
 329        ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0, 0x0, 2,
 330                                       params_width(params));
 331        if (ret < 0) {
 332                dev_err(rtd->dev, "set TDM slot err:%d\n", ret);
 333                return ret;
 334        }
 335
 336        return ret;
 337}
 338
 339static struct snd_soc_ops sof_rt5682_ops = {
 340        .hw_params = sof_rt5682_hw_params,
 341};
 342
 343static int sof_rt1015_hw_params(struct snd_pcm_substream *substream,
 344                                struct snd_pcm_hw_params *params)
 345{
 346        struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
 347        struct snd_soc_card *card = rtd->card;
 348        struct snd_soc_dai *codec_dai;
 349        int i, fs, ret;
 350
 351        if (!snd_soc_card_get_codec_dai(card, "rt1015-aif"))
 352                return 0;
 353
 354        if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_100FS)
 355                fs = 100;
 356        else
 357                fs = 64;
 358
 359        for_each_rtd_codec_dais(rtd, i, codec_dai) {
 360                ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK,
 361                                          params_rate(params) * fs,
 362                                          params_rate(params) * 256);
 363                if (ret < 0) {
 364                        dev_err(card->dev, "failed to set pll\n");
 365                        return ret;
 366                }
 367                /* Configure sysclk for codec */
 368                ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL,
 369                                             params_rate(params) * 256,
 370                                             SND_SOC_CLOCK_IN);
 371                if (ret < 0) {
 372                        dev_err(card->dev, "failed to set sysclk\n");
 373                        return ret;
 374                }
 375
 376                if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_100FS) {
 377                        if (!strcmp(codec_dai->component->name, "i2c-10EC1015:00")) {
 378                                ret = snd_soc_dai_set_tdm_slot(codec_dai,
 379                                                               0x0, 0x1, 4, 24);
 380                                if (ret < 0) {
 381                                        dev_err(card->dev, "failed to set tdm slot\n");
 382                                        return ret;
 383                                }
 384                        }
 385
 386                        if (!strcmp(codec_dai->component->name, "i2c-10EC1015:01")) {
 387                                ret = snd_soc_dai_set_tdm_slot(codec_dai,
 388                                                               0x0, 0x2, 4, 24);
 389                                if (ret < 0) {
 390                                        dev_err(card->dev, "failed to set tdm slot\n");
 391                                        return ret;
 392                                }
 393                        }
 394                }
 395        }
 396
 397        return 0;
 398}
 399
 400static struct snd_soc_ops sof_rt1015_ops = {
 401        .hw_params = sof_rt1015_hw_params,
 402};
 403
 404static struct snd_soc_dai_link_component platform_component[] = {
 405        {
 406                /* name might be overridden during probe */
 407                .name = "0000:00:1f.3"
 408        }
 409};
 410
 411static int sof_card_late_probe(struct snd_soc_card *card)
 412{
 413        struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
 414        struct snd_soc_component *component = NULL;
 415        struct snd_soc_dapm_context *dapm = &card->dapm;
 416        char jack_name[NAME_SIZE];
 417        struct sof_hdmi_pcm *pcm;
 418        int err;
 419        int i = 0;
 420
 421        /* HDMI is not supported by SOF on Baytrail/CherryTrail */
 422        if (is_legacy_cpu)
 423                return 0;
 424
 425        if (list_empty(&ctx->hdmi_pcm_list))
 426                return -EINVAL;
 427
 428        if (ctx->common_hdmi_codec_drv) {
 429                pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm,
 430                                       head);
 431                component = pcm->codec_dai->component;
 432                return hda_dsp_hdmi_build_controls(card, component);
 433        }
 434
 435        list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 436                component = pcm->codec_dai->component;
 437                snprintf(jack_name, sizeof(jack_name),
 438                         "HDMI/DP, pcm=%d Jack", pcm->device);
 439                err = snd_soc_card_jack_new(card, jack_name,
 440                                            SND_JACK_AVOUT, &sof_hdmi[i],
 441                                            NULL, 0);
 442
 443                if (err)
 444                        return err;
 445
 446                err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 447                                          &sof_hdmi[i]);
 448                if (err < 0)
 449                        return err;
 450
 451                i++;
 452        }
 453
 454        if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) {
 455                /* Disable Left and Right Spk pin after boot */
 456                snd_soc_dapm_disable_pin(dapm, "Left Spk");
 457                snd_soc_dapm_disable_pin(dapm, "Right Spk");
 458                err = snd_soc_dapm_sync(dapm);
 459                if (err < 0)
 460                        return err;
 461        }
 462        return hdac_hdmi_jack_port_init(component, &card->dapm);
 463}
 464
 465static const struct snd_kcontrol_new sof_controls[] = {
 466        SOC_DAPM_PIN_SWITCH("Headphone Jack"),
 467        SOC_DAPM_PIN_SWITCH("Headset Mic"),
 468        SOC_DAPM_PIN_SWITCH("Left Spk"),
 469        SOC_DAPM_PIN_SWITCH("Right Spk"),
 470
 471};
 472
 473static const struct snd_soc_dapm_widget sof_widgets[] = {
 474        SND_SOC_DAPM_HP("Headphone Jack", NULL),
 475        SND_SOC_DAPM_MIC("Headset Mic", NULL),
 476        SND_SOC_DAPM_SPK("Left Spk", NULL),
 477        SND_SOC_DAPM_SPK("Right Spk", NULL),
 478};
 479
 480static const struct snd_soc_dapm_widget dmic_widgets[] = {
 481        SND_SOC_DAPM_MIC("SoC DMIC", NULL),
 482};
 483
 484static const struct snd_soc_dapm_route sof_map[] = {
 485        /* HP jack connectors - unknown if we have jack detection */
 486        { "Headphone Jack", NULL, "HPOL" },
 487        { "Headphone Jack", NULL, "HPOR" },
 488
 489        /* other jacks */
 490        { "IN1P", NULL, "Headset Mic" },
 491};
 492
 493static const struct snd_soc_dapm_route speaker_map_lr[] = {
 494        { "Left Spk", NULL, "Left SPO" },
 495        { "Right Spk", NULL, "Right SPO" },
 496};
 497
 498static const struct snd_soc_dapm_route dmic_map[] = {
 499        /* digital mics */
 500        {"DMic", NULL, "SoC DMIC"},
 501};
 502
 503static int speaker_codec_init_lr(struct snd_soc_pcm_runtime *rtd)
 504{
 505        return snd_soc_dapm_add_routes(&rtd->card->dapm, speaker_map_lr,
 506                                       ARRAY_SIZE(speaker_map_lr));
 507}
 508
 509static int dmic_init(struct snd_soc_pcm_runtime *rtd)
 510{
 511        struct snd_soc_card *card = rtd->card;
 512        int ret;
 513
 514        ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets,
 515                                        ARRAY_SIZE(dmic_widgets));
 516        if (ret) {
 517                dev_err(card->dev, "DMic widget addition failed: %d\n", ret);
 518                /* Don't need to add routes if widget addition failed */
 519                return ret;
 520        }
 521
 522        ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map,
 523                                      ARRAY_SIZE(dmic_map));
 524
 525        if (ret)
 526                dev_err(card->dev, "DMic map addition failed: %d\n", ret);
 527
 528        return ret;
 529}
 530
 531static struct snd_soc_codec_conf rt1015_amp_conf[] = {
 532        {
 533                .dlc = COMP_CODEC_CONF("i2c-10EC1015:00"),
 534                .name_prefix = "Left",
 535        },
 536        {
 537                .dlc = COMP_CODEC_CONF("i2c-10EC1015:01"),
 538                .name_prefix = "Right",
 539        },
 540};
 541
 542/* sof audio machine driver for rt5682 codec */
 543static struct snd_soc_card sof_audio_card_rt5682 = {
 544        .name = "rt5682", /* the sof- prefix is added by the core */
 545        .owner = THIS_MODULE,
 546        .controls = sof_controls,
 547        .num_controls = ARRAY_SIZE(sof_controls),
 548        .dapm_widgets = sof_widgets,
 549        .num_dapm_widgets = ARRAY_SIZE(sof_widgets),
 550        .dapm_routes = sof_map,
 551        .num_dapm_routes = ARRAY_SIZE(sof_map),
 552        .fully_routed = true,
 553        .late_probe = sof_card_late_probe,
 554};
 555
 556static struct snd_soc_dai_link_component rt5682_component[] = {
 557        {
 558                .name = "i2c-10EC5682:00",
 559                .dai_name = "rt5682-aif1",
 560        }
 561};
 562
 563static struct snd_soc_dai_link_component dmic_component[] = {
 564        {
 565                .name = "dmic-codec",
 566                .dai_name = "dmic-hifi",
 567        }
 568};
 569
 570static struct snd_soc_dai_link_component rt1015_components[] = {
 571        {
 572                .name = "i2c-10EC1015:00",
 573                .dai_name = "rt1015-aif",
 574        },
 575        {
 576                .name = "i2c-10EC1015:01",
 577                .dai_name = "rt1015-aif",
 578        },
 579};
 580
 581static struct snd_soc_dai_link_component dummy_component[] = {
 582        {
 583                .name = "snd-soc-dummy",
 584                .dai_name = "snd-soc-dummy-dai",
 585        }
 586};
 587
 588static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
 589                                                          int ssp_codec,
 590                                                          int ssp_amp,
 591                                                          int dmic_be_num,
 592                                                          int hdmi_num)
 593{
 594        struct snd_soc_dai_link_component *idisp_components;
 595        struct snd_soc_dai_link_component *cpus;
 596        struct snd_soc_dai_link *links;
 597        int i, id = 0;
 598
 599        links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) *
 600                             sof_audio_card_rt5682.num_links, GFP_KERNEL);
 601        cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component) *
 602                             sof_audio_card_rt5682.num_links, GFP_KERNEL);
 603        if (!links || !cpus)
 604                goto devm_err;
 605
 606        /* codec SSP */
 607        links[id].name = devm_kasprintf(dev, GFP_KERNEL,
 608                                        "SSP%d-Codec", ssp_codec);
 609        if (!links[id].name)
 610                goto devm_err;
 611
 612        links[id].id = id;
 613        links[id].codecs = rt5682_component;
 614        links[id].num_codecs = ARRAY_SIZE(rt5682_component);
 615        links[id].platforms = platform_component;
 616        links[id].num_platforms = ARRAY_SIZE(platform_component);
 617        links[id].init = sof_rt5682_codec_init;
 618        links[id].exit = sof_rt5682_codec_exit;
 619        links[id].ops = &sof_rt5682_ops;
 620        links[id].dpcm_playback = 1;
 621        links[id].dpcm_capture = 1;
 622        links[id].no_pcm = 1;
 623        links[id].cpus = &cpus[id];
 624        links[id].num_cpus = 1;
 625        if (is_legacy_cpu) {
 626                links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
 627                                                          "ssp%d-port",
 628                                                          ssp_codec);
 629                if (!links[id].cpus->dai_name)
 630                        goto devm_err;
 631        } else {
 632                /*
 633                 * Currently, On SKL+ platforms MCLK will be turned off in sof
 634                 * runtime suspended, and it will go into runtime suspended
 635                 * right after playback is stop. However, rt5682 will output
 636                 * static noise if sysclk turns off during playback. Set
 637                 * ignore_pmdown_time to power down rt5682 immediately and
 638                 * avoid the noise.
 639                 * It can be removed once we can control MCLK by driver.
 640                 */
 641                links[id].ignore_pmdown_time = 1;
 642                links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
 643                                                          "SSP%d Pin",
 644                                                          ssp_codec);
 645                if (!links[id].cpus->dai_name)
 646                        goto devm_err;
 647        }
 648        id++;
 649
 650        /* dmic */
 651        if (dmic_be_num > 0) {
 652                /* at least we have dmic01 */
 653                links[id].name = "dmic01";
 654                links[id].cpus = &cpus[id];
 655                links[id].cpus->dai_name = "DMIC01 Pin";
 656                links[id].init = dmic_init;
 657                if (dmic_be_num > 1) {
 658                        /* set up 2 BE links at most */
 659                        links[id + 1].name = "dmic16k";
 660                        links[id + 1].cpus = &cpus[id + 1];
 661                        links[id + 1].cpus->dai_name = "DMIC16k Pin";
 662                        dmic_be_num = 2;
 663                }
 664        }
 665
 666        for (i = 0; i < dmic_be_num; i++) {
 667                links[id].id = id;
 668                links[id].num_cpus = 1;
 669                links[id].codecs = dmic_component;
 670                links[id].num_codecs = ARRAY_SIZE(dmic_component);
 671                links[id].platforms = platform_component;
 672                links[id].num_platforms = ARRAY_SIZE(platform_component);
 673                links[id].ignore_suspend = 1;
 674                links[id].dpcm_capture = 1;
 675                links[id].no_pcm = 1;
 676                id++;
 677        }
 678
 679        /* HDMI */
 680        if (hdmi_num > 0) {
 681                idisp_components = devm_kzalloc(dev,
 682                                   sizeof(struct snd_soc_dai_link_component) *
 683                                   hdmi_num, GFP_KERNEL);
 684                if (!idisp_components)
 685                        goto devm_err;
 686        }
 687        for (i = 1; i <= hdmi_num; i++) {
 688                links[id].name = devm_kasprintf(dev, GFP_KERNEL,
 689                                                "iDisp%d", i);
 690                if (!links[id].name)
 691                        goto devm_err;
 692
 693                links[id].id = id;
 694                links[id].cpus = &cpus[id];
 695                links[id].num_cpus = 1;
 696                links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
 697                                                          "iDisp%d Pin", i);
 698                if (!links[id].cpus->dai_name)
 699                        goto devm_err;
 700
 701                idisp_components[i - 1].name = "ehdaudio0D2";
 702                idisp_components[i - 1].dai_name = devm_kasprintf(dev,
 703                                                                  GFP_KERNEL,
 704                                                                  "intel-hdmi-hifi%d",
 705                                                                  i);
 706                if (!idisp_components[i - 1].dai_name)
 707                        goto devm_err;
 708
 709                links[id].codecs = &idisp_components[i - 1];
 710                links[id].num_codecs = 1;
 711                links[id].platforms = platform_component;
 712                links[id].num_platforms = ARRAY_SIZE(platform_component);
 713                links[id].init = sof_hdmi_init;
 714                links[id].dpcm_playback = 1;
 715                links[id].no_pcm = 1;
 716                id++;
 717        }
 718
 719        /* speaker amp */
 720        if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) {
 721                links[id].name = devm_kasprintf(dev, GFP_KERNEL,
 722                                                "SSP%d-Codec", ssp_amp);
 723                if (!links[id].name)
 724                        goto devm_err;
 725
 726                links[id].id = id;
 727                if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_PRESENT) {
 728                        links[id].codecs = rt1015_components;
 729                        links[id].num_codecs = ARRAY_SIZE(rt1015_components);
 730                        links[id].init = speaker_codec_init_lr;
 731                        links[id].ops = &sof_rt1015_ops;
 732                } else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) {
 733                        sof_rt1015p_dai_link(&links[id]);
 734                } else if (sof_rt5682_quirk &
 735                                SOF_MAX98373_SPEAKER_AMP_PRESENT) {
 736                        links[id].codecs = max_98373_components;
 737                        links[id].num_codecs = ARRAY_SIZE(max_98373_components);
 738                        links[id].init = max_98373_spk_codec_init;
 739                        links[id].ops = &max_98373_ops;
 740                        /* feedback stream */
 741                        links[id].dpcm_capture = 1;
 742                } else if (sof_rt5682_quirk &
 743                                SOF_MAX98360A_SPEAKER_AMP_PRESENT) {
 744                        max_98360a_dai_link(&links[id]);
 745                } else if (sof_rt5682_quirk &
 746                                SOF_RT1011_SPEAKER_AMP_PRESENT) {
 747                        sof_rt1011_dai_link(&links[id]);
 748                } else {
 749                        max_98357a_dai_link(&links[id]);
 750                }
 751                links[id].platforms = platform_component;
 752                links[id].num_platforms = ARRAY_SIZE(platform_component);
 753                links[id].dpcm_playback = 1;
 754                links[id].no_pcm = 1;
 755                links[id].cpus = &cpus[id];
 756                links[id].num_cpus = 1;
 757                if (is_legacy_cpu) {
 758                        links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
 759                                                                  "ssp%d-port",
 760                                                                  ssp_amp);
 761                        if (!links[id].cpus->dai_name)
 762                                goto devm_err;
 763
 764                } else {
 765                        links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
 766                                                                  "SSP%d Pin",
 767                                                                  ssp_amp);
 768                        if (!links[id].cpus->dai_name)
 769                                goto devm_err;
 770                }
 771                id++;
 772        }
 773
 774        /* BT audio offload */
 775        if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) {
 776                int port = (sof_rt5682_quirk & SOF_BT_OFFLOAD_SSP_MASK) >>
 777                                SOF_BT_OFFLOAD_SSP_SHIFT;
 778
 779                links[id].id = id;
 780                links[id].cpus = &cpus[id];
 781                links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
 782                                                          "SSP%d Pin", port);
 783                if (!links[id].cpus->dai_name)
 784                        goto devm_err;
 785                links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port);
 786                if (!links[id].name)
 787                        goto devm_err;
 788                links[id].codecs = dummy_component;
 789                links[id].num_codecs = ARRAY_SIZE(dummy_component);
 790                links[id].platforms = platform_component;
 791                links[id].num_platforms = ARRAY_SIZE(platform_component);
 792                links[id].dpcm_playback = 1;
 793                links[id].dpcm_capture = 1;
 794                links[id].no_pcm = 1;
 795                links[id].num_cpus = 1;
 796        }
 797
 798        return links;
 799devm_err:
 800        return NULL;
 801}
 802
 803static int sof_audio_probe(struct platform_device *pdev)
 804{
 805        struct snd_soc_dai_link *dai_links;
 806        struct snd_soc_acpi_mach *mach;
 807        struct sof_card_private *ctx;
 808        int dmic_be_num, hdmi_num;
 809        int ret, ssp_amp, ssp_codec;
 810
 811        ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
 812        if (!ctx)
 813                return -ENOMEM;
 814
 815        if (pdev->id_entry && pdev->id_entry->driver_data)
 816                sof_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data;
 817
 818        dmi_check_system(sof_rt5682_quirk_table);
 819
 820        mach = pdev->dev.platform_data;
 821
 822        /* A speaker amp might not be present when the quirk claims one is.
 823         * Detect this via whether the machine driver match includes quirk_data.
 824         */
 825        if ((sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) && !mach->quirk_data)
 826                sof_rt5682_quirk &= ~SOF_SPEAKER_AMP_PRESENT;
 827
 828        if (soc_intel_is_byt() || soc_intel_is_cht()) {
 829                is_legacy_cpu = 1;
 830                dmic_be_num = 0;
 831                hdmi_num = 0;
 832                /* default quirk for legacy cpu */
 833                sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
 834                                                SOF_RT5682_MCLK_BYTCHT_EN |
 835                                                SOF_RT5682_SSP_CODEC(2);
 836        } else {
 837                dmic_be_num = 2;
 838                hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >>
 839                         SOF_RT5682_NUM_HDMIDEV_SHIFT;
 840                /* default number of HDMI DAI's */
 841                if (!hdmi_num)
 842                        hdmi_num = 3;
 843        }
 844
 845        /* need to get main clock from pmc */
 846        if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
 847                ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
 848                if (IS_ERR(ctx->mclk)) {
 849                        ret = PTR_ERR(ctx->mclk);
 850
 851                        dev_err(&pdev->dev,
 852                                "Failed to get MCLK from pmc_plt_clk_3: %d\n",
 853                                ret);
 854                        return ret;
 855                }
 856
 857                ret = clk_prepare_enable(ctx->mclk);
 858                if (ret < 0) {
 859                        dev_err(&pdev->dev,
 860                                "could not configure MCLK state");
 861                        return ret;
 862                }
 863        }
 864
 865        dev_dbg(&pdev->dev, "sof_rt5682_quirk = %lx\n", sof_rt5682_quirk);
 866
 867        ssp_amp = (sof_rt5682_quirk & SOF_RT5682_SSP_AMP_MASK) >>
 868                        SOF_RT5682_SSP_AMP_SHIFT;
 869
 870        ssp_codec = sof_rt5682_quirk & SOF_RT5682_SSP_CODEC_MASK;
 871
 872        /* compute number of dai links */
 873        sof_audio_card_rt5682.num_links = 1 + dmic_be_num + hdmi_num;
 874
 875        if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT)
 876                sof_audio_card_rt5682.num_links++;
 877
 878        if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT)
 879                max_98373_set_codec_conf(&sof_audio_card_rt5682);
 880        else if (sof_rt5682_quirk & SOF_RT1011_SPEAKER_AMP_PRESENT)
 881                sof_rt1011_codec_conf(&sof_audio_card_rt5682);
 882        else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT)
 883                sof_rt1015p_codec_conf(&sof_audio_card_rt5682);
 884
 885        if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
 886                sof_audio_card_rt5682.num_links++;
 887
 888        dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp,
 889                                              dmic_be_num, hdmi_num);
 890        if (!dai_links)
 891                return -ENOMEM;
 892
 893        sof_audio_card_rt5682.dai_link = dai_links;
 894
 895        if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_PRESENT) {
 896                sof_audio_card_rt5682.codec_conf = rt1015_amp_conf;
 897                sof_audio_card_rt5682.num_configs = ARRAY_SIZE(rt1015_amp_conf);
 898        }
 899
 900        INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
 901
 902        sof_audio_card_rt5682.dev = &pdev->dev;
 903
 904        /* set platform name for each dailink */
 905        ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_rt5682,
 906                                                    mach->mach_params.platform);
 907        if (ret)
 908                return ret;
 909
 910        ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
 911
 912        snd_soc_card_set_drvdata(&sof_audio_card_rt5682, ctx);
 913
 914        return devm_snd_soc_register_card(&pdev->dev,
 915                                          &sof_audio_card_rt5682);
 916}
 917
 918static const struct platform_device_id board_ids[] = {
 919        {
 920                .name = "sof_rt5682",
 921        },
 922        {
 923                .name = "tgl_mx98357a_rt5682",
 924                .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
 925                                        SOF_RT5682_SSP_CODEC(0) |
 926                                        SOF_SPEAKER_AMP_PRESENT |
 927                                        SOF_RT5682_SSP_AMP(1) |
 928                                        SOF_RT5682_NUM_HDMIDEV(4) |
 929                                        SOF_BT_OFFLOAD_SSP(2) |
 930                                        SOF_SSP_BT_OFFLOAD_PRESENT),
 931        },
 932        {
 933                .name = "jsl_rt5682_rt1015",
 934                .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
 935                                        SOF_RT5682_MCLK_24MHZ |
 936                                        SOF_RT5682_SSP_CODEC(0) |
 937                                        SOF_SPEAKER_AMP_PRESENT |
 938                                        SOF_RT1015_SPEAKER_AMP_PRESENT |
 939                                        SOF_RT5682_SSP_AMP(1)),
 940        },
 941        {
 942                .name = "tgl_mx98373_rt5682",
 943                .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
 944                                        SOF_RT5682_SSP_CODEC(0) |
 945                                        SOF_SPEAKER_AMP_PRESENT |
 946                                        SOF_MAX98373_SPEAKER_AMP_PRESENT |
 947                                        SOF_RT5682_SSP_AMP(1) |
 948                                        SOF_RT5682_NUM_HDMIDEV(4) |
 949                                        SOF_BT_OFFLOAD_SSP(2) |
 950                                        SOF_SSP_BT_OFFLOAD_PRESENT),
 951        },
 952        {
 953                .name = "jsl_rt5682_mx98360a",
 954                .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
 955                                        SOF_RT5682_MCLK_24MHZ |
 956                                        SOF_RT5682_SSP_CODEC(0) |
 957                                        SOF_SPEAKER_AMP_PRESENT |
 958                                        SOF_MAX98360A_SPEAKER_AMP_PRESENT |
 959                                        SOF_RT5682_SSP_AMP(1)),
 960        },
 961        {
 962                .name = "cml_rt1015_rt5682",
 963                .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
 964                                        SOF_RT5682_MCLK_24MHZ |
 965                                        SOF_RT5682_SSP_CODEC(0) |
 966                                        SOF_SPEAKER_AMP_PRESENT |
 967                                        SOF_RT1015_SPEAKER_AMP_PRESENT |
 968                                        SOF_RT1015_SPEAKER_AMP_100FS |
 969                                        SOF_RT5682_SSP_AMP(1)),
 970        },
 971        {
 972                .name = "tgl_rt1011_rt5682",
 973                .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
 974                                        SOF_RT5682_SSP_CODEC(0) |
 975                                        SOF_SPEAKER_AMP_PRESENT |
 976                                        SOF_RT1011_SPEAKER_AMP_PRESENT |
 977                                        SOF_RT5682_SSP_AMP(1) |
 978                                        SOF_RT5682_NUM_HDMIDEV(4) |
 979                                        SOF_BT_OFFLOAD_SSP(2) |
 980                                        SOF_SSP_BT_OFFLOAD_PRESENT),
 981        },
 982        {
 983                .name = "jsl_rt5682_rt1015p",
 984                .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
 985                                        SOF_RT5682_MCLK_24MHZ |
 986                                        SOF_RT5682_SSP_CODEC(0) |
 987                                        SOF_SPEAKER_AMP_PRESENT |
 988                                        SOF_RT1015P_SPEAKER_AMP_PRESENT |
 989                                        SOF_RT5682_SSP_AMP(1)),
 990        },
 991        {
 992                .name = "adl_mx98373_rt5682",
 993                .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
 994                                        SOF_RT5682_SSP_CODEC(0) |
 995                                        SOF_SPEAKER_AMP_PRESENT |
 996                                        SOF_MAX98373_SPEAKER_AMP_PRESENT |
 997                                        SOF_RT5682_SSP_AMP(1) |
 998                                        SOF_RT5682_NUM_HDMIDEV(4) |
 999                                        SOF_BT_OFFLOAD_SSP(2) |
1000                                        SOF_SSP_BT_OFFLOAD_PRESENT),
1001        },
1002        {
1003                .name = "adl_mx98357a_rt5682",
1004                .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1005                                        SOF_RT5682_SSP_CODEC(0) |
1006                                        SOF_SPEAKER_AMP_PRESENT |
1007                                        SOF_RT5682_SSP_AMP(2) |
1008                                        SOF_RT5682_NUM_HDMIDEV(4)),
1009        },
1010        { }
1011};
1012MODULE_DEVICE_TABLE(platform, board_ids);
1013
1014static struct platform_driver sof_audio = {
1015        .probe = sof_audio_probe,
1016        .driver = {
1017                .name = "sof_rt5682",
1018                .pm = &snd_soc_pm_ops,
1019        },
1020        .id_table = board_ids,
1021};
1022module_platform_driver(sof_audio)
1023
1024/* Module information */
1025MODULE_DESCRIPTION("SOF Audio Machine driver");
1026MODULE_AUTHOR("Bard Liao <bard.liao@intel.com>");
1027MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
1028MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
1029MODULE_LICENSE("GPL v2");
1030MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
1031MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
1032