Commit 72138519 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

Merge tag 'asoc-fix-v6.16-rc2' of...

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.
parents 60599e4f 16ea4666
Loading
Loading
Loading
Loading
+19 −5
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0-only

=====================================================================
Audio drivers for Cirrus Logic CS35L54/56/57 Boosted Smart Amplifiers
=====================================================================
========================================================================
Audio drivers for Cirrus Logic CS35L54/56/57/63 Boosted Smart Amplifiers
========================================================================
:Copyright: 2025 Cirrus Logic, Inc. and
                 Cirrus Logic International Semiconductor Ltd.

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

The high-level summary of this document is:

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

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

@@ -34,6 +34,7 @@ The cs35l56 drivers support:
* CS35L54
* CS35L56
* CS35L57
* CS35L63

There are two drivers in the kernel

@@ -104,6 +105,13 @@ In this example the SSID is 10280c63.

The format of the firmware file names is:

SoundWire (except CS35L56 Rev B0):
    cs35lxx-b0-dsp1-misc-SSID[-spkidX]-l?u?

SoundWire CS35L56 Rev B0:
    cs35lxx-b0-dsp1-misc-SSID[-spkidX]-ampN

Non-SoundWire (HDA and I2S):
    cs35lxx-b0-dsp1-misc-SSID[-spkidX]-ampN

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

The CS35L56 Rev B0 continues to use the old filename scheme because a
large number of firmware files have already been published with these
names.

Sound Open Firmware and ALSA topology files
-------------------------------------------

+14 −0
Original line number Diff line number Diff line
@@ -451,6 +451,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
			DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 17 D7VEK"),
		}
	},
	{
		.driver_data = &acp6x_card,
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."),
			DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 17 D7VF"),
		}
	},
	{
		.driver_data = &acp6x_card,
		.matches = {
@@ -514,6 +521,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
			DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16z-n000"),
		}
	},
	{
		.driver_data = &acp6x_card,
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Victus by HP Gaming Laptop 15-fb2xxx"),
		}
	},
	{
		.driver_data = &acp6x_card,
		.matches = {
+0 −1
Original line number Diff line number Diff line
@@ -2,7 +2,6 @@ config SND_SOC_APPLE_MCA
	tristate "Apple Silicon MCA driver"
	depends on ARCH_APPLE || COMPILE_TEST
	select SND_DMAENGINE_PCM
	default ARCH_APPLE
	help
	  This option enables an ASoC platform driver for MCA peripherals found
	  on Apple Silicon SoCs.
+10 −8
Original line number Diff line number Diff line
@@ -238,16 +238,15 @@ static const struct regmap_bus cs35l56_regmap_bus_sdw = {
	.val_format_endian_default = REGMAP_ENDIAN_BIG,
};

static int cs35l56_sdw_set_cal_index(struct cs35l56_private *cs35l56)
static int cs35l56_sdw_get_unique_id(struct cs35l56_private *cs35l56)
{
	int ret;

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

	cs35l56->base.cal_index = ret & 0xf;
	cs35l56->sdw_unique_id = ret & 0xf;

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

	pm_runtime_get_noresume(cs35l56->base.dev);

	if (cs35l56->base.cal_index < 0) {
		ret = cs35l56_sdw_set_cal_index(cs35l56);
		if (ret < 0)
	ret = cs35l56_sdw_get_unique_id(cs35l56);
	if (ret)
		goto out;
	}

	/* SoundWire UniqueId is used to index the calibration array */
	if (cs35l56->base.cal_index < 0)
		cs35l56->base.cal_index = cs35l56->sdw_unique_id;

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

	cs35l56->base.dev = dev;
	cs35l56->sdw_peripheral = peripheral;
	cs35l56->sdw_link_num = peripheral->bus->link_id;
	INIT_WORK(&cs35l56->sdw_irq_work, cs35l56_sdw_irq_work);

	dev_set_drvdata(dev, cs35l56);
+63 −9
Original line number Diff line number Diff line
@@ -706,17 +706,41 @@ static int cs35l56_write_cal(struct cs35l56_private *cs35l56)
	return ret;
}

static void cs35l56_reinit_patch(struct cs35l56_private *cs35l56)
static int cs35l56_dsp_download_and_power_up(struct cs35l56_private *cs35l56,
					     bool load_firmware)
{
	int ret;

	/* Use wm_adsp to load and apply the firmware patch and coefficient files */
	ret = wm_adsp_power_up(&cs35l56->dsp, true);
	/*
	 * Abort the first load if it didn't find the suffixed bins and
	 * we have an alternate fallback suffix.
	 */
	cs35l56->dsp.bin_mandatory = (load_firmware && cs35l56->fallback_fw_suffix);

	ret = wm_adsp_power_up(&cs35l56->dsp, load_firmware);
	if ((ret == -ENOENT) && cs35l56->dsp.bin_mandatory) {
		cs35l56->dsp.fwf_suffix = cs35l56->fallback_fw_suffix;
		cs35l56->fallback_fw_suffix = NULL;
		cs35l56->dsp.bin_mandatory = false;
		ret = wm_adsp_power_up(&cs35l56->dsp, load_firmware);
	}

	if (ret) {
		dev_dbg(cs35l56->base.dev, "%s: wm_adsp_power_up ret %d\n", __func__, ret);
		return;
		dev_dbg(cs35l56->base.dev, "wm_adsp_power_up ret %d\n", ret);
		return ret;
	}

	return 0;
}

static void cs35l56_reinit_patch(struct cs35l56_private *cs35l56)
{
	int ret;

	ret = cs35l56_dsp_download_and_power_up(cs35l56, true);
	if (ret)
		return;

	cs35l56_write_cal(cs35l56);

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

	mutex_lock(&cs35l56->base.irq_lock);

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

static int cs35l56_set_fw_suffix(struct cs35l56_private *cs35l56)
{
	if (cs35l56->dsp.fwf_suffix)
		return 0;

	if (!cs35l56->sdw_peripheral)
		return 0;

	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 name as an alternate.
	 */
	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;
}

static int cs35l56_component_probe(struct snd_soc_component *component)
{
	struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
@@ -892,6 +942,10 @@ static int cs35l56_component_probe(struct snd_soc_component *component)
		return -ENOMEM;

	cs35l56->component = component;
	ret = cs35l56_set_fw_suffix(cs35l56);
	if (ret)
		return ret;

	wm_adsp2_component_probe(&cs35l56->dsp, component);

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