2023-02-13 14:50:37

by Stefan Binding

[permalink] [raw]
Subject: [PATCH v2 0/3] Fixes and Improvements for CS35L41 HDA

Fixes issue in calibration, where return codes were misinterpreted.
Enable High Pass filter to reduce pops and clicks.
Add improvement to ensure firmware and tuning files are always loaded
together. This ensure the firmware is alsways running with valid
coefficients.

Stefan Binding (2):
ALSA: hda: cs35l41: Ensure firmware/tuning pairs are always loaded
ALSA: hda: cs35l41: Enable Amp High Pass Filter

Vitaly Rodionov (1):
ALSA: hda: cs35l41: Correct error condition handling

sound/pci/hda/cs35l41_hda.c | 109 ++++++++++++++++-----------------
sound/pci/hda/hda_cs_dsp_ctl.c | 4 +-
2 files changed, 56 insertions(+), 57 deletions(-)

--
2.34.1



2023-02-13 14:50:40

by Stefan Binding

[permalink] [raw]
Subject: [PATCH v2 2/3] ALSA: hda: cs35l41: Ensure firmware/tuning pairs are always loaded

To ensure firmware for cs35l41 is correctly running, it is necessary
that a corresponding tuning file is also loaded. Without both,
the firmware may not be performing correctly
Ensure that if we load the firmware, we have also loaded the correct
tuning file. Otherwise, fall back to default firmware and tuning.
If default tuning is also missing, then disable DSP firmware.

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

diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c
index f7815ee24f83..1aad2604b9db 100644
--- a/sound/pci/hda/cs35l41_hda.c
+++ b/sound/pci/hda/cs35l41_hda.c
@@ -178,11 +178,10 @@ static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41,
cs35l41->speaker_id, "wmfw");
if (!ret) {
/* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */
- cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT,
- cs35l41->acpi_subsystem_id, cs35l41->amp_name,
- cs35l41->speaker_id, "bin");
- return 0;
+ return cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
+ CS35L41_FIRMWARE_ROOT,
+ cs35l41->acpi_subsystem_id, cs35l41->amp_name,
+ cs35l41->speaker_id, "bin");
}

/* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */
@@ -191,10 +190,10 @@ static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41,
cs35l41->amp_name, -1, "wmfw");
if (!ret) {
/* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */
- cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id,
- cs35l41->amp_name, cs35l41->speaker_id, "bin");
- return 0;
+ return cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
+ CS35L41_FIRMWARE_ROOT,
+ cs35l41->acpi_subsystem_id, cs35l41->amp_name,
+ cs35l41->speaker_id, "bin");
}

/* try cirrus/part-dspN-fwtype-sub<-spkidN>.wmfw */
@@ -209,11 +208,10 @@ static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41,
cs35l41->amp_name, cs35l41->speaker_id, "bin");
if (ret)
/* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */
- cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT,
- cs35l41->acpi_subsystem_id,
- NULL, cs35l41->speaker_id, "bin");
- return 0;
+ return cs35l41_request_firmware_file(cs35l41, coeff_firmware,
+ coeff_filename, CS35L41_FIRMWARE_ROOT,
+ cs35l41->acpi_subsystem_id, NULL,
+ cs35l41->speaker_id, "bin");
}

/* try cirrus/part-dspN-fwtype-sub.wmfw */
@@ -224,29 +222,16 @@ static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41,
/* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
CS35L41_FIRMWARE_ROOT,
- cs35l41->acpi_subsystem_id,
- cs35l41->amp_name, cs35l41->speaker_id, "bin");
+ cs35l41->acpi_subsystem_id, cs35l41->amp_name,
+ cs35l41->speaker_id, "bin");
if (ret)
/* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */
- cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT,
- cs35l41->acpi_subsystem_id,
- NULL, cs35l41->speaker_id, "bin");
- return 0;
- }
-
- /* fallback try cirrus/part-dspN-fwtype.wmfw */
- ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
- CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "wmfw");
- if (!ret) {
- /* fallback try cirrus/part-dspN-fwtype.bin */
- cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "bin");
- return 0;
+ return cs35l41_request_firmware_file(cs35l41, coeff_firmware,
+ coeff_filename, CS35L41_FIRMWARE_ROOT,
+ cs35l41->acpi_subsystem_id, NULL,
+ cs35l41->speaker_id, "bin");
}

