Skip to content

Commit cd40dad

Browse files
Stefan Bindingtiwai
Stefan Binding
authored andcommitted
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]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 943f4e6 commit cd40dad

File tree

1 file changed

+51
-52
lines changed

1 file changed

+51
-52
lines changed

sound/pci/hda/cs35l41_hda.c

Lines changed: 51 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,10 @@ static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41,
178178
cs35l41->speaker_id, "wmfw");
179179
if (!ret) {
180180
/* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */
181-
cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
182-
CS35L41_FIRMWARE_ROOT,
183-
cs35l41->acpi_subsystem_id, cs35l41->amp_name,
184-
cs35l41->speaker_id, "bin");
185-
return 0;
181+
return cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
182+
CS35L41_FIRMWARE_ROOT,
183+
cs35l41->acpi_subsystem_id, cs35l41->amp_name,
184+
cs35l41->speaker_id, "bin");
186185
}
187186

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

200199
/* try cirrus/part-dspN-fwtype-sub<-spkidN>.wmfw */
@@ -209,11 +208,10 @@ static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41,
209208
cs35l41->amp_name, cs35l41->speaker_id, "bin");
210209
if (ret)
211210
/* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */
212-
cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
213-
CS35L41_FIRMWARE_ROOT,
214-
cs35l41->acpi_subsystem_id,
215-
NULL, cs35l41->speaker_id, "bin");
216-
return 0;
211+
return cs35l41_request_firmware_file(cs35l41, coeff_firmware,
212+
coeff_filename, CS35L41_FIRMWARE_ROOT,
213+
cs35l41->acpi_subsystem_id, NULL,
214+
cs35l41->speaker_id, "bin");
217215
}
218216

219217
/* try cirrus/part-dspN-fwtype-sub.wmfw */
@@ -224,29 +222,16 @@ static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41,
224222
/* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */
225223
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
226224
CS35L41_FIRMWARE_ROOT,
227-
cs35l41->acpi_subsystem_id,
228-
cs35l41->amp_name, cs35l41->speaker_id, "bin");
225+
cs35l41->acpi_subsystem_id, cs35l41->amp_name,
226+
cs35l41->speaker_id, "bin");
229227
if (ret)
230228
/* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */
231-
cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
232-
CS35L41_FIRMWARE_ROOT,
233-
cs35l41->acpi_subsystem_id,
234-
NULL, cs35l41->speaker_id, "bin");
235-
return 0;
236-
}
237-
238-
/* fallback try cirrus/part-dspN-fwtype.wmfw */
239-
ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
240-
CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "wmfw");
241-
if (!ret) {
242-
/* fallback try cirrus/part-dspN-fwtype.bin */
243-
cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
244-
CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "bin");
245-
return 0;
229+
return cs35l41_request_firmware_file(cs35l41, coeff_firmware,
230+
coeff_filename, CS35L41_FIRMWARE_ROOT,
231+
cs35l41->acpi_subsystem_id, NULL,
232+
cs35l41->speaker_id, "bin");
246233
}
247234

248-
dev_warn(cs35l41->dev, "Failed to request firmware\n");
249-
250235
return ret;
251236
}
252237

@@ -258,20 +243,24 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41,
258243
{
259244
int ret;
260245

261-
if (cs35l41->speaker_id > -1)
262-
return cs35l41_request_firmware_files_spkid(cs35l41, wmfw_firmware, wmfw_filename,
263-
coeff_firmware, coeff_filename);
246+
if (cs35l41->speaker_id > -1) {
247+
ret = cs35l41_request_firmware_files_spkid(cs35l41, wmfw_firmware, wmfw_filename,
248+
coeff_firmware, coeff_filename);
249+
goto out;
250+
251+
}
264252

265253
/* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */
266254
ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
267255
CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id,
268256
cs35l41->amp_name, -1, "wmfw");
269257
if (!ret) {
270258
/* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */
271-
cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
272-
CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id,
273-
cs35l41->amp_name, -1, "bin");
274-
return 0;
259+
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
260+
CS35L41_FIRMWARE_ROOT,
261+
cs35l41->acpi_subsystem_id, cs35l41->amp_name,
262+
-1, "bin");
263+
goto out;
275264
}
276265

277266
/* try cirrus/part-dspN-fwtype-sub.wmfw */
@@ -286,25 +275,35 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41,
286275
cs35l41->amp_name, -1, "bin");
287276
if (ret)
288277
/* try cirrus/part-dspN-fwtype-sub.bin */
289-
cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
290-
CS35L41_FIRMWARE_ROOT,
291-
cs35l41->acpi_subsystem_id,
292-
NULL, -1, "bin");
293-
return 0;
278+
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
279+
CS35L41_FIRMWARE_ROOT,
280+
cs35l41->acpi_subsystem_id, NULL, -1,
281+
"bin");
294282
}
295283

284+
out:
285+
if (!ret)
286+
return 0;
287+
288+
/* Handle fallback */
289+
dev_warn(cs35l41->dev, "Falling back to default firmware.\n");
290+
291+
release_firmware(*wmfw_firmware);
292+
kfree(*wmfw_filename);
293+
296294
/* fallback try cirrus/part-dspN-fwtype.wmfw */
297295
ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
298296
CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "wmfw");
299-
if (!ret) {
297+
if (!ret)
300298
/* fallback try cirrus/part-dspN-fwtype.bin */
301-
cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
302-
CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "bin");
303-
return 0;
304-
}
305-
306-
dev_warn(cs35l41->dev, "Failed to request firmware\n");
299+
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
300+
CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "bin");
307301

302+
if (ret) {
303+
release_firmware(*wmfw_firmware);
304+
kfree(*wmfw_filename);
305+
dev_warn(cs35l41->dev, "Unable to find firmware and tuning\n");
306+
}
308307
return ret;
309308
}
310309

0 commit comments

Comments
 (0)