Skip to content

Commit

Permalink
ALSA: hda: cs35l41: Ensure firmware/tuning pairs are always loaded
Browse files Browse the repository at this point in the history
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 <sbinding@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230213145008.1215849-3-sbinding@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Stefan Binding authored and Takashi Iwai committed Feb 14, 2023
1 parent 943f4e6 commit cd40dad
Showing 1 changed file with 51 additions and 52 deletions.
103 changes: 51 additions & 52 deletions sound/pci/hda/cs35l41_hda.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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 */
Expand All @@ -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 */
Expand All @@ -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;
}

Expand All @@ -258,20 +243,24 @@ 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,
CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id,
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 */
Expand All @@ -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;
}

Expand Down

0 comments on commit cd40dad

Please sign in to comment.