From: Richard Fitzgerald <rf@opensource.cirrus.com>
To: Khalil <khalilst@gmail.com>,
broonie@kernel.org, hdegoede@kernel.org,
ilpo.jarvinen@linux.intel.com
Cc: linux-spi@vger.kernel.org, platform-driver-x86@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH 1/2] platform/x86: serial-multi-instantiate: Add GPIO chip select support for SPI devices
Date: Mon, 23 Feb 2026 15:50:25 +0000 [thread overview]
Message-ID: <16fc29fb-f6e7-4d64-91cd-419bb7d42c2d@opensource.cirrus.com> (raw)
In-Reply-To: <20260215135524.1171065-2-khalil@rentman.nl>
On 15/02/2026 1:55 pm, Khalil wrote:
> To: broonie@kernel.org, hdegoede@kernel.org, ilpo.jarvinen@linux.intel.com
> Cc: rf@opensource.cirrus.com, linux-spi@vger.kernel.org,
> platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org
>
> Some ACPI platforms (e.g., HP/ASUS laptops with Intel Lunar Lake and
> dual CS35L56 amplifiers) have a broken cs-gpios property in the SPI
The only Asus model we are aware of with CS35L56 and a cs-gpios problem
is the GU605C. That was fixed by a BIOS update so doesn't need a kernel
workaround. Is this the Asus you are referring to? Or is there another?
> controller's _DSD that only declares the first chip select. The second
> chip select GPIO is defined as a GpioIo resource in the peripheral's
Maybe the second. Maybe the first. It depends on the hardware.
Some laptops have four amps and four chip selects.
> ACPI node but is not referenced by the controller.
>
> This causes the SPI framework to have no GPIO descriptor for CS > 0,
> so the chip select line is never toggled for the second device.
>
It fails before that matters. The driver for that device will never be
probed because SPI core rejects the invalid chip select.
> Fix this by acquiring the chip select GPIO from the ACPI GpioIo resource
> in serial-multi-instantiate and installing it on the controller's
> cs_gpiods array. The GPIO must be set on the controller (not the device)
> because __spi_add_device() unconditionally overwrites spi->cs_gpiod[]
> from ctlr->cs_gpiods[cs].
If you change __spi_add_device() so it doesn't overwrite preset cs_gpiod
you could set it on the device. You wouldn't have to mess around with
the controller configuration after the controller has probed.
Alternatively, if you can make the amp driver probe, it can fix itself
up like the cs35l41_hda driver does. Maybe you can use this
special case in the SPI core:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/spi/spi.c?h=linux-6.19.y#n616
...
> +/*
> + * ACPI GPIO mapping for the chip select GpioIo resource.
> + * Maps "cs-gpios" to the first GpioIo resource in the ACPI _CRS.
> + */
> +static const struct acpi_gpio_params smi_cs_gpio_params = { 0, 0, false };
> +
> +static const struct acpi_gpio_mapping smi_cs_gpio_mapping[] = {
> + { "cs-gpios", &smi_cs_gpio_params, 1 },
> + { }
> +};
> +
> #define IRQ_RESOURCE_TYPE GENMASK(1, 0)
> #define IRQ_RESOURCE_NONE 0
> #define IRQ_RESOURCE_GPIO 1
> @@ -114,8 +128,11 @@
> struct acpi_device *adev = ACPI_COMPANION(dev);
> struct spi_controller *ctlr;
> struct spi_device *spi_dev;
> + struct gpio_desc *cs_gpio = NULL;
> char name[50];
> int i, ret, count;
> + bool gpio_mapped = false;
> + u16 cs;
>
> ret = acpi_spi_count_resources(adev);
> if (ret < 0)
> @@ -139,6 +156,72 @@
> }
>
> ctlr = spi_dev->controller;
> + cs = spi_get_chipselect(spi_dev, 0);
> +
> + if (cs >= ctlr->num_chipselect) {
> + dev_info(dev, "Increasing num_chipselect from %u to %u for CS%u\n",
> + ctlr->num_chipselect, cs + 1, cs);
> + ctlr->num_chipselect = cs + 1;
> + }
> +
> + /*
> + * For devices with CS > 0, use GPIO chip select from ACPI
> + * GpioIo resource. The GPIO must be set on the controller's
> + * cs_gpiods array (not the device's cs_gpiod) because
> + * __spi_add_device() overwrites spi->cs_gpiod from
> + * ctlr->cs_gpiods[cs]. Also reallocate the array since
> + * a broken ACPI cs-gpios property may have undersized it.
> + *
> + * SPI_CONTROLLER_GPIO_SS ensures the framework calls both
> + * the GPIO toggle and controller->set_cs (for clock gate
> + * management on Intel LPSS controllers).
> + */
Only do this fixup for models where you know what the cs-gpios mappings
should be.
> + if (cs > 0 && !gpio_mapped) {
> + ret = devm_acpi_dev_add_driver_gpios(dev, smi_cs_gpio_mapping);
> + if (ret)
> + dev_warn(dev, "Failed to add GPIO mapping: %d\n", ret);
> + else
> + gpio_mapped = true;
> + }
> +
> + if (cs > 0 && gpio_mapped && !cs_gpio) {
> + cs_gpio = devm_gpiod_get(dev, "cs", GPIOD_OUT_HIGH);
> + if (IS_ERR(cs_gpio)) {
> + dev_warn(dev, "Failed to get CS GPIO: %ld\n",
> + PTR_ERR(cs_gpio));
> + cs_gpio = NULL;
> + } else {
> + dev_info(dev, "Got CS GPIO for amp CS%u\n", cs);
> + }
> + }
> +
> + if (cs > 0 && cs_gpio) {
> + /*
> + * Set GPIO on the controller's cs_gpiods array so
> + * __spi_add_device() will propagate it to the device.
> + * Reallocate the array to fit the new num_chipselect.
> + */
> + struct gpio_desc **new_gpiods;
> +
> + new_gpiods = devm_kcalloc(&ctlr->dev,
> + ctlr->num_chipselect,
> + sizeof(*new_gpiods),
> + GFP_KERNEL);
> + if (new_gpiods) {
> + if (ctlr->cs_gpiods)
> + new_gpiods[0] = ctlr->cs_gpiods[0];
> + new_gpiods[cs] = cs_gpio;
> + ctlr->cs_gpiods = new_gpiods;
> + ctlr->flags |= SPI_CONTROLLER_GPIO_SS;
Messing with the configuration of a probed SPI controller seems risky.
next prev parent reply other threads:[~2026-02-23 15:50 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-15 13:55 [RFC PATCH 0/2] Fix second CS35L56 amplifier on Intel LPSS SPI with broken ACPI cs-gpios Khalil
2026-02-15 13:55 ` [RFC PATCH 1/2] platform/x86: serial-multi-instantiate: Add GPIO chip select support for SPI devices Khalil
2026-02-23 15:50 ` Richard Fitzgerald [this message]
2026-04-11 18:04 ` [PATCH v2 0/3] Fix CS35L56 amplifier on Intel LPSS SPI with broken ACPI cs-gpios Khalil
2026-04-11 18:04 ` [PATCH 1/3] spi: Preserve preset cs_gpiod in __spi_add_device() Khalil
2026-04-11 18:04 ` [PATCH 2/3] platform/x86: serial-multi-instantiate: Fix SPI chip select on platforms with incomplete ACPI cs-gpios Khalil
2026-04-11 18:04 ` [PATCH 3/3] spi: pxa2xx: Handle clock gating for GPIO chip select devices Khalil
2026-04-11 21:57 ` [PATCH v2 0/3] Fix CS35L56 amplifier on Intel LPSS SPI with broken ACPI cs-gpios Mark Brown
2026-04-13 8:48 ` Richard Fitzgerald
2026-04-13 9:02 ` Richard Fitzgerald
2026-04-12 16:31 ` Khalil
2026-04-12 16:31 ` [PATCH 1/3] spi: Preserve preset cs_gpiod in __spi_add_device() Khalil
2026-04-12 16:31 ` [PATCH 2/3] platform/x86: serial-multi-instantiate: Fix SPI chip select on platforms with incomplete ACPI cs-gpios Khalil
2026-04-12 16:31 ` [PATCH 3/3] spi: pxa2xx: Handle clock gating for GPIO chip select devices Khalil
2026-02-15 13:55 ` [RFC PATCH 2/2] spi: pxa2xx: Handle dynamic " Khalil
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=16fc29fb-f6e7-4d64-91cd-419bb7d42c2d@opensource.cirrus.com \
--to=rf@opensource.cirrus.com \
--cc=broonie@kernel.org \
--cc=hdegoede@kernel.org \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=khalilst@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-spi@vger.kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox