Skip to content

Commit 629ba12

Browse files
macchianbroonie
authored andcommitted
ASoC: Intel: boards: split woofer and tweeter support
Support Woofer stereo speakers by default and optionally Tweeter stereo speakers with a DMI quirk Signed-off-by: Mac Chiang <mac.chiang@intel.com> Link: https://lore.kernel.org/r/1584931764-2778-1-git-send-email-mac.chiang@intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 4eb542c commit 629ba12

File tree

1 file changed

+180
-42
lines changed

1 file changed

+180
-42
lines changed

sound/soc/intel/boards/cml_rt1011_rt5682.c

+180-42
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,36 @@
3030
#define CML_RT5682_CODEC_DAI "rt5682-aif1"
3131
#define NAME_SIZE 32
3232

33+
#define SOF_RT1011_SPEAKER_WL BIT(0)
34+
#define SOF_RT1011_SPEAKER_WR BIT(1)
35+
#define SOF_RT1011_SPEAKER_TL BIT(2)
36+
#define SOF_RT1011_SPEAKER_TR BIT(3)
37+
#define SPK_CH 4
38+
39+
/* Default: Woofer speakers */
40+
static unsigned long sof_rt1011_quirk = SOF_RT1011_SPEAKER_WL |
41+
SOF_RT1011_SPEAKER_WR;
42+
43+
static int sof_rt1011_quirk_cb(const struct dmi_system_id *id)
44+
{
45+
sof_rt1011_quirk = (unsigned long)id->driver_data;
46+
return 1;
47+
}
48+
49+
static const struct dmi_system_id sof_rt1011_quirk_table[] = {
50+
{
51+
.callback = sof_rt1011_quirk_cb,
52+
.matches = {
53+
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
54+
DMI_MATCH(DMI_PRODUCT_NAME, "Helios"),
55+
},
56+
.driver_data = (void *)(SOF_RT1011_SPEAKER_WL | SOF_RT1011_SPEAKER_WR |
57+
SOF_RT1011_SPEAKER_TL | SOF_RT1011_SPEAKER_TR),
58+
},
59+
{
60+
}
61+
};
62+
3363
static struct snd_soc_jack hdmi_jack[3];
3464