- dev_warn(cs35l41->dev, "Failed to request firmware\n");
-
return ret;
}

@@ -258,9 +243,12 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41,
{
int ret;

- if (cs35l41->speaker_id > -1)
- return cs35l41_request_firmware_files_spkid(cs35l41, wmfw_firmware, wmfw_filename,
- coeff_firmware, coeff_filename);
+ if (cs35l41->speaker_id > -1) {
+ ret = cs35l41_request_firmware_files_spkid(cs35l41, wmfw_firmware, wmfw_filename,
+ coeff_firmware, coeff_filename);
+ goto out;
+
+ }

/* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */
ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
@@ -268,10 +256,11 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41,
cs35l41->amp_name, -1, "wmfw");
if (!ret) {
/* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */
- cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id,
- cs35l41->amp_name, -1, "bin");
- return 0;
+ ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
+ CS35L41_FIRMWARE_ROOT,
+ cs35l41->acpi_subsystem_id, cs35l41->amp_name,
+ -1, "bin");
+ goto out;
}

/* try cirrus/part-dspN-fwtype-sub.wmfw */
@@ -286,25 +275,35 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41,
cs35l41->amp_name, -1, "bin");
if (ret)
/* try cirrus/part-dspN-fwtype-sub.bin */
- cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT,
- cs35l41->acpi_subsystem_id,
- NULL, -1, "bin");
- return 0;
+ ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
+ CS35L41_FIRMWARE_ROOT,
+ cs35l41->acpi_subsystem_id, NULL, -1,
+ "bin");
}

+out:
+ if (!ret)
+ return 0;
+
+ /* Handle fallback */
+ dev_warn(cs35l41->dev, "Falling back to default firmware.\n");
+
+ release_firmware(*wmfw_firmware);
+ kfree(*wmfw_filename);
+
/* fallback try cirrus/part-dspN-fwtype.wmfw */
ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "wmfw");
- if (!ret) {
+ if (!ret)
/* fallback try cirrus/part-dspN-fwtype.bin */
- cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "bin");
- return 0;
- }
-
- dev_warn(cs35l41->dev, "Failed to request firmware\n");
+ ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
+ CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "bin");

+ if (ret) {
+ release_firmware(*wmfw_firmware);
+ kfree(*wmfw_filename);
+ dev_warn(cs35l41->dev, "Unable to find firmware and tuning\n");
+ }
return ret;
}

--
2.34.1


2023-02-13 14:50:42

by Stefan Binding

[permalink] [raw]
Subject: [PATCH v2 1/3] ALSA: hda: cs35l41: Correct error condition handling

From: Vitaly Rodionov <[email protected]>

Function cs_dsp_coeff_write_ctrl() can return 3 possible values:
0 - no change, 1 - value has changed and -1 - error, so positive value
is not an error.
Fixes: 7406bdbc4fb8 ("ASoC: wm_adsp: Return whether changed when writing controls")

Signed-off-by: Vitaly Rodionov <[email protected]>
Signed-off-by: Stefan Binding <[email protected]>
---
sound/pci/hda/hda_cs_dsp_ctl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c
index 5433f6227ac9..463ca06036bf 100644
--- a/sound/pci/hda/hda_cs_dsp_ctl.c
+++ b/sound/pci/hda/hda_cs_dsp_ctl.c
@@ -218,10 +218,10 @@ int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type,
cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg);
ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, buf, len);
mutex_unlock(&dsp->pwr_lock);
- if (ret)
+ if (ret < 0)
return ret;

- if (cs_ctl->flags & WMFW_CTL_FLAG_SYS)
+ if (ret == 0 || (cs_ctl->flags & WMFW_CTL_FLAG_SYS))
return 0;

ctl = cs_ctl->priv;
--
2.34.1


2023-02-14 14:08:47

by Takashi Iwai

[permalink] [raw]
Subject: Re: [PATCH v2 0/3] Fixes and Improvements for CS35L41 HDA

