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