3565
struct hdmi_pcm {
@@ -48,26 +78,30 @@ struct card_private {
4878
static const struct snd_kcontrol_new cml_controls[] = {
4979
SOC_DAPM_PIN_SWITCH("Headphone Jack"),
5080
SOC_DAPM_PIN_SWITCH("Headset Mic"),
51-
SOC_DAPM_PIN_SWITCH("TL Ext Spk"),
52-
SOC_DAPM_PIN_SWITCH("TR Ext Spk"),
5381
SOC_DAPM_PIN_SWITCH("WL Ext Spk"),
5482
SOC_DAPM_PIN_SWITCH("WR Ext Spk"),
5583
};
5684

85+
static const struct snd_kcontrol_new cml_rt1011_tt_controls[] = {
86+
SOC_DAPM_PIN_SWITCH("TL Ext Spk"),
87+
SOC_DAPM_PIN_SWITCH("TR Ext Spk"),
88+
};
89+
5790
static const struct snd_soc_dapm_widget cml_rt1011_rt5682_widgets[] = {
58-
SND_SOC_DAPM_SPK("TL Ext Spk", NULL),
59-
SND_SOC_DAPM_SPK("TR Ext Spk", NULL),
6091
SND_SOC_DAPM_SPK("WL Ext Spk", NULL),
6192
SND_SOC_DAPM_SPK("WR Ext Spk", NULL),
6293
SND_SOC_DAPM_HP("Headphone Jack", NULL),
6394
SND_SOC_DAPM_MIC("Headset Mic", NULL),
6495
SND_SOC_DAPM_MIC("SoC DMIC", NULL),
6596
};
6697

98+
static const struct snd_soc_dapm_widget cml_rt1011_tt_widgets[] = {
99+
SND_SOC_DAPM_SPK("TL Ext Spk", NULL),
100+
SND_SOC_DAPM_SPK("TR Ext Spk", NULL),
101+
};
102+
67103
static const struct snd_soc_dapm_route cml_rt1011_rt5682_map[] = {
68-
/*speaker*/
69-
{"TL Ext Spk", NULL, "TL SPO"},
70-
{"TR Ext Spk", NULL, "TR SPO"},
104+
/*WL/WR speaker*/
71105
{"WL Ext Spk", NULL, "WL SPO"},
72106
{"WR Ext Spk", NULL, "WR SPO"},
73107

@@ -82,6 +116,12 @@ static const struct snd_soc_dapm_route cml_rt1011_rt5682_map[] = {
82116
{"DMic", NULL, "SoC DMIC"},
83117
};
84118

119+
static const struct snd_soc_dapm_route cml_rt1011_tt_map[] = {
120+
/*TL/TR speaker*/
121+
{"TL Ext Spk", NULL, "TL SPO" },
122+
{"TR Ext Spk", NULL, "TR SPO" },
123+
};
124+
85125
static int cml_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
86126
{
87127
struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
@@ -121,6 +161,35 @@ static int cml_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
121161
return ret;
122162
};
123163

164+
static int cml_rt1011_spk_init(struct snd_soc_pcm_runtime *rtd)
165+
{
166+
int ret = 0;
167+
struct snd_soc_card *card = rtd->card;
168+
169+
if (sof_rt1011_quirk & (SOF_RT1011_SPEAKER_TL |
170+
SOF_RT1011_SPEAKER_TR)) {
171+
172+
ret = snd_soc_add_card_controls(card, cml_rt1011_tt_controls,
173+
ARRAY_SIZE(cml_rt1011_tt_controls));
174+
if (ret)
175+
return ret;
176+
177+
ret = snd_soc_dapm_new_controls(&card->dapm,
178+
cml_rt1011_tt_widgets,
179+
ARRAY_SIZE(cml_rt1011_tt_widgets));
180+
if (ret)
181+
return ret;
182+
183+
ret = snd_soc_dapm_add_routes(&card->dapm, cml_rt1011_tt_map,
184+
ARRAY_SIZE(cml_rt1011_tt_map));
185+
186+
if (ret)
187+
return ret;
188+
}
189+
190+
return ret;
191+
}
192+
124193
static int cml_rt5682_hw_params(struct snd_pcm_substream *substream,
125194
struct snd_pcm_hw_params *params)
126195
{
@@ -191,30 +260,38 @@ static int cml_rt1011_hw_params(struct snd_pcm_substream *substream,
191260
* The feedback is captured for each codec individually.
192261
* Hence all 4 codecs use 1 Tx slot each for feedback.
193262
*/
194-
if (!strcmp(codec_dai->component->name, "i2c-10EC1011:00")) {
195-
ret = snd_soc_dai_set_tdm_slot(codec_dai,
196-
0x4, 0x1, 4, 24);
197-
if (ret < 0)
198-
break;
199-
}
200-
if (!strcmp(codec_dai->component->name, "i2c-10EC1011:02")) {
201-
ret = snd_soc_dai_set_tdm_slot(codec_dai,
202-
0x1, 0x1, 4, 24);
203-
if (ret < 0)
204-
break;
263+
if (sof_rt1011_quirk & (SOF_RT1011_SPEAKER_WL |
264+
SOF_RT1011_SPEAKER_WR)) {
265+
if (!strcmp(codec_dai->component->name, "i2c-10EC1011:00")) {
266+
ret = snd_soc_dai_set_tdm_slot(codec_dai,
267+
0x4, 0x1, 4, 24);
268+
if (ret < 0)
269+
break;
270+
}
271+
272+
if (!strcmp(codec_dai->component->name, "i2c-10EC1011:01")) {
273+
ret = snd_soc_dai_set_tdm_slot(codec_dai,
274+
0x8, 0x2, 4, 24);
275+
if (ret < 0)
276+
break;
277+
}
205278
}
206-
/* TDM Rx slot 2 is used for Right Woofer & Tweeters pair */
207-
if (!strcmp(codec_dai->component->name, "i2c-10EC1011:01")) {
208-
ret = snd_soc_dai_set_tdm_slot(codec_dai,
209-
0x8, 0x2, 4, 24);
210-
if (ret < 0)
211-
break;
212-
}
213-
if (!strcmp(codec_dai->component->name, "i2c-10EC1011:03")) {
214-
ret = snd_soc_dai_set_tdm_slot(codec_dai,
215-
0x2, 0x2, 4, 24);
216-
if (ret < 0)
217-
break;
279+
280+
if (sof_rt1011_quirk & (SOF_RT1011_SPEAKER_TL |
281+
SOF_RT1011_SPEAKER_TR)) {
282+
if (!strcmp(codec_dai->component->name, "i2c-10EC1011:02")) {
283+
ret = snd_soc_dai_set_tdm_slot(codec_dai,
284+
0x1, 0x1, 4, 24);
285+
if (ret < 0)
286+
break;
287+
}
288+
289+
if (!strcmp(codec_dai->component->name, "i2c-10EC1011:03")) {
290+
ret = snd_soc_dai_set_tdm_slot(codec_dai,
291+
0x2, 0x2, 4, 24);
292+
if (ret < 0)
293+
break;
294+
}
218295
}
219296
}
220297
if (ret < 0)
@@ -302,9 +379,7 @@ SND_SOC_DAILINK_DEF(ssp1_pin,
302379
SND_SOC_DAILINK_DEF(ssp1_codec,
303380
DAILINK_COMP_ARRAY(
304381
/* WL */ COMP_CODEC("i2c-10EC1011:00", CML_RT1011_CODEC_DAI),
305-
/* WR */ COMP_CODEC("i2c-10EC1011:01", CML_RT1011_CODEC_DAI),
306-
/* TL */ COMP_CODEC("i2c-10EC1011:02", CML_RT1011_CODEC_DAI),
307-
/* TR */ COMP_CODEC("i2c-10EC1011:03", CML_RT1011_CODEC_DAI)));
382+
/* WR */ COMP_CODEC("i2c-10EC1011:01", CML_RT1011_CODEC_DAI)));
308383

309384
SND_SOC_DAILINK_DEF(dmic_pin,
310385
DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin")));
@@ -398,6 +473,7 @@ static struct snd_soc_dai_link cml_rt1011_rt5682_dailink[] = {
398473
.dpcm_playback = 1,
399474
.dpcm_capture = 1, /* Capture stream provides Feedback */
400475
.no_pcm = 1,
476+
.init = cml_rt1011_spk_init,
401477
.ops = &cml_rt1011_ops,
402478
SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform),
403479
},
@@ -412,14 +488,6 @@ static struct snd_soc_codec_conf rt1011_conf[] = {
412488
.dlc = COMP_CODEC_CONF("i2c-10EC1011:01"),
413489
.name_prefix = "WR",
414490
},
415-
{
416-
.dlc = COMP_CODEC_CONF("i2c-10EC1011:02"),
417-
.name_prefix = "TL",
418-
},
419-
{
420-
.dlc = COMP_CODEC_CONF("i2c-10EC1011:03"),
421-
.name_prefix = "TR",
422-
},
423491
};
424492

425493
/* Cometlake audio machine driver for RT1011 and RT5682 */
@@ -441,10 +509,12 @@ static struct snd_soc_card snd_soc_card_cml = {
441509

442510
static int snd_cml_rt1011_probe(struct platform_device *pdev)
443511
{
512+
struct snd_soc_dai_link_component *rt1011_dais_components;
513+
struct snd_soc_codec_conf *rt1011_dais_confs;
444514
struct card_private *ctx;
445515
struct snd_soc_acpi_mach *mach;
446516
const char *platform_name;
447-
int ret;
517+
int ret, i;
448518

449519
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
450520
if (!ctx)
@@ -455,6 +525,73 @@ static int snd_cml_rt1011_probe(struct platform_device *pdev)
455525
snd_soc_card_cml.dev = &pdev->dev;
456526
platform_name = mach->mach_params.platform;
457527

528+
dmi_check_system(sof_rt1011_quirk_table);
529+
530+
dev_info(&pdev->dev, "sof_rt1011_quirk = %lx\n", sof_rt1011_quirk);
531+
532+
if (sof_rt1011_quirk & (SOF_RT1011_SPEAKER_TL |
533+
SOF_RT1011_SPEAKER_TR)) {
534+
rt1011_dais_confs = devm_kzalloc(&pdev->dev,
535+
sizeof(struct snd_soc_codec_conf) *
536+
SPK_CH, GFP_KERNEL);
537+
538+
if (!rt1011_dais_confs)
539+
return -ENOMEM;
540+
541+
rt1011_dais_components = devm_kzalloc(&pdev->dev,
542+
sizeof(struct snd_soc_dai_link_component) *
543+
SPK_CH, GFP_KERNEL);
544+
545+
if (!rt1011_dais_components)
546+
return -ENOMEM;
547+
548+
for (i = 0; i < SPK_CH; i++) {
549+
rt1011_dais_confs[i].dlc.name = devm_kasprintf(&pdev->dev,
550+
GFP_KERNEL,
551+
"i2c-10EC1011:0%d",
552+
i);
553+
554+
if (!rt1011_dais_confs[i].dlc.name)
555+
return -ENOMEM;
556+
557+
switch (i) {
558+
case 0:
559+
rt1011_dais_confs[i].name_prefix = "WL";
560+
break;
561+
case 1:
562+
rt1011_dais_confs[i].name_prefix = "WR";
563+
break;
564+
case 2:
565+
rt1011_dais_confs[i].name_prefix = "TL";
566+
break;
567+
case 3:
568+
rt1011_dais_confs[i].name_prefix = "TR";
569+
break;
570+
default:
571+
return -EINVAL;
572+
}
573+
rt1011_dais_components[i].name = devm_kasprintf(&pdev->dev,
574+
GFP_KERNEL,
575+
"i2c-10EC1011:0%d",
576+
i);
577+
if (!rt1011_dais_components[i].name)
578+
return -ENOMEM;
579+
580+
rt1011_dais_components[i].dai_name = CML_RT1011_CODEC_DAI;
581+
}
582+
583+
snd_soc_card_cml.codec_conf = rt1011_dais_confs;
584+
snd_soc_card_cml.num_configs = SPK_CH;
585+
586+
for (i = 0; i < ARRAY_SIZE(cml_rt1011_rt5682_dailink); i++) {
587+
if (!strcmp(cml_rt1011_rt5682_dailink[i].codecs->dai_name,
588+
CML_RT1011_CODEC_DAI)) {
589+
cml_rt1011_rt5682_dailink[i].codecs = rt1011_dais_components;
590+
cml_rt1011_rt5682_dailink[i].num_codecs = SPK_CH;
591+
}
592+
}
593+
}
594+
458595
/* set platform name for each dailink */
459596
ret = snd_soc_fixup_dai_links_platform_name(&snd_soc_card_cml,
460597
platform_name);
@@ -482,5 +619,6 @@ MODULE_DESCRIPTION("Cometlake Audio Machine driver - RT1011 and RT5682 in I2S mo
482619
MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
483620
MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
484621
MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>");
622+
MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
485623
MODULE_LICENSE("GPL v2");
486624
MODULE_ALIAS("platform:cml_rt1011_rt5682");

0 commit comments

Comments
 (0)