Re: [PATCH v3] ALSA: hda: cs35l41: Enable VSPK on UX3405CA when ACPI leaves GPIO1 unused

From: Stefan Binding

Date: Fri Oct 16 2026 - 12:45:39 EST


I'm not sure why this change is needed?

The issue with this particular laptop is related to missing Calibration, rather 
than any issue in the driver or ACPI.

I don't think disabling VSPK for one of the amps would be required for anything.
By default the GPIOs on both amps will get enabled during playback, which will
in turn enable External Boost on the Amps.

Thanks,

Stefan

On 15/10/2026 23:29, Gemayel Lira wrote:
> The ASUS Zenbook 14 UX3405CA (SSID 1043:1A63) already has a valid _DSD
> and uses missing_speaker_id_gpio2. ACPI sets cirrus,gpio1-func to VSPK
> on the left amplifier and unused on the right, so the right channel
> binds with VSPK: 0 and volume drops shortly after playback starts.
>
> After parsing ACPI, enable VSPK on GPIO1 when it was left unused.
>
> Signed-off-by: Gemayel Lira <gemayellira@xxxxxxxxx>
> ---
> Changes in v3:
> - Rebased onto tiwai/sound for-next. missing_speaker_id_gpio2 is still
> used only by SSID 10431A63, so the GPIO1 change does not touch other
> laptops.
> - No functional change from v2. Still no generic_dsd_config and no
> internal-boost override.
> - Test kernel is now Ubuntu 7.0.0-38-generic. The running proof is the
> out-of-tree module of this hunk (srcversion 955693DEB4FC9A01D9EF0EC):
> both amps VSPK: 1, SPKID: 1, firmware
> spk-prot-10431a63-spkid1-{l,r}0.bin. No PM -110 or SPI -16 with that
> module. One earlier S3 on 7.0.0-27 reloaded both amps with no resume
> error. Not a multi-cycle S3 claim.
>
> v2 discussion:
> Stefan Binding replied that enabling GPIO1 on the second amp should not
> have an effect and asked for a bugzilla:
> https://bugzilla.kernel.org/show_bug.cgi?id=221896
> On 2026-09-25 (comment #15) he wrote that this unit has no
> CirrusSmartAmpCalibrationData EFI variable and that missing calibration
> is not something the driver can supply; contact the laptop vendor.
> This patch does not invent calibration data. It only sets GPIO1 to
> VSPK_SWITCH when ACPI left the function unused, which is what stops the
> right channel binding with VSPK: 0.
>
> v1: Message-ID:
> <CAD96ZT+SnRnGr4Xd+NJkkVNpj8XrzL3Ete=pRgz05mqxAzbU2w@xxxxxxxxxxxxxx>
> v2: Message-ID:
> <CAD96ZTJzEwiNwJm4ujLS4+X_KChi4+_sD0j-m+aE+_9i+eUGcA@xxxxxxxxxxxxxx>
>
> .../hda/codecs/side-codecs/cs35l41_hda_property.c | 15 ++++++++++++++-
> 1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/sound/hda/codecs/side-codecs/cs35l41_hda_property.c
> b/sound/hda/codecs/side-codecs/cs35l41_hda_property.c
> index 272421d1b..002771848 100644
> --- a/sound/hda/codecs/side-codecs/cs35l41_hda_property.c
> +++ b/sound/hda/codecs/side-codecs/cs35l41_hda_property.c
> @@ -479,7 +479,20 @@ static int missing_speaker_id_gpio2(struct
> cs35l41_hda *cs35l41, struct device *
> return ret;
> }
>
> - return cs35l41_hda_parse_acpi(cs35l41, physdev, id);
> + ret = cs35l41_hda_parse_acpi(cs35l41, physdev, id);
> + if (ret)
> + return ret;
> +
> + /*
> + * ACPI on 10431A63 sets gpio1 to VSPK on the left amp and unused
> + * on the right, so the right channel binds with VSPK: 0.
> + */
> + if (cs35l41->hw_cfg.gpio1.func == CS35L41_NOT_USED) {
> + cs35l41->hw_cfg.gpio1.func = CS35l41_VSPK_SWITCH;
> + cs35l41->hw_cfg.gpio1.valid = true;
> + }
> +
> + return 0;
> }
>
> struct cs35l41_prop_model {
>
> base-commit: 7f21312381fee99f58b383fa07374da3c614aec4