From 8116483407076b81af0efb14f6d69aefaecbf3d8 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 15 Jul 2022 09:41:41 -0500 Subject: [PATCH 1/4] ASoC: Intel: sof_sdw: avoid oops in error handling While tinkering with ACPI work-arounds for the HP Omen 16 support, we identified a corner case where the headset codec device properties are not set in the codec .init when -EPROBE_DEFER is returned, but released unconditionally in the .exit(). This leads to a kernel oops [ 4.186891] sof_sdw sof_sdw: snd_soc_register_card failed -517 [ 4.186896] BUG: kernel NULL pointer dereference, address: 00000000000003f0 [ 4.186914] Oops: 0000 [#1] PREEMPT SMP NOPTI [ 4.186926] RIP: 0010:dev_fwnode+0x5/0x20 [ 4.186974] device_remove_software_node+0x10/0x80 [ 4.186982] sof_sdw_rt711_exit+0x19/0x30 [snd_soc_sof_sdw] [ 4.186990] mc_dailink_exit_loop+0x94/0xc0 [snd_soc_sof_sdw] [ 4.186996] ? rt711_rtd_init+0x170/0x170 [snd_soc_sof_sdw] A similar error case can occur if the addition of the device property fails. We need to test if the property was successfully added before removing it. BugLink: https://github.com/thesofproject/linux/issues/3727 Fixes: 768ad6d80db2d ("ASoC: Intel: sof_sdw: handle errors on card registration") Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220715144144.274770-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw_rt711.c | 3 +++ sound/soc/intel/boards/sof_sdw_rt711_sdca.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/sound/soc/intel/boards/sof_sdw_rt711.c b/sound/soc/intel/boards/sof_sdw_rt711.c index 49ff0871e9e7..8291967f23f3 100644 --- a/sound/soc/intel/boards/sof_sdw_rt711.c +++ b/sound/soc/intel/boards/sof_sdw_rt711.c @@ -139,6 +139,9 @@ int sof_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_l { struct mc_private *ctx = snd_soc_card_get_drvdata(card); + if (!ctx->headset_codec_dev) + return 0; + device_remove_software_node(ctx->headset_codec_dev); put_device(ctx->headset_codec_dev); diff --git a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c index b3fc32bacfa8..7f16304d025b 100644 --- a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c +++ b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c @@ -140,6 +140,9 @@ int sof_sdw_rt711_sdca_exit(struct snd_soc_card *card, struct snd_soc_dai_link * { struct mc_private *ctx = snd_soc_card_get_drvdata(card); + if (!ctx->headset_codec_dev) + return 0; + device_remove_software_node(ctx->headset_codec_dev); put_device(ctx->headset_codec_dev); From 8d38cc2997c55a877dac2672a92f221fe59e4c9e Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 15 Jul 2022 09:41:42 -0500 Subject: [PATCH 2/4] ASoC: Intel: soc-acpi: add table for HP Omen 16-k0005TX This device has an RT711-SDCA headset codec on link0 and an RT1316 amplifier on link3. BugLink: https://github.com/thesofproject/sof/issues/5955 Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220715144144.274770-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- .../intel/common/soc-acpi-intel-adl-match.c | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) 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 fea087d3fa15..6957d801f241 100644 --- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c @@ -137,6 +137,15 @@ static const struct snd_soc_acpi_adr_device rt1316_2_single_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1316_3_single_adr[] = { + { + .adr = 0x000330025D131601ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt1316-1" + } +}; + static const struct snd_soc_acpi_adr_device rt714_0_adr[] = { { .adr = 0x000030025D071401ull, @@ -326,6 +335,20 @@ static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link2_rt714_link0[] = { {} }; +static const struct snd_soc_acpi_link_adr adl_sdw_rt711_link0_rt1316_link3[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_sdca_0_adr), + .adr_d = rt711_sdca_0_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt1316_3_single_adr), + .adr_d = rt1316_3_single_adr, + }, + {} +}; + static const struct snd_soc_acpi_adr_device mx8373_2_adr[] = { { .adr = 0x000223019F837300ull, @@ -546,6 +569,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-adl-rt1316-l2-mono-rt714-l0.tplg", }, + { + .link_mask = 0x9, /* 2 active links required */ + .links = adl_sdw_rt711_link0_rt1316_link3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-adl-rt711-l0-rt1316-l3.tplg", + }, { .link_mask = 0x1, /* link0 required */ .links = adl_rvp, From f7bbdf5bcc6ec66efa010aed77eaf5a90faf6ba5 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 15 Jul 2022 09:41:43 -0500 Subject: [PATCH 3/4] ASoC: Intel: sof_sdw: add quirk for HP Omen 16-k0005TX The JD2 jack detection was selected based on similar settings from other platforms based on RT711-SDCA. BugLink: https://github.com/thesofproject/sof/issues/5955 Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220715144144.274770-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 0c47d76a79e2..12f243ef04bf 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -315,6 +315,15 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { RT711_JD2 | SOF_SDW_FOUR_SPK), }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16-k0xxx"), + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + RT711_JD2), + }, /* MeteorLake devices */ { .callback = sof_sdw_quirk_cb, From ba4c6a1a8f1b3a178a67fd3ceffa876971a5789f Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 15 Jul 2022 09:41:44 -0500 Subject: [PATCH 4/4] ASoC: SOF: Intel: enable dmic handling with 2 or fewer SoundWire links When PCH-attached DMICs are used on a SoundWire-based platform, all known devices pin-mux SoundWire link2 and link3 with DMIC, and only use link0 and link1 for SoundWire. The HP Omen16 is the first exception to the rule, with SoundWire using link0 and link3. Rather than using a fixed mask, let's count the number of SoundWire links used. BugLink: https://github.com/thesofproject/sof/issues/5966 Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220715144144.274770-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index b7fa95ea1090..be3c4f1d8ff5 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -1406,12 +1406,12 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev /* * DMICs use up to 4 pins and are typically pin-muxed with SoundWire - * link 2 and 3, thus we only try to enable dmics if all conditions - * are true: - * a) link 2 and 3 are not used by SoundWire + * link 2 and 3, or link 1 and 2, thus we only try to enable dmics + * if all conditions are true: + * a) 2 or fewer links are used by SoundWire * b) the NHLT table reports the presence of microphones */ - if (!(mach->link_mask & GENMASK(3, 2))) { + if (hweight_long(mach->link_mask) <= 2) { const char *tplg_filename = mach->sof_tplg_filename; int ret;