On Mon, 13 Feb 2023 15:50:05 +0100,
Stefan Binding wrote:
>
> Fixes issue in calibration, where return codes were misinterpreted.
> Enable High Pass filter to reduce pops and clicks.
> Add improvement to ensure firmware and tuning files are always loaded
> together. This ensure the firmware is alsways running with valid
> coefficients.
>
> Stefan Binding (2):
> ALSA: hda: cs35l41: Ensure firmware/tuning pairs are always loaded
> ALSA: hda: cs35l41: Enable Amp High Pass Filter
>
> Vitaly Rodionov (1):
> ALSA: hda: cs35l41: Correct error condition handling

Applied all three patches now to for-next branch.


thanks,

Takashi

2023-02-26 11:17:22

by Richard Fitzgerald

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] ALSA: hda: cs35l41: Correct error condition handling

On 13/2/23 14:50, Stefan Binding wrote:
> From: Vitaly Rodionov <[email protected]>
>
> Function cs_dsp_coeff_write_ctrl() can return 3 possible values:
> 0 - no change, 1 - value has changed and -1 - error, so positive value
> is not an error.
> Fixes: 7406bdbc4fb8 ("ASoC: wm_adsp: Return whether changed when writing controls")
>
> Signed-off-by: Vitaly Rodionov <[email protected]>
> Signed-off-by: Stefan Binding <[email protected]>
> ---
> sound/pci/hda/hda_cs_dsp_ctl.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c
> index 5433f6227ac9..463ca06036bf 100644
> --- a/sound/pci/hda/hda_cs_dsp_ctl.c
> +++ b/sound/pci/hda/hda_cs_dsp_ctl.c
> @@ -218,10 +218,10 @@ int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type,
> cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg);
> ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, buf, len);
> mutex_unlock(&dsp->pwr_lock);
> - if (ret)
> + if (ret < 0)
> return ret;
>
> - if (cs_ctl->flags & WMFW_CTL_FLAG_SYS)
> + if (ret == 0 || (cs_ctl->flags & WMFW_CTL_FLAG_SYS))
> return 0;
>
> ctl = cs_ctl->priv;

Hi Takashi

Could you queue this patch as a bugfix for 6.2 please?
The cs_dsp patch to return 1 for changed has gone into 6.2
but we missed that this hda_cs_dsp code would break.

2023-02-27 23:48:09

by Takashi Iwai

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] ALSA: hda: cs35l41: Correct error condition handling

On Sun, 26 Feb 2023 12:16:43 +0100,
Richard Fitzgerald wrote:
>
> On 13/2/23 14:50, Stefan Binding wrote:
> > From: Vitaly Rodionov <[email protected]>
> >
> > Function cs_dsp_coeff_write_ctrl() can return 3 possible values:
> > 0 - no change, 1 - value has changed and -1 - error, so positive value
> > is not an error.
> > Fixes: 7406bdbc4fb8 ("ASoC: wm_adsp: Return whether changed when writing controls")
> >
> > Signed-off-by: Vitaly Rodionov <[email protected]>
> > Signed-off-by: Stefan Binding <[email protected]>
> > ---
> > sound/pci/hda/hda_cs_dsp_ctl.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c
> > index 5433f6227ac9..463ca06036bf 100644
> > --- a/sound/pci/hda/hda_cs_dsp_ctl.c
> > +++ b/sound/pci/hda/hda_cs_dsp_ctl.c
> > @@ -218,10 +218,10 @@ int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type,
> > cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg);
> > ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, buf, len);
> > mutex_unlock(&dsp->pwr_lock);
> > - if (ret)
> > + if (ret < 0)
> > return ret;
> > - if (cs_ctl->flags & WMFW_CTL_FLAG_SYS)
> > + if (ret == 0 || (cs_ctl->flags & WMFW_CTL_FLAG_SYS))
> > return 0;
> > ctl = cs_ctl->priv;
>
> Hi Takashi
>
> Could you queue this patch as a bugfix for 6.2 please?
> The cs_dsp patch to return 1 for changed has gone into 6.2
> but we missed that this hda_cs_dsp code would break.

Could you just request the cherry-pick of the necessary fix commits
via [email protected] (with Cc to Greg / Sasha)?

I've been still traveling in this week, so it's better for you doing
that by yourself.


thanks,

Takashi