[PATCH] ASoC: amd: acp: Add kcontrols and widgets per-codec in common code

From: Alper Nebi Yasak
Date: Fri Aug 18 2023 - 04:04:25 EST


Commit 7ac3404c2e21 ("ASoC: amd: acp: Map missing jack kcontrols") adds
card kcontrols and DAPM widgets corresponding to jacks for Headphone and
Headset Mic. But these were already being added in acp-legacy-mach.c and
acp-sof-mach.c, so this causes a probe error:

sof_mach rt5682s-hs-rt1019: control 2:0:0:Headphone Jack Switch:0 is already present
sof_mach rt5682s-hs-rt1019: ASoC: Failed to add Headphone Jack Switch: -16
sof_mach rt5682s-hs-rt1019: devm_snd_soc_register_card(sof-rt5682s-hs-rt1019) failed: -16
sof_mach: probe of rt5682s-hs-rt1019 failed with error -16

Removing the new duplicates from the common code might be enough to fix
the issue. But some of the codecs use different kcontrols and widgets.
NAU8821 alone has an "Int Mic". MAX98360A has a single "Spk", while
RT1019 has "Left Spk" and "Right Spk" (and two codec instances with name
prefixes).

Since there are per-codec differences, add the kcontrols and widgets
in the common code as each dai-link is being initialized, instead of in
the two machine drivers' probe().

Also, MAX98388 has Left and Right instances, but uses a single "SPK"
widget. That seems weird, so normalize it to use two widgets (one per
each instance like RT1019) while we're adding controls.

Fixes: 7ac3404c2e21 ("ASoC: amd: acp: Map missing jack kcontrols")
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@xxxxxxxxx>
---
Applies onto linux-next.

sound/soc/amd/acp/acp-legacy-mach.c | 22 +---------
sound/soc/amd/acp/acp-mach-common.c | 68 +++++++++++++++++++++++++++--
sound/soc/amd/acp/acp-sof-mach.c | 21 +--------
3 files changed, 67 insertions(+), 44 deletions(-)

diff --git a/sound/soc/amd/acp/acp-legacy-mach.c b/sound/soc/amd/acp/acp-legacy-mach.c
index 676ad50638d0..6d57d17ddfd7 100644
--- a/sound/soc/amd/acp/acp-legacy-mach.c
+++ b/sound/soc/amd/acp/acp-legacy-mach.c
@@ -75,23 +75,6 @@ static struct acp_card_drvdata rt5682s_rt1019_rmb_data = {
.tdm_mode = false,
};

-static const struct snd_kcontrol_new acp_controls[] = {
- SOC_DAPM_PIN_SWITCH("Headphone Jack"),
- SOC_DAPM_PIN_SWITCH("Headset Mic"),
- SOC_DAPM_PIN_SWITCH("Spk"),
- SOC_DAPM_PIN_SWITCH("Left Spk"),
- SOC_DAPM_PIN_SWITCH("Right Spk"),
-
-};
-
-static const struct snd_soc_dapm_widget acp_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
- SND_SOC_DAPM_SPK("Spk", NULL),
- SND_SOC_DAPM_SPK("Left Spk", NULL),
- SND_SOC_DAPM_SPK("Right Spk", NULL),
-};
-
static int acp_asoc_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = NULL;
@@ -110,11 +93,8 @@ static int acp_asoc_probe(struct platform_device *pdev)
card->dev = dev;
card->owner = THIS_MODULE;
card->name = pdev->id_entry->name;
- card->dapm_widgets = acp_widgets;
- card->num_dapm_widgets = ARRAY_SIZE(acp_widgets);
- card->controls = acp_controls;
- card->num_controls = ARRAY_SIZE(acp_controls);
card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
+ /* Widgets and controls added per-codec in acp-mach-common.c */

acp_card_drvdata = card->drvdata;
dmi_id = dmi_first_match(acp_quirk_table);
diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c
index f3abaa182fbb..a06af82b8056 100644
--- a/sound/soc/amd/acp/acp-mach-common.c
+++ b/sound/soc/amd/acp/acp-mach-common.c
@@ -513,6 +513,16 @@ SND_SOC_DAILINK_DEF(rt1019,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"),
COMP_CODEC("i2c-10EC1019:01", "rt1019-aif")));

