2024-04-29 15:49:39

by Stefan Binding

[permalink] [raw]
Subject: [PATCH v1 0/2] ALSA: hda: cs35l41: Ignore errors when configuring interrupts to allow laptops with bad ACPI to play audio

Some laptops have a bad _CRS defined for its interrupt.
This errors out inside the driver probe for CS35L41 HDA.
However, there is no fix in software for this bad configuration,
and it is unlikely to get a new BIOS, therefore it is better to
allow the laptop to continue probe, instead of erroring out inside
the probe. The interrupt is only used for Error Detection and
recovery, without the interrupt the driver will continue to function,
but errors will not be detected, and recovery will require a reboot.

Also add support for ASUS ROG 2024 laptops.
These laptops were released without _DSD, so need to be added into
the CS35L41 config table. Quirks for these laptops already exist.

Stefan Binding (2):
ALSA: hda: cs35l41: Ignore errors when configuring IRQs
ALSA: hda: cs35l41: Add support for ASUS ROG 2024 Laptops

sound/pci/hda/cs35l41_hda.c | 69 +++++++++++++++++++---------
sound/pci/hda/cs35l41_hda_property.c | 10 ++++
2 files changed, 57 insertions(+), 22 deletions(-)

--
2.34.1



2024-04-29 15:49:43

by Stefan Binding

[permalink] [raw]
Subject: [PATCH v1 2/2] ALSA: hda: cs35l41: Add support for ASUS ROG 2024 Laptops

All of these laptops do not have _DSD, so need to be added to the
configuration table.

