ASoC: amd: acp: Add kcontrols and widgets per-codec in common code
authorAlper Nebi Yasak <alpernebiyasak@gmail.com>
Fri, 18 Aug 2023 08:03:14 +0000 (11:03 +0300)
committerMark Brown <broonie@kernel.org>
Fri, 18 Aug 2023 12:55:06 +0000 (13:55 +0100)
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@gmail.com>
Link: https://lore.kernel.org/r/20230818080314.32991-1-alpernebiyasak@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/amd/acp/acp-legacy-mach.c
sound/soc/amd/acp/acp-mach-common.c
sound/soc/amd/acp/acp-sof-mach.c

index 676ad50638d0d01b5a6217a1ca40478db6329762..6d57d17ddfd77096ff123f3ab7e872fbd20213ab 100644 (file)
@@ -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);
index f3abaa182fbb08c160cd2bfc2886d25a4b5e67fb..a06af82b805656f8b45a9c0045744391cea69877 100644 (file)
@@ -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));
 }
index a1c893f33f741e72558f5977663154b89515e01d..5223033a122f86fc290f054c8dae98e12639678a 100644 (file)
@@ -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);