Skip to content

Commit 7213851

Browse files
committed
Merge tag 'asoc-fix-v6.16-rc2' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Fixes for v6.16 A relatively large collection of fixes and updates that came in since the merge window. Of note are a couple of Cirrus ones which change the firmware naming for some newly added devices, and a fix from Laurentiu for issues booting firmwares on the DSPs on i.MX8 SoCs.
2 parents 60599e4 + 16ea466 commit 7213851

File tree

14 files changed

+154
-35
lines changed

14 files changed

+154
-35
lines changed

Documentation/sound/codecs/cs35l56.rst

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
.. SPDX-License-Identifier: GPL-2.0-only
22
3-
=====================================================================
4-
Audio drivers for Cirrus Logic CS35L54/56/57 Boosted Smart Amplifiers
5-
=====================================================================
3+
========================================================================
4+
Audio drivers for Cirrus Logic CS35L54/56/57/63 Boosted Smart Amplifiers
5+
========================================================================
66
:Copyright: 2025 Cirrus Logic, Inc. and
77
Cirrus Logic International Semiconductor Ltd.
88

@@ -13,11 +13,11 @@ Summary
1313

1414
The high-level summary of this document is:
1515

16-
**If you have a laptop that uses CS35L54/56/57 amplifiers but audio is not
16+
**If you have a laptop that uses CS35L54/56/57/63 amplifiers but audio is not
1717
working, DO NOT ATTEMPT TO USE FIRMWARE AND SETTINGS FROM ANOTHER LAPTOP,
1818
EVEN IF THAT LAPTOP SEEMS SIMILAR.**
1919

20-
The CS35L54/56/57 amplifiers must be correctly configured for the power
20+
The CS35L54/56/57/63 amplifiers must be correctly configured for the power
2121
supply voltage, speaker impedance, maximum speaker voltage/current, and
2222
other external hardware connections.
2323

@@ -34,6 +34,7 @@ The cs35l56 drivers support:
3434
* CS35L54
3535
* CS35L56
3636
* CS35L57
37+
* CS35L63
3738

3839
There are two drivers in the kernel
3940

@@ -104,19 +105,32 @@ In this example the SSID is 10280c63.
104105

105106
The format of the firmware file names is:
106107

108+
SoundWire (except CS35L56 Rev B0):
109+
cs35lxx-b0-dsp1-misc-SSID[-spkidX]-l?u?
110+
111+
SoundWire CS35L56 Rev B0:
112+
cs35lxx-b0-dsp1-misc-SSID[-spkidX]-ampN
113+
114+
Non-SoundWire (HDA and I2S):
107115
cs35lxx-b0-dsp1-misc-SSID[-spkidX]-ampN
108116

109117
Where:
110118

111119
* cs35lxx-b0 is the amplifier model and silicon revision. This information
112120
is logged by the driver during initialization.
113121
* SSID is the 8-digit hexadecimal SSID value.
122+
* l?u? is the physical address on the SoundWire bus of the amp this
123+
file applies to.
114124
* ampN is the amplifier number (for example amp1). This is the same as
115125
the prefix on the ALSA control names except that it is always lower-case
116126
in the file name.
117127
* spkidX is an optional part, used for laptops that have firmware
118128
configurations for different makes and models of internal speakers.
119129

130+
The CS35L56 Rev B0 continues to use the old filename scheme because a
131+
large number of firmware files have already been published with these
132+
names.
133+
120134
Sound Open Firmware and ALSA topology files
121135
-------------------------------------------
122136