+static const struct snd_kcontrol_new rt1019_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Left Spk"),
+ SOC_DAPM_PIN_SWITCH("Right Spk"),
+};
+
+static const struct snd_soc_dapm_widget rt1019_widgets[] = {
+ SND_SOC_DAPM_SPK("Left Spk", NULL),
+ SND_SOC_DAPM_SPK("Right Spk", NULL),
+};
+
static const struct snd_soc_dapm_route rt1019_map_lr[] = {
{ "Left Spk", NULL, "Left SPO" },
{ "Right Spk", NULL, "Right SPO" },
@@ -533,10 +543,25 @@ static int acp_card_rt1019_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
struct acp_card_drvdata *drvdata = card->drvdata;
+ int ret;

if (drvdata->amp_codec_id != RT1019)
return -EINVAL;

+ ret = snd_soc_dapm_new_controls(&card->dapm, rt1019_widgets,
+ ARRAY_SIZE(rt1019_widgets));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_add_card_controls(card, rt1019_controls,
+ ARRAY_SIZE(rt1019_controls));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
+ return ret;
+ }
+
return snd_soc_dapm_add_routes(&rtd->card->dapm, rt1019_map_lr,
ARRAY_SIZE(rt1019_map_lr));
}
@@ -667,6 +692,14 @@ static const struct snd_soc_ops acp_card_rt1019_ops = {
SND_SOC_DAILINK_DEF(max98360a,
DAILINK_COMP_ARRAY(COMP_CODEC("MX98360A:00", "HiFi")));

+static const struct snd_kcontrol_new max98360a_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Spk"),
+};
+
+static const struct snd_soc_dapm_widget max98360a_widgets[] = {
+ SND_SOC_DAPM_SPK("Spk", NULL),
+};
+
static const struct snd_soc_dapm_route max98360a_map[] = {
{"Spk", NULL, "Speaker"},
};
@@ -675,10 +708,25 @@ static int acp_card_maxim_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
struct acp_card_drvdata *drvdata = card->drvdata;
+ int ret;

if (drvdata->amp_codec_id != MAX98360A)
return -EINVAL;

+ ret = snd_soc_dapm_new_controls(&card->dapm, max98360a_widgets,
+ ARRAY_SIZE(max98360a_widgets));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_add_card_controls(card, max98360a_controls,
+ ARRAY_SIZE(max98360a_controls));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
+ return ret;
+ }
+
return snd_soc_dapm_add_routes(&rtd->card->dapm, max98360a_map,
ARRAY_SIZE(max98360a_map));
}
@@ -744,13 +792,19 @@ SND_SOC_DAILINK_DEF(max98388,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ADS8388:00", "max98388-aif1"),
COMP_CODEC("i2c-ADS8388:01", "max98388-aif1")));

+static const struct snd_kcontrol_new max98388_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Left Spk"),
+ SOC_DAPM_PIN_SWITCH("Right Spk"),
+};
+
static const struct snd_soc_dapm_widget max98388_widgets[] = {
- SND_SOC_DAPM_SPK("SPK", NULL),
+ SND_SOC_DAPM_SPK("Left Spk", NULL),
+ SND_SOC_DAPM_SPK("Right Spk", NULL),
};

static const struct snd_soc_dapm_route max98388_map[] = {
- { "SPK", NULL, "Left BE_OUT" },
- { "SPK", NULL, "Right BE_OUT" },
+ { "Left Spk", NULL, "Left BE_OUT" },
+ { "Right Spk", NULL, "Right BE_OUT" },
};

static struct snd_soc_codec_conf max98388_conf[] = {
@@ -803,6 +857,14 @@ static int acp_card_max98388_init(struct snd_soc_pcm_runtime *rtd)
/* Don't need to add routes if widget addition failed */
return ret;
}
+
+ ret = snd_soc_add_card_controls(card, max98388_controls,
+ ARRAY_SIZE(max98388_controls));
+ if (ret) {
+ dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
+ return ret;
+ }
+
return snd_soc_dapm_add_routes(&rtd->card->dapm, max98388_map,
ARRAY_SIZE(max98388_map));
}
diff --git a/sound/soc/amd/acp/acp-sof-mach.c b/sound/soc/amd/acp/acp-sof-mach.c
index a1c893f33f74..5223033a122f 100644
--- a/sound/soc/amd/acp/acp-sof-mach.c
+++ b/sound/soc/amd/acp/acp-sof-mach.c
@@ -94,22 +94,6 @@ static struct acp_card_drvdata sof_nau8821_max98388_data = {
.tdm_mode = false,
};

-static const struct snd_kcontrol_new acp_controls[] = {
- SOC_DAPM_PIN_SWITCH("Headphone Jack"),
- SOC_DAPM_PIN_SWITCH("Headset Mic"),
- SOC_DAPM_PIN_SWITCH("Spk"),
- SOC_DAPM_PIN_SWITCH("Left Spk"),
- SOC_DAPM_PIN_SWITCH("Right Spk"),
-};
-
-static const struct snd_soc_dapm_widget acp_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
- SND_SOC_DAPM_SPK("Spk", NULL),
- SND_SOC_DAPM_SPK("Left Spk", NULL),
- SND_SOC_DAPM_SPK("Right Spk", NULL),
-};
-
static int acp_sof_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = NULL;
@@ -128,11 +112,8 @@ static int acp_sof_probe(struct platform_device *pdev)
card->dev = dev;
card->owner = THIS_MODULE;
card->name = pdev->id_entry->name;
- card->dapm_widgets = acp_widgets;
- card->num_dapm_widgets = ARRAY_SIZE(acp_widgets);
- card->controls = acp_controls;
- card->num_controls = ARRAY_SIZE(acp_controls);
card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
+ /* Widgets and controls added per-codec in acp-mach-common.c */

acp_card_drvdata = card->drvdata;
dmi_id = dmi_first_match(acp_quirk_table);

base-commit: 47762f08697484cf0c2f2904b8c52375ed26c8cb
--
2.40.1