mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 06:34:12 +08:00
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 <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>
This commit is contained in:
parent
943f4e64ee
commit
cd40dad2ca
@ -178,11 +178,10 @@ static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41,
|
|||||||
cs35l41->speaker_id, "wmfw");
|
cs35l41->speaker_id, "wmfw");
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
/* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */
|
/* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */
|
||||||
cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
|
return cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
|
||||||
CS35L41_FIRMWARE_ROOT,
|
CS35L41_FIRMWARE_ROOT,
|
||||||
cs35l41->acpi_subsystem_id, cs35l41->amp_name,
|
cs35l41->acpi_subsystem_id, cs35l41->amp_name,
|
||||||
cs35l41->speaker_id, "bin");
|
cs35l41->speaker_id, "bin");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */
|
/* 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");
|
cs35l41->amp_name, -1, "wmfw");
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
/* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */
|
/* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */
|
||||||
cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
|
return cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
|
||||||
CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id,
|
CS35L41_FIRMWARE_ROOT,
|
||||||
cs35l41->amp_name, cs35l41->speaker_id, "bin");
|
cs35l41->acpi_subsystem_id, cs35l41->amp_name,
|
||||||
return 0;
|
cs35l41->speaker_id, "bin");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try cirrus/part-dspN-fwtype-sub<-spkidN>.wmfw */
|
/* 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");
|
cs35l41->amp_name, cs35l41->speaker_id, "bin");
|
||||||
if (ret)
|
if (ret)
|
||||||
/* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */
|
/* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */
|
||||||
cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
|
return cs35l41_request_firmware_file(cs35l41, coeff_firmware,
|
||||||
CS35L41_FIRMWARE_ROOT,
|
coeff_filename, CS35L41_FIRMWARE_ROOT,
|
||||||
cs35l41->acpi_subsystem_id,
|
cs35l41->acpi_subsystem_id, NULL,
|
||||||
NULL, cs35l41->speaker_id, "bin");
|
cs35l41->speaker_id, "bin");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try cirrus/part-dspN-fwtype-sub.wmfw */
|
/* 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 */
|
/* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */
|
||||||
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
|
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
|
||||||
CS35L41_FIRMWARE_ROOT,
|
CS35L41_FIRMWARE_ROOT,
|
||||||
cs35l41->acpi_subsystem_id,
|
cs35l41->acpi_subsystem_id, cs35l41->amp_name,
|
||||||
cs35l41->amp_name, cs35l41->speaker_id, "bin");
|
cs35l41->speaker_id, "bin");
|
||||||
if (ret)
|
if (ret)
|
||||||
/* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */
|
/* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */
|
||||||
cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
|
return cs35l41_request_firmware_file(cs35l41, coeff_firmware,
|
||||||
CS35L41_FIRMWARE_ROOT,
|
coeff_filename, CS35L41_FIRMWARE_ROOT,
|
||||||
cs35l41->acpi_subsystem_id,
|
cs35l41->acpi_subsystem_id, NULL,
|
||||||
NULL, cs35l41->speaker_id, "bin");
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_warn(cs35l41->dev, "Failed to request firmware\n");
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,9 +243,12 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41,
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (cs35l41->speaker_id > -1)
|
if (cs35l41->speaker_id > -1) {
|
||||||
return cs35l41_request_firmware_files_spkid(cs35l41, wmfw_firmware, wmfw_filename,
|
ret = cs35l41_request_firmware_files_spkid(cs35l41, wmfw_firmware, wmfw_filename,
|
||||||
coeff_firmware, coeff_filename);
|
coeff_firmware, coeff_filename);
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */
|
/* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */
|
||||||
ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
|
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");
|
cs35l41->amp_name, -1, "wmfw");
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
/* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */
|
/* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */
|
||||||
cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
|
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
|
||||||
CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id,
|
CS35L41_FIRMWARE_ROOT,
|
||||||
cs35l41->amp_name, -1, "bin");
|
cs35l41->acpi_subsystem_id, cs35l41->amp_name,
|
||||||
return 0;
|
-1, "bin");
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try cirrus/part-dspN-fwtype-sub.wmfw */
|
/* 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");
|
cs35l41->amp_name, -1, "bin");
|
||||||
if (ret)
|
if (ret)
|
||||||
/* try cirrus/part-dspN-fwtype-sub.bin */
|
/* try cirrus/part-dspN-fwtype-sub.bin */
|
||||||
cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
|
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
|
||||||
CS35L41_FIRMWARE_ROOT,
|
CS35L41_FIRMWARE_ROOT,
|
||||||
cs35l41->acpi_subsystem_id,
|
cs35l41->acpi_subsystem_id, NULL, -1,
|
||||||
NULL, -1, "bin");
|
"bin");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 */
|
/* fallback try cirrus/part-dspN-fwtype.wmfw */
|
||||||
ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
|
ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
|
||||||
CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "wmfw");
|
CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "wmfw");
|
||||||
if (!ret) {
|
if (!ret)
|
||||||
/* fallback try cirrus/part-dspN-fwtype.bin */
|
/* fallback try cirrus/part-dspN-fwtype.bin */
|
||||||
cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
|
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
|
||||||
CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "bin");
|
CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "bin");
|
||||||
return 0;
|
|
||||||
|
if (ret) {
|
||||||
|
release_firmware(*wmfw_firmware);
|
||||||
|
kfree(*wmfw_filename);
|
||||||
|
dev_warn(cs35l41->dev, "Unable to find firmware and tuning\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_warn(cs35l41->dev, "Failed to request firmware\n");
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user