sound/soc/amd/yc/acp6x-mach.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
451451
DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 17 D7VEK"),
452452
}
453453
},
454+
{
455+
.driver_data = &acp6x_card,
456+
.matches = {
457+
DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."),
458+
DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 17 D7VF"),
459+
}
460+
},
454461
{
455462
.driver_data = &acp6x_card,
456463
.matches = {
@@ -514,6 +521,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
514521
DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16z-n000"),
515522
}
516523
},
524+
{
525+
.driver_data = &acp6x_card,
526+
.matches = {
527+
DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
528+
DMI_MATCH(DMI_PRODUCT_NAME, "Victus by HP Gaming Laptop 15-fb2xxx"),
529+
}
530+
},
517531
{
518532
.driver_data = &acp6x_card,
519533
.matches = {

sound/soc/apple/Kconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ config SND_SOC_APPLE_MCA
22
tristate "Apple Silicon MCA driver"
33
depends on ARCH_APPLE || COMPILE_TEST
44
select SND_DMAENGINE_PCM
5-
default ARCH_APPLE
65
help
76
This option enables an ASoC platform driver for MCA peripherals found
87
on Apple Silicon SoCs.

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: 63 additions & 9 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

@@ -853,6 +875,34 @@ static void cs35l56_dsp_work(struct work_struct *work)
853875
pm_runtime_put_autosuspend(cs35l56->base.dev);
854876
}
855877

878+
static int cs35l56_set_fw_suffix(struct cs35l56_private *cs35l56)
879+
{
880+
if (cs35l56->dsp.fwf_suffix)
881+
return 0;
882+
883+
if (!cs35l56->sdw_peripheral)
884+
return 0;
885+
886+
cs35l56->dsp.fwf_suffix = devm_kasprintf(cs35l56->base.dev, GFP_KERNEL,
887+
"l%uu%u",
888+
cs35l56->sdw_link_num,
889+
cs35l56->sdw_unique_id);
890+
if (!cs35l56->dsp.fwf_suffix)
891+
return -ENOMEM;
892+
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+
903+
return 0;
904+
}
905+
856906
static int cs35l56_component_probe(struct snd_soc_component *component)
857907
{
858908
struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
@@ -892,6 +942,10 @@ static int cs35l56_component_probe(struct snd_soc_component *component)
892942
return -ENOMEM;
893943

894944
cs35l56->component = component;
945+
ret = cs35l56_set_fw_suffix(cs35l56);
946+
if (ret)
947+
return ret;
948+
895949
wm_adsp2_component_probe(&cs35l56->dsp, component);
896950

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

sound/soc/codecs/cs35l56.h

Lines changed: 3 additions & 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;
@@ -52,6 +53,8 @@ struct cs35l56_private {
5253
bool tdm_mode;
5354
bool sysclk_set;
5455
u8 old_sdw_clock_scale;
56+
u8 sdw_link_num;
57+
u8 sdw_unique_id;
5558
};
5659

5760
extern const struct dev_pm_ops cs35l56_pm_ops_i2c_spi;

sound/soc/codecs/cs48l32.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2162,6 +2162,10 @@ static int cs48l32_hw_params(struct snd_pcm_substream *substream,
21622162
n_slots_multiple = 1;
21632163

21642164
sclk_target = snd_soc_tdm_params_to_bclk(params, slotw, n_slots, n_slots_multiple);
2165+
if (sclk_target < 0) {
2166+
cs48l32_asp_err(dai, "Invalid parameters\n");
2167+
return sclk_target;
2168+
}
21652169

21662170
for (i = 0; i < ARRAY_SIZE(cs48l32_sclk_rates); i++) {
21672171
if ((cs48l32_sclk_rates[i].freq >= sclk_target) &&

sound/soc/codecs/es8326.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,8 +1079,7 @@ static void es8326_init(struct snd_soc_component *component)
10791079
regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00);
10801080
regmap_write(es8326->regmap, ES8326_INTOUT_IO,
10811081
es8326->interrupt_clk);
1082-
regmap_write(es8326->regmap, ES8326_SDINOUT1_IO,
1083-
(ES8326_IO_DMIC_CLK << ES8326_SDINOUT1_SHIFT));
1082+
regmap_write(es8326->regmap, ES8326_SDINOUT1_IO, ES8326_IO_INPUT);
10841083
regmap_write(es8326->regmap, ES8326_SDINOUT23_IO, ES8326_IO_INPUT);
10851084

10861085
regmap_write(es8326->regmap, ES8326_ANA_PDN, 0x00);

sound/soc/codecs/wm_adsp.c

Lines changed: 18 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
}
@@ -997,11 +1000,17 @@ int wm_adsp_power_up(struct wm_adsp *dsp, bool load_firmware)
9971000
return ret;
9981001
}
9991002

1003+
if (dsp->bin_mandatory && !coeff_firmware) {
1004+
ret = -ENOENT;
1005+
goto err;
1006+
}
1007+
10001008
ret = cs_dsp_power_up(&dsp->cs_dsp,
10011009
wmfw_firmware, wmfw_filename,
10021010
coeff_firmware, coeff_filename,
10031011
wm_adsp_fw_text[dsp->fw]);
10041012

1013+
err:
10051014
wm_adsp_release_firmware_files(dsp,
10061015
wmfw_firmware, wmfw_filename,
10071016
coeff_firmware, coeff_filename);

sound/soc/codecs/wm_adsp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@ 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;
3536

3637
int fw;
3738
bool wmfw_optional;
39+
bool bin_mandatory;
3840

3941
struct work_struct boot_work;
4042
int (*control_add)(struct wm_adsp *dsp, struct cs_dsp_coeff_ctl *cs_ctl);

0 commit comments

Comments
 (0)