diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c index 55b4d0d55712..abea782bcd3f 100644 --- a/sound/soc/codecs/cs35l56.c +++ b/sound/soc/codecs/cs35l56.c @@ -1109,27 +1109,68 @@ static const struct snd_kcontrol_new cs35l56_cal_data_restore_controls[] = { static int cs35l56_set_fw_suffix(struct cs35l56_private *cs35l56) { + unsigned short vendor, device; + const char *vendor_id; + int ret; + if (cs35l56->dsp.fwf_suffix) return 0; - if (!cs35l56->sdw_peripheral) - return 0; + if (cs35l56->sdw_peripheral) { + cs35l56->dsp.fwf_suffix = devm_kasprintf(cs35l56->base.dev, GFP_KERNEL, + "l%uu%u", + cs35l56->sdw_link_num, + cs35l56->sdw_unique_id); + if (!cs35l56->dsp.fwf_suffix) + return -ENOMEM; - cs35l56->dsp.fwf_suffix = devm_kasprintf(cs35l56->base.dev, GFP_KERNEL, - "l%uu%u", - cs35l56->sdw_link_num, - cs35l56->sdw_unique_id); - if (!cs35l56->dsp.fwf_suffix) - return -ENOMEM; + /* + * There are published firmware files for L56 B0 silicon using + * the ALSA prefix as the filename suffix. Default to trying these + * first, with the new SoundWire suffix as a fallback. + * None of these older systems use a vendor-specific ID. + */ + if ((cs35l56->base.type == 0x56) && (cs35l56->base.rev == 0xb0)) { + cs35l56->fallback_fw_suffix = cs35l56->dsp.fwf_suffix; + cs35l56->dsp.fwf_suffix = cs35l56->component->name_prefix; + + return 0; + } + } /* - * There are published firmware files for L56 B0 silicon using - * the ALSA prefix as the filename suffix. Default to trying these - * first, with the new name as an alternate. + * Some manufacturers use the same SSID on multiple products and have + * a vendor-specific qualifier to distinguish different models. + * Models with the same SSID but different qualifier might require + * different audio firmware, or they might all have the same audio + * firmware. + * Try searching for a firmware with this qualifier first, else + * fallback to standard naming. */ - if ((cs35l56->base.type == 0x56) && (cs35l56->base.rev == 0xb0)) { - cs35l56->fallback_fw_suffix = cs35l56->dsp.fwf_suffix; - cs35l56->dsp.fwf_suffix = cs35l56->component->name_prefix; + if (snd_soc_card_get_pci_ssid(cs35l56->component->card, &vendor, &device) < 0) { + vendor_id = cs_amp_devm_get_vendor_specific_variant_id(cs35l56->base.dev, -1, -1); + } else { + vendor_id = cs_amp_devm_get_vendor_specific_variant_id(cs35l56->base.dev, + vendor, device); + } + ret = PTR_ERR_OR_ZERO(vendor_id); + if (ret == -ENOENT) + return 0; + else if (ret) + return ret; + + if (vendor_id) { + if (cs35l56->dsp.fwf_suffix) + cs35l56->fallback_fw_suffix = cs35l56->dsp.fwf_suffix; + else + cs35l56->fallback_fw_suffix = cs35l56->component->name_prefix; + + cs35l56->dsp.fwf_suffix = devm_kasprintf(cs35l56->base.dev, GFP_KERNEL, + "%s-%s", + vendor_id, + cs35l56->fallback_fw_suffix); + if (!cs35l56->dsp.fwf_suffix) + return -ENOMEM; } return 0;