* [PATCH v2] spi: cs42l43: Workaround for wrong speaker ID on Dell XPS 13 DX13260
@ 2026-10-01 8:58 Richard Fitzgerald
2026-10-01 10:17 ` Charles Keepax
0 siblings, 1 reply; 2+ messages in thread
From: Richard Fitzgerald @ 2026-10-01 8:58 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-spi, linux-kernel, patches
On Dell XPS 13 DX13260 create an acpi_gpio_mapping with exactly two
GPIO entries to point at the two pins in the GpioIo(). Use this to
read the speaker ID GPIOs.
This fixes problems on Dell XPS 13 DX13260:
- No speaker audio
- The wrong firmware was loaded so the speaker protection did not match
the speaker characteristics.
The Dell XPS 13 DX13260 has two speaker ID GPIOs, to form a 2-bit ID. The
ACPI GpioIo() has both pins but the Linux-specific spk-id-gpios property
only has a mapping to the first pin. This meant that the speaker ID was
wrong in most cases, and that would lead to the codec driver loading the
wrong amp firmware, or not finding a firmware (as 0 is not a valid ID on
this laptop).
Assisted-by: Codex:gpt-6-sol
Reported-by: Wiza Jalakasi <wjalakasi@gmail.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221956
Tested-by: Wiza Jalakasi <wjalakasi@gmail.com>
Fixes: f3c605147741e ("spi: cs42l43: Add GPIO speaker id support to the bridge configuration")
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
Changes in V2:
- Rewritten to be a DMI-specific quirk. We need to leave the original
GPIO code in place to support a proposed ACPI change for future
products.
- As it's now a quirk for the specific model it is hardcoded to be
two GPIOs.
drivers/spi/spi-cs42l43.c | 97 +++++++++++++++++++++++++++++++++++++++
1 file changed, 97 insertions(+)
diff --git a/drivers/spi/spi-cs42l43.c b/drivers/spi/spi-cs42l43.c
index 7106a8a4f2805..6772abb483dd3 100644
--- a/drivers/spi/spi-cs42l43.c
+++ b/drivers/spi/spi-cs42l43.c
@@ -11,6 +11,7 @@
#include <linux/bitfield.h>
#include <linux/cleanup.h>
#include <linux/device.h>
+#include <linux/dmi.h>
#include <linux/errno.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
@@ -215,12 +216,108 @@ static size_t cs42l43_spi_max_length(struct spi_device *spi)
return CS42L43_SPI_MAX_LENGTH;
}
+/*
+ * Workaround needed for two speaker ID pins in one ACPI GpioIo() but
+ * the Linux-specific _DSD property only contains one pin.
+ * Create a temporary acpi_gpio_mapping pointing at both pins.
+ */
+static const struct acpi_gpio_params cs42l43_2bit_speaker_id_from_one_gpioio_params[] = {
+ [0] = {
+ .crs_entry_index = 0,
+ .line_index = 0,
+ },
+ [1] = {
+ .crs_entry_index = 0,
+ .line_index = 1,
+ },
+};
+
+static const struct acpi_gpio_mapping cs42l43_2bit_speaker_id_from_one_gpioio_mapping[] = {
+ {
+ .name = "spk-id-quirk-gpios",
+ .data = cs42l43_2bit_speaker_id_from_one_gpioio_params,
+ .size = ARRAY_SIZE(cs42l43_2bit_speaker_id_from_one_gpioio_params),
+ },
+ { }
+};
+
+static int cs42l43_get_2bit_speaker_id_from_one_gpioio(struct cs42l43_spi *priv, int *result)
+{
+ struct fwnode_reference_args args;
+ struct acpi_device *adev;
+ struct gpio_desc *desc;
+ u32 spkid = 0;
+ int i, ret;
+
+ /* Use the _DSD property to get the node containing the GpioIo() */
+ ret = fwnode_property_get_reference_args(dev_fwnode(priv->dev), "spk-id-gpios",
+ NULL, 3, 0, &args);
+ if (ret)
+ return ret;
+
+ struct fwnode_handle *fwnode __free(fwnode_handle) = args.fwnode;
+
+ /* An acpi_gpio_mapping must be added to the node that contains the GpioIo() */
+ adev = to_acpi_device_node(fwnode);
+ if (!adev)
+ return -EINVAL;
+
+ ret = acpi_dev_add_driver_gpios(adev, cs42l43_2bit_speaker_id_from_one_gpioio_mapping);
+ if (ret)
+ return ret;
+
+ /* gpiod_get_array() can't read from a mapping in a child node */
+ for (i = 0; i < ARRAY_SIZE(cs42l43_2bit_speaker_id_from_one_gpioio_params); i++) {
+ desc = fwnode_gpiod_get_index(fwnode, "spk-id-quirk", i, GPIOD_IN,
+ dev_name(priv->dev));
+ if (IS_ERR(desc)) {
+ ret = PTR_ERR(desc);
+ goto out;
+ }
+
+ ret = gpiod_get_value_cansleep(desc);
+ gpiod_put(desc);
+ if (ret < 0)
+ goto out;
+
+ spkid |= (u32)ret << i;
+ }
+
+ dev_dbg(priv->dev, "spk-id-gpios = %u\n", spkid);
+ *result = spkid;
+ ret = 0;
+out:
+ acpi_dev_remove_driver_gpios(adev);
+
+ return ret;
+}
+
+static const struct dmi_system_id cs42l43_spk_id_quirks[] = {
+ {
+ .ident = "Dell XPS 13 DX13260",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0E53"),
+ },
+ .driver_data = cs42l43_get_2bit_speaker_id_from_one_gpioio,
+ },
+ { }
+};
+
static int cs42l43_get_speaker_id_gpios(struct cs42l43_spi *priv, int *result)
{
+ const struct dmi_system_id *dmi_id;
struct gpio_descs *descs;
u32 spkid;
int i, ret;
+ dmi_id = dmi_first_match(cs42l43_spk_id_quirks);
+ if (dmi_id) {
+ int (*get_speaker_id)(struct cs42l43_spi *priv, int *result) = dmi_id->driver_data;
+
+ return get_speaker_id(priv, result);
+ }
+
descs = gpiod_get_array_optional(priv->dev, "spk-id", GPIOD_IN);
if (!descs)
return 0;
--
2.47.3
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH v2] spi: cs42l43: Workaround for wrong speaker ID on Dell XPS 13 DX13260
2026-10-01 8:58 [PATCH v2] spi: cs42l43: Workaround for wrong speaker ID on Dell XPS 13 DX13260 Richard Fitzgerald
@ 2026-10-01 10:17 ` Charles Keepax
0 siblings, 0 replies; 2+ messages in thread
From: Charles Keepax @ 2026-10-01 10:17 UTC (permalink / raw)
To: Richard Fitzgerald; +Cc: broonie, linux-sound, linux-spi, linux-kernel, patches
On Thu, Oct 01, 2026 at 09:58:30AM +0100, Richard Fitzgerald wrote:
> On Dell XPS 13 DX13260 create an acpi_gpio_mapping with exactly two
> GPIO entries to point at the two pins in the GpioIo(). Use this to
> read the speaker ID GPIOs.
>
> This fixes problems on Dell XPS 13 DX13260:
>
> - No speaker audio
> - The wrong firmware was loaded so the speaker protection did not match
> the speaker characteristics.
>
> The Dell XPS 13 DX13260 has two speaker ID GPIOs, to form a 2-bit ID. The
> ACPI GpioIo() has both pins but the Linux-specific spk-id-gpios property
> only has a mapping to the first pin. This meant that the speaker ID was
> wrong in most cases, and that would lead to the codec driver loading the
> wrong amp firmware, or not finding a firmware (as 0 is not a valid ID on
> this laptop).
>
> Assisted-by: Codex:gpt-6-sol
> Reported-by: Wiza Jalakasi <wjalakasi@gmail.com>
> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221956
> Tested-by: Wiza Jalakasi <wjalakasi@gmail.com>
> Fixes: f3c605147741e ("spi: cs42l43: Add GPIO speaker id support to the bridge configuration")
> Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
> ---
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Thanks,
Charles
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-01 10:17 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-01 8:58 [PATCH v2] spi: cs42l43: Workaround for wrong speaker ID on Dell XPS 13 DX13260 Richard Fitzgerald
2026-10-01 10:17 ` Charles Keepax
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®