Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

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>

authored by

Alper Nebi Yasak and committed by
Mark Brown
919a4a94 aa98697c

+67 -44
+1 -21
sound/soc/amd/acp/acp-legacy-mach.c
··· 75 75 .tdm_mode = false, 76 76 }; 77 77 78 - static const struct snd_kcontrol_new acp_controls[] = { 79 - SOC_DAPM_PIN_SWITCH("Headphone Jack"), 80 - SOC_DAPM_PIN_SWITCH("Headset Mic"), 81 - SOC_DAPM_PIN_SWITCH("Spk"), 82 - SOC_DAPM_PIN_SWITCH("Left Spk"), 83 - SOC_DAPM_PIN_SWITCH("Right Spk"), 84 - 85 - }; 86 - 87 - static const struct snd_soc_dapm_widget acp_widgets[] = { 88 - SND_SOC_DAPM_HP("Headphone Jack", NULL), 89 - SND_SOC_DAPM_MIC("Headset Mic", NULL), 90 - SND_SOC_DAPM_SPK("Spk", NULL), 91 - SND_SOC_DAPM_SPK("Left Spk", NULL), 92 - SND_SOC_DAPM_SPK("Right Spk", NULL), 93 - }; 94 - 95 78 static int acp_asoc_probe(struct platform_device *pdev) 96 79 { 97 80 struct snd_soc_card *card = NULL; ··· 93 110 card->dev = dev; 94 111 card->owner = THIS_MODULE; 95 112 card->name = pdev->id_entry->name; 96 - card->dapm_widgets = acp_widgets; 97 - card->num_dapm_widgets = ARRAY_SIZE(acp_widgets); 98 - card->controls = acp_controls; 99 - card->num_controls = ARRAY_SIZE(acp_controls); 100 113 card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data; 114 + /* Widgets and controls added per-codec in acp-mach-common.c */ 101 115 102 116 acp_card_drvdata = card->drvdata; 103 117 dmi_id = dmi_first_match(acp_quirk_table);
+65 -3
sound/soc/amd/acp/acp-mach-common.c
··· 513 513 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"), 514 514 COMP_CODEC("i2c-10EC1019:01", "rt1019-aif"))); 515 515 516 + static const struct snd_kcontrol_new rt1019_controls[] = { 517 + SOC_DAPM_PIN_SWITCH("Left Spk"), 518 + SOC_DAPM_PIN_SWITCH("Right Spk"), 519 + }; 520 + 521 + static const struct snd_soc_dapm_widget rt1019_widgets[] = { 522 + SND_SOC_DAPM_SPK("Left Spk", NULL), 523 + SND_SOC_DAPM_SPK("Right Spk", NULL), 524 + }; 525 + 516 526 static const struct snd_soc_dapm_route rt1019_map_lr[] = { 517 527 { "Left Spk", NULL, "Left SPO" }, 518 528 { "Right Spk", NULL, "Right SPO" }, ··· 543 533 { 544 534 struct snd_soc_card *card = rtd->card; 545 535 struct acp_card_drvdata *drvdata = card->drvdata; 536 + int ret; 546 537 547 538 if (drvdata->amp_codec_id != RT1019) 548 539 return -EINVAL; 540 + 541 + ret = snd_soc_dapm_new_controls(&card->dapm, rt1019_widgets, 542 + ARRAY_SIZE(rt1019_widgets)); 543 + if (ret) { 544 + dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret); 545 + return ret; 546 + } 547 + 548 + ret = snd_soc_add_card_controls(card, rt1019_controls, 549 + ARRAY_SIZE(rt1019_controls)); 550 + if (ret) { 551 + dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret); 552 + return ret; 553 + } 549 554 550 555 return snd_soc_dapm_add_routes(&rtd->card->dapm, rt1019_map_lr, 551 556 ARRAY_SIZE(rt1019_map_lr)); ··· 692 667 SND_SOC_DAILINK_DEF(max98360a, 693 668 DAILINK_COMP_ARRAY(COMP_CODEC("MX98360A:00", "HiFi"))); 694 669 670 + static const struct snd_kcontrol_new max98360a_controls[] = { 671 + SOC_DAPM_PIN_SWITCH("Spk"), 672 + }; 673 + 674 + static const struct snd_soc_dapm_widget max98360a_widgets[] = { 675 + SND_SOC_DAPM_SPK("Spk", NULL), 676 + }; 677 + 695 678 static const struct snd_soc_dapm_route max98360a_map[] = { 696 679 {"Spk", NULL, "Speaker"}, 697 680 }; ··· 708 675 { 709 676 struct snd_soc_card *card = rtd->card; 710 677 struct acp_card_drvdata *drvdata = card->drvdata; 678 + int ret; 711 679 712 680 if (drvdata->amp_codec_id != MAX98360A) 713 681 return -EINVAL; 682 + 683 + ret = snd_soc_dapm_new_controls(&card->dapm, max98360a_widgets, 684 + ARRAY_SIZE(max98360a_widgets)); 685 + if (ret) { 686 + dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret); 687 + return ret; 688 + } 689 + 690 + ret = snd_soc_add_card_controls(card, max98360a_controls, 691 + ARRAY_SIZE(max98360a_controls)); 692 + if (ret) { 693 + dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret); 694 + return ret; 695 + } 714 696 715 697 return snd_soc_dapm_add_routes(&rtd->card->dapm, max98360a_map, 716 698 ARRAY_SIZE(max98360a_map)); ··· 792 744 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ADS8388:00", "max98388-aif1"), 793 745 COMP_CODEC("i2c-ADS8388:01", "max98388-aif1"))); 794 746 747 + static const struct snd_kcontrol_new max98388_controls[] = { 748 + SOC_DAPM_PIN_SWITCH("Left Spk"), 749 + SOC_DAPM_PIN_SWITCH("Right Spk"), 750 + }; 751 + 795 752 static const struct snd_soc_dapm_widget max98388_widgets[] = { 796 - SND_SOC_DAPM_SPK("SPK", NULL), 753 + SND_SOC_DAPM_SPK("Left Spk", NULL), 754 + SND_SOC_DAPM_SPK("Right Spk", NULL), 797 755 }; 798 756 799 757 static const struct snd_soc_dapm_route max98388_map[] = { 800 - { "SPK", NULL, "Left BE_OUT" }, 801 - { "SPK", NULL, "Right BE_OUT" }, 758 + { "Left Spk", NULL, "Left BE_OUT" }, 759 + { "Right Spk", NULL, "Right BE_OUT" }, 802 760 }; 803 761 804 762 static struct snd_soc_codec_conf max98388_conf[] = { ··· 857 803 /* Don't need to add routes if widget addition failed */ 858 804 return ret; 859 805 } 806 + 807 + ret = snd_soc_add_card_controls(card, max98388_controls, 808 + ARRAY_SIZE(max98388_controls)); 809 + if (ret) { 810 + dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret); 811 + return ret; 812 + } 813 + 860 814 return snd_soc_dapm_add_routes(&rtd->card->dapm, max98388_map, 861 815 ARRAY_SIZE(max98388_map)); 862 816 }
+1 -20
sound/soc/amd/acp/acp-sof-mach.c
··· 94 94 .tdm_mode = false, 95 95 }; 96 96 97 - static const struct snd_kcontrol_new acp_controls[] = { 98 - SOC_DAPM_PIN_SWITCH("Headphone Jack"), 99 - SOC_DAPM_PIN_SWITCH("Headset Mic"), 100 - SOC_DAPM_PIN_SWITCH("Spk"), 101 - SOC_DAPM_PIN_SWITCH("Left Spk"), 102 - SOC_DAPM_PIN_SWITCH("Right Spk"), 103 - }; 104 - 105 - static const struct snd_soc_dapm_widget acp_widgets[] = { 106 - SND_SOC_DAPM_HP("Headphone Jack", NULL), 107 - SND_SOC_DAPM_MIC("Headset Mic", NULL), 108 - SND_SOC_DAPM_SPK("Spk", NULL), 109 - SND_SOC_DAPM_SPK("Left Spk", NULL), 110 - SND_SOC_DAPM_SPK("Right Spk", NULL), 111 - }; 112 - 113 97 static int acp_sof_probe(struct platform_device *pdev) 114 98 { 115 99 struct snd_soc_card *card = NULL; ··· 112 128 card->dev = dev; 113 129 card->owner = THIS_MODULE; 114 130 card->name = pdev->id_entry->name; 115 - card->dapm_widgets = acp_widgets; 116 - card->num_dapm_widgets = ARRAY_SIZE(acp_widgets); 117 - card->controls = acp_controls; 118 - card->num_controls = ARRAY_SIZE(acp_controls); 119 131 card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data; 132 + /* Widgets and controls added per-codec in acp-mach-common.c */ 120 133 121 134 acp_card_drvdata = card->drvdata; 122 135 dmi_id = dmi_first_match(acp_quirk_table);