Skip to content

Commit d1fc768

Browse files
rfvirgilbroonie
authored andcommitted
ASoC: cs35l56: Use SoundWire address as firmware name suffix for new silicon
Use the SoundWire link number and device unique ID as the firmware file qualifier suffix on CS35L57, CS35L63 and revisions of CS35L56 after B0. The change in wm_adsp needed to support this has been included in this patch because it is fairly trivial. 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 a 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 the redundant intermediate alias. This ensures the firmware is applied to the amp it was intended for. There have not been any firmwares published for CS35L57 or CS35L63, so these can safely be switched to using the SoundWire unique address as the suffix string. Also note that the machine driver in older kernel version only has match entries for the CS35L56 Soundwire identity so any future product with a cs35L57 or CS35L63 would require a new kernel anyway. There are already many published firmware for CS35L56 B0 silicon so this keeps the original naming scheme on those, to preserve backward compatibility. Note that although sdw_slave.id contains a unique_id field, this cannot be trusted because the SoundWire core code also puts magic values into it that it uses as a flag. So the unique ID is read from the chip register. Signed-off-by: Richard Fitzgerald <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 6325766 commit d1fc768

File tree

5 files changed

+54
-17
lines changed

5 files changed

+54
-17
lines changed

sound/soc/codecs/cs35l56-sdw.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -238,16 +238,15 @@ static const struct regmap_bus cs35l56_regmap_bus_sdw = {
238238
.val_format_endian_default = REGMAP_ENDIAN_BIG,
239239
};
240240

241-
static int cs35l56_sdw_set_cal_index(struct cs35l56_private *cs35l56)
241+
static int cs35l56_sdw_get_unique_id(struct cs35l56_private *cs35l56)
242242
{
243243
int ret;
244244

245-
/* SoundWire UniqueId is used to index the calibration array */
246245
ret = sdw_read_no_pm(cs35l56->sdw_peripheral, SDW_SCP_DEVID_0);
247246
if (ret < 0)
248247
return ret;
249248

250-
cs35l56->base.cal_index = ret & 0xf;
249+
cs35l56->sdw_unique_id = ret & 0xf;
251250

252251
return 0;
253252
}
@@ -259,11 +258,13 @@ static void cs35l56_sdw_init(struct sdw_slave *peripheral)
259258

260259
pm_runtime_get_noresume(cs35l56->base.dev);
261260

262-
if (cs35l56->base.cal_index < 0) {
263-
ret = cs35l56_sdw_set_cal_index(cs35l56);
264-
if (ret < 0)
265-
goto out;
266-
}
261+
ret = cs35l56_sdw_get_unique_id(cs35l56);
262+
if (ret)
263+
goto out;
264+
265+
/* SoundWire UniqueId is used to index the calibration array */
266+
if (cs35l56->base.cal_index < 0)
267+
cs35l56->base.cal_index = cs35l56->sdw_unique_id;
267268

