Skip to content

Commit 551fb55

Browse files
brentlubroonie
authored andcommitted
ASoC: Intel: sof_realtek_common: support 4xALC1011 amplifier
Add support for boards with four ALC1011 amplifiers. Configuration is copied from cml_rt1011_rt5682 machine driver for backward compatibility with existing cml devices. Reviewed-by: Chao Song <chao.song@linux.intel.com> Signed-off-by: Brent Lu <brent.lu@intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20240411220347.131267-10-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent fe18a4b commit 551fb55

3 files changed

Lines changed: 162 additions & 24 deletions

File tree

sound/soc/intel/boards/sof_realtek_common.c

Lines changed: 158 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,55 @@
1515
#include "../../codecs/rt1011.h"
1616
#include "../../codecs/rt1015.h"
1717
#include "../../codecs/rt1308.h"
18+
#include "../common/soc-intel-quirks.h"
1819
#include "sof_realtek_common.h"
1920

2021
/*
21-
* Current only 2-amp configuration is supported for rt1011
22+
* Common structures and functions
23+
*/
24+
static const struct snd_kcontrol_new realtek_4spk_kcontrols[] = {
25+
SOC_DAPM_PIN_SWITCH("WL Ext Spk"),
26+
SOC_DAPM_PIN_SWITCH("WR Ext Spk"),
27+
SOC_DAPM_PIN_SWITCH("TL Ext Spk"),
28+
SOC_DAPM_PIN_SWITCH("TR Ext Spk"),
29+
};
30+
31+
static const struct snd_soc_dapm_widget realtek_4spk_widgets[] = {
32+
SND_SOC_DAPM_SPK("WL Ext Spk", NULL),
33+
SND_SOC_DAPM_SPK("WR Ext Spk", NULL),
34+
SND_SOC_DAPM_SPK("TL Ext Spk", NULL),
35+
SND_SOC_DAPM_SPK("TR Ext Spk", NULL),
36+
};
37+
38+
/* helper function to get the number of specific codec */
39+
static unsigned int get_num_codecs(const char *hid)
40+
{
41+
struct acpi_device *adev;
42+
unsigned int dev_num = 0;
43+
44+
for_each_acpi_dev_match(adev, hid, NULL, -1)
45+
dev_num++;
46+
47+
return dev_num;
48+
}
49+
50+
/*
51+
* Realtek ALC1011
2252
*/
2353
static const struct snd_soc_dapm_route speaker_map_lr[] = {
2454
/* speaker */
2555
{ "Left Spk", NULL, "Left SPO" },
2656
{ "Right Spk", NULL, "Right SPO" },
2757
};
2858

29-
/*
30-
* Make sure device's Unique ID follows this configuration:
31-
*
32-
* Two speakers:
33-
* 0: left, 1: right
34-
* Four speakers:
35-
* 0: Woofer left, 1: Woofer right
36-
* 2: Tweeter left, 3: Tweeter right
37-
*/
38-
static struct snd_soc_codec_conf rt1011_codec_confs[] = {
59+
static const struct snd_soc_dapm_route rt1011_4spk_routes[] = {
60+
{"WL Ext Spk", NULL, "WL SPO" },
61+
{"WR Ext Spk", NULL, "WR SPO" },
62+
{"TL Ext Spk", NULL, "TL SPO" },
63+
{"TR Ext Spk", NULL, "TR SPO" },
64+
};
65+
66+
static struct snd_soc_codec_conf rt1011_2spk_codec_confs[] = {
3967
{
4068
.dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME),
4169
.name_prefix = "Left",
@@ -46,6 +74,25 @@ static struct snd_soc_codec_conf rt1011_codec_confs[] = {
4674
},
4775
};
4876

77+
static struct snd_soc_codec_conf rt1011_4spk_codec_confs[] = {
78+
{
79+
.dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME),
80+
.name_prefix = "WL",
81+
},
82+
{
83+
.dlc = COMP_CODEC_CONF(RT1011_DEV1_NAME),
84+
.name_prefix = "WR",
85+
},
86+
{
87+
.dlc = COMP_CODEC_CONF(RT1011_DEV2_NAME),
88+
.name_prefix = "TL",
89+
},
90+
{
91+
.dlc = COMP_CODEC_CONF(RT1011_DEV3_NAME),
92+
.name_prefix = "TR",
93+
},
94+
};
95+
4996
static struct snd_soc_dai_link_component rt1011_dai_link_components[] = {
5097
{
5198
.name = RT1011_DEV0_NAME,
@@ -55,6 +102,14 @@ static struct snd_soc_dai_link_component rt1011_dai_link_components[] = {
55102
.name = RT1011_DEV1_NAME,
56103
.dai_name = RT1011_CODEC_DAI,
57104
},
105+
{
106+
.name = RT1011_DEV2_NAME,
107+
.dai_name = RT1011_CODEC_DAI,
108+
},
109+
{
110+
.name = RT1011_DEV3_NAME,
111+
.dai_name = RT1011_CODEC_DAI,
112+
},
58113
};
59114

60115
static const struct {
@@ -63,6 +118,8 @@ static const struct {
63118
} rt1011_tdm_mask[] = {
64119
{.tx = 0x4, .rx = 0x1},
65120
{.tx = 0x8, .rx = 0x2},
121+
{.tx = 0x1, .rx = 0x1},
122+
{.tx = 0x2, .rx = 0x2},
66123
};
67124

68125
static int rt1011_hw_params(struct snd_pcm_substream *substream,
@@ -118,28 +175,109 @@ static const struct snd_soc_ops rt1011_ops = {
118175
static int rt1011_init(struct snd_soc_pcm_runtime *rtd)
119176
{
120177
struct snd_soc_card *card = rtd->card;
178+
unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID);
121179
int ret;
122180

123-
ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map_lr,
124-
ARRAY_SIZE(speaker_map_lr));
125-
if (ret)
126-
dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret);
181+
switch (num_codecs) {
182+
case 2:
183+
if (!soc_intel_is_cml()) {
184+
ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map_lr,
185+
ARRAY_SIZE(speaker_map_lr));
186+
if (ret) {
187+
dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n",
188+
ret);
189+
return ret;
190+
}
191+
192+
break;
193+
}
194+
195+
/*
196+
* register speaker widgets "WL Ext Spk" and "WR Ext Spk" to
197+
* keep backward compatible with cml devices
198+
*/
199+
fallthrough;
200+
case 4:
201+
ret = snd_soc_dapm_new_controls(&card->dapm, realtek_4spk_widgets,
202+
num_codecs);
203+
if (ret) {
204+
dev_err(rtd->dev, "fail to add rt1011 widgets, ret %d\n",
205+
ret);
206+
return ret;
207+
}
208+
209+
ret = snd_soc_add_card_controls(card, realtek_4spk_kcontrols,
210+
num_codecs);
211+
if (ret) {
212+
dev_err(rtd->dev, "fail to add rt1011 controls, ret %d\n",
213+
ret);
214+
return ret;
215+
}
216+
217+
ret = snd_soc_dapm_add_routes(&card->dapm, rt1011_4spk_routes,
218+
num_codecs);
219+
if (ret) {
220+
dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n",
221+
ret);
222+
return ret;
223+
}
224+
break;
225+
default:
226+
dev_err(rtd->dev, "rt1011: invalid num_codecs %d\n", num_codecs);
227+
return -EINVAL;
228+
}
229+
127230
return ret;
128231
}
129232

