Skip to content

Commit e5d5b3a

Browse files
rfvirgilbroonie
authored andcommitted
ASoC: cs35l56: Use SoundWire address as alternate firmware suffix on L56 B0
Use the SoundWire link number and device unique ID as the firmware file qualifier suffix on CS35L56 B0 if .bin files are not found with the older suffix. Some changes in wm_adsp needed to support this have been included in this patch because they are trivial. The allows future products with CS35L56 B0 silicon to use the same firmware file naming as CS35L57 and cs35L63, while retaining backward compatibility for firmware that has already been published with the old naming scheme. The old suffix is searched first, partly because there are already many files using that naming scheme, but also because they are a smaller subset of all the possible fallback name options offered by wm_adsp so we know that it will either find the qualified files or fail. All the firmware files already published have the wmfw qualified with only the ACPI SSID and the bin files qualified with both SSID and the suffix. Originally, the firmware file names indicated which amplifier instance they were for by appending the ALSA prefix string. This is the standard ASoC way of distinguishing different instances of the same device. However, on SoundWire systems the SoundWire physical unique address is available as a unique identifier for each amp, and this address is hardwired by the address pin on the amp. The firmware files are specific for each physical amp so they must be applied to that amp. Using the ALSA prefix for the filename qualifier means that to name a firmware file it must be determined what prefix string the machine driver will assign to each device and then use that to name the firmware file correctly. This is straightforward in traditional ASoC systems where the machine driver is specific to a particular piece of hardware. But on SoundWire the machine driver is generic and can handle a very wide range of hardware. It is more difficult to determine exactly what the prefix will be on any particular production device, and more prone to mistakes. Also, when the machine driver switches to generating this automatically from SDCA properties in ACPI, there is an additional layer of complexity in determining the mapping. This uncertainty is unnecessary because the firmware is built for a specific amp. with known address, so we can use that directly instead of introducing a redundant intermediate alias. This ensures the firmware is applied to the amp it was intended for. There are already many published firmware for CS35L56 B0 silicon so this first looks for the original name suffix, to keep backward compatibility. If this doesn't find .bin files it will switch to using the new name suffix so that future products using CS35L56 B0 can start to use the new suffix. Signed-off-by: Richard Fitzgerald <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent d1fc768 commit e5d5b3a

File tree

4 files changed

+50
-17
lines changed

4 files changed

+50
-17
lines changed

sound/soc/codecs/cs35l56.c

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -706,17 +706,41 @@ static int cs35l56_write_cal(struct cs35l56_private *cs35l56)
706706
return ret;
707707
}
708708