268269
ret = cs35l56_init(cs35l56);
269270
if (ret < 0) {
@@ -587,6 +588,7 @@ static int cs35l56_sdw_probe(struct sdw_slave *peripheral, const struct sdw_devi
587588

588589
cs35l56->base.dev = dev;
589590
cs35l56->sdw_peripheral = peripheral;
591+
cs35l56->sdw_link_num = peripheral->bus->link_id;
590592
INIT_WORK(&cs35l56->sdw_irq_work, cs35l56_sdw_irq_work);
591593

592594
dev_set_drvdata(dev, cs35l56);

sound/soc/codecs/cs35l56.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,31 @@ static void cs35l56_dsp_work(struct work_struct *work)
853853
pm_runtime_put_autosuspend(cs35l56->base.dev);
854854
}
855855

856+
static int cs35l56_set_fw_suffix(struct cs35l56_private *cs35l56)
857+
{
858+
if (cs35l56->dsp.fwf_suffix)
859+
return 0;
860+
861+
if (!cs35l56->sdw_peripheral)
862+
return 0;
863+
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+
871+
cs35l56->dsp.fwf_suffix = devm_kasprintf(cs35l56->base.dev, GFP_KERNEL,
872+
"l%uu%u",
873+
cs35l56->sdw_link_num,
874+
cs35l56->sdw_unique_id);
875+
if (!cs35l56->dsp.fwf_suffix)
876+
return -ENOMEM;
877+
878+
return 0;
879+
}
880+
856881
static int cs35l56_component_probe(struct snd_soc_component *component)
857882
{
858883
struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
@@ -891,6 +916,10 @@ static int cs35l56_component_probe(struct snd_soc_component *component)
891916
if (!cs35l56->dsp.part)
892917
return -ENOMEM;
893918

919+
ret = cs35l56_set_fw_suffix(cs35l56);
920+
if (ret)
921+
return ret;
922+
894923
cs35l56->component = component;
895924
wm_adsp2_component_probe(&cs35l56->dsp, component);
896925

sound/soc/codecs/cs35l56.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ struct cs35l56_private {
5252
bool tdm_mode;
5353
bool sysclk_set;
5454
u8 old_sdw_clock_scale;
55+
u8 sdw_link_num;
56+
u8 sdw_unique_id;
5557
};
5658

5759
extern const struct dev_pm_ops cs35l56_pm_ops_i2c_spi;

sound/soc/codecs/wm_adsp.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -783,16 +783,19 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
783783
char **coeff_filename)
784784
{
785785
const char *system_name = dsp->system_name;
786-
const char *asoc_component_prefix = dsp->component->name_prefix;
786+
const char *suffix = dsp->component->name_prefix;
787787
int ret = 0;
788788

789-
if (system_name && asoc_component_prefix) {
789+
if (dsp->fwf_suffix)
790+
suffix = dsp->fwf_suffix;
791+
792+
if (system_name && suffix) {
790793
if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
791794
cirrus_dir, system_name,
792-
asoc_component_prefix, "wmfw")) {
795+
suffix, "wmfw")) {
793796
wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
794797
cirrus_dir, system_name,
795-
asoc_component_prefix, "bin");
798+
suffix, "bin");
796799
return 0;
797800
}
798801
}
@@ -801,10 +804,10 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
801804
if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
802805
cirrus_dir, system_name,
803806
NULL, "wmfw")) {
804-
if (asoc_component_prefix)
807+
if (suffix)
805808
wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
806809
cirrus_dir, system_name,
807-
asoc_component_prefix, "bin");
810+
suffix, "bin");
808811

809812
if (!*coeff_firmware)
810813
wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
@@ -816,10 +819,10 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
816819

817820
/* Check system-specific bin without wmfw before falling back to generic */
818821
if (dsp->wmfw_optional && system_name) {
819-
if (asoc_component_prefix)
822+
if (suffix)
820823
wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
821824
cirrus_dir, system_name,
822-
asoc_component_prefix, "bin");
825+
suffix, "bin");
823826

824827
if (!*coeff_firmware)
825828
wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
@@ -850,7 +853,7 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
850853
adsp_err(dsp, "Failed to request firmware <%s>%s-%s-%s<-%s<%s>>.wmfw\n",
851854
cirrus_dir, dsp->part,
852855
dsp->fwf_name ? dsp->fwf_name : dsp->cs_dsp.name,
853-
wm_adsp_fw[dsp->fw].file, system_name, asoc_component_prefix);
856+
wm_adsp_fw[dsp->fw].file, system_name, suffix);
854857

855858
return -ENOENT;
856859
}

sound/soc/codecs/wm_adsp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ struct wm_adsp {
2929
const char *part;
3030
const char *fwf_name;
3131
const char *system_name;
32+
const char *fwf_suffix;
3233
struct snd_soc_component *component;
3334

3435
unsigned int sys_config_size;

0 commit comments

Comments
 (0)