Signed-off-by: Stefan Binding <[email protected]>
---
sound/pci/hda/cs35l41_hda_property.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/sound/pci/hda/cs35l41_hda_property.c b/sound/pci/hda/cs35l41_hda_property.c
index be97e973accb..ad9b6abdf269 100644
--- a/sound/pci/hda/cs35l41_hda_property.c
+++ b/sound/pci/hda/cs35l41_hda_property.c
@@ -97,6 +97,7 @@ static const struct cs35l41_config cs35l41_config_table[] = {
{ "10431863", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "104318D3", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{ "10431A83", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
+ { "10431B93", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431C9F", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431CAF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431CCF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
@@ -110,6 +111,10 @@ static const struct cs35l41_config cs35l41_config_table[] = {
{ "10431F12", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431F1F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
{ "10431F62", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
+ { "10433A20", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
+ { "10433A30", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
+ { "10433A40", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
+ { "10433A50", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10433A60", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "17AA3865", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
{ "17AA3866", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
@@ -492,6 +497,7 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CSC3551", "10431863", generic_dsd_config },
{ "CSC3551", "104318D3", generic_dsd_config },
{ "CSC3551", "10431A83", generic_dsd_config },
+ { "CSC3551", "10431B93", generic_dsd_config },
{ "CSC3551", "10431C9F", generic_dsd_config },
{ "CSC3551", "10431CAF", generic_dsd_config },
{ "CSC3551", "10431CCF", generic_dsd_config },
@@ -505,6 +511,10 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CSC3551", "10431F12", generic_dsd_config },
{ "CSC3551", "10431F1F", generic_dsd_config },
{ "CSC3551", "10431F62", generic_dsd_config },
+ { "CSC3551", "10433A20", generic_dsd_config },
+ { "CSC3551", "10433A30", generic_dsd_config },
+ { "CSC3551", "10433A40", generic_dsd_config },
+ { "CSC3551", "10433A50", generic_dsd_config },
{ "CSC3551", "10433A60", generic_dsd_config },
{ "CSC3551", "17AA3865", generic_dsd_config },
{ "CSC3551", "17AA3866", generic_dsd_config },
--
2.34.1


2024-04-29 15:49:54

by Stefan Binding

[permalink] [raw]
Subject: [PATCH v1 1/2] ALSA: hda: cs35l41: Ignore errors when configuring IRQs

IRQs used for CS35L41 HDA are used to detect and attempt to recover
from errors. Without these interrupts, the driver should behave as
normal.

For laptops which contain a bad configuration for the interrupt in the
BIOS, the current behaviour of failing when trying to configure the
interrupt means the probe fails, and audio is broken.

It is better for the user experience if the driver instead warns that
no interrupt is configured rather than simply failing.
The drawback is that if an error occurs without the interrupt, we
firstly would not be able to trace the issue, and secondly would not
be able to attempt to recover from the issue, but this is better than
failing immediately.

Signed-off-by: Stefan Binding <[email protected]>
---
sound/pci/hda/cs35l41_hda.c | 69 +++++++++++++++++++++++++------------
1 file changed, 47 insertions(+), 22 deletions(-)

diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c
index 74076fa45dd6..6c49e5c6cd20 100644
--- a/sound/pci/hda/cs35l41_hda.c
+++ b/sound/pci/hda/cs35l41_hda.c
@@ -1594,13 +1594,56 @@ static struct regmap_irq_chip cs35l41_regmap_irq_chip = {
.runtime_pm = true,
};

+static void cs35l41_configure_interrupt(struct cs35l41_hda *cs35l41, int irq_pol)
+{
+ int irq;
+ int ret;
+ int i;
+
+ if (!cs35l41->irq) {
+ dev_warn(cs35l41->dev, "No Interrupt Found");
+ goto err;
+ }
+
+ ret = devm_regmap_add_irq_chip(cs35l41->dev, cs35l41->regmap, cs35l41->irq,
+ IRQF_ONESHOT | IRQF_SHARED | irq_pol,
+ 0, &cs35l41_regmap_irq_chip, &cs35l41->irq_data);
+ if (ret) {
+ dev_dbg(cs35l41->dev, "Unable to add IRQ Chip: %d.", ret);
+ goto err;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(cs35l41_irqs); i++) {
+ irq = regmap_irq_get_virq(cs35l41->irq_data, cs35l41_irqs[i].irq);
+ if (irq < 0) {
+ ret = irq;
+ dev_dbg(cs35l41->dev, "Unable to map IRQ %s: %d.", cs35l41_irqs[i].name,
+ ret);
+ goto err;
+ }
+
+ ret = devm_request_threaded_irq(cs35l41->dev, irq, NULL,
+ cs35l41_irqs[i].handler,
+ IRQF_ONESHOT | IRQF_SHARED | irq_pol,
+ cs35l41_irqs[i].name, cs35l41);
+ if (ret) {
+ dev_dbg(cs35l41->dev, "Unable to allocate IRQ %s:: %d.",
+ cs35l41_irqs[i].name, ret);
+ goto err;
+ }
+ }
+ return;
+err:
+ dev_warn(cs35l41->dev,
+ "IRQ Config Failed. Amp errors may not be recoverable without reboot.");
+}
+
static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41)
{
struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
bool using_irq = false;
- int irq, irq_pol;
+ int irq_pol;
int ret;
- int i;

if (!cs35l41->hw_cfg.valid)
return -EINVAL;
@@ -1643,26 +1686,8 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41)

irq_pol = cs35l41_gpio_config(cs35l41->regmap, hw_cfg);

- if (cs35l41->irq && using_irq) {
- ret = devm_regmap_add_irq_chip(cs35l41->dev, cs35l41->regmap, cs35l41->irq,
- IRQF_ONESHOT | IRQF_SHARED | irq_pol,
- 0, &cs35l41_regmap_irq_chip, &cs35l41->irq_data);
- if (ret)
- return ret;
-
- for (i = 0; i < ARRAY_SIZE(cs35l41_irqs); i++) {
- irq = regmap_irq_get_virq(cs35l41->irq_data, cs35l41_irqs[i].irq);
- if (irq < 0)
- return irq;
-
- ret = devm_request_threaded_irq(cs35l41->dev, irq, NULL,
- cs35l41_irqs[i].handler,
- IRQF_ONESHOT | IRQF_SHARED | irq_pol,
- cs35l41_irqs[i].name, cs35l41);
- if (ret)
- return ret;
- }
- }
+ if (using_irq)
+ cs35l41_configure_interrupt(cs35l41, irq_pol);

return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos);
}
--
2.34.1


2024-04-30 07:30:46

by Takashi Iwai

[permalink] [raw]
Subject: Re: [PATCH v1 0/2] ALSA: hda: cs35l41: Ignore errors when configuring interrupts to allow laptops with bad ACPI to play audio

On Mon, 29 Apr 2024 17:48:51 +0200,
Stefan Binding wrote:
>
> Some laptops have a bad _CRS defined for its interrupt.
> This errors out inside the driver probe for CS35L41 HDA.
> However, there is no fix in software for this bad configuration,
> and it is unlikely to get a new BIOS, therefore it is better to
> allow the laptop to continue probe, instead of erroring out inside
> the probe. The interrupt is only used for Error Detection and
> recovery, without the interrupt the driver will continue to function,
> but errors will not be detected, and recovery will require a reboot.
>
> Also add support for ASUS ROG 2024 laptops.
> These laptops were released without _DSD, so need to be added into
> the CS35L41 config table. Quirks for these laptops already exist.
>
> Stefan Binding (2):
> ALSA: hda: cs35l41: Ignore errors when configuring IRQs
> ALSA: hda: cs35l41: Add support for ASUS ROG 2024 Laptops

Thanks, applied both patches to for-next branch now.


Takashi