709-
static void cs35l56_reinit_patch(struct cs35l56_private *cs35l56)
709+
static int cs35l56_dsp_download_and_power_up(struct cs35l56_private *cs35l56,
710+
bool load_firmware)
710711
{
711712
int ret;
712713

713-
/* Use wm_adsp to load and apply the firmware patch and coefficient files */
714-
ret = wm_adsp_power_up(&cs35l56->dsp, true);
714+
/*
715+
* Abort the first load if it didn't find the suffixed bins and
716+
* we have an alternate fallback suffix.
717+
*/
718+
cs35l56->dsp.bin_mandatory = (load_firmware && cs35l56->fallback_fw_suffix);
719+
720+
ret = wm_adsp_power_up(&cs35l56->dsp, load_firmware);
721+
if ((ret == -ENOENT) && cs35l56->dsp.bin_mandatory) {
722+
cs35l56->dsp.fwf_suffix = cs35l56->fallback_fw_suffix;
723+
cs35l56->fallback_fw_suffix = NULL;
724+
cs35l56->dsp.bin_mandatory = false;
725+
ret = wm_adsp_power_up(&cs35l56->dsp, load_firmware);
726+
}
727+
715728
if (ret) {
716-
dev_dbg(cs35l56->base.dev, "%s: wm_adsp_power_up ret %d\n", __func__, ret);
717-
return;
729+
dev_dbg(cs35l56->base.dev, "wm_adsp_power_up ret %d\n", ret);
730+
return ret;
718731
}
719732

733+
return 0;
734+
}
735+
736+
static void cs35l56_reinit_patch(struct cs35l56_private *cs35l56)
737+
{
738+
int ret;
739+
740+
ret = cs35l56_dsp_download_and_power_up(cs35l56, true);
741+
if (ret)
742+
return;
743+
720744
cs35l56_write_cal(cs35l56);
721745

722746
/* Always REINIT after applying patch or coefficients */
@@ -750,11 +774,9 @@ static void cs35l56_patch(struct cs35l56_private *cs35l56, bool firmware_missing
750774
* but only if firmware is missing. If firmware is already patched just
751775
* power-up wm_adsp without downloading firmware.
752776
*/
753-
ret = wm_adsp_power_up(&cs35l56->dsp, !!firmware_missing);
754-
if (ret) {
755-
dev_dbg(cs35l56->base.dev, "%s: wm_adsp_power_up ret %d\n", __func__, ret);
777+
ret = cs35l56_dsp_download_and_power_up(cs35l56, firmware_missing);
778+
if (ret)
756779
goto err;
757-
}
758780

759781
mutex_lock(&cs35l56->base.irq_lock);
760782

@@ -861,20 +883,23 @@ static int cs35l56_set_fw_suffix(struct cs35l56_private *cs35l56)
861883
if (!cs35l56->sdw_peripheral)
862884
return 0;
863885

864-
/*
865-
* There are published firmware files for L56 B0 silicon using
866-
* the default wm_adsp name suffixing so don't change those.
867-
*/
868-
if ((cs35l56->base.type == 0x56) && (cs35l56->base.rev == 0xb0))
869-
return 0;
870-
871886
cs35l56->dsp.fwf_suffix = devm_kasprintf(cs35l56->base.dev, GFP_KERNEL,
872887
"l%uu%u",
873888
cs35l56->sdw_link_num,
874889
cs35l56->sdw_unique_id);
875890
if (!cs35l56->dsp.fwf_suffix)
876891
return -ENOMEM;
877892

893+
/*
894+
* There are published firmware files for L56 B0 silicon using
895+
* the ALSA prefix as the filename suffix. Default to trying these
896+
* first, with the new name as an alternate.
897+
*/
898+
if ((cs35l56->base.type == 0x56) && (cs35l56->base.rev == 0xb0)) {
899+
cs35l56->fallback_fw_suffix = cs35l56->dsp.fwf_suffix;
900+
cs35l56->dsp.fwf_suffix = cs35l56->component->name_prefix;
901+
}
902+
878903
return 0;
879904
}
880905

@@ -916,11 +941,11 @@ static int cs35l56_component_probe(struct snd_soc_component *component)
916941
if (!cs35l56->dsp.part)
917942
return -ENOMEM;
918943

944+
cs35l56->component = component;
919945
ret = cs35l56_set_fw_suffix(cs35l56);
920946
if (ret)
921947
return ret;
922948

923-
cs35l56->component = component;
924949
wm_adsp2_component_probe(&cs35l56->dsp, component);
925950

926951
debugfs_create_bool("init_done", 0444, debugfs_root, &cs35l56->base.init_done);

sound/soc/codecs/cs35l56.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct cs35l56_private {
3838
struct snd_soc_component *component;
3939
struct regulator_bulk_data supplies[CS35L56_NUM_BULK_SUPPLIES];
4040
struct sdw_slave *sdw_peripheral;
41+
const char *fallback_fw_suffix;
4142
struct work_struct sdw_irq_work;
4243
bool sdw_irq_no_unmask;
4344
bool soft_resetting;

sound/soc/codecs/wm_adsp.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,11 +1000,17 @@ int wm_adsp_power_up(struct wm_adsp *dsp, bool load_firmware)
10001000
return ret;
10011001
}
10021002

1003+
if (dsp->bin_mandatory && !coeff_firmware) {
1004+
ret = -ENOENT;
1005+
goto err;
1006+
}
1007+
10031008
ret = cs_dsp_power_up(&dsp->cs_dsp,
10041009
wmfw_firmware, wmfw_filename,
10051010
coeff_firmware, coeff_filename,
10061011
wm_adsp_fw_text[dsp->fw]);
10071012

1013+
err:
10081014
wm_adsp_release_firmware_files(dsp,
10091015
wmfw_firmware, wmfw_filename,
10101016
coeff_firmware, coeff_filename);

sound/soc/codecs/wm_adsp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ struct wm_adsp {
3636

3737
int fw;
3838
bool wmfw_optional;
39+
bool bin_mandatory;
3940

4041
struct work_struct boot_work;
4142
int (*control_add)(struct wm_adsp *dsp, struct cs_dsp_coeff_ctl *cs_ctl);

0 commit comments

Comments
 (0)