cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sof_rt5682.c (31978B)


      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/rt5682s.h>
     22#include <sound/soc-acpi.h>
     23#include "../../codecs/rt5682.h"
     24#include "../../codecs/rt5682s.h"
     25#include "../../codecs/hdac_hdmi.h"
     26#include "../common/soc-intel-quirks.h"
     27#include "hda_dsp_common.h"
     28#include "sof_maxim_common.h"
     29#include "sof_realtek_common.h"
     30
     31#define NAME_SIZE 32
     32
     33#define SOF_RT5682_SSP_CODEC(quirk)		((quirk) & GENMASK(2, 0))
     34#define SOF_RT5682_SSP_CODEC_MASK			(GENMASK(2, 0))
     35#define SOF_RT5682_MCLK_EN			BIT(3)
     36#define SOF_RT5682_MCLK_24MHZ			BIT(4)
     37#define SOF_SPEAKER_AMP_PRESENT		BIT(5)
     38#define SOF_RT5682_SSP_AMP_SHIFT		6
     39#define SOF_RT5682_SSP_AMP_MASK                 (GENMASK(8, 6))
     40#define SOF_RT5682_SSP_AMP(quirk)	\
     41	(((quirk) << SOF_RT5682_SSP_AMP_SHIFT) & SOF_RT5682_SSP_AMP_MASK)
     42#define SOF_RT5682_MCLK_BYTCHT_EN		BIT(9)
     43#define SOF_RT5682_NUM_HDMIDEV_SHIFT		10
     44#define SOF_RT5682_NUM_HDMIDEV_MASK		(GENMASK(12, 10))
     45#define SOF_RT5682_NUM_HDMIDEV(quirk)	\
     46	((quirk << SOF_RT5682_NUM_HDMIDEV_SHIFT) & SOF_RT5682_NUM_HDMIDEV_MASK)
     47#define SOF_RT1011_SPEAKER_AMP_PRESENT		BIT(13)
     48#define SOF_RT1015_SPEAKER_AMP_PRESENT		BIT(14)
     49#define SOF_RT1015_SPEAKER_AMP_100FS		BIT(15)
     50#define SOF_RT1015P_SPEAKER_AMP_PRESENT		BIT(16)
     51#define SOF_MAX98373_SPEAKER_AMP_PRESENT	BIT(17)
     52#define SOF_MAX98360A_SPEAKER_AMP_PRESENT	BIT(18)
     53
     54/* BT audio offload: reserve 3 bits for future */
     55#define SOF_BT_OFFLOAD_SSP_SHIFT		19
     56#define SOF_BT_OFFLOAD_SSP_MASK		(GENMASK(21, 19))
     57#define SOF_BT_OFFLOAD_SSP(quirk)	\
     58	(((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK)
     59#define SOF_SSP_BT_OFFLOAD_PRESENT		BIT(22)
     60#define SOF_RT5682S_HEADPHONE_CODEC_PRESENT	BIT(23)
     61#define SOF_MAX98390_SPEAKER_AMP_PRESENT	BIT(24)
     62#define SOF_MAX98390_TWEETER_SPEAKER_PRESENT	BIT(25)
     63#define SOF_RT1019_SPEAKER_AMP_PRESENT	BIT(26)
     64
     65
     66/* Default: MCLK on, MCLK 19.2M, SSP0  */
     67static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
     68					SOF_RT5682_SSP_CODEC(0);
     69
     70static int is_legacy_cpu;
     71
     72static struct snd_soc_jack sof_hdmi[3];
     73
     74struct sof_hdmi_pcm {
     75	struct list_head head;
     76	struct snd_soc_dai *codec_dai;
     77	int device;
     78};
     79
     80struct sof_card_private {
     81	struct clk *mclk;
     82	struct snd_soc_jack sof_headset;
     83	struct list_head hdmi_pcm_list;
     84	bool common_hdmi_codec_drv;
     85	bool idisp_codec;
     86};
     87
     88static int sof_rt5682_quirk_cb(const struct dmi_system_id *id)
     89{
     90	sof_rt5682_quirk = (unsigned long)id->driver_data;
     91	return 1;
     92}
     93
     94static const struct dmi_system_id sof_rt5682_quirk_table[] = {
     95	{
     96		.callback = sof_rt5682_quirk_cb,
     97		.matches = {
     98			DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
     99			DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max"),
    100		},
    101		.driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)),
    102	},
    103	{
    104		.callback = sof_rt5682_quirk_cb,
    105		.matches = {
    106			DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
    107			DMI_MATCH(DMI_PRODUCT_NAME, "UP-CHT01"),
    108		},
    109		.driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)),
    110	},
    111	{
    112		.callback = sof_rt5682_quirk_cb,
    113		.matches = {
    114			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
    115			DMI_MATCH(DMI_PRODUCT_NAME, "WhiskeyLake Client"),
    116		},
    117		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
    118					SOF_RT5682_MCLK_24MHZ |
    119					SOF_RT5682_SSP_CODEC(1)),
    120	},
    121	{
    122		/*
    123		 * Dooly is hatch family but using rt1015 amp so it
    124		 * requires a quirk before "Google_Hatch".
    125		 */
    126		.callback = sof_rt5682_quirk_cb,
    127		.matches = {
    128			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
    129			DMI_MATCH(DMI_PRODUCT_NAME, "Dooly"),
    130		},
    131		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
    132					SOF_RT5682_MCLK_24MHZ |
    133					SOF_RT5682_SSP_CODEC(0) |
    134					SOF_SPEAKER_AMP_PRESENT |
    135					SOF_RT1015_SPEAKER_AMP_PRESENT |
    136					SOF_RT1015_SPEAKER_AMP_100FS |
    137					SOF_RT5682_SSP_AMP(1)),
    138	},
    139	{
    140		.callback = sof_rt5682_quirk_cb,
    141		.matches = {
    142			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Hatch"),
    143		},
    144		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
    145					SOF_RT5682_MCLK_24MHZ |
    146					SOF_RT5682_SSP_CODEC(0) |
    147					SOF_SPEAKER_AMP_PRESENT |
    148					SOF_RT5682_SSP_AMP(1)),
    149	},
    150	{
    151		.callback = sof_rt5682_quirk_cb,
    152		.matches = {
    153			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
    154			DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"),
    155		},
    156		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
    157					SOF_RT5682_SSP_CODEC(0)),
    158	},
    159	{
    160		.callback = sof_rt5682_quirk_cb,
    161		.matches = {
    162			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Volteer"),
    163			DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98373_ALC5682I_I2S_UP4"),
    164		},
    165		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
    166					SOF_RT5682_SSP_CODEC(0) |
    167					SOF_SPEAKER_AMP_PRESENT |
    168					SOF_MAX98373_SPEAKER_AMP_PRESENT |
    169					SOF_RT5682_SSP_AMP(2) |
    170					SOF_RT5682_NUM_HDMIDEV(4)),
    171	},
    172	{
    173		.callback = sof_rt5682_quirk_cb,
    174		.matches = {
    175			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
    176			DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"),
    177			DMI_MATCH(DMI_OEM_STRING, "AUDIO-ADL_MAX98373_ALC5682I_I2S"),
    178		},
    179		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
    180					SOF_RT5682_SSP_CODEC(0) |
    181					SOF_SPEAKER_AMP_PRESENT |
    182					SOF_MAX98373_SPEAKER_AMP_PRESENT |
    183					SOF_RT5682_SSP_AMP(2) |
    184					SOF_RT5682_NUM_HDMIDEV(4)),
    185	},
    186	{
    187		.callback = sof_rt5682_quirk_cb,
    188		.matches = {
    189			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Brya"),
    190			DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98390_ALC5682I_I2S"),
    191		},
    192		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
    193					SOF_RT5682_SSP_CODEC(0) |
    194					SOF_SPEAKER_AMP_PRESENT |
    195					SOF_MAX98390_SPEAKER_AMP_PRESENT |
    196					SOF_RT5682_SSP_AMP(2) |
    197					SOF_RT5682_NUM_HDMIDEV(4)),
    198	},
    199	{
    200		.callback = sof_rt5682_quirk_cb,
    201		.matches = {
    202			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Brya"),
    203			DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98390_ALC5682I_I2S_4SPK"),
    204		},
    205		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
    206					SOF_RT5682_SSP_CODEC(0) |
    207					SOF_SPEAKER_AMP_PRESENT |
    208					SOF_MAX98390_SPEAKER_AMP_PRESENT |
    209					SOF_MAX98390_TWEETER_SPEAKER_PRESENT |
    210					SOF_RT5682_SSP_AMP(1) |
    211					SOF_RT5682_NUM_HDMIDEV(4) |
    212					SOF_BT_OFFLOAD_SSP(2) |
    213					SOF_SSP_BT_OFFLOAD_PRESENT),
    214
    215	},
    216	{
    217		.callback = sof_rt5682_quirk_cb,
    218		.matches = {
    219			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Brya"),
    220			DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98360_ALC5682I_I2S_AMP_SSP2"),
    221		},
    222		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
    223					SOF_RT5682_SSP_CODEC(0) |
    224					SOF_SPEAKER_AMP_PRESENT |
    225					SOF_MAX98360A_SPEAKER_AMP_PRESENT |
    226					SOF_RT5682_SSP_AMP(2) |
    227					SOF_RT5682_NUM_HDMIDEV(4)),
    228	},
    229	{}
    230};
    231
    232static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd)
    233{
    234	struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
    235	struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
    236	struct sof_hdmi_pcm *pcm;
    237
    238	pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
    239	if (!pcm)
    240		return -ENOMEM;
    241
    242	/* dai_link id is 1:1 mapped to the PCM device */
    243	pcm->device = rtd->dai_link->id;
    244	pcm->codec_dai = dai;
    245
    246	list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
    247
    248	return 0;
    249}
    250
    251static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
    252{
    253	struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
    254	struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
    255	struct snd_soc_jack *jack;
    256	int ret;
    257
    258	/* need to enable ASRC function for 24MHz mclk rate */
    259	if ((sof_rt5682_quirk & SOF_RT5682_MCLK_EN) &&
    260	    (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ)) {
    261		if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT)
    262			rt5682s_sel_asrc_clk_src(component,
    263						 RT5682S_DA_STEREO1_FILTER |
    264						 RT5682S_AD_STEREO1_FILTER,
    265						 RT5682S_CLK_SEL_I2S1_ASRC);
    266		else
    267			rt5682_sel_asrc_clk_src(component,
    268						RT5682_DA_STEREO1_FILTER |
    269						RT5682_AD_STEREO1_FILTER,
    270						RT5682_CLK_SEL_I2S1_ASRC);
    271	}
    272
    273	if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
    274		/*
    275		 * The firmware might enable the clock at
    276		 * boot (this information may or may not
    277		 * be reflected in the enable clock register).
    278		 * To change the rate we must disable the clock
    279		 * first to cover these cases. Due to common
    280		 * clock framework restrictions that do not allow
    281		 * to disable a clock that has not been enabled,
    282		 * we need to enable the clock first.
    283		 */
    284		ret = clk_prepare_enable(ctx->mclk);
    285		if (!ret)
    286			clk_disable_unprepare(ctx->mclk);
    287
    288		ret = clk_set_rate(ctx->mclk, 19200000);
    289
    290		if (ret)
    291			dev_err(rtd->dev, "unable to set MCLK rate\n");
    292	}
    293
    294	/*
    295	 * Headset buttons map to the google Reference headset.
    296	 * These can be configured by userspace.
    297	 */
    298	ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
    299				    SND_JACK_HEADSET | SND_JACK_BTN_0 |
    300				    SND_JACK_BTN_1 | SND_JACK_BTN_2 |
    301				    SND_JACK_BTN_3,
    302				    &ctx->sof_headset);
    303	if (ret) {
    304		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
    305		return ret;
    306	}
    307
    308	jack = &ctx->sof_headset;
    309
    310	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
    311	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
    312	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
    313	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
    314	ret = snd_soc_component_set_jack(component, jack, NULL);
    315
    316	if (ret) {
    317		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
    318		return ret;
    319	}
    320
    321	return ret;
    322};
    323
    324static void sof_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd)
    325{
    326	struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
    327
    328	snd_soc_component_set_jack(component, NULL, NULL);
    329}
    330
    331static int sof_rt5682_hw_params(struct snd_pcm_substream *substream,
    332				struct snd_pcm_hw_params *params)
    333{
    334	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
    335	struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
    336	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
    337	int pll_id, pll_source, pll_in, pll_out, clk_id, ret;
    338
    339	if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) {
    340		if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
    341			ret = clk_prepare_enable(ctx->mclk);
    342			if (ret < 0) {
    343				dev_err(rtd->dev,
    344					"could not configure MCLK state");
    345				return ret;
    346			}
    347		}
    348
    349		if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT)
    350			pll_source = RT5682S_PLL_S_MCLK;
    351		else
    352			pll_source = RT5682_PLL1_S_MCLK;
    353
    354		/* get the tplg configured mclk. */
    355		pll_in = sof_dai_get_mclk(rtd);
    356
    357		/* mclk from the quirk is the first choice */
    358		if (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ) {
    359			if (pll_in != 24000000)
    360				dev_warn(rtd->dev, "configure wrong mclk in tplg, please use 24MHz.\n");
    361			pll_in = 24000000;
    362		} else if (pll_in == 0) {
    363			/* use default mclk if not specified correct in topology */
    364			pll_in = 19200000;
    365		} else if (pll_in < 0) {
    366			return pll_in;
    367		}
    368	} else {
    369		if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT)
    370			pll_source = RT5682S_PLL_S_BCLK1;
    371		else
    372			pll_source = RT5682_PLL1_S_BCLK1;
    373
    374		pll_in = params_rate(params) * 50;
    375	}
    376
    377	if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) {
    378		pll_id = RT5682S_PLL2;
    379		clk_id = RT5682S_SCLK_S_PLL2;
    380	} else {
    381		pll_id = RT5682_PLL1;
    382		clk_id = RT5682_SCLK_S_PLL1;
    383	}
    384
    385	pll_out = params_rate(params) * 512;
    386
    387	/* when MCLK is 512FS, no need to set PLL configuration additionally. */
    388	if (pll_in == pll_out)
    389		clk_id = RT5682S_SCLK_S_MCLK;
    390	else {
    391		/* Configure pll for codec */
    392		ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source, pll_in,
    393					  pll_out);
    394		if (ret < 0)
    395			dev_err(rtd->dev, "snd_soc_dai_set_pll err = %d\n", ret);
    396	}
    397
    398	/* Configure sysclk for codec */
    399	ret = snd_soc_dai_set_sysclk(codec_dai, clk_id,
    400				     pll_out, SND_SOC_CLOCK_IN);
    401	if (ret < 0)
    402		dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
    403
    404	/*
    405	 * slot_width should equal or large than data length, set them
    406	 * be the same
    407	 */
    408	ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0, 0x0, 2,
    409				       params_width(params));
    410	if (ret < 0) {
    411		dev_err(rtd->dev, "set TDM slot err:%d\n", ret);
    412		return ret;
    413	}
    414
    415	return ret;
    416}
    417
    418static struct snd_soc_ops sof_rt5682_ops = {
    419	.hw_params = sof_rt5682_hw_params,
    420};
    421
    422static struct snd_soc_dai_link_component platform_component[] = {
    423	{
    424		/* name might be overridden during probe */
    425		.name = "0000:00:1f.3"
    426	}
    427};
    428
    429static int sof_card_late_probe(struct snd_soc_card *card)
    430{
    431	struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
    432	struct snd_soc_component *component = NULL;
    433	struct snd_soc_dapm_context *dapm = &card->dapm;
    434	char jack_name[NAME_SIZE];
    435	struct sof_hdmi_pcm *pcm;
    436	int err;
    437	int i = 0;
    438
    439	/* HDMI is not supported by SOF on Baytrail/CherryTrail */
    440	if (is_legacy_cpu || !ctx->idisp_codec)
    441		return 0;
    442
    443	if (list_empty(&ctx->hdmi_pcm_list))
    444		return -EINVAL;
    445
    446	if (ctx->common_hdmi_codec_drv) {
    447		pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm,
    448				       head);
    449		component = pcm->codec_dai->component;
    450		return hda_dsp_hdmi_build_controls(card, component);
    451	}
    452
    453	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
    454		component = pcm->codec_dai->component;
    455		snprintf(jack_name, sizeof(jack_name),
    456			 "HDMI/DP, pcm=%d Jack", pcm->device);
    457		err = snd_soc_card_jack_new(card, jack_name,
    458					    SND_JACK_AVOUT, &sof_hdmi[i]);
    459
    460		if (err)
    461			return err;
    462
    463		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
    464					  &sof_hdmi[i]);
    465		if (err < 0)
    466			return err;
    467
    468		i++;
    469	}
    470
    471	if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) {
    472		/* Disable Left and Right Spk pin after boot */
    473		snd_soc_dapm_disable_pin(dapm, "Left Spk");
    474		snd_soc_dapm_disable_pin(dapm, "Right Spk");
    475		err = snd_soc_dapm_sync(dapm);
    476		if (err < 0)
    477			return err;
    478	}
    479
    480	return hdac_hdmi_jack_port_init(component, &card->dapm);
    481}
    482
    483static const struct snd_kcontrol_new sof_controls[] = {
    484	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
    485	SOC_DAPM_PIN_SWITCH("Headset Mic"),
    486	SOC_DAPM_PIN_SWITCH("Left Spk"),
    487	SOC_DAPM_PIN_SWITCH("Right Spk"),
    488
    489};
    490
    491static const struct snd_soc_dapm_widget sof_widgets[] = {
    492	SND_SOC_DAPM_HP("Headphone Jack", NULL),
    493	SND_SOC_DAPM_MIC("Headset Mic", NULL),
    494	SND_SOC_DAPM_SPK("Left Spk", NULL),
    495	SND_SOC_DAPM_SPK("Right Spk", NULL),
    496};
    497
    498static const struct snd_soc_dapm_widget dmic_widgets[] = {
    499	SND_SOC_DAPM_MIC("SoC DMIC", NULL),
    500};
    501
    502static const struct snd_soc_dapm_route sof_map[] = {
    503	/* HP jack connectors - unknown if we have jack detection */
    504	{ "Headphone Jack", NULL, "HPOL" },
    505	{ "Headphone Jack", NULL, "HPOR" },
    506
    507	/* other jacks */
    508	{ "IN1P", NULL, "Headset Mic" },
    509};
    510
    511static const struct snd_soc_dapm_route dmic_map[] = {
    512	/* digital mics */
    513	{"DMic", NULL, "SoC DMIC"},
    514};
    515
    516static int dmic_init(struct snd_soc_pcm_runtime *rtd)
    517{
    518	struct snd_soc_card *card = rtd->card;
    519	int ret;
    520
    521	ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets,
    522					ARRAY_SIZE(dmic_widgets));
    523	if (ret) {
    524		dev_err(card->dev, "DMic widget addition failed: %d\n", ret);
    525		/* Don't need to add routes if widget addition failed */
    526		return ret;
    527	}
    528
    529	ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map,
    530				      ARRAY_SIZE(dmic_map));
    531
    532	if (ret)
    533		dev_err(card->dev, "DMic map addition failed: %d\n", ret);
    534
    535	return ret;
    536}
    537
    538/* sof audio machine driver for rt5682 codec */
    539static struct snd_soc_card sof_audio_card_rt5682 = {
    540	.name = "rt5682", /* the sof- prefix is added by the core */
    541	.owner = THIS_MODULE,
    542	.controls = sof_controls,
    543	.num_controls = ARRAY_SIZE(sof_controls),
    544	.dapm_widgets = sof_widgets,
    545	.num_dapm_widgets = ARRAY_SIZE(sof_widgets),
    546	.dapm_routes = sof_map,
    547	.num_dapm_routes = ARRAY_SIZE(sof_map),
    548	.fully_routed = true,
    549	.late_probe = sof_card_late_probe,
    550};
    551
    552static struct snd_soc_dai_link_component rt5682_component[] = {
    553	{
    554		.name = "i2c-10EC5682:00",
    555		.dai_name = "rt5682-aif1",
    556	}
    557};
    558
    559static struct snd_soc_dai_link_component rt5682s_component[] = {
    560	{
    561		.name = "i2c-RTL5682:00",
    562		.dai_name = "rt5682s-aif1",
    563	}
    564};
    565
    566static struct snd_soc_dai_link_component dmic_component[] = {
    567	{
    568		.name = "dmic-codec",
    569		.dai_name = "dmic-hifi",
    570	}
    571};
    572
    573static struct snd_soc_dai_link_component dummy_component[] = {
    574	{
    575		.name = "snd-soc-dummy",
    576		.dai_name = "snd-soc-dummy-dai",
    577	}
    578};
    579
    580#define IDISP_CODEC_MASK	0x4
    581
    582static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
    583							  int ssp_codec,
    584							  int ssp_amp,
    585							  int dmic_be_num,
    586							  int hdmi_num,
    587							  bool idisp_codec)
    588{
    589	struct snd_soc_dai_link_component *idisp_components;
    590	struct snd_soc_dai_link_component *cpus;
    591	struct snd_soc_dai_link *links;
    592	int i, id = 0;
    593
    594	links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) *
    595			     sof_audio_card_rt5682.num_links, GFP_KERNEL);
    596	cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component) *
    597			     sof_audio_card_rt5682.num_links, GFP_KERNEL);
    598	if (!links || !cpus)
    599		goto devm_err;
    600
    601	/* codec SSP */
    602	links[id].name = devm_kasprintf(dev, GFP_KERNEL,
    603					"SSP%d-Codec", ssp_codec);
    604	if (!links[id].name)
    605		goto devm_err;
    606
    607	links[id].id = id;
    608	if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) {
    609		links[id].codecs = rt5682s_component;
    610		links[id].num_codecs = ARRAY_SIZE(rt5682s_component);
    611	} else {
    612		links[id].codecs = rt5682_component;
    613		links[id].num_codecs = ARRAY_SIZE(rt5682_component);
    614	}
    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		if (idisp_codec) {
    702			idisp_components[i - 1].name = "ehdaudio0D2";
    703			idisp_components[i - 1].dai_name = devm_kasprintf(dev,
    704									  GFP_KERNEL,
    705									  "intel-hdmi-hifi%d",
    706									  i);
    707			if (!idisp_components[i - 1].dai_name)
    708				goto devm_err;
    709		} else {
    710			idisp_components[i - 1].name = "snd-soc-dummy";
    711			idisp_components[i - 1].dai_name = "snd-soc-dummy-dai";
    712		}
    713
    714		links[id].codecs = &idisp_components[i - 1];
    715		links[id].num_codecs = 1;
    716		links[id].platforms = platform_component;
    717		links[id].num_platforms = ARRAY_SIZE(platform_component);
    718		links[id].init = sof_hdmi_init;
    719		links[id].dpcm_playback = 1;
    720		links[id].no_pcm = 1;
    721		id++;
    722	}
    723
    724	/* speaker amp */
    725	if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) {
    726		links[id].name = devm_kasprintf(dev, GFP_KERNEL,
    727						"SSP%d-Codec", ssp_amp);
    728		if (!links[id].name)
    729			goto devm_err;
    730
    731		links[id].id = id;
    732		if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_PRESENT) {
    733			sof_rt1015_dai_link(&links[id], (sof_rt5682_quirk &
    734					SOF_RT1015_SPEAKER_AMP_100FS) ? 100 : 64);
    735		} else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) {
    736			sof_rt1015p_dai_link(&links[id]);
    737		} else if (sof_rt5682_quirk & SOF_RT1019_SPEAKER_AMP_PRESENT) {
    738			sof_rt1019_dai_link(&links[id]);
    739		} else if (sof_rt5682_quirk &
    740				SOF_MAX98373_SPEAKER_AMP_PRESENT) {
    741			links[id].codecs = max_98373_components;
    742			links[id].num_codecs = ARRAY_SIZE(max_98373_components);
    743			links[id].init = max_98373_spk_codec_init;
    744			links[id].ops = &max_98373_ops;
    745			/* feedback stream */
    746			links[id].dpcm_capture = 1;
    747		} else if (sof_rt5682_quirk &
    748				SOF_MAX98360A_SPEAKER_AMP_PRESENT) {
    749			max_98360a_dai_link(&links[id]);
    750		} else if (sof_rt5682_quirk &
    751				SOF_RT1011_SPEAKER_AMP_PRESENT) {
    752			sof_rt1011_dai_link(&links[id]);
    753		} else if (sof_rt5682_quirk &
    754				SOF_MAX98390_SPEAKER_AMP_PRESENT) {
    755			if (sof_rt5682_quirk &
    756				SOF_MAX98390_TWEETER_SPEAKER_PRESENT) {
    757				links[id].codecs = max_98390_4spk_components;
    758				links[id].num_codecs = ARRAY_SIZE(max_98390_4spk_components);
    759			} else {
    760				links[id].codecs = max_98390_components;
    761				links[id].num_codecs = ARRAY_SIZE(max_98390_components);
    762			}
    763			links[id].init = max_98390_spk_codec_init;
    764			links[id].ops = &max_98390_ops;
    765			links[id].dpcm_capture = 1;
    766
    767		} else {
    768			max_98357a_dai_link(&links[id]);
    769		}
    770		links[id].platforms = platform_component;
    771		links[id].num_platforms = ARRAY_SIZE(platform_component);
    772		links[id].dpcm_playback = 1;
    773		links[id].no_pcm = 1;
    774		links[id].cpus = &cpus[id];
    775		links[id].num_cpus = 1;
    776		if (is_legacy_cpu) {
    777			links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
    778								  "ssp%d-port",
    779								  ssp_amp);
    780			if (!links[id].cpus->dai_name)
    781				goto devm_err;
    782
    783		} else {
    784			links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
    785								  "SSP%d Pin",
    786								  ssp_amp);
    787			if (!links[id].cpus->dai_name)
    788				goto devm_err;
    789		}
    790		id++;
    791	}
    792
    793	/* BT audio offload */
    794	if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) {
    795		int port = (sof_rt5682_quirk & SOF_BT_OFFLOAD_SSP_MASK) >>
    796				SOF_BT_OFFLOAD_SSP_SHIFT;
    797
    798		links[id].id = id;
    799		links[id].cpus = &cpus[id];
    800		links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
    801							  "SSP%d Pin", port);
    802		if (!links[id].cpus->dai_name)
    803			goto devm_err;
    804		links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port);
    805		if (!links[id].name)
    806			goto devm_err;
    807		links[id].codecs = dummy_component;
    808		links[id].num_codecs = ARRAY_SIZE(dummy_component);
    809		links[id].platforms = platform_component;
    810		links[id].num_platforms = ARRAY_SIZE(platform_component);
    811		links[id].dpcm_playback = 1;
    812		links[id].dpcm_capture = 1;
    813		links[id].no_pcm = 1;
    814		links[id].num_cpus = 1;
    815	}
    816
    817	return links;
    818devm_err:
    819	return NULL;
    820}
    821
    822static int sof_audio_probe(struct platform_device *pdev)
    823{
    824	struct snd_soc_dai_link *dai_links;
    825	struct snd_soc_acpi_mach *mach;
    826	struct sof_card_private *ctx;
    827	int dmic_be_num, hdmi_num;
    828	int ret, ssp_amp, ssp_codec;
    829
    830	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
    831	if (!ctx)
    832		return -ENOMEM;
    833
    834	if (pdev->id_entry && pdev->id_entry->driver_data)
    835		sof_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data;
    836
    837	dmi_check_system(sof_rt5682_quirk_table);
    838
    839	mach = pdev->dev.platform_data;
    840
    841	/* A speaker amp might not be present when the quirk claims one is.
    842	 * Detect this via whether the machine driver match includes quirk_data.
    843	 */
    844	if ((sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) && !mach->quirk_data)
    845		sof_rt5682_quirk &= ~SOF_SPEAKER_AMP_PRESENT;
    846
    847	/* Detect the headset codec variant */
    848	if (acpi_dev_present("RTL5682", NULL, -1))
    849		sof_rt5682_quirk |= SOF_RT5682S_HEADPHONE_CODEC_PRESENT;
    850
    851	/* Detect the headset codec variant to support machines in DMI quirk */
    852	if (acpi_dev_present("RTL5682", NULL, -1))
    853		sof_rt5682_quirk |= SOF_RT5682S_HEADPHONE_CODEC_PRESENT;
    854
    855	if (soc_intel_is_byt() || soc_intel_is_cht()) {
    856		is_legacy_cpu = 1;
    857		dmic_be_num = 0;
    858		hdmi_num = 0;
    859		/* default quirk for legacy cpu */
    860		sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
    861						SOF_RT5682_MCLK_BYTCHT_EN |
    862						SOF_RT5682_SSP_CODEC(2);
    863	} else {
    864		dmic_be_num = 2;
    865		hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >>
    866			 SOF_RT5682_NUM_HDMIDEV_SHIFT;
    867		/* default number of HDMI DAI's */
    868		if (!hdmi_num)
    869			hdmi_num = 3;
    870
    871		if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
    872			ctx->idisp_codec = true;
    873	}
    874
    875	/* need to get main clock from pmc */
    876	if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
    877		ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
    878		if (IS_ERR(ctx->mclk)) {
    879			ret = PTR_ERR(ctx->mclk);
    880
    881			dev_err(&pdev->dev,
    882				"Failed to get MCLK from pmc_plt_clk_3: %d\n",
    883				ret);
    884			return ret;
    885		}
    886
    887		ret = clk_prepare_enable(ctx->mclk);
    888		if (ret < 0) {
    889			dev_err(&pdev->dev,
    890				"could not configure MCLK state");
    891			return ret;
    892		}
    893	}
    894
    895	dev_dbg(&pdev->dev, "sof_rt5682_quirk = %lx\n", sof_rt5682_quirk);
    896
    897	ssp_amp = (sof_rt5682_quirk & SOF_RT5682_SSP_AMP_MASK) >>
    898			SOF_RT5682_SSP_AMP_SHIFT;
    899
    900	ssp_codec = sof_rt5682_quirk & SOF_RT5682_SSP_CODEC_MASK;
    901
    902	/* compute number of dai links */
    903	sof_audio_card_rt5682.num_links = 1 + dmic_be_num + hdmi_num;
    904
    905	if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT)
    906		sof_audio_card_rt5682.num_links++;
    907
    908	if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT)
    909		max_98373_set_codec_conf(&sof_audio_card_rt5682);
    910	else if (sof_rt5682_quirk & SOF_RT1011_SPEAKER_AMP_PRESENT)
    911		sof_rt1011_codec_conf(&sof_audio_card_rt5682);
    912	else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT)
    913		sof_rt1015p_codec_conf(&sof_audio_card_rt5682);
    914	else if (sof_rt5682_quirk & SOF_MAX98390_SPEAKER_AMP_PRESENT) {
    915		if (sof_rt5682_quirk & SOF_MAX98390_TWEETER_SPEAKER_PRESENT)
    916			max_98390_set_codec_conf(&sof_audio_card_rt5682,
    917						 ARRAY_SIZE(max_98390_4spk_components));
    918		else
    919			max_98390_set_codec_conf(&sof_audio_card_rt5682,
    920						 ARRAY_SIZE(max_98390_components));
    921	}
    922
    923	if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
    924		sof_audio_card_rt5682.num_links++;
    925
    926	dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp,
    927					      dmic_be_num, hdmi_num, ctx->idisp_codec);
    928	if (!dai_links)
    929		return -ENOMEM;
    930
    931	sof_audio_card_rt5682.dai_link = dai_links;
    932
    933	if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_PRESENT)
    934		sof_rt1015_codec_conf(&sof_audio_card_rt5682);
    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_mx98357_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_mx98360",
    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_mx98357_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		.name = "adl_max98390_rt5682",
   1048		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
   1049					SOF_RT5682_SSP_CODEC(0) |
   1050					SOF_SPEAKER_AMP_PRESENT |
   1051					SOF_MAX98390_SPEAKER_AMP_PRESENT |
   1052					SOF_RT5682_SSP_AMP(1) |
   1053					SOF_RT5682_NUM_HDMIDEV(4) |
   1054					SOF_BT_OFFLOAD_SSP(2) |
   1055					SOF_SSP_BT_OFFLOAD_PRESENT),
   1056	},
   1057	{
   1058		.name = "adl_mx98360_rt5682",
   1059		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
   1060					SOF_RT5682_SSP_CODEC(0) |
   1061					SOF_SPEAKER_AMP_PRESENT |
   1062					SOF_MAX98360A_SPEAKER_AMP_PRESENT |
   1063					SOF_RT5682_SSP_AMP(1) |
   1064					SOF_RT5682_NUM_HDMIDEV(4) |
   1065					SOF_BT_OFFLOAD_SSP(2) |
   1066					SOF_SSP_BT_OFFLOAD_PRESENT),
   1067	},
   1068	{
   1069		.name = "adl_rt5682",
   1070		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
   1071					SOF_RT5682_SSP_CODEC(0) |
   1072					SOF_RT5682_NUM_HDMIDEV(4) |
   1073					SOF_BT_OFFLOAD_SSP(2) |
   1074					SOF_SSP_BT_OFFLOAD_PRESENT),
   1075	},
   1076	{
   1077		.name = "adl_rt1019_rt5682s",
   1078		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
   1079					SOF_RT5682_SSP_CODEC(0) |
   1080					SOF_RT5682S_HEADPHONE_CODEC_PRESENT |
   1081					SOF_SPEAKER_AMP_PRESENT |
   1082					SOF_RT1019_SPEAKER_AMP_PRESENT |
   1083					SOF_RT5682_SSP_AMP(1) |
   1084					SOF_RT5682_NUM_HDMIDEV(4)),
   1085	},
   1086	{ }
   1087};
   1088MODULE_DEVICE_TABLE(platform, board_ids);
   1089
   1090static struct platform_driver sof_audio = {
   1091	.probe = sof_audio_probe,
   1092	.driver = {
   1093		.name = "sof_rt5682",
   1094		.pm = &snd_soc_pm_ops,
   1095	},
   1096	.id_table = board_ids,
   1097};
   1098module_platform_driver(sof_audio)
   1099
   1100/* Module information */
   1101MODULE_DESCRIPTION("SOF Audio Machine driver");
   1102MODULE_AUTHOR("Bard Liao <bard.liao@intel.com>");
   1103MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
   1104MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
   1105MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
   1106MODULE_LICENSE("GPL v2");
   1107MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
   1108MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
   1109MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON);