1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright(c) 2019-2020 Intel Corporation.
5 * Intel SOF Machine Driver with Realtek rt5682 Codec
6 * and speaker codec MAX98357A or RT1015.
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/rt5682.h>
20 #include <sound/soc-acpi.h>
21 #include "../../codecs/rt1015.h"
22 #include "../../codecs/rt5682.h"
23 #include "../../codecs/hdac_hdmi.h"
24 #include "../common/soc-intel-quirks.h"
25 #include "hda_dsp_common.h"
26 #include "sof_maxim_common.h"
27 #include "sof_realtek_common.h"
31 #define SOF_RT5682_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0))
32 #define SOF_RT5682_SSP_CODEC_MASK (GENMASK(2, 0))
33 #define SOF_RT5682_MCLK_EN BIT(3)
34 #define SOF_RT5682_MCLK_24MHZ BIT(4)
35 #define SOF_SPEAKER_AMP_PRESENT BIT(5)
36 #define SOF_RT5682_SSP_AMP_SHIFT 6
37 #define SOF_RT5682_SSP_AMP_MASK (GENMASK(8, 6))
38 #define SOF_RT5682_SSP_AMP(quirk) \
39 (((quirk) << SOF_RT5682_SSP_AMP_SHIFT) & SOF_RT5682_SSP_AMP_MASK)
40 #define SOF_RT5682_MCLK_BYTCHT_EN BIT(9)
41 #define SOF_RT5682_NUM_HDMIDEV_SHIFT 10
42 #define SOF_RT5682_NUM_HDMIDEV_MASK (GENMASK(12, 10))
43 #define SOF_RT5682_NUM_HDMIDEV(quirk) \
44 ((quirk << SOF_RT5682_NUM_HDMIDEV_SHIFT) & SOF_RT5682_NUM_HDMIDEV_MASK)
45 #define SOF_RT1011_SPEAKER_AMP_PRESENT BIT(13)
46 #define SOF_RT1015_SPEAKER_AMP_PRESENT BIT(14)
47 #define SOF_RT1015_SPEAKER_AMP_100FS BIT(15)
48 #define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(16)
49 #define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(17)
51 /* Default: MCLK on, MCLK 19.2M, SSP0 */
52 static unsigned long sof_rt5682_quirk
= SOF_RT5682_MCLK_EN
|
53 SOF_RT5682_SSP_CODEC(0);
55 static int is_legacy_cpu
;
57 static struct snd_soc_jack sof_hdmi
[3];
60 struct list_head head
;
61 struct snd_soc_dai
*codec_dai
;
65 struct sof_card_private
{
67 struct snd_soc_jack sof_headset
;
68 struct list_head hdmi_pcm_list
;
69 bool common_hdmi_codec_drv
;
72 static int sof_rt5682_quirk_cb(const struct dmi_system_id
*id
)
74 sof_rt5682_quirk
= (unsigned long)id
->driver_data
;
78 static const struct dmi_system_id sof_rt5682_quirk_table
[] = {
80 .callback
= sof_rt5682_quirk_cb
,
82 DMI_MATCH(DMI_SYS_VENDOR
, "Circuitco"),
83 DMI_MATCH(DMI_PRODUCT_NAME
, "Minnowboard Max"),
85 .driver_data
= (void *)(SOF_RT5682_SSP_CODEC(2)),
88 .callback
= sof_rt5682_quirk_cb
,
90 DMI_MATCH(DMI_SYS_VENDOR
, "AAEON"),
91 DMI_MATCH(DMI_PRODUCT_NAME
, "UP-CHT01"),
93 .driver_data
= (void *)(SOF_RT5682_SSP_CODEC(2)),
96 .callback
= sof_rt5682_quirk_cb
,
98 DMI_MATCH(DMI_SYS_VENDOR
, "Intel Corporation"),
99 DMI_MATCH(DMI_PRODUCT_NAME
, "WhiskeyLake Client"),
101 .driver_data
= (void *)(SOF_RT5682_MCLK_EN
|
102 SOF_RT5682_MCLK_24MHZ
|
103 SOF_RT5682_SSP_CODEC(1)),
107 * Dooly is hatch family but using rt1015 amp so it
108 * requires a quirk before "Google_Hatch".
110 .callback
= sof_rt5682_quirk_cb
,
112 DMI_MATCH(DMI_SYS_VENDOR
, "HP"),
113 DMI_MATCH(DMI_PRODUCT_NAME
, "Dooly"),
115 .driver_data
= (void *)(SOF_RT5682_MCLK_EN
|
116 SOF_RT5682_MCLK_24MHZ
|
117 SOF_RT5682_SSP_CODEC(0) |
118 SOF_SPEAKER_AMP_PRESENT
|
119 SOF_RT1015_SPEAKER_AMP_PRESENT
|
120 SOF_RT1015_SPEAKER_AMP_100FS
|
121 SOF_RT5682_SSP_AMP(1)),
124 .callback
= sof_rt5682_quirk_cb
,
126 DMI_MATCH(DMI_PRODUCT_FAMILY
, "Google_Hatch"),
128 .driver_data
= (void *)(SOF_RT5682_MCLK_EN
|
129 SOF_RT5682_MCLK_24MHZ
|
130 SOF_RT5682_SSP_CODEC(0) |
131 SOF_SPEAKER_AMP_PRESENT
|
132 SOF_RT5682_SSP_AMP(1)),
135 .callback
= sof_rt5682_quirk_cb
,
137 DMI_MATCH(DMI_SYS_VENDOR
, "Intel Corporation"),
138 DMI_MATCH(DMI_PRODUCT_NAME
, "Ice Lake Client"),
140 .driver_data
= (void *)(SOF_RT5682_MCLK_EN
|
141 SOF_RT5682_SSP_CODEC(0)),
144 .callback
= sof_rt5682_quirk_cb
,
146 DMI_MATCH(DMI_PRODUCT_FAMILY
, "Google_Volteer"),
147 DMI_MATCH(DMI_OEM_STRING
, "AUDIO-MAX98373_ALC5682I_I2S_UP4"),
149 .driver_data
= (void *)(SOF_RT5682_MCLK_EN
|
150 SOF_RT5682_SSP_CODEC(0) |
151 SOF_SPEAKER_AMP_PRESENT
|
152 SOF_MAX98373_SPEAKER_AMP_PRESENT
|
153 SOF_RT5682_SSP_AMP(2) |
154 SOF_RT5682_NUM_HDMIDEV(4)),
159 static int sof_hdmi_init(struct snd_soc_pcm_runtime
*rtd
)
161 struct sof_card_private
*ctx
= snd_soc_card_get_drvdata(rtd
->card
);
162 struct snd_soc_dai
*dai
= asoc_rtd_to_codec(rtd
, 0);
163 struct sof_hdmi_pcm
*pcm
;
165 pcm
= devm_kzalloc(rtd
->card
->dev
, sizeof(*pcm
), GFP_KERNEL
);
169 /* dai_link id is 1:1 mapped to the PCM device */
170 pcm
->device
= rtd
->dai_link
->id
;
171 pcm
->codec_dai
= dai
;
173 list_add_tail(&pcm
->head
, &ctx
->hdmi_pcm_list
);
178 static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime
*rtd
)
180 struct sof_card_private
*ctx
= snd_soc_card_get_drvdata(rtd
->card
);
181 struct snd_soc_component
*component
= asoc_rtd_to_codec(rtd
, 0)->component
;
182 struct snd_soc_jack
*jack
;
185 /* need to enable ASRC function for 24MHz mclk rate */
186 if ((sof_rt5682_quirk
& SOF_RT5682_MCLK_EN
) &&
187 (sof_rt5682_quirk
& SOF_RT5682_MCLK_24MHZ
)) {
188 rt5682_sel_asrc_clk_src(component
, RT5682_DA_STEREO1_FILTER
|
189 RT5682_AD_STEREO1_FILTER
,
190 RT5682_CLK_SEL_I2S1_ASRC
);
193 if (sof_rt5682_quirk
& SOF_RT5682_MCLK_BYTCHT_EN
) {
195 * The firmware might enable the clock at
196 * boot (this information may or may not
197 * be reflected in the enable clock register).
198 * To change the rate we must disable the clock
199 * first to cover these cases. Due to common
200 * clock framework restrictions that do not allow
201 * to disable a clock that has not been enabled,
202 * we need to enable the clock first.
204 ret
= clk_prepare_enable(ctx
->mclk
);
206 clk_disable_unprepare(ctx
->mclk
);
208 ret
= clk_set_rate(ctx
->mclk
, 19200000);
211 dev_err(rtd
->dev
, "unable to set MCLK rate\n");
215 * Headset buttons map to the google Reference headset.
216 * These can be configured by userspace.
218 ret
= snd_soc_card_jack_new(rtd
->card
, "Headset Jack",
219 SND_JACK_HEADSET
| SND_JACK_BTN_0
|
220 SND_JACK_BTN_1
| SND_JACK_BTN_2
|
222 &ctx
->sof_headset
, NULL
, 0);
224 dev_err(rtd
->dev
, "Headset Jack creation failed: %d\n", ret
);
228 jack
= &ctx
->sof_headset
;
230 snd_jack_set_key(jack
->jack
, SND_JACK_BTN_0
, KEY_PLAYPAUSE
);
231 snd_jack_set_key(jack
->jack
, SND_JACK_BTN_1
, KEY_VOICECOMMAND
);
232 snd_jack_set_key(jack
->jack
, SND_JACK_BTN_2
, KEY_VOLUMEUP
);
233 snd_jack_set_key(jack
->jack
, SND_JACK_BTN_3
, KEY_VOLUMEDOWN
);
234 ret
= snd_soc_component_set_jack(component
, jack
, NULL
);
237 dev_err(rtd
->dev
, "Headset Jack call-back failed: %d\n", ret
);
244 static void sof_rt5682_codec_exit(struct snd_soc_pcm_runtime
*rtd
)
246 struct snd_soc_component
*component
= asoc_rtd_to_codec(rtd
, 0)->component
;
248 snd_soc_component_set_jack(component
, NULL
, NULL
);
251 static int sof_rt5682_hw_params(struct snd_pcm_substream
*substream
,
252 struct snd_pcm_hw_params
*params
)
254 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
255 struct sof_card_private
*ctx
= snd_soc_card_get_drvdata(rtd
->card
);
256 struct snd_soc_dai
*codec_dai
= asoc_rtd_to_codec(rtd
, 0);
257 int clk_id
, clk_freq
, pll_out
, ret
;
259 if (sof_rt5682_quirk
& SOF_RT5682_MCLK_EN
) {
260 if (sof_rt5682_quirk
& SOF_RT5682_MCLK_BYTCHT_EN
) {
261 ret
= clk_prepare_enable(ctx
->mclk
);
264 "could not configure MCLK state");
269 clk_id
= RT5682_PLL1_S_MCLK
;
270 if (sof_rt5682_quirk
& SOF_RT5682_MCLK_24MHZ
)
275 clk_id
= RT5682_PLL1_S_BCLK1
;
276 clk_freq
= params_rate(params
) * 50;
279 pll_out
= params_rate(params
) * 512;
281 ret
= snd_soc_dai_set_pll(codec_dai
, 0, clk_id
, clk_freq
, pll_out
);
283 dev_err(rtd
->dev
, "snd_soc_dai_set_pll err = %d\n", ret
);
285 /* Configure sysclk for codec */
286 ret
= snd_soc_dai_set_sysclk(codec_dai
, RT5682_SCLK_S_PLL1
,
287 pll_out
, SND_SOC_CLOCK_IN
);
289 dev_err(rtd
->dev
, "snd_soc_dai_set_sysclk err = %d\n", ret
);
292 * slot_width should equal or large than data length, set them
295 ret
= snd_soc_dai_set_tdm_slot(codec_dai
, 0x0, 0x0, 2,
296 params_width(params
));
298 dev_err(rtd
->dev
, "set TDM slot err:%d\n", ret
);
305 static struct snd_soc_ops sof_rt5682_ops
= {
306 .hw_params
= sof_rt5682_hw_params
,
309 static int sof_rt1015_hw_params(struct snd_pcm_substream
*substream
,
310 struct snd_pcm_hw_params
*params
)
312 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
313 struct snd_soc_card
*card
= rtd
->card
;
314 struct snd_soc_dai
*codec_dai
;
317 if (!snd_soc_card_get_codec_dai(card
, "rt1015-aif"))
320 if (sof_rt5682_quirk
& SOF_RT1015_SPEAKER_AMP_100FS
)
325 for_each_rtd_codec_dais(rtd
, i
, codec_dai
) {
326 /* Set tdm/i2s1 master bclk ratio */
327 ret
= snd_soc_dai_set_bclk_ratio(codec_dai
, fs
);
329 dev_err(card
->dev
, "failed to set bclk ratio\n");
333 ret
= snd_soc_dai_set_pll(codec_dai
, 0, RT1015_PLL_S_BCLK
,
334 params_rate(params
) * fs
,
335 params_rate(params
) * 256);
337 dev_err(card
->dev
, "failed to set pll\n");
340 /* Configure sysclk for codec */
341 ret
= snd_soc_dai_set_sysclk(codec_dai
, RT1015_SCLK_S_PLL
,
342 params_rate(params
) * 256,
345 dev_err(card
->dev
, "failed to set sysclk\n");
349 if (sof_rt5682_quirk
& SOF_RT1015_SPEAKER_AMP_100FS
) {
350 if (!strcmp(codec_dai
->component
->name
, "i2c-10EC1015:00")) {
351 ret
= snd_soc_dai_set_tdm_slot(codec_dai
,
354 dev_err(card
->dev
, "failed to set tdm slot\n");
359 if (!strcmp(codec_dai
->component
->name
, "i2c-10EC1015:01")) {
360 ret
= snd_soc_dai_set_tdm_slot(codec_dai
,
363 dev_err(card
->dev
, "failed to set tdm slot\n");
373 static struct snd_soc_ops sof_rt1015_ops
= {
374 .hw_params
= sof_rt1015_hw_params
,
377 static struct snd_soc_dai_link_component platform_component
[] = {
379 /* name might be overridden during probe */
380 .name
= "0000:00:1f.3"
384 static int sof_card_late_probe(struct snd_soc_card
*card
)
386 struct sof_card_private
*ctx
= snd_soc_card_get_drvdata(card
);
387 struct snd_soc_component
*component
= NULL
;
388 struct snd_soc_dapm_context
*dapm
= &card
->dapm
;
389 char jack_name
[NAME_SIZE
];
390 struct sof_hdmi_pcm
*pcm
;
394 /* HDMI is not supported by SOF on Baytrail/CherryTrail */
398 if (list_empty(&ctx
->hdmi_pcm_list
))
401 if (ctx
->common_hdmi_codec_drv
) {
402 pcm
= list_first_entry(&ctx
->hdmi_pcm_list
, struct sof_hdmi_pcm
,
404 component
= pcm
->codec_dai
->component
;
405 return hda_dsp_hdmi_build_controls(card
, component
);
408 list_for_each_entry(pcm
, &ctx
->hdmi_pcm_list
, head
) {
409 component
= pcm
->codec_dai
->component
;
410 snprintf(jack_name
, sizeof(jack_name
),
411 "HDMI/DP, pcm=%d Jack", pcm
->device
);
412 err
= snd_soc_card_jack_new(card
, jack_name
,
413 SND_JACK_AVOUT
, &sof_hdmi
[i
],
419 err
= hdac_hdmi_jack_init(pcm
->codec_dai
, pcm
->device
,
427 if (sof_rt5682_quirk
& SOF_MAX98373_SPEAKER_AMP_PRESENT
) {
428 /* Disable Left and Right Spk pin after boot */
429 snd_soc_dapm_disable_pin(dapm
, "Left Spk");
430 snd_soc_dapm_disable_pin(dapm
, "Right Spk");
431 err
= snd_soc_dapm_sync(dapm
);
435 return hdac_hdmi_jack_port_init(component
, &card
->dapm
);
438 static const struct snd_kcontrol_new sof_controls
[] = {
439 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
440 SOC_DAPM_PIN_SWITCH("Headset Mic"),
441 SOC_DAPM_PIN_SWITCH("Spk"),
442 SOC_DAPM_PIN_SWITCH("Left Spk"),
443 SOC_DAPM_PIN_SWITCH("Right Spk"),
447 static const struct snd_soc_dapm_widget sof_widgets
[] = {
448 SND_SOC_DAPM_HP("Headphone Jack", NULL
),
449 SND_SOC_DAPM_MIC("Headset Mic", NULL
),
450 SND_SOC_DAPM_SPK("Spk", NULL
),
451 SND_SOC_DAPM_SPK("Left Spk", NULL
),
452 SND_SOC_DAPM_SPK("Right Spk", NULL
),
455 static const struct snd_soc_dapm_widget dmic_widgets
[] = {
456 SND_SOC_DAPM_MIC("SoC DMIC", NULL
),
459 static const struct snd_soc_dapm_route sof_map
[] = {
460 /* HP jack connectors - unknown if we have jack detection */
461 { "Headphone Jack", NULL
, "HPOL" },
462 { "Headphone Jack", NULL
, "HPOR" },
465 { "IN1P", NULL
, "Headset Mic" },
468 static const struct snd_soc_dapm_route speaker_map
[] = {
470 { "Spk", NULL
, "Speaker" },
473 static const struct snd_soc_dapm_route speaker_map_lr
[] = {
474 { "Left Spk", NULL
, "Left SPO" },
475 { "Right Spk", NULL
, "Right SPO" },
478 static const struct snd_soc_dapm_route dmic_map
[] = {
480 {"DMic", NULL
, "SoC DMIC"},
483 static int speaker_codec_init_lr(struct snd_soc_pcm_runtime
*rtd
)
485 return snd_soc_dapm_add_routes(&rtd
->card
->dapm
, speaker_map_lr
,
486 ARRAY_SIZE(speaker_map_lr
));
489 static int speaker_codec_init(struct snd_soc_pcm_runtime
*rtd
)
491 struct snd_soc_card
*card
= rtd
->card
;
494 ret
= snd_soc_dapm_add_routes(&card
->dapm
, speaker_map
,
495 ARRAY_SIZE(speaker_map
));
498 dev_err(rtd
->dev
, "Speaker map addition failed: %d\n", ret
);
502 static int dmic_init(struct snd_soc_pcm_runtime
*rtd
)
504 struct snd_soc_card
*card
= rtd
->card
;
507 ret
= snd_soc_dapm_new_controls(&card
->dapm
, dmic_widgets
,
508 ARRAY_SIZE(dmic_widgets
));
510 dev_err(card
->dev
, "DMic widget addition failed: %d\n", ret
);
511 /* Don't need to add routes if widget addition failed */
515 ret
= snd_soc_dapm_add_routes(&card
->dapm
, dmic_map
,
516 ARRAY_SIZE(dmic_map
));
519 dev_err(card
->dev
, "DMic map addition failed: %d\n", ret
);
524 static struct snd_soc_codec_conf rt1015_amp_conf
[] = {
526 .dlc
= COMP_CODEC_CONF("i2c-10EC1015:00"),
527 .name_prefix
= "Left",
530 .dlc
= COMP_CODEC_CONF("i2c-10EC1015:01"),
531 .name_prefix
= "Right",
535 /* sof audio machine driver for rt5682 codec */
536 static struct snd_soc_card sof_audio_card_rt5682
= {
537 .name
= "rt5682", /* the sof- prefix is added by the core */
538 .owner
= THIS_MODULE
,
539 .controls
= sof_controls
,
540 .num_controls
= ARRAY_SIZE(sof_controls
),
541 .dapm_widgets
= sof_widgets
,
542 .num_dapm_widgets
= ARRAY_SIZE(sof_widgets
),
543 .dapm_routes
= sof_map
,
544 .num_dapm_routes
= ARRAY_SIZE(sof_map
),
545 .fully_routed
= true,
546 .late_probe
= sof_card_late_probe
,
549 static struct snd_soc_dai_link_component rt5682_component
[] = {
551 .name
= "i2c-10EC5682:00",
552 .dai_name
= "rt5682-aif1",
556 static struct snd_soc_dai_link_component dmic_component
[] = {
558 .name
= "dmic-codec",
559 .dai_name
= "dmic-hifi",
563 static struct snd_soc_dai_link_component max98357a_component
[] = {
565 .name
= "MX98357A:00",
570 static struct snd_soc_dai_link_component max98360a_component
[] = {
572 .name
= "MX98360A:00",
577 static struct snd_soc_dai_link_component rt1015_components
[] = {
579 .name
= "i2c-10EC1015:00",
580 .dai_name
= "rt1015-aif",
583 .name
= "i2c-10EC1015:01",
584 .dai_name
= "rt1015-aif",
588 static struct snd_soc_dai_link
*sof_card_dai_links_create(struct device
*dev
,
594 struct snd_soc_dai_link_component
*idisp_components
;
595 struct snd_soc_dai_link_component
*cpus
;
596 struct snd_soc_dai_link
*links
;
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
);
607 links
[id
].name
= devm_kasprintf(dev
, GFP_KERNEL
,
608 "SSP%d-Codec", ssp_codec
);
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
].nonatomic
= true;
621 links
[id
].dpcm_playback
= 1;
622 links
[id
].dpcm_capture
= 1;
623 links
[id
].no_pcm
= 1;
624 links
[id
].cpus
= &cpus
[id
];
625 links
[id
].num_cpus
= 1;
627 links
[id
].cpus
->dai_name
= devm_kasprintf(dev
, GFP_KERNEL
,
630 if (!links
[id
].cpus
->dai_name
)
634 * Currently, On SKL+ platforms MCLK will be turned off in sof
635 * runtime suspended, and it will go into runtime suspended
636 * right after playback is stop. However, rt5682 will output
637 * static noise if sysclk turns off during playback. Set
638 * ignore_pmdown_time to power down rt5682 immediately and
640 * It can be removed once we can control MCLK by driver.
642 links
[id
].ignore_pmdown_time
= 1;
643 links
[id
].cpus
->dai_name
= devm_kasprintf(dev
, GFP_KERNEL
,
646 if (!links
[id
].cpus
->dai_name
)
652 if (dmic_be_num
> 0) {
653 /* at least we have dmic01 */
654 links
[id
].name
= "dmic01";
655 links
[id
].cpus
= &cpus
[id
];
656 links
[id
].cpus
->dai_name
= "DMIC01 Pin";
657 links
[id
].init
= dmic_init
;
658 if (dmic_be_num
> 1) {
659 /* set up 2 BE links at most */
660 links
[id
+ 1].name
= "dmic16k";
661 links
[id
+ 1].cpus
= &cpus
[id
+ 1];
662 links
[id
+ 1].cpus
->dai_name
= "DMIC16k Pin";
667 for (i
= 0; i
< dmic_be_num
; i
++) {
669 links
[id
].num_cpus
= 1;
670 links
[id
].codecs
= dmic_component
;
671 links
[id
].num_codecs
= ARRAY_SIZE(dmic_component
);
672 links
[id
].platforms
= platform_component
;
673 links
[id
].num_platforms
= ARRAY_SIZE(platform_component
);
674 links
[id
].ignore_suspend
= 1;
675 links
[id
].dpcm_capture
= 1;
676 links
[id
].no_pcm
= 1;
682 idisp_components
= devm_kzalloc(dev
,
683 sizeof(struct snd_soc_dai_link_component
) *
684 hdmi_num
, GFP_KERNEL
);
685 if (!idisp_components
)
688 for (i
= 1; i
<= hdmi_num
; i
++) {
689 links
[id
].name
= devm_kasprintf(dev
, GFP_KERNEL
,
695 links
[id
].cpus
= &cpus
[id
];
696 links
[id
].num_cpus
= 1;
697 links
[id
].cpus
->dai_name
= devm_kasprintf(dev
, GFP_KERNEL
,
699 if (!links
[id
].cpus
->dai_name
)
702 idisp_components
[i
- 1].name
= "ehdaudio0D2";
703 idisp_components
[i
- 1].dai_name
= devm_kasprintf(dev
,
707 if (!idisp_components
[i
- 1].dai_name
)
710 links
[id
].codecs
= &idisp_components
[i
- 1];
711 links
[id
].num_codecs
= 1;
712 links
[id
].platforms
= platform_component
;
713 links
[id
].num_platforms
= ARRAY_SIZE(platform_component
);
714 links
[id
].init
= sof_hdmi_init
;
715 links
[id
].dpcm_playback
= 1;
716 links
[id
].no_pcm
= 1;
721 if (sof_rt5682_quirk
& SOF_SPEAKER_AMP_PRESENT
) {
722 links
[id
].name
= devm_kasprintf(dev
, GFP_KERNEL
,
723 "SSP%d-Codec", ssp_amp
);
728 if (sof_rt5682_quirk
& SOF_RT1015_SPEAKER_AMP_PRESENT
) {
729 links
[id
].codecs
= rt1015_components
;
730 links
[id
].num_codecs
= ARRAY_SIZE(rt1015_components
);
731 links
[id
].init
= speaker_codec_init_lr
;
732 links
[id
].ops
= &sof_rt1015_ops
;
733 } else if (sof_rt5682_quirk
&
734 SOF_MAX98373_SPEAKER_AMP_PRESENT
) {
735 links
[id
].codecs
= max_98373_components
;
736 links
[id
].num_codecs
= ARRAY_SIZE(max_98373_components
);
737 links
[id
].init
= max98373_spk_codec_init
;
738 links
[id
].ops
= &max_98373_ops
;
739 /* feedback stream */
740 links
[id
].dpcm_capture
= 1;
741 } else if (sof_rt5682_quirk
&
742 SOF_MAX98360A_SPEAKER_AMP_PRESENT
) {
743 links
[id
].codecs
= max98360a_component
;
744 links
[id
].num_codecs
= ARRAY_SIZE(max98360a_component
);
745 links
[id
].init
= speaker_codec_init
;
746 } else if (sof_rt5682_quirk
&
747 SOF_RT1011_SPEAKER_AMP_PRESENT
) {
748 sof_rt1011_dai_link(&links
[id
]);
750 links
[id
].codecs
= max98357a_component
;
751 links
[id
].num_codecs
= ARRAY_SIZE(max98357a_component
);
752 links
[id
].init
= speaker_codec_init
;
754 links
[id
].platforms
= platform_component
;
755 links
[id
].num_platforms
= ARRAY_SIZE(platform_component
);
756 links
[id
].nonatomic
= true;
757 links
[id
].dpcm_playback
= 1;
758 links
[id
].no_pcm
= 1;
759 links
[id
].cpus
= &cpus
[id
];
760 links
[id
].num_cpus
= 1;
762 links
[id
].cpus
->dai_name
= devm_kasprintf(dev
, GFP_KERNEL
,
765 if (!links
[id
].cpus
->dai_name
)
769 links
[id
].cpus
->dai_name
= devm_kasprintf(dev
, GFP_KERNEL
,
772 if (!links
[id
].cpus
->dai_name
)
782 static int sof_audio_probe(struct platform_device
*pdev
)
784 struct snd_soc_dai_link
*dai_links
;
785 struct snd_soc_acpi_mach
*mach
;
786 struct sof_card_private
*ctx
;
787 int dmic_be_num
, hdmi_num
;
788 int ret
, ssp_amp
, ssp_codec
;
790 ctx
= devm_kzalloc(&pdev
->dev
, sizeof(*ctx
), GFP_KERNEL
);
794 if (pdev
->id_entry
&& pdev
->id_entry
->driver_data
)
795 sof_rt5682_quirk
= (unsigned long)pdev
->id_entry
->driver_data
;
797 dmi_check_system(sof_rt5682_quirk_table
);
799 mach
= pdev
->dev
.platform_data
;
801 /* A speaker amp might not be present when the quirk claims one is.
802 * Detect this via whether the machine driver match includes quirk_data.
804 if ((sof_rt5682_quirk
& SOF_SPEAKER_AMP_PRESENT
) && !mach
->quirk_data
)
805 sof_rt5682_quirk
&= ~SOF_SPEAKER_AMP_PRESENT
;
807 if (soc_intel_is_byt() || soc_intel_is_cht()) {
811 /* default quirk for legacy cpu */
812 sof_rt5682_quirk
= SOF_RT5682_MCLK_EN
|
813 SOF_RT5682_MCLK_BYTCHT_EN
|
814 SOF_RT5682_SSP_CODEC(2);
817 hdmi_num
= (sof_rt5682_quirk
& SOF_RT5682_NUM_HDMIDEV_MASK
) >>
818 SOF_RT5682_NUM_HDMIDEV_SHIFT
;
819 /* default number of HDMI DAI's */
824 /* need to get main clock from pmc */
825 if (sof_rt5682_quirk
& SOF_RT5682_MCLK_BYTCHT_EN
) {
826 ctx
->mclk
= devm_clk_get(&pdev
->dev
, "pmc_plt_clk_3");
827 if (IS_ERR(ctx
->mclk
)) {
828 ret
= PTR_ERR(ctx
->mclk
);
831 "Failed to get MCLK from pmc_plt_clk_3: %d\n",
836 ret
= clk_prepare_enable(ctx
->mclk
);
839 "could not configure MCLK state");
844 dev_dbg(&pdev
->dev
, "sof_rt5682_quirk = %lx\n", sof_rt5682_quirk
);
846 ssp_amp
= (sof_rt5682_quirk
& SOF_RT5682_SSP_AMP_MASK
) >>
847 SOF_RT5682_SSP_AMP_SHIFT
;
849 ssp_codec
= sof_rt5682_quirk
& SOF_RT5682_SSP_CODEC_MASK
;
851 /* compute number of dai links */
852 sof_audio_card_rt5682
.num_links
= 1 + dmic_be_num
+ hdmi_num
;
854 if (sof_rt5682_quirk
& SOF_SPEAKER_AMP_PRESENT
)
855 sof_audio_card_rt5682
.num_links
++;
857 if (sof_rt5682_quirk
& SOF_MAX98373_SPEAKER_AMP_PRESENT
)
858 sof_max98373_codec_conf(&sof_audio_card_rt5682
);
859 else if (sof_rt5682_quirk
& SOF_RT1011_SPEAKER_AMP_PRESENT
)
860 sof_rt1011_codec_conf(&sof_audio_card_rt5682
);
862 dai_links
= sof_card_dai_links_create(&pdev
->dev
, ssp_codec
, ssp_amp
,
863 dmic_be_num
, hdmi_num
);
867 sof_audio_card_rt5682
.dai_link
= dai_links
;
869 if (sof_rt5682_quirk
& SOF_RT1015_SPEAKER_AMP_PRESENT
) {
870 sof_audio_card_rt5682
.codec_conf
= rt1015_amp_conf
;
871 sof_audio_card_rt5682
.num_configs
= ARRAY_SIZE(rt1015_amp_conf
);
874 INIT_LIST_HEAD(&ctx
->hdmi_pcm_list
);
876 sof_audio_card_rt5682
.dev
= &pdev
->dev
;
878 /* set platform name for each dailink */
879 ret
= snd_soc_fixup_dai_links_platform_name(&sof_audio_card_rt5682
,
880 mach
->mach_params
.platform
);
884 ctx
->common_hdmi_codec_drv
= mach
->mach_params
.common_hdmi_codec_drv
;
886 snd_soc_card_set_drvdata(&sof_audio_card_rt5682
, ctx
);
888 return devm_snd_soc_register_card(&pdev
->dev
,
889 &sof_audio_card_rt5682
);
892 static const struct platform_device_id board_ids
[] = {
894 .name
= "sof_rt5682",
897 .name
= "tgl_max98357a_rt5682",
898 .driver_data
= (kernel_ulong_t
)(SOF_RT5682_MCLK_EN
|
899 SOF_RT5682_SSP_CODEC(0) |
900 SOF_SPEAKER_AMP_PRESENT
|
901 SOF_RT5682_SSP_AMP(1) |
902 SOF_RT5682_NUM_HDMIDEV(4)),
905 .name
= "jsl_rt5682_rt1015",
906 .driver_data
= (kernel_ulong_t
)(SOF_RT5682_MCLK_EN
|
907 SOF_RT5682_MCLK_24MHZ
|
908 SOF_RT5682_SSP_CODEC(0) |
909 SOF_SPEAKER_AMP_PRESENT
|
910 SOF_RT1015_SPEAKER_AMP_PRESENT
|
911 SOF_RT5682_SSP_AMP(1)),
914 .name
= "tgl_max98373_rt5682",
915 .driver_data
= (kernel_ulong_t
)(SOF_RT5682_MCLK_EN
|
916 SOF_RT5682_SSP_CODEC(0) |
917 SOF_SPEAKER_AMP_PRESENT
|
918 SOF_MAX98373_SPEAKER_AMP_PRESENT
|
919 SOF_RT5682_SSP_AMP(1) |
920 SOF_RT5682_NUM_HDMIDEV(4)),
923 .name
= "jsl_rt5682_max98360a",
924 .driver_data
= (kernel_ulong_t
)(SOF_RT5682_MCLK_EN
|
925 SOF_RT5682_MCLK_24MHZ
|
926 SOF_RT5682_SSP_CODEC(0) |
927 SOF_SPEAKER_AMP_PRESENT
|
928 SOF_MAX98360A_SPEAKER_AMP_PRESENT
|
929 SOF_RT5682_SSP_AMP(1)),
932 .name
= "cml_rt1015_rt5682",
933 .driver_data
= (kernel_ulong_t
)(SOF_RT5682_MCLK_EN
|
934 SOF_RT5682_MCLK_24MHZ
|
935 SOF_RT5682_SSP_CODEC(0) |
936 SOF_SPEAKER_AMP_PRESENT
|
937 SOF_RT1015_SPEAKER_AMP_PRESENT
|
938 SOF_RT1015_SPEAKER_AMP_100FS
|
939 SOF_RT5682_SSP_AMP(1)),
942 .name
= "tgl_rt1011_rt5682",
943 .driver_data
= (kernel_ulong_t
)(SOF_RT5682_MCLK_EN
|
944 SOF_RT5682_SSP_CODEC(0) |
945 SOF_SPEAKER_AMP_PRESENT
|
946 SOF_RT1011_SPEAKER_AMP_PRESENT
|
947 SOF_RT5682_SSP_AMP(1) |
948 SOF_RT5682_NUM_HDMIDEV(4)),
953 static struct platform_driver sof_audio
= {
954 .probe
= sof_audio_probe
,
956 .name
= "sof_rt5682",
957 .pm
= &snd_soc_pm_ops
,
959 .id_table
= board_ids
,
961 module_platform_driver(sof_audio
)
963 /* Module information */
964 MODULE_DESCRIPTION("SOF Audio Machine driver");
965 MODULE_AUTHOR("Bard Liao <bard.liao@intel.com>");
966 MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
967 MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
968 MODULE_LICENSE("GPL v2");
969 MODULE_ALIAS("platform:sof_rt5682");
970 MODULE_ALIAS("platform:tgl_max98357a_rt5682");
971 MODULE_ALIAS("platform:jsl_rt5682_rt1015");
972 MODULE_ALIAS("platform:tgl_max98373_rt5682");
973 MODULE_ALIAS("platform:jsl_rt5682_max98360a");
974 MODULE_ALIAS("platform:cml_rt1015_rt5682");
975 MODULE_ALIAS("platform:tgl_rt1011_rt5682");