From 28809aaeabdf2c01ffe597553146527d1fba3589 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 Oct 2023 12:34:02 -0500 Subject: [PATCH 01/10] ASoC: intel: sof_sdw: Stop processing CODECs when enough are found When adding CODECs to a DAI link, the code should stop processing more CODECs when the expected number of CODECs are discovered. This fixes a small corner case issue introduced when support for different devices on the same SoundWire link was added. In the case of aggregated devices everything is fine, as all devices intended for the DAI link will be marked with the same group and any not intended for that DAI are skipped by the group check. However for non-aggregated devices the group check is bypassed and the current code does not stop after it has found the first device. Meaning if additional non-aggregated devices are present on the same SoundWire link they will be erroneously added into the DAI link. Fix this issue, and provide a small optimisation by ceasing to process devices once we have reached the required number of devices for the current DAI link. Fixes: 317dcdecaf7a ("ASoC: intel: sof_sdw: Allow different devices on the same link") Signed-off-by: Charles Keepax Reviewed-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20231019173411.166759-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index c5d555cc6f8e..ad1d01ebbcd9 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1409,7 +1409,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, continue; /* j reset after loop, adr_index only applies to first link */ - for (; j < adr_link_next->num_adr; j++) { + for (; j < adr_link_next->num_adr && codec_dlc_index < codec_num; j++) { const struct snd_soc_acpi_endpoint *endpoints; endpoints = adr_link_next->adr_d[j].endpoints; From a92ccd574390149d3d64488ec5fe1e9b80e5f74c Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 Oct 2023 12:34:03 -0500 Subject: [PATCH 02/10] ASoC: intel: sof_sdw_cs42l43: Some trivial formatting clean ups No functional change, just some trivial whitespace fixups. Reviewed-by: Bard Liao Signed-off-by: Charles Keepax Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20231019173411.166759-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw_cs42l43.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw_cs42l43.c b/sound/soc/intel/boards/sof_sdw_cs42l43.c index dc3062cc3a43..9b072c745f10 100644 --- a/sound/soc/intel/boards/sof_sdw_cs42l43.c +++ b/sound/soc/intel/boards/sof_sdw_cs42l43.c @@ -47,7 +47,8 @@ static int cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_card *card = rtd->card; int ret; - card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s hs:cs42l43", card->components); + card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s hs:cs42l43", + card->components); if (!card->components) return -ENOMEM; @@ -60,7 +61,6 @@ static int cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd) ret = snd_soc_dapm_add_routes(&card->dapm, cs42l43_hs_map, ARRAY_SIZE(cs42l43_hs_map)); - if (ret) { dev_err(card->dev, "cs42l43 hs map addition failed: %d\n", ret); return ret; @@ -104,7 +104,6 @@ int sof_sdw_cs42l43_hs_init(struct snd_soc_card *card, const struct snd_soc_acpi * No need to test if (!playback) like other codecs as cs42l43 uses separated dai for * playback and capture, and sof_sdw_cs42l43_init is only linked to the playback dai. */ - dai_links->init = cs42l43_hs_rtd_init; return 0; @@ -129,7 +128,6 @@ static int cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd) ret = snd_soc_dapm_add_routes(&card->dapm, cs42l43_dmic_map, ARRAY_SIZE(cs42l43_dmic_map)); - if (ret) dev_err(card->dev, "cs42l43 dmic map addition failed: %d\n", ret); @@ -141,5 +139,6 @@ int sof_sdw_cs42l43_dmic_init(struct snd_soc_card *card, const struct snd_soc_ac bool playback) { dai_links->init = cs42l43_dmic_rtd_init; + return 0; } From d74bad3b74524e4f34c97903ad170d9061bcfbd9 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 Oct 2023 12:34:04 -0500 Subject: [PATCH 03/10] ASoC: intel: sof_sdw_cs42l43: Create separate jacks for hp and mic It makes sense to report the microphone separately from the headphones, that way ALSA UCM can differentiate between switching the playback and the capture. For example, still using the built-in microphone path when a 3-pole headset is inserted. Reviewed-by: Bard Liao Signed-off-by: Charles Keepax Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20231019173411.166759-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw_cs42l43.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw_cs42l43.c b/sound/soc/intel/boards/sof_sdw_cs42l43.c index 9b072c745f10..360f11b72aa2 100644 --- a/sound/soc/intel/boards/sof_sdw_cs42l43.c +++ b/sound/soc/intel/boards/sof_sdw_cs42l43.c @@ -39,6 +39,17 @@ static const struct snd_soc_dapm_route cs42l43_dmic_map[] = { { "cs42l43 PDM2_DIN", NULL, "DMIC" }, }; +static struct snd_soc_jack_pin sof_jack_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static int cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; @@ -66,12 +77,13 @@ static int cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_card_jack_new(card, "Headphone Jack", - SND_JACK_MECHANICAL | SND_JACK_AVOUT | - SND_JACK_HEADSET | SND_JACK_LINEOUT | - SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3, - jack); + ret = snd_soc_card_jack_new_pins(card, "Jack", + SND_JACK_MECHANICAL | SND_JACK_AVOUT | + SND_JACK_HEADSET | SND_JACK_LINEOUT | + SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3, + jack, sof_jack_pins, + ARRAY_SIZE(sof_jack_pins)); if (ret) { dev_err(card->dev, "Failed to create jack: %d\n", ret); return ret; From 10626812b5987b3a05adf6b4f4417e7398b7047c Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 Oct 2023 12:34:05 -0500 Subject: [PATCH 04/10] ASoC: intel: sof_sdw: Move the builtin microphones to dataport 1 cs42l43 supports 4 hardwired microphones, but only supports up to 2 microphone headsets. Only dataport 1 can support 4 channel capture, but that is currently used for the headset microphone. Switch things around such that DP1 is used for the builtin mics and DP2 is used for the headset microphones. Reviewed-by: Bard Liao Signed-off-by: Charles Keepax Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20231019173411.166759-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index ad1d01ebbcd9..3312ad8a563b 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -939,16 +939,16 @@ static struct sof_sdw_codec_info codec_info_list[] = { { .direction = {false, true}, .dai_name = "cs42l43-dp1", - .dai_type = SOF_SDW_DAI_TYPE_JACK, - .dailink = {SDW_UNUSED_DAI_ID, SDW_JACK_IN_DAI_ID}, + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = sof_sdw_cs42l43_dmic_init, }, { .direction = {false, true}, .dai_name = "cs42l43-dp2", - .dai_type = SOF_SDW_DAI_TYPE_MIC, - .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, - .init = sof_sdw_cs42l43_dmic_init, - } + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_UNUSED_DAI_ID, SDW_JACK_IN_DAI_ID}, + }, }, .dai_num = 3, }, From 5c072ca8e1b7545b280d5416ecef77e3b0891a2c Mon Sep 17 00:00:00 2001 From: Terry Cheong Date: Thu, 19 Oct 2023 12:34:06 -0500 Subject: [PATCH 05/10] ASoC: Intel: sof_nau8825: add RPL support for MAX98360A amp Adding support back to RPL devices that lost audio after the RPL/ADL split. The hardware configuration is: SSP0: NAU88L25/NAU88L25YGB codec SSP1: MAX98360A amplifier Reviewed-by: Bard Liao Signed-off-by: Terry Cheong Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20231019173411.166759-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_nau8825.c | 8 ++++++++ sound/soc/intel/common/soc-acpi-intel-rpl-match.c | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/sound/soc/intel/boards/sof_nau8825.c b/sound/soc/intel/boards/sof_nau8825.c index 116281262859..44f5c359ae95 100644 --- a/sound/soc/intel/boards/sof_nau8825.c +++ b/sound/soc/intel/boards/sof_nau8825.c @@ -553,6 +553,14 @@ static const struct platform_device_id board_ids[] = { SOF_BT_OFFLOAD_SSP(2) | SOF_SSP_BT_OFFLOAD_PRESENT), }, + { + .name = "rpl_mx98360a_8825", + .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | + SOF_NAU8825_SSP_AMP(1) | + SOF_NAU8825_NUM_HDMIDEV(4) | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, { .name = "rpl_nau8318_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | diff --git a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c index 19cfdcdbfdf7..5b6f57e3a583 100644 --- a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c @@ -407,6 +407,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = { .quirk_data = &rpl_max98373_amp, .sof_tplg_filename = "sof-rpl-max98373-nau8825.tplg", }, + { + .id = "10508825", + .drv_name = "rpl_mx98360a_8825", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &rpl_max98360a_amp, + .sof_tplg_filename = "sof-rpl-max98360a-nau8825.tplg", + }, { .id = "10508825", .drv_name = "rpl_nau8318_8825", From 7fce91bab644f13e8a861ebf9c4c98a8072b6abc Mon Sep 17 00:00:00 2001 From: Brent Lu Date: Thu, 19 Oct 2023 12:34:07 -0500 Subject: [PATCH 06/10] ASoC: Intel: board_helpers: support dmic link initialization Add functions for machine drivers to initialize dmic01 and dmic16k DAI links. Reviewed-by: Bard Liao Signed-off-by: Brent Lu Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20231019173411.166759-7-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_board_helpers.c | 92 ++++++++++++++++++++++ sound/soc/intel/boards/sof_board_helpers.h | 10 +++ 2 files changed, 102 insertions(+) diff --git a/sound/soc/intel/boards/sof_board_helpers.c b/sound/soc/intel/boards/sof_board_helpers.c index 627742ce84bd..ce2967850c2d 100644 --- a/sound/soc/intel/boards/sof_board_helpers.c +++ b/sound/soc/intel/boards/sof_board_helpers.c @@ -36,9 +36,49 @@ int sof_intel_board_card_late_probe(struct snd_soc_card *card) } EXPORT_SYMBOL_NS(sof_intel_board_card_late_probe, SND_SOC_INTEL_SOF_BOARD_HELPERS); +/* + * DMIC DAI Link + */ +static const struct snd_soc_dapm_widget dmic_widgets[] = { + SND_SOC_DAPM_MIC("SoC DMIC", NULL), +}; + +static const struct snd_soc_dapm_route dmic_routes[] = { + {"DMic", NULL, "SoC DMIC"}, +}; + +static int dmic_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, + ARRAY_SIZE(dmic_widgets)); + if (ret) { + dev_err(rtd->dev, "fail to add dmic widgets, ret %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, dmic_routes, + ARRAY_SIZE(dmic_routes)); + if (ret) { + dev_err(rtd->dev, "fail to add dmic routes, ret %d\n", ret); + return ret; + } + + return 0; +} + /* * DAI Link Helpers */ +static struct snd_soc_dai_link_component dmic_component[] = { + { + .name = "dmic-codec", + .dai_name = "dmic-hifi", + } +}; + static struct snd_soc_dai_link_component platform_component[] = { { /* name might be overridden during probe */ @@ -46,6 +86,58 @@ static struct snd_soc_dai_link_component platform_component[] = { } }; +int sof_intel_board_set_dmic_link(struct device *dev, + struct snd_soc_dai_link *link, int be_id, + enum sof_dmic_be_type be_type) +{ + struct snd_soc_dai_link_component *cpus; + + /* cpus */ + cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component), + GFP_KERNEL); + if (!cpus) + return -ENOMEM; + + switch (be_type) { + case SOF_DMIC_01: + dev_dbg(dev, "link %d: dmic01\n", be_id); + + link->name = "dmic01"; + cpus->dai_name = "DMIC01 Pin"; + break; + case SOF_DMIC_16K: + dev_dbg(dev, "link %d: dmic16k\n", be_id); + + link->name = "dmic16k"; + cpus->dai_name = "DMIC16k Pin"; + break; + default: + dev_err(dev, "invalid be type %d\n", be_type); + return -EINVAL; + } + + link->cpus = cpus; + link->num_cpus = 1; + + /* codecs */ + link->codecs = dmic_component; + link->num_codecs = ARRAY_SIZE(dmic_component); + + /* platforms */ + link->platforms = platform_component; + link->num_platforms = ARRAY_SIZE(platform_component); + + link->id = be_id; + if (be_type == SOF_DMIC_01) + link->init = dmic_init; + link->ignore_suspend = 1; + link->no_pcm = 1; + link->dpcm_capture = 1; + + return 0; +} +EXPORT_SYMBOL_NS(sof_intel_board_set_dmic_link, SND_SOC_INTEL_SOF_BOARD_HELPERS); + int sof_intel_board_set_intel_hdmi_link(struct device *dev, struct snd_soc_dai_link *link, int be_id, int hdmi_id, bool idisp_codec) diff --git a/sound/soc/intel/boards/sof_board_helpers.h b/sound/soc/intel/boards/sof_board_helpers.h index 7a15ddaa3a2c..df99f576c1d8 100644 --- a/sound/soc/intel/boards/sof_board_helpers.h +++ b/sound/soc/intel/boards/sof_board_helpers.h @@ -28,6 +28,7 @@ struct sof_rt5682_private { * @hdmi: init data for hdmi dai link * @codec_type: type of headset codec * @amp_type: type of speaker amplifier + * @dmic_be_num: number of Intel PCH DMIC BE link * @hdmi_num: number of Intel HDMI BE link * @rt5682: private data for rt5682 machine driver */ @@ -38,6 +39,7 @@ struct sof_card_private { enum sof_ssp_codec codec_type; enum sof_ssp_codec amp_type; + int dmic_be_num; int hdmi_num; union { @@ -45,8 +47,16 @@ struct sof_card_private { }; }; +enum sof_dmic_be_type { + SOF_DMIC_01, + SOF_DMIC_16K, +}; + int sof_intel_board_card_late_probe(struct snd_soc_card *card); +int sof_intel_board_set_dmic_link(struct device *dev, + struct snd_soc_dai_link *link, int be_id, + enum sof_dmic_be_type be_type); int sof_intel_board_set_intel_hdmi_link(struct device *dev, struct snd_soc_dai_link *link, int be_id, int hdmi_id, bool idisp_codec); From a1360c45a445f0824d4723136a9e993c94b77be8 Mon Sep 17 00:00:00 2001 From: Brent Lu Date: Thu, 19 Oct 2023 12:34:08 -0500 Subject: [PATCH 07/10] ASoC: Intel: sof_cs42l42: use common module for DMIC links Use intel_board module for dmic01 and dmic16k DAI link initialization. Reviewed-by: Bard Liao Signed-off-by: Brent Lu Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20231019173411.166759-8-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_cs42l42.c | 121 +++++++-------------------- 1 file changed, 32 insertions(+), 89 deletions(-) diff --git a/sound/soc/intel/boards/sof_cs42l42.c b/sound/soc/intel/boards/sof_cs42l42.c index 6c7d0c85f1a0..1f760fc4cab2 100644 --- a/sound/soc/intel/boards/sof_cs42l42.c +++ b/sound/soc/intel/boards/sof_cs42l42.c @@ -160,10 +160,6 @@ static const struct snd_soc_dapm_widget sof_widgets[] = { SND_SOC_DAPM_MIC("Headset Mic", NULL), }; -static const struct snd_soc_dapm_widget dmic_widgets[] = { - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - static const struct snd_soc_dapm_route sof_map[] = { /* HP jack connectors - unknown if we have jack detection */ {"Headphone Jack", NULL, "HP"}, @@ -172,33 +168,6 @@ static const struct snd_soc_dapm_route sof_map[] = { {"HS", NULL, "Headset Mic"}, }; -static const struct snd_soc_dapm_route dmic_map[] = { - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, -}; - -static int dmic_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, - ARRAY_SIZE(dmic_widgets)); - if (ret) { - dev_err(card->dev, "DMic widget addition failed: %d\n", ret); - /* Don't need to add routes if widget addition failed */ - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, - ARRAY_SIZE(dmic_map)); - - if (ret) - dev_err(card->dev, "DMic map addition failed: %d\n", ret); - - return ret; -} - /* sof audio machine driver for cs42l42 codec */ static struct snd_soc_card sof_audio_card_cs42l42 = { .name = "cs42l42", /* the sof- prefix is added by the core */ @@ -220,13 +189,6 @@ static struct snd_soc_dai_link_component cs42l42_component[] = { } }; -static struct snd_soc_dai_link_component dmic_component[] = { - { - .name = "dmic-codec", - .dai_name = "dmic-hifi", - } -}; - static int create_spk_amp_dai_links(struct device *dev, struct snd_soc_dai_link *links, struct snd_soc_dai_link_component *cpus, @@ -322,47 +284,6 @@ static int create_hp_codec_dai_links(struct device *dev, return -ENOMEM; } -static int create_dmic_dai_links(struct device *dev, - struct snd_soc_dai_link *links, - struct snd_soc_dai_link_component *cpus, - int *id, int dmic_be_num) -{ - int i; - - /* dmic */ - if (dmic_be_num <= 0) - return 0; - - /* at least we have dmic01 */ - links[*id].name = "dmic01"; - links[*id].cpus = &cpus[*id]; - links[*id].cpus->dai_name = "DMIC01 Pin"; - links[*id].init = dmic_init; - if (dmic_be_num > 1) { - /* set up 2 BE links at most */ - links[*id + 1].name = "dmic16k"; - links[*id + 1].cpus = &cpus[*id + 1]; - links[*id + 1].cpus->dai_name = "DMIC16k Pin"; - dmic_be_num = 2; - } - - for (i = 0; i < dmic_be_num; i++) { - links[*id].id = *id; - links[*id].num_cpus = 1; - links[*id].codecs = dmic_component; - links[*id].num_codecs = ARRAY_SIZE(dmic_component); - links[*id].platforms = platform_component; - links[*id].num_platforms = ARRAY_SIZE(platform_component); - links[*id].ignore_suspend = 1; - links[*id].dpcm_capture = 1; - links[*id].no_pcm = 1; - - (*id)++; - } - - return 0; -} - static int create_bt_offload_dai_links(struct device *dev, struct snd_soc_dai_link *links, struct snd_soc_dai_link_component *cpus, @@ -446,11 +367,34 @@ sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type, } break; case LINK_DMIC: - ret = create_dmic_dai_links(dev, links, cpus, &id, dmic_be_num); - if (ret < 0) { - dev_err(dev, "fail to create dmic dai links, ret %d\n", - ret); - goto devm_err; + if (dmic_be_num > 0) { + /* at least we have dmic01 */ + ret = sof_intel_board_set_dmic_link(dev, + &links[id], + id, + SOF_DMIC_01); + if (ret) { + dev_err(dev, "fail to create dmic01 link, ret %d\n", + ret); + goto devm_err; + } + + id++; + } + + if (dmic_be_num > 1) { + /* set up 2 BE links at most */ + ret = sof_intel_board_set_dmic_link(dev, + &links[id], + id, + SOF_DMIC_16K); + if (ret) { + dev_err(dev, "fail to create dmic16k link, ret %d\n", + ret); + goto devm_err; + } + + id++; } break; case LINK_HDMI: @@ -496,7 +440,6 @@ static int sof_audio_probe(struct platform_device *pdev) struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; struct snd_soc_dai_link *dai_links; struct sof_card_private *ctx; - int dmic_be_num; int ret, ssp_bt, ssp_amp, ssp_codec; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); @@ -510,10 +453,10 @@ static int sof_audio_probe(struct platform_device *pdev) ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev); if (soc_intel_is_glk()) { - dmic_be_num = 1; + ctx->dmic_be_num = 1; ctx->hdmi_num = 3; } else { - dmic_be_num = 2; + ctx->dmic_be_num = 2; ctx->hdmi_num = (sof_cs42l42_quirk & SOF_CS42L42_NUM_HDMIDEV_MASK) >> SOF_CS42L42_NUM_HDMIDEV_SHIFT; /* default number of HDMI DAI's */ @@ -535,7 +478,7 @@ static int sof_audio_probe(struct platform_device *pdev) ssp_codec = sof_cs42l42_quirk & SOF_CS42L42_SSP_CODEC_MASK; /* compute number of dai links */ - sof_audio_card_cs42l42.num_links = 1 + dmic_be_num + ctx->hdmi_num; + sof_audio_card_cs42l42.num_links = 1 + ctx->dmic_be_num + ctx->hdmi_num; if (ctx->amp_type != CODEC_NONE) sof_audio_card_cs42l42.num_links++; @@ -544,7 +487,7 @@ static int sof_audio_probe(struct platform_device *pdev) dai_links = sof_card_dai_links_create(&pdev->dev, ctx->amp_type, ssp_codec, ssp_amp, ssp_bt, - dmic_be_num, ctx->hdmi_num, + ctx->dmic_be_num, ctx->hdmi_num, ctx->hdmi.idisp_codec); if (!dai_links) return -ENOMEM; From f56daafc94ec4c46349ced8d2b91873b98dd5482 Mon Sep 17 00:00:00 2001 From: Brent Lu Date: Thu, 19 Oct 2023 12:34:09 -0500 Subject: [PATCH 08/10] ASoC: Intel: sof_nau8825: use common module for DMIC links Use intel_board module for dmic01 and dmic16k DAI link initialization. Reviewed-by: Bard Liao Signed-off-by: Brent Lu Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20231019173411.166759-9-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_nau8825.c | 81 ++++++---------------------- 1 file changed, 17 insertions(+), 64 deletions(-) diff --git a/sound/soc/intel/boards/sof_nau8825.c b/sound/soc/intel/boards/sof_nau8825.c index 44f5c359ae95..dc2821a012d4 100644 --- a/sound/soc/intel/boards/sof_nau8825.c +++ b/sound/soc/intel/boards/sof_nau8825.c @@ -177,10 +177,6 @@ static const struct snd_soc_dapm_widget sof_widgets[] = { SND_SOC_DAPM_SPK("Right Spk", NULL), }; -static const struct snd_soc_dapm_widget dmic_widgets[] = { - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - static const struct snd_soc_dapm_route sof_map[] = { /* HP jack connectors - unknown if we have jack detection */ { "Headphone Jack", NULL, "HPOL" }, @@ -190,33 +186,6 @@ static const struct snd_soc_dapm_route sof_map[] = { { "MIC", NULL, "Headset Mic" }, }; -static const struct snd_soc_dapm_route dmic_map[] = { - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, -}; - -static int dmic_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, - ARRAY_SIZE(dmic_widgets)); - if (ret) { - dev_err(card->dev, "DMic widget addition failed: %d\n", ret); - /* Don't need to add routes if widget addition failed */ - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, - ARRAY_SIZE(dmic_map)); - - if (ret) - dev_err(card->dev, "DMic map addition failed: %d\n", ret); - - return ret; -} - /* sof audio machine driver for nau8825 codec */ static struct snd_soc_card sof_audio_card_nau8825 = { .name = "nau8825", /* the sof- prefix is added by the core */ @@ -238,13 +207,6 @@ static struct snd_soc_dai_link_component nau8825_component[] = { } }; -static struct snd_soc_dai_link_component dmic_component[] = { - { - .name = "dmic-codec", - .dai_name = "dmic-hifi", - } -}; - static struct snd_soc_dai_link * sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type, int ssp_codec, int ssp_amp, int dmic_be_num, @@ -294,29 +256,21 @@ sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type, /* dmic */ if (dmic_be_num > 0) { /* at least we have dmic01 */ - links[id].name = "dmic01"; - links[id].cpus = &cpus[id]; - links[id].cpus->dai_name = "DMIC01 Pin"; - links[id].init = dmic_init; - if (dmic_be_num > 1) { - /* set up 2 BE links at most */ - links[id + 1].name = "dmic16k"; - links[id + 1].cpus = &cpus[id + 1]; - links[id + 1].cpus->dai_name = "DMIC16k Pin"; - dmic_be_num = 2; - } + ret = sof_intel_board_set_dmic_link(dev, &links[id], id, + SOF_DMIC_01); + if (ret) + return NULL; + + id++; } - for (i = 0; i < dmic_be_num; i++) { - links[id].id = id; - links[id].num_cpus = 1; - links[id].codecs = dmic_component; - links[id].num_codecs = ARRAY_SIZE(dmic_component); - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].ignore_suspend = 1; - links[id].dpcm_capture = 1; - links[id].no_pcm = 1; + if (dmic_be_num > 1) { + /* set up 2 BE links at most */ + ret = sof_intel_board_set_dmic_link(dev, &links[id], id, + SOF_DMIC_16K); + if (ret) + return NULL; + id++; } @@ -414,7 +368,6 @@ static int sof_audio_probe(struct platform_device *pdev) struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; struct snd_soc_dai_link *dai_links; struct sof_card_private *ctx; - int dmic_be_num; int ret, ssp_amp, ssp_codec; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); @@ -430,7 +383,7 @@ static int sof_audio_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "sof_nau8825_quirk = %lx\n", sof_nau8825_quirk); /* default number of DMIC DAI's */ - dmic_be_num = 2; + ctx->dmic_be_num = 2; ctx->hdmi_num = (sof_nau8825_quirk & SOF_NAU8825_NUM_HDMIDEV_MASK) >> SOF_NAU8825_NUM_HDMIDEV_SHIFT; /* default number of HDMI DAI's */ @@ -446,7 +399,7 @@ static int sof_audio_probe(struct platform_device *pdev) ssp_codec = sof_nau8825_quirk & SOF_NAU8825_SSP_CODEC_MASK; /* compute number of dai links */ - sof_audio_card_nau8825.num_links = 1 + dmic_be_num + ctx->hdmi_num; + sof_audio_card_nau8825.num_links = 1 + ctx->dmic_be_num + ctx->hdmi_num; if (ctx->amp_type != CODEC_NONE) sof_audio_card_nau8825.num_links++; @@ -455,8 +408,8 @@ static int sof_audio_probe(struct platform_device *pdev) sof_audio_card_nau8825.num_links++; dai_links = sof_card_dai_links_create(&pdev->dev, ctx->amp_type, - ssp_codec, ssp_amp, dmic_be_num, - ctx->hdmi_num, + ssp_codec, ssp_amp, + ctx->dmic_be_num, ctx->hdmi_num, ctx->hdmi.idisp_codec); if (!dai_links) return -ENOMEM; From c51fc25db18fe49e357455da726dd0ca98a43534 Mon Sep 17 00:00:00 2001 From: Brent Lu Date: Thu, 19 Oct 2023 12:34:10 -0500 Subject: [PATCH 09/10] ASoC: Intel: sof_rt5682: use common module for DMIC links Use intel_board module for dmic01 and dmic16k DAI link initialization. Reviewed-by: Bard Liao Signed-off-by: Brent Lu Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20231019173411.166759-10-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_rt5682.c | 81 ++++++----------------------- 1 file changed, 17 insertions(+), 64 deletions(-) diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 1e90dff61b9b..06ad15af46de 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -503,10 +503,6 @@ static const struct snd_soc_dapm_widget sof_widgets[] = { SND_SOC_DAPM_SPK("Right Spk", NULL), }; -static const struct snd_soc_dapm_widget dmic_widgets[] = { - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - static const struct snd_soc_dapm_route sof_map[] = { /* HP jack connectors - unknown if we have jack detection */ { "Headphone Jack", NULL, "HPOL" }, @@ -522,11 +518,6 @@ static const struct snd_soc_dapm_route rt5650_spk_dapm_routes[] = { { "Right Spk", NULL, "SPOR" }, }; -static const struct snd_soc_dapm_route dmic_map[] = { - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, -}; - static int rt5650_spk_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; @@ -540,28 +531,6 @@ static int rt5650_spk_init(struct snd_soc_pcm_runtime *rtd) return ret; } -static int dmic_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, - ARRAY_SIZE(dmic_widgets)); - if (ret) { - dev_err(card->dev, "DMic widget addition failed: %d\n", ret); - /* Don't need to add routes if widget addition failed */ - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, - ARRAY_SIZE(dmic_map)); - - if (ret) - dev_err(card->dev, "DMic map addition failed: %d\n", ret); - - return ret; -} - /* sof audio machine driver for rt5682 codec */ static struct snd_soc_card sof_audio_card_rt5682 = { .name = "rt5682", /* the sof- prefix is added by the core */ @@ -601,13 +570,6 @@ static struct snd_soc_dai_link_component rt5650_components[] = { } }; -static struct snd_soc_dai_link_component dmic_component[] = { - { - .name = "dmic-codec", - .dai_name = "dmic-hifi", - } -}; - static struct snd_soc_dai_link * sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec codec_type, enum sof_ssp_codec amp_type, int ssp_codec, @@ -692,29 +654,21 @@ sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec codec_type, /* dmic */ if (dmic_be_num > 0) { /* at least we have dmic01 */ - links[id].name = "dmic01"; - links[id].cpus = &cpus[id]; - links[id].cpus->dai_name = "DMIC01 Pin"; - links[id].init = dmic_init; - if (dmic_be_num > 1) { - /* set up 2 BE links at most */ - links[id + 1].name = "dmic16k"; - links[id + 1].cpus = &cpus[id + 1]; - links[id + 1].cpus->dai_name = "DMIC16k Pin"; - dmic_be_num = 2; - } + ret = sof_intel_board_set_dmic_link(dev, &links[id], id, + SOF_DMIC_01); + if (ret) + return NULL; + + id++; } - for (i = 0; i < dmic_be_num; i++) { - links[id].id = id; - links[id].num_cpus = 1; - links[id].codecs = dmic_component; - links[id].num_codecs = ARRAY_SIZE(dmic_component); - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].ignore_suspend = 1; - links[id].dpcm_capture = 1; - links[id].no_pcm = 1; + if (dmic_be_num > 1) { + /* set up 2 BE links at most */ + ret = sof_intel_board_set_dmic_link(dev, &links[id], id, + SOF_DMIC_16K); + if (ret) + return NULL; + id++; } @@ -865,7 +819,6 @@ static int sof_audio_probe(struct platform_device *pdev) struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; struct snd_soc_dai_link *dai_links; struct sof_card_private *ctx; - int dmic_be_num; int ret, ssp_amp, ssp_codec; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); @@ -891,7 +844,7 @@ static int sof_audio_probe(struct platform_device *pdev) if (soc_intel_is_byt() || soc_intel_is_cht()) { ctx->rt5682.is_legacy_cpu = true; - dmic_be_num = 0; + ctx->dmic_be_num = 0; /* HDMI is not supported by SOF on Baytrail/CherryTrail */ ctx->hdmi_num = 0; /* default quirk for legacy cpu */ @@ -899,7 +852,7 @@ static int sof_audio_probe(struct platform_device *pdev) SOF_RT5682_MCLK_BYTCHT_EN | SOF_RT5682_SSP_CODEC(2); } else { - dmic_be_num = 2; + ctx->dmic_be_num = 2; ctx->hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >> SOF_RT5682_NUM_HDMIDEV_SHIFT; /* default number of HDMI DAI's */ @@ -938,7 +891,7 @@ static int sof_audio_probe(struct platform_device *pdev) ssp_codec = sof_rt5682_quirk & SOF_RT5682_SSP_CODEC_MASK; /* compute number of dai links */ - sof_audio_card_rt5682.num_links = 1 + dmic_be_num + ctx->hdmi_num; + sof_audio_card_rt5682.num_links = 1 + ctx->dmic_be_num + ctx->hdmi_num; if (ctx->amp_type != CODEC_NONE) sof_audio_card_rt5682.num_links++; @@ -953,7 +906,7 @@ static int sof_audio_probe(struct platform_device *pdev) dai_links = sof_card_dai_links_create(&pdev->dev, ctx->codec_type, ctx->amp_type, ssp_codec, ssp_amp, - dmic_be_num, ctx->hdmi_num, + ctx->dmic_be_num, ctx->hdmi_num, ctx->hdmi.idisp_codec, ctx->rt5682.is_legacy_cpu); if (!dai_links) From f6b415faf6796963a56117f851378afe0ac33699 Mon Sep 17 00:00:00 2001 From: Brent Lu Date: Thu, 19 Oct 2023 12:34:11 -0500 Subject: [PATCH 10/10] ASoC: Intel: sof_ssp_amp: use common module for DMIC links Use intel_board module for dmic01 and dmic16k DAI link initialization. Reviewed-by: Bard Liao Signed-off-by: Brent Lu Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20231019173411.166759-11-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_ssp_amp.c | 65 +++++++++------------------- 1 file changed, 21 insertions(+), 44 deletions(-) diff --git a/sound/soc/intel/boards/sof_ssp_amp.c b/sound/soc/intel/boards/sof_ssp_amp.c index 23c0d507789c..137ba64254bc 100644 --- a/sound/soc/intel/boards/sof_ssp_amp.c +++ b/sound/soc/intel/boards/sof_ssp_amp.c @@ -70,15 +70,6 @@ static const struct dmi_system_id chromebook_platforms[] = { {}, }; -static const struct snd_soc_dapm_widget sof_ssp_amp_dapm_widgets[] = { - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - -static const struct snd_soc_dapm_route sof_ssp_amp_dapm_routes[] = { - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, -}; - static int sof_card_late_probe(struct snd_soc_card *card) { return sof_intel_board_card_late_probe(card); @@ -87,10 +78,6 @@ static int sof_card_late_probe(struct snd_soc_card *card) static struct snd_soc_card sof_ssp_amp_card = { .name = "ssp_amp", .owner = THIS_MODULE, - .dapm_widgets = sof_ssp_amp_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(sof_ssp_amp_dapm_widgets), - .dapm_routes = sof_ssp_amp_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(sof_ssp_amp_dapm_routes), .fully_routed = true, .late_probe = sof_card_late_probe, }; @@ -102,17 +89,11 @@ static struct snd_soc_dai_link_component platform_component[] = { } }; -static struct snd_soc_dai_link_component dmic_component[] = { - { - .name = "dmic-codec", - .dai_name = "dmic-hifi", - } -}; - /* BE ID defined in sof-tgl-rt1308-hdmi-ssp.m4 */ #define HDMI_IN_BE_ID 0 #define SPK_BE_ID 2 #define DMIC01_BE_ID 3 +#define DMIC16K_BE_ID 4 #define INTEL_HDMI_BE_ID 5 static struct snd_soc_dai_link * @@ -207,28 +188,23 @@ sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type, /* dmic */ if (dmic_be_num > 0) { /* at least we have dmic01 */ - links[id].name = "dmic01"; - links[id].cpus = &cpus[id]; - links[id].cpus->dai_name = "DMIC01 Pin"; - if (dmic_be_num > 1) { - /* set up 2 BE links at most */ - links[id + 1].name = "dmic16k"; - links[id + 1].cpus = &cpus[id + 1]; - links[id + 1].cpus->dai_name = "DMIC16k Pin"; - dmic_be_num = 2; - } + be_id = fixed_be ? DMIC01_BE_ID : id; + ret = sof_intel_board_set_dmic_link(dev, &links[id], be_id, + SOF_DMIC_01); + if (ret) + return NULL; + + id++; } - for (i = 0; i < dmic_be_num; i++) { - links[id].id = fixed_be ? (DMIC01_BE_ID + i) : id; - links[id].num_cpus = 1; - links[id].codecs = dmic_component; - links[id].num_codecs = ARRAY_SIZE(dmic_component); - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].ignore_suspend = 1; - links[id].dpcm_capture = 1; - links[id].no_pcm = 1; + if (dmic_be_num > 1) { + /* set up 2 BE links at most */ + be_id = fixed_be ? DMIC16K_BE_ID : id; + ret = sof_intel_board_set_dmic_link(dev, &links[id], be_id, + SOF_DMIC_16K); + if (ret) + return NULL; + id++; } @@ -278,7 +254,6 @@ static int sof_ssp_amp_probe(struct platform_device *pdev) struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; struct snd_soc_dai_link *dai_links; struct sof_card_private *ctx; - int dmic_be_num = 0; int ret, ssp_codec; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); @@ -291,12 +266,14 @@ static int sof_ssp_amp_probe(struct platform_device *pdev) ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev); if (dmi_check_system(chromebook_platforms) || mach->mach_params.dmic_num > 0) - dmic_be_num = 2; + ctx->dmic_be_num = 2; + else + ctx->dmic_be_num = 0; ssp_codec = sof_ssp_amp_quirk & SOF_AMPLIFIER_SSP_MASK; /* set number of dai links */ - sof_ssp_amp_card.num_links = dmic_be_num; + sof_ssp_amp_card.num_links = ctx->dmic_be_num; if (ctx->amp_type != CODEC_NONE) sof_ssp_amp_card.num_links++; @@ -324,7 +301,7 @@ static int sof_ssp_amp_probe(struct platform_device *pdev) sof_ssp_amp_card.num_links++; dai_links = sof_card_dai_links_create(&pdev->dev, ctx->amp_type, - ssp_codec, dmic_be_num, + ssp_codec, ctx->dmic_be_num, ctx->hdmi_num, ctx->hdmi.idisp_codec); if (!dai_links)