130-
void sof_rt1011_dai_link(struct snd_soc_dai_link *link)
233+
void sof_rt1011_dai_link(struct device *dev, struct snd_soc_dai_link *link)
131234
{
235+
unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID);
236+
132237
link->codecs = rt1011_dai_link_components;
133-
link->num_codecs = ARRAY_SIZE(rt1011_dai_link_components);
238+
239+
switch (num_codecs) {
240+
case 2:
241+
case 4:
242+
link->num_codecs = num_codecs;
243+
break;
244+
default:
245+
dev_err(dev, "rt1011: invalid num_codecs %d\n", num_codecs);
246+
break;
247+
}
248+
134249
link->init = rt1011_init;
135250
link->ops = &rt1011_ops;
136251
}
137252
EXPORT_SYMBOL_NS(sof_rt1011_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
138253

139-
void sof_rt1011_codec_conf(struct snd_soc_card *card)
254+
void sof_rt1011_codec_conf(struct device *dev, struct snd_soc_card *card)
140255
{
141-
card->codec_conf = rt1011_codec_confs;
142-
card->num_configs = ARRAY_SIZE(rt1011_codec_confs);
256+
unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID);
257+
258+
switch (num_codecs) {
259+
case 2:
260+
if (soc_intel_is_cml()) {
261+
/*
262+
* use name prefix 'WL' and 'WR' for speaker widgets to
263+
* keep backward compatible with cml devices
264+
*/
265+
card->codec_conf = rt1011_4spk_codec_confs;
266+
} else {
267+
card->codec_conf = rt1011_2spk_codec_confs;
268+
}
269+
270+
card->num_configs = num_codecs;
271+
break;
272+
case 4:
273+
card->codec_conf = rt1011_4spk_codec_confs;
274+
card->num_configs = ARRAY_SIZE(rt1011_4spk_codec_confs);
275+
break;
276+
default:
277+
dev_err(dev, "rt1011: invalid num_codecs %d\n", num_codecs);
278+
break;
279+
}
280+
143281
}
144282
EXPORT_SYMBOL_NS(sof_rt1011_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON);
145283

sound/soc/intel/boards/sof_realtek_common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
#define RT1011_DEV2_NAME "i2c-" RT1011_ACPI_HID ":02"
2424
#define RT1011_DEV3_NAME "i2c-" RT1011_ACPI_HID ":03"
2525

26-
void sof_rt1011_dai_link(struct snd_soc_dai_link *link);
27-
void sof_rt1011_codec_conf(struct snd_soc_card *card);
26+
void sof_rt1011_dai_link(struct device *dev, struct snd_soc_dai_link *link);
27+
void sof_rt1011_codec_conf(struct device *dev, struct snd_soc_card *card);
2828

2929
/*
3030
* Realtek ALC1015 (AUTO)

sound/soc/intel/boards/sof_rt5682.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ sof_card_dai_links_create(struct device *dev, struct snd_soc_card *card,
576576
max_98390_dai_link(dev, ctx->amp_link);
577577
break;
578578
case CODEC_RT1011:
579-
sof_rt1011_dai_link(ctx->amp_link);
579+
sof_rt1011_dai_link(dev, ctx->amp_link);
580580
break;
581581
case CODEC_RT1015:
582582
sof_rt1015_dai_link(ctx->amp_link);
@@ -683,7 +683,7 @@ static int sof_audio_probe(struct platform_device *pdev)
683683
max_98390_set_codec_conf(&pdev->dev, &sof_audio_card_rt5682);
684684
break;
685685
case CODEC_RT1011:
686-
sof_rt1011_codec_conf(&sof_audio_card_rt5682);
686+
sof_rt1011_codec_conf(&pdev->dev, &sof_audio_card_rt5682);
687687
break;
688688
case CODEC_RT1015:
689689
sof_rt1015_codec_conf(&sof_audio_card_rt5682);

0 commit comments

Comments
 (0)