From e63e2810edd229e320249dc85c20c22f4894919e Mon Sep 17 00:00:00 2001 From: Balamurugan C Date: Mon, 31 Jul 2023 16:42:35 -0500 Subject: [PATCH 01/23] ASoC: Intel: soc-acpi: Add entry for rt711-sdca-sdw at link 0 in RPL match table Adding RT711 sdca SDW codec support with SDW0 link for RPL RVP platforms Reviewed-by: Bard Liao Signed-off-by: Balamurugan C Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/common/soc-acpi-intel-rpl-match.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) 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 302a08018572..99dc76c99f0d 100644 --- a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c @@ -308,6 +308,15 @@ static const struct snd_soc_acpi_link_adr rpl_sdw_rt1316_link12_rt714_link0[] = {} }; +static const struct snd_soc_acpi_link_adr rpl_sdca_rvp[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_sdca_0_adr), + .adr_d = rt711_sdca_0_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr rplp_crb[] = { { .mask = BIT(2), @@ -413,6 +422,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-rpl-rt711-l0.tplg", }, + { + .link_mask = 0x1, /* link0 required */ + .links = rpl_sdca_rvp, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-rpl-rt711-l0.tplg", + }, { .link_mask = 0x4, /* link2 required */ .links = rplp_crb, From 26d9726f667e18134bfc77a3e4e0da7518a8b180 Mon Sep 17 00:00:00 2001 From: Terry Cheong Date: Mon, 31 Jul 2023 16:42:36 -0500 Subject: [PATCH 02/23] ASoC: Intel: sof_rt5682: add RPL support for MAX98357A speaker Adding support back to RPL devices that lost audio after the RPL/ADL split. The hardware configuration is: SSP0: 10EC5682/RTL5682 codec SSP2: MAX98357A amplifier Reviewed-by: Bard Liao Signed-off-by: Terry Cheong Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_rt5682.c | 8 ++++++++ sound/soc/intel/common/soc-acpi-intel-rpl-match.c | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 0af1e0c3a9db..a5af6ae79933 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -1163,6 +1163,14 @@ static const struct platform_device_id board_ids[] = { SOF_BT_OFFLOAD_SSP(2) | SOF_SSP_BT_OFFLOAD_PRESENT), }, + { + .name = "rpl_mx98357_rt5682", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_RT5682_SSP_CODEC(0) | + SOF_SPEAKER_AMP_PRESENT | + SOF_RT5682_SSP_AMP(2) | + SOF_RT5682_NUM_HDMIDEV(4)), + }, { .name = "rpl_mx98360_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 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 99dc76c99f0d..4eefdb2dd45c 100644 --- a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c @@ -331,6 +331,11 @@ static const struct snd_soc_acpi_codecs rpl_rt5682_hp = { .codecs = {"10EC5682", "RTL5682"}, }; +static const struct snd_soc_acpi_codecs rpl_max98357a_amp = { + .num_codecs = 1, + .codecs = {"MX98357A"} +}; + static const struct snd_soc_acpi_codecs rpl_max98360a_amp = { .num_codecs = 1, .codecs = {"MX98360A"}, @@ -347,6 +352,13 @@ static const struct snd_soc_acpi_codecs rpl_rt1019p_amp = { }; struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = { + { + .comp_ids = &rpl_rt5682_hp, + .drv_name = "rpl_mx98357_rt5682", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &rpl_max98357a_amp, + .sof_tplg_filename = "sof-rpl-max98357a-rt5682.tplg", + }, { .comp_ids = &rpl_rt5682_hp, .drv_name = "rpl_mx98360_rt5682", From f3c37847c704c5d398fa6808c77e4f7c997c0abb Mon Sep 17 00:00:00 2001 From: apoorv Date: Mon, 31 Jul 2023 16:42:37 -0500 Subject: [PATCH 03/23] ASoC: Intel: sof_rt5682 add support for HDMI_In capture Adding support for 2 streams of HDMI-In capture via I2S with rt5682s codec variant Reviewed-by: CBM Reviewed-by: Bard Liao Signed-off-by: apoorv Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_rt5682.c | 47 +++++++++++++++++++ .../intel/common/soc-acpi-intel-adl-match.c | 7 +++ 2 files changed, 54 insertions(+) diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index a5af6ae79933..fae091b9b55c 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -62,6 +62,11 @@ #define SOF_RT1019_SPEAKER_AMP_PRESENT BIT(26) #define SOF_RT5650_HEADPHONE_CODEC_PRESENT BIT(27) +/* HDMI capture*/ +#define SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT 27 +#define SOF_SSP_HDMI_CAPTURE_PRESENT_MASK (GENMASK(30, 27)) +#define SOF_HDMI_CAPTURE_SSP_MASK(quirk) \ + (((quirk) << SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT) & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) /* Default: MCLK on, MCLK 19.2M, SSP0 */ static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN | @@ -670,6 +675,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, struct snd_soc_dai_link_component *cpus; struct snd_soc_dai_link *links; int i, id = 0; + int hdmi_id_offset = 0; links = devm_kcalloc(dev, sof_audio_card_rt5682.num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL); @@ -891,6 +897,34 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].num_cpus = 1; } + /* HDMI-In SSP */ + if (sof_rt5682_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) { + unsigned long hdmi_in_ssp = (sof_rt5682_quirk & + SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) >> + SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT; + int port = 0; + + for_each_set_bit(port, &hdmi_in_ssp, 32) { + links[id].cpus = &cpus[id]; + links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + "SSP%d Pin", port); + if (!links[id].cpus->dai_name) + return NULL; + links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-HDMI", port); + if (!links[id].name) + return NULL; + links[id].id = id + hdmi_id_offset; + links[id].codecs = &asoc_dummy_dlc; + links[id].num_codecs = 1; + links[id].platforms = platform_component; + links[id].num_platforms = ARRAY_SIZE(platform_component); + links[id].dpcm_capture = 1; + links[id].no_pcm = 1; + links[id].num_cpus = 1; + id++; + } + } + return links; devm_err: return NULL; @@ -997,6 +1031,11 @@ static int sof_audio_probe(struct platform_device *pdev) if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) sof_audio_card_rt5682.num_links++; + if (sof_rt5682_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) + sof_audio_card_rt5682.num_links += + hweight32((sof_rt5682_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) >> + SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT); + dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp, dmic_be_num, hdmi_num, ctx->idisp_codec); if (!dai_links) @@ -1163,6 +1202,14 @@ static const struct platform_device_id board_ids[] = { SOF_BT_OFFLOAD_SSP(2) | SOF_SSP_BT_OFFLOAD_PRESENT), }, + { + .name = "adl_rt5682_c1_h02", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_RT5682_SSP_CODEC(1) | + SOF_RT5682_NUM_HDMIDEV(3) | + /* SSP 0 and SSP 2 are used for HDMI IN */ + SOF_HDMI_CAPTURE_SSP_MASK(0x5)), + }, { .name = "rpl_mx98357_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c index bcd66e0094b4..8e995edf4c10 100644 --- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c @@ -568,6 +568,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { .quirk_data = &adl_max98390_amp, .sof_tplg_filename = "sof-adl-max98390-rt5682.tplg", }, + { + .comp_ids = &adl_rt5682_rt5682s_hp, + .drv_name = "adl_rt5682_c1_h02", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &adl_lt6911_hdmi, + .sof_tplg_filename = "sof-adl-rt5682-ssp1-hdmi-ssp02.tplg", + }, { .comp_ids = &adl_rt5682_rt5682s_hp, .drv_name = "adl_rt5682", From a14aded9299187bb17ef90700eb2cf1120ef5885 Mon Sep 17 00:00:00 2001 From: Uday M Bhat Date: Mon, 31 Jul 2023 16:42:38 -0500 Subject: [PATCH 04/23] ASoC: Intel: sof_sdw: Update BT offload config for soundwire config For soundwire config, SSP1 is used for BT offload. This is enabled in sof_sdw_quirk_table Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Signed-off-by: Uday M Bhat Signed-off-by: Jairaj Arava Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index dbee8c98ff01..b811446be4cd 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -467,7 +467,9 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Google"), DMI_MATCH(DMI_PRODUCT_NAME, "Rex"), }, - .driver_data = (void *)(SOF_SDW_PCH_DMIC), + .driver_data = (void *)(SOF_SDW_PCH_DMIC | + SOF_BT_OFFLOAD_SSP(1) | + SOF_SSP_BT_OFFLOAD_PRESENT), }, /* LunarLake devices */ { From 4b68ce6912fd87b1743eb2e66aeba81cae2067fe Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 31 Jul 2023 16:42:39 -0500 Subject: [PATCH 05/23] ASoC: Intel: sof_sdw: reorder SoundWire codecs in Kconfig No functionality change, just sort Realtek codecs using increasing part IDs. Reviewed-by: Ranjani Sridharan Reviewed-by: Rander Wang Reviewed-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 1fe830af2b84..141fba0f8c70 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -671,12 +671,12 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH select SND_SOC_RT711_SDCA_SDW select SND_SOC_RT712_SDCA_SDW select SND_SOC_RT712_SDCA_DMIC_SDW + select SND_SOC_RT715_SDW + select SND_SOC_RT715_SDCA_SDW select SND_SOC_RT1308_SDW select SND_SOC_RT1308 select SND_SOC_RT1316_SDW select SND_SOC_RT1318_SDW - select SND_SOC_RT715_SDW - select SND_SOC_RT715_SDCA_SDW select SND_SOC_RT5682_SDW select SND_SOC_CS42L42_SDW select SND_SOC_DMIC From 3390d4ed823e716618095c16ad6792f33cc66190 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 31 Jul 2023 16:42:40 -0500 Subject: [PATCH 06/23] ASoC: Intel: sof_sdw: allow mockup amplifier to provide feedback The capture setting are missing and preventing topologies with feedback from loading. Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-7-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index b811446be4cd..7e43be46cfa8 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -942,10 +942,10 @@ static struct sof_sdw_codec_info codec_info_list[] = { .version_id = 0, .dais = { { - .direction = {true, false}, + .direction = {true, true}, .dai_name = "sdw-mockup-aif1", .dai_type = SOF_SDW_DAI_TYPE_AMP, - .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, .init = NULL, }, }, From 616bee2c06ca1cd24631ae0db1b4cba1d6b9ad25 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 31 Jul 2023 16:42:41 -0500 Subject: [PATCH 07/23] ASoC: Intel: sof_sdw: rename link_id to be_id The link_id parameter in create_sdw_dailink is actually the BE link id. Rename it to be_id to be consistent with the caller and less confusion. No functionality change. Reviewed-by: Rander Wang Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-8-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 7e43be46cfa8..acaedd3b2224 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1354,7 +1354,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, int *cpu_id, bool *group_generated, struct snd_soc_codec_conf *codec_conf, - int codec_count, int *link_id, + int codec_count, int *be_id, int *codec_conf_index, bool *ignore_pch_dmic, bool append_dai_type, @@ -1433,9 +1433,9 @@ static int create_sdw_dailink(struct snd_soc_card *card, if (!codec_info->dais[dai_index].direction[stream]) continue; - *link_id = codec_info->dais[dai_index].dailink[stream]; - if (*link_id < 0) { - dev_err(dev, "Invalid dailink id %d\n", *link_id); + *be_id = codec_info->dais[dai_index].dailink[stream]; + if (*be_id < 0) { + dev_err(dev, "Invalid dailink id %d\n", *be_id); return -EINVAL; } @@ -1492,7 +1492,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, playback = (stream == SNDRV_PCM_STREAM_PLAYBACK); capture = (stream == SNDRV_PCM_STREAM_CAPTURE); - init_dai_link(dev, dai_links + *link_index, (*link_id)++, name, + init_dai_link(dev, dai_links + *link_index, (*be_id)++, name, playback, capture, cpus + *cpu_id, cpu_dai_num, codecs, codec_num, From 0cc85f2bfbcb84754ee6cd43a6fb9953f18cd2dc Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 31 Jul 2023 16:42:42 -0500 Subject: [PATCH 08/23] ASoC: Intel: sof_sdw: add support for SKU 0AFE Yet another missing configuration, with the standard configuration link0: rt711-sdca link 1 and 2: rt1316-sdca link3: rt714-sdca Link: https://github.com/thesofproject/sof/issues/7799 Reviewed-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-9-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index acaedd3b2224..ffb0cd0700c4 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -307,6 +307,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_FOUR_SPK), }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFE") + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + RT711_JD2 | + SOF_SDW_FOUR_SPK), + }, { .callback = sof_sdw_quirk_cb, .matches = { From 1d1062382b1807679e9001d79704112525576057 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 31 Jul 2023 16:42:43 -0500 Subject: [PATCH 09/23] ASoC: intel: sof_sdw: Use consistent variable naming for links The driver makes extensive use of both ACPI link and ASoC DAI link structs, often referring to both with the variable name link. Make the code a little easier to follow by consistently using adr_link for the ACPI bits and dai_links for the ASoC bits. Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Reviewed-by: Rander Wang Signed-off-by: Charles Keepax Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-10-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 118 ++++++++++++++++--------------- 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index ffb0cd0700c4..6f65f45bded6 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1021,10 +1021,10 @@ static inline int find_codec_info_acpi(const u8 *acpi_id) * Since some sdw slaves may be aggregated, the CPU DAI number * may be larger than the number of BE dailinks. */ -static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_link_adr *links, +static int get_sdw_dailink_info(struct device *dev, + const struct snd_soc_acpi_link_adr *adr_link, int *sdw_be_num, int *sdw_cpu_dai_num) { - const struct snd_soc_acpi_link_adr *link; bool group_visited[SDW_MAX_GROUPS]; bool no_aggregation; int i; @@ -1034,27 +1034,27 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li *sdw_cpu_dai_num = 0; *sdw_be_num = 0; - if (!links) + if (!adr_link) return -EINVAL; for (i = 0; i < SDW_MAX_GROUPS; i++) group_visited[i] = false; - for (link = links; link->num_adr; link++) { + for (; adr_link->num_adr; adr_link++) { const struct snd_soc_acpi_endpoint *endpoint; struct sof_sdw_codec_info *codec_info; int codec_index; int stream; u64 adr; - for (i = 0; i < link->num_adr; i++) { - adr = link->adr_d[i].adr; + for (i = 0; i < adr_link->num_adr; i++) { + adr = adr_link->adr_d[i].adr; codec_index = find_codec_info_part(adr); if (codec_index < 0) return codec_index; codec_info = &codec_info_list[codec_index]; - endpoint = link->adr_d[i].endpoints; + endpoint = adr_link->adr_d[i].endpoints; for (j = 0; j < codec_info->dai_num; j++) { /* count DAI number for playback and capture */ @@ -1102,7 +1102,7 @@ static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links dai_links->ops = ops; } -static bool is_unique_device(const struct snd_soc_acpi_link_adr *link, +static bool is_unique_device(const struct snd_soc_acpi_link_adr *adr_link, unsigned int sdw_version, unsigned int mfg_id, unsigned int part_id, @@ -1112,7 +1112,7 @@ static bool is_unique_device(const struct snd_soc_acpi_link_adr *link, { int i; - for (i = 0; i < link->num_adr; i++) { + for (i = 0; i < adr_link->num_adr; i++) { unsigned int sdw1_version, mfg1_id, part1_id, class1_id; u64 adr; @@ -1120,7 +1120,7 @@ static bool is_unique_device(const struct snd_soc_acpi_link_adr *link, if (i == index_in_link) continue; - adr = link->adr_d[i].adr; + adr = adr_link->adr_d[i].adr; sdw1_version = SDW_VERSION(adr); mfg1_id = SDW_MFG_ID(adr); @@ -1138,7 +1138,7 @@ static bool is_unique_device(const struct snd_soc_acpi_link_adr *link, } static int create_codec_dai_name(struct device *dev, - const struct snd_soc_acpi_link_adr *link, + const struct snd_soc_acpi_link_adr *adr_link, struct snd_soc_dai_link_component *codec, int offset, struct snd_soc_codec_conf *codec_conf, @@ -1151,19 +1151,19 @@ static int create_codec_dai_name(struct device *dev, int i; /* sanity check */ - if (*codec_conf_index + link->num_adr - adr_index > codec_count) { + if (*codec_conf_index + adr_link->num_adr - adr_index > codec_count) { dev_err(dev, "codec_conf: out-of-bounds access requested\n"); return -EINVAL; } - for (i = adr_index; i < link->num_adr; i++) { + for (i = adr_index; i < adr_link->num_adr; i++) { unsigned int sdw_version, unique_id, mfg_id; unsigned int link_id, part_id, class_id; int codec_index, comp_index; char *codec_str; u64 adr; - adr = link->adr_d[i].adr; + adr = adr_link->adr_d[i].adr; sdw_version = SDW_VERSION(adr); link_id = SDW_DISCO_LINK_ID(adr); @@ -1173,7 +1173,7 @@ static int create_codec_dai_name(struct device *dev, class_id = SDW_CLASS_ID(adr); comp_index = i - adr_index + offset; - if (is_unique_device(link, sdw_version, mfg_id, part_id, + if (is_unique_device(adr_link, sdw_version, mfg_id, part_id, class_id, i)) { codec_str = "sdw:%01x:%04x:%04x:%02x"; codec[comp_index].name = @@ -1204,7 +1204,7 @@ static int create_codec_dai_name(struct device *dev, codec_info_list[codec_index].dais[dai_index].dai_name; codec_conf[*codec_conf_index].dlc = codec[comp_index]; - codec_conf[*codec_conf_index].name_prefix = link->adr_d[i].name_prefix; + codec_conf[*codec_conf_index].name_prefix = adr_link->adr_d[i].name_prefix; ++*codec_conf_index; } @@ -1213,7 +1213,7 @@ static int create_codec_dai_name(struct device *dev, } static int set_codec_init_func(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, + const struct snd_soc_acpi_link_adr *adr_link, struct snd_soc_dai_link *dai_links, bool playback, int group_id, int adr_index, int dai_index) { @@ -1224,34 +1224,35 @@ static int set_codec_init_func(struct snd_soc_card *card, * Initialize the codec. If codec is part of an aggregated * group (group_id>0), initialize all codecs belonging to * same group. - * The first link should start with link->adr_d[adr_index] + * The first link should start with adr_link->adr_d[adr_index] * because that is the device that we want to initialize and * we should end immediately if it is not aggregated (group_id=0) */ - for ( ; i < link->num_adr; i++) { + for ( ; i < adr_link->num_adr; i++) { int codec_index; - codec_index = find_codec_info_part(link->adr_d[i].adr); + codec_index = find_codec_info_part(adr_link->adr_d[i].adr); if (codec_index < 0) return codec_index; /* The group_id is > 0 iff the codec is aggregated */ - if (link->adr_d[i].endpoints->group_id != group_id) + if (adr_link->adr_d[i].endpoints->group_id != group_id) continue; if (codec_info_list[codec_index].dais[dai_index].init) codec_info_list[codec_index].dais[dai_index].init(card, - link, + adr_link, dai_links, &codec_info_list[codec_index], playback); if (!group_id) return 0; } + i = 0; - link++; - } while (link->mask); + adr_link++; + } while (adr_link->mask); return 0; } @@ -1361,7 +1362,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, struct snd_soc_dai_link *dai_links, int sdw_be_num, int sdw_cpu_dai_num, struct snd_soc_dai_link_component *cpus, - const struct snd_soc_acpi_link_adr *link, + const struct snd_soc_acpi_link_adr *adr_link, int *cpu_id, bool *group_generated, struct snd_soc_codec_conf *codec_conf, int codec_count, int *be_id, @@ -1371,7 +1372,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, int adr_index, int dai_index) { - const struct snd_soc_acpi_link_adr *link_next; + const struct snd_soc_acpi_link_adr *adr_link_next; struct snd_soc_dai_link_component *codecs; struct sof_sdw_codec_info *codec_info; int cpu_dai_id[SDW_MAX_CPU_DAIS]; @@ -1385,7 +1386,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, int ret; int k; - ret = get_slave_info(link, dev, cpu_dai_id, &cpu_dai_num, &codec_num, + ret = get_slave_info(adr_link, dev, cpu_dai_id, &cpu_dai_num, &codec_num, &group_id, group_generated, adr_index); if (ret) return ret; @@ -1395,20 +1396,20 @@ static int create_sdw_dailink(struct snd_soc_card *card, return -ENOMEM; /* generate codec name on different links in the same group */ - for (link_next = link; link_next && link_next->num_adr && - i < cpu_dai_num; link_next++) { + for (adr_link_next = adr_link; adr_link_next && adr_link_next->num_adr && + i < cpu_dai_num; adr_link_next++) { const struct snd_soc_acpi_endpoint *endpoints; - endpoints = link_next->adr_d->endpoints; + endpoints = adr_link_next->adr_d->endpoints; if (group_id && (!endpoints->aggregated || endpoints->group_id != group_id)) continue; /* skip the link excluded by this processed group */ - if (cpu_dai_id[i] != ffs(link_next->mask) - 1) + if (cpu_dai_id[i] != ffs(adr_link_next->mask) - 1) continue; - ret = create_codec_dai_name(dev, link_next, codecs, codec_idx, + ret = create_codec_dai_name(dev, adr_link_next, codecs, codec_idx, codec_conf, codec_count, codec_conf_index, adr_index, dai_index); if (ret < 0) @@ -1416,11 +1417,11 @@ static int create_sdw_dailink(struct snd_soc_card *card, /* check next link to create codec dai in the processed group */ i++; - codec_idx += link_next->num_adr; + codec_idx += adr_link_next->num_adr; } /* find codec info to create BE DAI */ - codec_index = find_codec_info_part(link->adr_d[adr_index].adr); + codec_index = find_codec_info_part(adr_link->adr_d[adr_index].adr); if (codec_index < 0) return codec_index; codec_info = &codec_info_list[codec_index]; @@ -1516,7 +1517,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, set_dailink_map(sdw_codec_ch_maps, codec_num, cpu_dai_num); dai_links[*link_index].codec_ch_maps = sdw_codec_ch_maps; - ret = set_codec_init_func(card, link, dai_links + (*link_index)++, + ret = set_codec_init_func(card, adr_link, dai_links + (*link_index)++, playback, group_id, adr_index, dai_index); if (ret < 0) { dev_err(dev, "failed to init codec %d", codec_index); @@ -1589,7 +1590,7 @@ static int sof_card_dai_links_create(struct device *dev, int codec_conf_index = 0; bool group_generated[SDW_MAX_GROUPS]; int ssp_codec_index, ssp_mask; - struct snd_soc_dai_link *links; + struct snd_soc_dai_link *dai_links; int num_links, link_index = 0; char *name, *cpu_name; int total_cpu_dai_num; @@ -1650,14 +1651,14 @@ static int sof_card_dai_links_create(struct device *dev, /* allocate BE dailinks */ num_links = comp_num + sdw_be_num; - links = devm_kcalloc(dev, num_links, sizeof(*links), GFP_KERNEL); + dai_links = devm_kcalloc(dev, num_links, sizeof(*dai_links), GFP_KERNEL); /* allocated CPU DAIs */ total_cpu_dai_num = comp_num + sdw_cpu_dai_num; cpus = devm_kcalloc(dev, total_cpu_dai_num, sizeof(*cpus), GFP_KERNEL); - if (!links || !cpus) + if (!dai_links || !cpus) return -ENOMEM; /* SDW */ @@ -1731,9 +1732,9 @@ static int sof_card_dai_links_create(struct device *dev, return codec_index; for (j = 0; j < codec_info_list[codec_index].dai_num ; j++) { - ret = create_sdw_dailink(card, dev, &link_index, links, sdw_be_num, - sdw_cpu_dai_num, cpus, adr_link, - &cpu_id, group_generated, + ret = create_sdw_dailink(card, dev, &link_index, dai_links, + sdw_be_num, sdw_cpu_dai_num, cpus, + adr_link, &cpu_id, group_generated, codec_conf, codec_conf_count, &be_id, &codec_conf_index, &ignore_pch_dmic, append_dai_type, i, j); @@ -1785,13 +1786,13 @@ static int sof_card_dai_links_create(struct device *dev, playback = info->dais[0].direction[SNDRV_PCM_STREAM_PLAYBACK]; capture = info->dais[0].direction[SNDRV_PCM_STREAM_CAPTURE]; - init_dai_link(dev, links + link_index, be_id, name, + init_dai_link(dev, dai_links + link_index, be_id, name, playback, capture, cpus + cpu_id, 1, ssp_components, 1, NULL, info->ops); - ret = info->dais[0].init(card, NULL, links + link_index, info, 0); + ret = info->dais[0].init(card, NULL, dai_links + link_index, info, 0); if (ret < 0) return ret; @@ -1806,7 +1807,7 @@ static int sof_card_dai_links_create(struct device *dev, goto HDMI; } cpus[cpu_id].dai_name = "DMIC01 Pin"; - init_dai_link(dev, links + link_index, be_id, "dmic01", + init_dai_link(dev, dai_links + link_index, be_id, "dmic01", 0, 1, // DMIC only supports capture cpus + cpu_id, 1, dmic_component, 1, @@ -1814,7 +1815,7 @@ static int sof_card_dai_links_create(struct device *dev, INC_ID(be_id, cpu_id, link_index); cpus[cpu_id].dai_name = "DMIC16k Pin"; - init_dai_link(dev, links + link_index, be_id, "dmic16k", + init_dai_link(dev, dai_links + link_index, be_id, "dmic16k", 0, 1, // DMIC only supports capture cpus + cpu_id, 1, dmic_component, 1, @@ -1857,7 +1858,7 @@ static int sof_card_dai_links_create(struct device *dev, return -ENOMEM; cpus[cpu_id].dai_name = cpu_name; - init_dai_link(dev, links + link_index, be_id, name, + init_dai_link(dev, dai_links + link_index, be_id, name, 1, 0, // HDMI only supports playback cpus + cpu_id, 1, idisp_components + i, 1, @@ -1878,11 +1879,11 @@ static int sof_card_dai_links_create(struct device *dev, return -ENOMEM; cpus[cpu_id].dai_name = cpu_name; - init_dai_link(dev, links + link_index, be_id, name, 1, 1, - cpus + cpu_id, 1, &asoc_dummy_dlc, 1, NULL, NULL); + init_dai_link(dev, dai_links + link_index, be_id, name, 1, 1, + cpus + cpu_id, 1, &asoc_dummy_dlc, 1, NULL, NULL); } - card->dai_link = links; + card->dai_link = dai_links; card->num_links = num_links; card->codec_conf = codec_conf; @@ -1925,15 +1926,15 @@ static struct snd_soc_card card_sof_sdw = { static struct snd_soc_dai_link *mc_find_codec_dai_used(struct snd_soc_card *card, const char *dai_name) { - struct snd_soc_dai_link *link; + struct snd_soc_dai_link *dai_link; int i; int j; - for_each_card_prelinks(card, i, link) { - for (j = 0; j < link->num_codecs; j++) { + for_each_card_prelinks(card, i, dai_link) { + for (j = 0; j < dai_link->num_codecs; j++) { /* Check each codec in a link */ - if (!strcmp(link->codecs[j].dai_name, dai_name)) - return link; + if (!strcmp(dai_link->codecs[j].dai_name, dai_name)) + return dai_link; } } return NULL; @@ -1941,7 +1942,7 @@ static struct snd_soc_dai_link *mc_find_codec_dai_used(struct snd_soc_card *card static void mc_dailink_exit_loop(struct snd_soc_card *card) { - struct snd_soc_dai_link *link; + struct snd_soc_dai_link *dai_link; int ret; int i, j; @@ -1954,10 +1955,11 @@ static void mc_dailink_exit_loop(struct snd_soc_card *card) * We don't need to call .exit function if there is no matched * dai link found. */ - link = mc_find_codec_dai_used(card, codec_info_list[i].dais[j].dai_name); - if (link) { + dai_link = mc_find_codec_dai_used(card, + codec_info_list[i].dais[j].dai_name); + if (dai_link) { /* Do the .exit function if the codec dai is used in the link */ - ret = codec_info_list[i].dais[j].exit(card, link); + ret = codec_info_list[i].dais[j].exit(card, dai_link); if (ret) dev_warn(card->dev, "codec exit failed %d\n", From 4fc16d21b7abb969935162d8b01fba21496cf513 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 31 Jul 2023 16:42:44 -0500 Subject: [PATCH 10/23] ASoC: intel: sof_sdw: Rename codec_idx to codec_dlc_index Having two local variables called codec_idx and codec_index, that refer to different things is a little confusing. Rename codec_idx to codec_dlc_index to indicate it points into the dai_link_component array. Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Reviewed-by: Rander Wang Signed-off-by: Charles Keepax Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-11-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 6f65f45bded6..0743bf04aa88 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1378,7 +1378,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, int cpu_dai_id[SDW_MAX_CPU_DAIS]; int cpu_dai_num, cpu_dai_index; unsigned int group_id; - int codec_idx = 0; + int codec_dlc_index = 0; int codec_index; int codec_num; int stream; @@ -1409,7 +1409,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, if (cpu_dai_id[i] != ffs(adr_link_next->mask) - 1) continue; - ret = create_codec_dai_name(dev, adr_link_next, codecs, codec_idx, + ret = create_codec_dai_name(dev, adr_link_next, codecs, codec_dlc_index, codec_conf, codec_count, codec_conf_index, adr_index, dai_index); if (ret < 0) @@ -1417,7 +1417,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, /* check next link to create codec dai in the processed group */ i++; - codec_idx += adr_link_next->num_adr; + codec_dlc_index += adr_link_next->num_adr; } /* find codec info to create BE DAI */ From 08f62f6291bae6e0cc5f3f50e4e1043e6a270e80 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 31 Jul 2023 16:42:45 -0500 Subject: [PATCH 11/23] ASoC: intel: sof_sdw: Remove some extra line breaks Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Reviewed-by: Rander Wang Signed-off-by: Charles Keepax Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-12-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 0743bf04aa88..4f7ef83c21c5 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -523,7 +523,6 @@ int sdw_prepare(struct snd_pcm_substream *substream) dai = asoc_rtd_to_cpu(rtd, 0); sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); - if (IS_ERR(sdw_stream)) { dev_err(rtd->dev, "no stream found for DAI %s", dai->name); return PTR_ERR(sdw_stream); @@ -543,7 +542,6 @@ int sdw_trigger(struct snd_pcm_substream *substream, int cmd) dai = asoc_rtd_to_cpu(rtd, 0); sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); - if (IS_ERR(sdw_stream)) { dev_err(rtd->dev, "no stream found for DAI %s", dai->name); return PTR_ERR(sdw_stream); @@ -631,7 +629,6 @@ int sdw_hw_free(struct snd_pcm_substream *substream) dai = asoc_rtd_to_cpu(rtd, 0); sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); - if (IS_ERR(sdw_stream)) { dev_err(rtd->dev, "no stream found for DAI %s", dai->name); return PTR_ERR(sdw_stream); @@ -1107,8 +1104,7 @@ static bool is_unique_device(const struct snd_soc_acpi_link_adr *adr_link, unsigned int mfg_id, unsigned int part_id, unsigned int class_id, - int index_in_link - ) + int index_in_link) { int i; @@ -1232,7 +1228,6 @@ static int set_codec_init_func(struct snd_soc_card *card, int codec_index; codec_index = find_codec_info_part(adr_link->adr_d[i].adr); - if (codec_index < 0) return codec_index; From 18c45cb362fcd6918548a4e11128304aa634acf3 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 31 Jul 2023 16:42:46 -0500 Subject: [PATCH 12/23] ASoC: intel: sof_sdw: Use a module device table A module device table is generally preferred over hard coding a MODULE_ALIAS. Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Reviewed-by: Rander Wang Signed-off-by: Charles Keepax Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-13-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 4f7ef83c21c5..6b55bcdccccc 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -2045,6 +2045,12 @@ static void mc_remove(struct platform_device *pdev) mc_dailink_exit_loop(card); } +static const struct platform_device_id mc_id_table[] = { + { "sof_sdw", }, + {} +}; +MODULE_DEVICE_TABLE(platform, mc_id_table); + static struct platform_driver sof_sdw_driver = { .driver = { .name = "sof_sdw", @@ -2052,6 +2058,7 @@ static struct platform_driver sof_sdw_driver = { }, .probe = mc_probe, .remove_new = mc_remove, + .id_table = mc_id_table, }; module_platform_driver(sof_sdw_driver); @@ -2061,6 +2068,5 @@ MODULE_AUTHOR("Bard Liao "); MODULE_AUTHOR("Rander Wang "); MODULE_AUTHOR("Pierre-Louis Bossart "); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:sof_sdw"); MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); From 31a54f78ad1d294432d63e9f72db08dc14cca432 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 31 Jul 2023 16:42:47 -0500 Subject: [PATCH 13/23] ASoC: intel: sof_sdw: Simplify find_codec_info_acpi Use a return rather than a break and an additional range check. Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Reviewed-by: Rander Wang Signed-off-by: Charles Keepax Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-14-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 6b55bcdccccc..d3222f40d798 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1003,14 +1003,10 @@ static inline int find_codec_info_acpi(const u8 *acpi_id) return -EINVAL; for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) - if (!memcmp(codec_info_list[i].acpi_id, acpi_id, - ACPI_ID_LEN)) - break; + if (!memcmp(codec_info_list[i].acpi_id, acpi_id, ACPI_ID_LEN)) + return i; - if (i == ARRAY_SIZE(codec_info_list)) - return -EINVAL; - - return i; + return -EINVAL; } /* From fad1a9eff67d34b6f90cf4d1d2f1dc2632dfeeb4 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 31 Jul 2023 16:42:48 -0500 Subject: [PATCH 14/23] ASoC: intel: sof_sdw: Constify parameter to find_codec_part_info The address passed to find_codec_part_info should be const. Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Reviewed-by: Rander Wang Signed-off-by: Charles Keepax Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-15-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 d3222f40d798..fc67029b3a64 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -974,7 +974,7 @@ static struct sof_sdw_codec_info codec_info_list[] = { }, }; -static inline int find_codec_info_part(u64 adr) +static inline int find_codec_info_part(const u64 adr) { unsigned int part_id, sdw_version; int i; From 855e69f4ff9d726df4c8c47e7b40934fdb49d9c5 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 31 Jul 2023 16:42:49 -0500 Subject: [PATCH 15/23] ASoC: intel: sof_sdw: Minor tidy up of mc_probe Shuffle things around to group operations a little more, and consistently use card->dev. Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Reviewed-by: Rander Wang Signed-off-by: Charles Keepax Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-16-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index fc67029b3a64..d4f2711b6f26 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1964,34 +1964,34 @@ static void mc_dailink_exit_loop(struct snd_soc_card *card) static int mc_probe(struct platform_device *pdev) { struct snd_soc_card *card = &card_sof_sdw; - struct snd_soc_acpi_mach *mach; + struct snd_soc_acpi_mach *mach = dev_get_platdata(&pdev->dev); struct mc_private *ctx; int amp_num = 0, i; int ret; - dev_dbg(&pdev->dev, "Entry\n"); + card->dev = &pdev->dev; - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); + dev_dbg(card->dev, "Entry\n"); + + ctx = devm_kzalloc(card->dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; + INIT_LIST_HEAD(&ctx->hdmi_pcm_list); + + snd_soc_card_set_drvdata(card, ctx); + dmi_check_system(sof_sdw_quirk_table); if (quirk_override != -1) { - dev_info(&pdev->dev, "Overriding quirk 0x%lx => 0x%x\n", + dev_info(card->dev, "Overriding quirk 0x%lx => 0x%x\n", sof_sdw_quirk, quirk_override); sof_sdw_quirk = quirk_override; } - log_quirks(&pdev->dev); - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); + log_quirks(card->dev); - card->dev = &pdev->dev; - snd_soc_card_set_drvdata(card, ctx); - - mach = pdev->dev.platform_data; - ret = sof_card_dai_links_create(&pdev->dev, mach, - card); + ret = sof_card_dai_links_create(card->dev, mach, card); if (ret < 0) return ret; @@ -2022,7 +2022,7 @@ static int mc_probe(struct platform_device *pdev) card->long_name = sdw_card_long_name; /* Register the card */ - ret = devm_snd_soc_register_card(&pdev->dev, card); + ret = devm_snd_soc_register_card(card->dev, card); if (ret) { dev_err(card->dev, "snd_soc_register_card failed %d\n", ret); mc_dailink_exit_loop(card); From febac07b4c69242d7870944457c3a1158ab97bdc Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 31 Jul 2023 16:42:50 -0500 Subject: [PATCH 16/23] ASoC: intel: sof_sdw: Remove redundant parameters in dai creation Pull the device and mach struct out of the card rather than explicitly passing to sof_card_dai_links_create. Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Reviewed-by: Rander Wang Signed-off-by: Charles Keepax Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-17-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index d4f2711b6f26..dc5337ea75da 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1348,8 +1348,7 @@ static void set_dailink_map(struct snd_soc_dai_link_codec_ch_map *sdw_codec_ch_m static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"}; -static int create_sdw_dailink(struct snd_soc_card *card, - struct device *dev, int *link_index, +static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, struct snd_soc_dai_link *dai_links, int sdw_be_num, int sdw_cpu_dai_num, struct snd_soc_dai_link_component *cpus, @@ -1363,6 +1362,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, int adr_index, int dai_index) { + struct device *dev = card->dev; const struct snd_soc_acpi_link_adr *adr_link_next; struct snd_soc_dai_link_component *codecs; struct sof_sdw_codec_info *codec_info; @@ -1563,10 +1563,10 @@ static int sof_card_codec_conf_alloc(struct device *dev, return 0; } -static int sof_card_dai_links_create(struct device *dev, - struct snd_soc_acpi_mach *mach, - struct snd_soc_card *card) +static int sof_card_dai_links_create(struct snd_soc_card *card) { + struct device *dev = card->dev; + struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev); int ssp_num, sdw_be_num = 0, hdmi_num = 0, dmic_num; struct mc_private *ctx = snd_soc_card_get_drvdata(card); struct snd_soc_dai_link_component *idisp_components; @@ -1723,7 +1723,7 @@ static int sof_card_dai_links_create(struct device *dev, return codec_index; for (j = 0; j < codec_info_list[codec_index].dai_num ; j++) { - ret = create_sdw_dailink(card, dev, &link_index, dai_links, + ret = create_sdw_dailink(card, &link_index, dai_links, sdw_be_num, sdw_cpu_dai_num, cpus, adr_link, &cpu_id, group_generated, codec_conf, codec_conf_count, @@ -1991,7 +1991,7 @@ static int mc_probe(struct platform_device *pdev) log_quirks(card->dev); - ret = sof_card_dai_links_create(card->dev, mach, card); + ret = sof_card_dai_links_create(card); if (ret < 0) return ret; From 8673e68b594684fac53398ec5783a6c8469a07a1 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 31 Jul 2023 16:42:51 -0500 Subject: [PATCH 17/23] ASoC: intel: sof_sdw: Move amp_num initialisation to mc_probe The amp_num member of the info struct is zeroed at the start of sof_card_dai_links_create, but then summed in mc_probe after sof_card_dai_links_create is called. It is a little clearer to hoist the initialisation out of sof_card_dai_links_create so it is on the same level as the summation. Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Reviewed-by: Rander Wang Signed-off-by: Charles Keepax Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-18-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index dc5337ea75da..1a60965439dd 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1599,10 +1599,6 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) if (ret < 0) return ret; - /* reset amp_num to ensure amp_num++ starts from 0 in each probe */ - for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) - codec_info_list[i].amp_num = 0; - if (mach_params->codec_mask & IDISP_CODEC_MASK) { ctx->idisp_codec = true; @@ -1991,6 +1987,10 @@ static int mc_probe(struct platform_device *pdev) log_quirks(card->dev); + /* reset amp_num to ensure amp_num++ starts from 0 in each probe */ + for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) + codec_info_list[i].amp_num = 0; + ret = sof_card_dai_links_create(card); if (ret < 0) return ret; From 656dd91a3a1ca27a02d9a79d1720b2ca40d272cf Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 31 Jul 2023 16:42:52 -0500 Subject: [PATCH 18/23] ASoC: Intel: sof_sdw: break earlier when a adr link contains different codecs create_codec_dai_name() is used to create codec component's information in different adr links. We can and should break before we do anything. Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-19-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 1a60965439dd..846ba8e1515c 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1157,6 +1157,15 @@ static int create_codec_dai_name(struct device *dev, adr = adr_link->adr_d[i].adr; + codec_index = find_codec_info_part(adr); + if (codec_index < 0) + return codec_index; + if (_codec_index != -1 && codec_index != _codec_index) { + dev_dbg(dev, "Different devices on the same sdw link\n"); + break; + } + _codec_index = codec_index; + sdw_version = SDW_VERSION(adr); link_id = SDW_DISCO_LINK_ID(adr); unique_id = SDW_UNIQUE_ID(adr); @@ -1183,15 +1192,6 @@ static int create_codec_dai_name(struct device *dev, if (!codec[comp_index].name) return -ENOMEM; - codec_index = find_codec_info_part(adr); - if (codec_index < 0) - return codec_index; - if (_codec_index != -1 && codec_index != _codec_index) { - dev_dbg(dev, "Different devices on the same sdw link\n"); - break; - } - _codec_index = codec_index; - codec[comp_index].dai_name = codec_info_list[codec_index].dais[dai_index].dai_name; From 009582008182bc0a2956d245fd0362e036f31dfe Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 31 Jul 2023 16:42:53 -0500 Subject: [PATCH 19/23] ASoC: intel: sof_sdw: Allow direct specification of CODEC name Add support for MFD based CODEC drivers, by allowing the CODEC name to not be the SoundWire device directly. Signed-off-by: Charles Keepax Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-20-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 6 +++++- sound/soc/intel/boards/sof_sdw_common.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 846ba8e1515c..e6faed2b99b2 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1174,7 +1174,11 @@ static int create_codec_dai_name(struct device *dev, class_id = SDW_CLASS_ID(adr); comp_index = i - adr_index + offset; - if (is_unique_device(adr_link, sdw_version, mfg_id, part_id, + if (codec_info_list[codec_index].codec_name) { + codec[comp_index].name = + devm_kstrdup(dev, codec_info_list[codec_index].codec_name, + GFP_KERNEL); + } else if (is_unique_device(adr_link, sdw_version, mfg_id, part_id, class_id, i)) { codec_str = "sdw:%01x:%04x:%04x:%02x"; codec[comp_index].name = diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index 37402170d5f9..fe234b98eb64 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -80,6 +80,7 @@ struct sof_sdw_dai_info { struct sof_sdw_codec_info { const int part_id; const int version_id; + const char *codec_name; int amp_num; const u8 acpi_id[ACPI_ID_LEN]; const bool ignore_pch_dmic; From 4754e29c779fe2a2677ba62896daf4bf980602a1 Mon Sep 17 00:00:00 2001 From: Chao Song Date: Mon, 31 Jul 2023 16:42:54 -0500 Subject: [PATCH 20/23] ASoC: Intel: sof_sdw: add cs35l56 codec info Add cs35l56 support in sof_sdw machine driver. Reviewed-by: Rander Wang Signed-off-by: Chao Song Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-21-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/Kconfig | 1 + sound/soc/intel/boards/Makefile | 2 +- sound/soc/intel/boards/sof_sdw.c | 13 +++++++ sound/soc/intel/boards/sof_sdw_common.h | 6 ++++ sound/soc/intel/boards/sof_sdw_cs_amp.c | 47 +++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 sound/soc/intel/boards/sof_sdw_cs_amp.c diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 141fba0f8c70..0ae6eecc8851 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -679,6 +679,7 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH select SND_SOC_RT1318_SDW select SND_SOC_RT5682_SDW select SND_SOC_CS42L42_SDW + select SND_SOC_CS35L56_SDW select SND_SOC_DMIC select SND_SOC_INTEL_HDA_DSP_COMMON select SND_SOC_INTEL_SOF_MAXIM_COMMON diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index 931415d9cf6f..a570b5b40f22 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -42,7 +42,7 @@ snd-soc-sof-sdw-objs += sof_sdw.o \ sof_sdw_rt711.o sof_sdw_rt_sdca_jack_common.o \ sof_sdw_rt712_sdca.o sof_sdw_rt715.o \ sof_sdw_rt715_sdca.o sof_sdw_dmic.o \ - sof_sdw_cs42l42.o \ + sof_sdw_cs42l42.o sof_sdw_cs_amp.o \ sof_sdw_hdmi.o obj-$(CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH) += snd-soc-sof_rt5682.o obj-$(CONFIG_SND_SOC_INTEL_SOF_CS42L42_MACH) += snd-soc-sof_cs42l42.o diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index e6faed2b99b2..5dbfcd88ab3c 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -903,6 +903,19 @@ static struct sof_sdw_codec_info codec_info_list[] = { }, .dai_num = 1, }, + { + .part_id = 0x3556, + .dais = { + { + .direction = {true, true}, + .dai_name = "cs35l56-sdw1", + .dai_type = SOF_SDW_DAI_TYPE_AMP, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, + .init = sof_sdw_cs_amp_init, + }, + }, + .dai_num = 1, + }, { .part_id = 0x4242, .dais = { diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index fe234b98eb64..2f4fe6bc3d5d 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -206,4 +206,10 @@ int sof_sdw_cs42l42_init(struct snd_soc_card *card, struct sof_sdw_codec_info *info, bool playback); +/* CS AMP support */ +int sof_sdw_cs_amp_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); #endif diff --git a/sound/soc/intel/boards/sof_sdw_cs_amp.c b/sound/soc/intel/boards/sof_sdw_cs_amp.c new file mode 100644 index 000000000000..98f6546f484b --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_cs_amp.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2023 Intel Corporation + +/* + * sof_sdw_cs_amp - Helpers to handle CS35L56 from generic machine driver + */ + +#include +#include +#include +#include +#include "sof_sdw_common.h" + +#define CODEC_NAME_SIZE 8 + +static int cs_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + const char *dai_name = rtd->dai_link->codecs->dai_name; + struct snd_soc_card *card = rtd->card; + char codec_name[CODEC_NAME_SIZE]; + + snprintf(codec_name, CODEC_NAME_SIZE, "%s", dai_name); + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s spk:%s", + card->components, codec_name); + if (!card->components) + return -ENOMEM; + + return 0; +} + + +int sof_sdw_cs_amp_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + /* Count amp number and do init on playback link only. */ + if (!playback) + return 0; + + info->amp_num++; + dai_links->init = cs_spk_init; + + return 0; +} From 98a7a1143f83289a84cba6dab60a4531cc4dfae2 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 31 Jul 2023 16:42:55 -0500 Subject: [PATCH 21/23] ASoC: intel: sof_sdw: Clean up DAI link counting The counting of each of the types of DAI link is a bit messy with things added onto an intermediate variable as it goes along. Re-order things a little to keep the order consistent with the rest of the function and simplify the process down to a variable for each type of DAI and then sum them at the end. Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Signed-off-by: Charles Keepax Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-22-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 67 +++++++++++++++----------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 5dbfcd88ab3c..dc6ea21b3341 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1584,12 +1584,12 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) { struct device *dev = card->dev; struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev); - int ssp_num, sdw_be_num = 0, hdmi_num = 0, dmic_num; + int sdw_be_num = 0, ssp_num = 0, dmic_num = 0, hdmi_num = 0, bt_num = 0; struct mc_private *ctx = snd_soc_card_get_drvdata(card); struct snd_soc_dai_link_component *idisp_components; struct snd_soc_dai_link_component *ssp_components; - struct snd_soc_acpi_mach_params *mach_params; - const struct snd_soc_acpi_link_adr *adr_link; + struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; + const struct snd_soc_acpi_link_adr *adr_link = mach_params->links; struct snd_soc_dai_link_component *cpus; struct snd_soc_codec_conf *codec_conf; bool append_dai_type = false; @@ -1606,16 +1606,31 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) int i, j, be_id = 0; int codec_index; int cpu_id = 0; - int comp_num; int ret; - mach_params = &mach->mach_params; - /* allocate codec conf, will be populated when dailinks are created */ ret = sof_card_codec_conf_alloc(dev, mach_params, &codec_conf, &codec_conf_count); if (ret < 0) return ret; + ret = get_sdw_dailink_info(dev, adr_link, &sdw_be_num, &sdw_cpu_dai_num); + if (ret < 0) { + dev_err(dev, "failed to get sdw link info %d\n", ret); + return ret; + } + + /* + * on generic tgl platform, I2S or sdw mode is supported + * based on board rework. A ACPI device is registered in + * system only when I2S mode is supported, not sdw mode. + * Here check ACPI ID to confirm I2S is supported. + */ + ssp_codec_index = find_codec_info_acpi(mach->id); + if (ssp_codec_index >= 0) { + ssp_mask = SOF_SSP_GET_PORT(sof_sdw_quirk); + ssp_num = hweight_long(ssp_mask); + } + if (mach_params->codec_mask & IDISP_CODEC_MASK) { ctx->idisp_codec = true; @@ -1625,44 +1640,26 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) hdmi_num = SOF_PRE_TGL_HDMI_COUNT; } - ssp_mask = SOF_SSP_GET_PORT(sof_sdw_quirk); - /* - * on generic tgl platform, I2S or sdw mode is supported - * based on board rework. A ACPI device is registered in - * system only when I2S mode is supported, not sdw mode. - * Here check ACPI ID to confirm I2S is supported. - */ - ssp_codec_index = find_codec_info_acpi(mach->id); - ssp_num = ssp_codec_index >= 0 ? hweight_long(ssp_mask) : 0; - comp_num = hdmi_num + ssp_num; - - ret = get_sdw_dailink_info(dev, mach_params->links, - &sdw_be_num, &sdw_cpu_dai_num); - if (ret < 0) { - dev_err(dev, "failed to get sdw link info %d", ret); - return ret; - } - /* enable dmic01 & dmic16k */ - dmic_num = (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num) ? 2 : 0; - comp_num += dmic_num; + if (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num) + dmic_num = 2; if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) - comp_num++; + bt_num = 1; - dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d", sdw_be_num, ssp_num, - dmic_num, ctx->idisp_codec ? hdmi_num : 0); + dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d, bt: %d\n", + sdw_be_num, ssp_num, dmic_num, hdmi_num, bt_num); /* allocate BE dailinks */ - num_links = comp_num + sdw_be_num; + num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num; dai_links = devm_kcalloc(dev, num_links, sizeof(*dai_links), GFP_KERNEL); + if (!dai_links) + return -ENOMEM; /* allocated CPU DAIs */ - total_cpu_dai_num = comp_num + sdw_cpu_dai_num; - cpus = devm_kcalloc(dev, total_cpu_dai_num, sizeof(*cpus), - GFP_KERNEL); - - if (!dai_links || !cpus) + total_cpu_dai_num = sdw_cpu_dai_num + ssp_num + dmic_num + hdmi_num + bt_num; + cpus = devm_kcalloc(dev, total_cpu_dai_num, sizeof(*cpus), GFP_KERNEL); + if (!cpus) return -ENOMEM; /* SDW */ From a386162e7dc2c8bc1be2777b1c6d41156f69b210 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 31 Jul 2023 16:42:56 -0500 Subject: [PATCH 22/23] ASoC: intel: sof_sdw: Merge codec_conf_alloc into dailink_info Rename get_sdw_dailink_info to simply get_dailink_info and have it also return the number of codecs present. Then hoist the allocation of the codec conf structure up into sof_card_dai_links_create. This saves an extra loop through the adr_link array, allows us to get rid of sof_card_codec_conf_alloc and makes the allocation more explicit. Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Signed-off-by: Charles Keepax Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-23-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 75 ++++++++++---------------------- 1 file changed, 23 insertions(+), 52 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index dc6ea21b3341..25644eff5251 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1027,9 +1027,9 @@ static inline int find_codec_info_acpi(const u8 *acpi_id) * Since some sdw slaves may be aggregated, the CPU DAI number * may be larger than the number of BE dailinks. */ -static int get_sdw_dailink_info(struct device *dev, - const struct snd_soc_acpi_link_adr *adr_link, - int *sdw_be_num, int *sdw_cpu_dai_num) +static int get_dailink_info(struct device *dev, + const struct snd_soc_acpi_link_adr *adr_link, + int *sdw_be_num, int *sdw_cpu_dai_num, int *codecs_num) { bool group_visited[SDW_MAX_GROUPS]; bool no_aggregation; @@ -1058,8 +1058,17 @@ static int get_sdw_dailink_info(struct device *dev, codec_index = find_codec_info_part(adr); if (codec_index < 0) return codec_index; + codec_info = &codec_info_list[codec_index]; + *codecs_num += codec_info->dai_num; + + if (!adr_link->adr_d[i].name_prefix) { + dev_err(dev, "codec 0x%llx does not have a name prefix\n", + adr_link->adr_d[i].adr); + return -EINVAL; + } + endpoint = adr_link->adr_d[i].endpoints; for (j = 0; j < codec_info->dai_num; j++) { @@ -1540,46 +1549,6 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, #define IDISP_CODEC_MASK 0x4 -static int sof_card_codec_conf_alloc(struct device *dev, - struct snd_soc_acpi_mach_params *mach_params, - struct snd_soc_codec_conf **codec_conf, - int *codec_conf_count) -{ - const struct snd_soc_acpi_link_adr *adr_link; - struct snd_soc_codec_conf *c_conf; - int num_codecs = 0; - int codec_index; - int i; - - adr_link = mach_params->links; - if (!adr_link) - return -EINVAL; - - /* generate DAI links by each sdw link */ - for (; adr_link->num_adr; adr_link++) { - for (i = 0; i < adr_link->num_adr; i++) { - if (!adr_link->adr_d[i].name_prefix) { - dev_err(dev, "codec 0x%llx does not have a name prefix\n", - adr_link->adr_d[i].adr); - return -EINVAL; - } - codec_index = find_codec_info_part(adr_link->adr_d[i].adr); - if (codec_index < 0) - return codec_index; - num_codecs += codec_info_list[codec_index].dai_num; - } - } - - c_conf = devm_kzalloc(dev, num_codecs * sizeof(*c_conf), GFP_KERNEL); - if (!c_conf) - return -ENOMEM; - - *codec_conf = c_conf; - *codec_conf_count = num_codecs; - - return 0; -} - static int sof_card_dai_links_create(struct snd_soc_card *card) { struct device *dev = card->dev; @@ -1594,7 +1563,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) struct snd_soc_codec_conf *codec_conf; bool append_dai_type = false; bool ignore_pch_dmic = false; - int codec_conf_count; + int codec_conf_num = 0; int codec_conf_index = 0; bool group_generated[SDW_MAX_GROUPS]; int ssp_codec_index, ssp_mask; @@ -1608,12 +1577,8 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) int cpu_id = 0; int ret; - /* allocate codec conf, will be populated when dailinks are created */ - ret = sof_card_codec_conf_alloc(dev, mach_params, &codec_conf, &codec_conf_count); - if (ret < 0) - return ret; - - ret = get_sdw_dailink_info(dev, adr_link, &sdw_be_num, &sdw_cpu_dai_num); + ret = get_dailink_info(dev, adr_link, &sdw_be_num, &sdw_cpu_dai_num, + &codec_conf_num); if (ret < 0) { dev_err(dev, "failed to get sdw link info %d\n", ret); return ret; @@ -1662,6 +1627,12 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) if (!cpus) return -ENOMEM; + /* allocate codec conf, will be populated when dailinks are created */ + codec_conf = devm_kcalloc(dev, codec_conf_num, sizeof(*codec_conf), + GFP_KERNEL); + if (!codec_conf) + return -ENOMEM; + /* SDW */ if (!sdw_be_num) goto SSP; @@ -1736,7 +1707,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) ret = create_sdw_dailink(card, &link_index, dai_links, sdw_be_num, sdw_cpu_dai_num, cpus, adr_link, &cpu_id, group_generated, - codec_conf, codec_conf_count, + codec_conf, codec_conf_num, &be_id, &codec_conf_index, &ignore_pch_dmic, append_dai_type, i, j); if (ret < 0) { @@ -1888,7 +1859,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) card->num_links = num_links; card->codec_conf = codec_conf; - card->num_configs = codec_conf_count; + card->num_configs = codec_conf_num; return 0; } From a60ed3b738705dbcb4afce9a24af00e2671edf19 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 31 Jul 2023 16:42:57 -0500 Subject: [PATCH 23/23] ASoC: intel: sof_sdw: Move group_generated logic Hoist the handling logic for group_generated up to the sof_card_dai_links_create level. This avoids the need to pass the array through multiple levels of functions. Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Signed-off-by: Charles Keepax Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230731214257.444605-24-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 25644eff5251..fd27e211211b 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1291,7 +1291,7 @@ static int set_codec_init_func(struct snd_soc_card *card, static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link, struct device *dev, int *cpu_dai_id, int *cpu_dai_num, int *codec_num, unsigned int *group_id, - bool *group_generated, int adr_index) + int adr_index) { const struct snd_soc_acpi_adr_device *adr_d; const struct snd_soc_acpi_link_adr *adr_next; @@ -1351,11 +1351,6 @@ static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link, } } - /* - * indicate CPU DAIs for this group have been generated - * to avoid generating CPU DAIs for this group again. - */ - group_generated[*group_id] = true; *cpu_dai_num = index; return 0; @@ -1379,8 +1374,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, int sdw_be_num, int sdw_cpu_dai_num, struct snd_soc_dai_link_component *cpus, const struct snd_soc_acpi_link_adr *adr_link, - int *cpu_id, bool *group_generated, - struct snd_soc_codec_conf *codec_conf, + int *cpu_id, struct snd_soc_codec_conf *codec_conf, int codec_count, int *be_id, int *codec_conf_index, bool *ignore_pch_dmic, @@ -1404,7 +1398,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, int k; ret = get_slave_info(adr_link, dev, cpu_dai_id, &cpu_dai_num, &codec_num, - &group_id, group_generated, adr_index); + &group_id, adr_index); if (ret) return ret; @@ -1559,13 +1553,14 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) struct snd_soc_dai_link_component *ssp_components; struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; const struct snd_soc_acpi_link_adr *adr_link = mach_params->links; + bool aggregation = !(sof_sdw_quirk & SOF_SDW_NO_AGGREGATION); struct snd_soc_dai_link_component *cpus; struct snd_soc_codec_conf *codec_conf; bool append_dai_type = false; bool ignore_pch_dmic = false; int codec_conf_num = 0; int codec_conf_index = 0; - bool group_generated[SDW_MAX_GROUPS]; + bool group_generated[SDW_MAX_GROUPS] = { }; int ssp_codec_index, ssp_mask; struct snd_soc_dai_link *dai_links; int num_links, link_index = 0; @@ -1641,14 +1636,6 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) if (!adr_link) return -EINVAL; - /* - * SoundWire Slaves aggregated in the same group may be - * located on different hardware links. Clear array to indicate - * CPU DAIs for this group have not been generated. - */ - for (i = 0; i < SDW_MAX_GROUPS; i++) - group_generated[i] = false; - for (i = 0; i < SDW_MAX_LINKS; i++) sdw_pin_index[i] = SDW_INTEL_BIDIR_PDI_BASE; @@ -1706,7 +1693,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) for (j = 0; j < codec_info_list[codec_index].dai_num ; j++) { ret = create_sdw_dailink(card, &link_index, dai_links, sdw_be_num, sdw_cpu_dai_num, cpus, - adr_link, &cpu_id, group_generated, + adr_link, &cpu_id, codec_conf, codec_conf_num, &be_id, &codec_conf_index, &ignore_pch_dmic, append_dai_type, i, j); @@ -1715,6 +1702,9 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) return ret; } } + + if (aggregation && endpoint->aggregated) + group_generated[endpoint->group_id] = true; } }