Merge tag 'sound-6.16-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai:
"A collection of small fixes. All changes are device-specific at this
time:
- Fixes for Cirrus codecs with SoundWire, including firmware name
updates
- Fix for i.MX8 SoC DSP
- Usual HD-audio, USB-audio, and ASoC AMD quirks
- Fixes for legendary SoundBlaster AWE32 ISA device (a real one, we
still got a bug report after 25 years)
- Minor build fixes"
* tag 'sound-6.16-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (24 commits)
ALSA: hda/realtek: Enable headset Mic on Positivo P15X
ASoC: Intel: sof-function-topology-lib: Print out the unsupported dmic count
ASoC: doc: cs35l56: Add CS35L63 to the list of supported devices
ASoC: SOF: imx8: add core shutdown operation for imx8/imx8x
ALSA: hda/realtek: Add quirk for Asus GA605K
ALSA: hda/realtek: enable headset mic on Latitude 5420 Rugged
ASoC: amd: yc: update quirk data for HP Victus
ASoC: apple: mca: Drop default ARCH_APPLE in Kconfig
ALSA: usb-audio: Rename ALSA kcontrol PCM and PCM1 for the KTMicro sound card
ASoC: amd: yc: Add quirk for MSI Bravo 17 D7VF internal mic
ASoC: doc: cs35l56: Update to add new SoundWire firmware filename suffix
ASoC: cs35l56: Use SoundWire address as alternate firmware suffix on L56 B0
ASoC: cs35l56: Use SoundWire address as firmware name suffix for new silicon
ASoC: sdw_utils: Fix potential NULL pointer deref in is_sdca_endpoint_present()
ALSA: sb: Force to disable DMAs once when DMA mode is changed
ALSA: sb: Don't allow changing the DMA mode during operations
ALSA: hda/realtek: Add quirk for Asus GU605C
ALSA: hda/realtek: Fix built-in mic on ASUS VivoBook X513EA
ALSA: hda/realtek - Add mute LED support for HP Victus 16-s1xxx and HP Victus 15-fa1xxx
ALSA: ctxfi: Replace deprecated strcpy() with strscpy()
...
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
.. 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
|
||||
-------------------------------------------
|
||||
|
||||
|
||||
@@ -703,6 +703,9 @@ static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ct
|
||||
unsigned char nval, oval;
|
||||
int change;
|
||||
|
||||
if (chip->mode & (SB_MODE_PLAYBACK | SB_MODE_CAPTURE))
|
||||
return -EBUSY;
|
||||
|
||||
nval = ucontrol->value.enumerated.item[0];
|
||||
if (nval > 2)
|
||||
return -EINVAL;
|
||||
@@ -711,6 +714,10 @@ static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ct
|
||||
change = nval != oval;
|
||||
snd_sb16_set_dma_mode(chip, nval);
|
||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
||||
if (change) {
|
||||
snd_dma_disable(chip->dma8);
|
||||
snd_dma_disable(chip->dma16);
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,8 +98,8 @@ ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
strcpy(card->driver, "SB-XFi");
|
||||
strcpy(card->shortname, "Creative X-Fi");
|
||||
strscpy(card->driver, "SB-XFi");
|
||||
strscpy(card->shortname, "Creative X-Fi");
|
||||
snprintf(card->longname, sizeof(card->longname), "%s %s %s",
|
||||
card->shortname, atc->chip_name, atc->model_name);
|
||||
|
||||
|
||||
@@ -2283,6 +2283,8 @@ static const struct snd_pci_quirk power_save_denylist[] = {
|
||||
SND_PCI_QUIRK(0x1734, 0x1232, "KONTRON SinglePC", 0),
|
||||
/* Dell ALC3271 */
|
||||
SND_PCI_QUIRK(0x1028, 0x0962, "Dell ALC3271", 0),
|
||||
/* https://bugzilla.kernel.org/show_bug.cgi?id=220210 */
|
||||
SND_PCI_QUIRK(0x17aa, 0x5079, "Lenovo Thinkpad E15", 0),
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -8030,6 +8030,9 @@ enum {
|
||||
ALC294_FIXUP_ASUS_CS35L41_SPI_2,
|
||||
ALC274_FIXUP_HP_AIO_BIND_DACS,
|
||||
ALC287_FIXUP_PREDATOR_SPK_CS35L41_I2C_2,
|
||||
ALC285_FIXUP_ASUS_GA605K_HEADSET_MIC,
|
||||
ALC285_FIXUP_ASUS_GA605K_I2C_SPEAKER2_TO_DAC1,
|
||||
ALC269_FIXUP_POSITIVO_P15X_HEADSET_MIC,
|
||||
};
|
||||
|
||||
/* A special fixup for Lenovo C940 and Yoga Duet 7;
|
||||
@@ -10414,6 +10417,26 @@ static const struct hda_fixup alc269_fixups[] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc274_fixup_hp_aio_bind_dacs,
|
||||
},
|
||||
[ALC285_FIXUP_ASUS_GA605K_HEADSET_MIC] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
{ 0x19, 0x03a11050 },
|
||||
{ 0x1b, 0x03a11c30 },
|
||||
{ }
|
||||
},
|
||||
.chained = true,
|
||||
.chain_id = ALC285_FIXUP_ASUS_GA605K_I2C_SPEAKER2_TO_DAC1
|
||||
},
|
||||
[ALC285_FIXUP_ASUS_GA605K_I2C_SPEAKER2_TO_DAC1] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc285_fixup_speaker2_to_dac1,
|
||||
},
|
||||
[ALC269_FIXUP_POSITIVO_P15X_HEADSET_MIC] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc269_fixup_limit_int_mic_boost,
|
||||
.chained = true,
|
||||
.chain_id = ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
@@ -10509,6 +10532,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
|
||||
SND_PCI_QUIRK(0x1028, 0x0879, "Dell Latitude 5420 Rugged", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
|
||||
@@ -10787,6 +10811,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8b97, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8bb3, "HP Slim OMEN", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8bb4, "HP Slim OMEN", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8bc8, "HP Victus 15-fa1xxx", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
|
||||
SND_PCI_QUIRK(0x103c, 0x8bcd, "HP Omen 16-xd0xxx", ALC245_FIXUP_HP_MUTE_LED_V1_COEFBIT),
|
||||
SND_PCI_QUIRK(0x103c, 0x8bdd, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8bde, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
@@ -10840,6 +10865,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8c91, "HP EliteBook 660", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8c96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8c97, "HP ZBook", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8c9c, "HP Victus 16-s1xxx (MB 8C9C)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
|
||||
SND_PCI_QUIRK(0x103c, 0x8ca1, "HP ZBook Power", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8ca2, "HP ZBook Power", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8ca4, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
@@ -10904,6 +10930,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8e60, "HP Trekker ", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8e61, "HP Trekker ", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8e62, "HP Trekker ", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1032, "ASUS VivoBook X513EA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1043, 0x1034, "ASUS GU605C", ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1),
|
||||
SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
|
||||
SND_PCI_QUIRK(0x1043, 0x1054, "ASUS G614FH/FM/FP", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
@@ -10932,6 +10960,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1043, 0x1313, "Asus K42JZ", ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1043, 0x1314, "ASUS GA605K", ALC285_FIXUP_ASUS_GA605K_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
|
||||
SND_PCI_QUIRK(0x1043, 0x1433, "ASUS GX650PY/PZ/PV/PU/PYV/PZV/PIV/PVV", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC),
|
||||
@@ -11384,6 +11413,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x2782, 0x0214, "VAIO VJFE-CL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
||||
SND_PCI_QUIRK(0x2782, 0x0228, "Infinix ZERO BOOK 13", ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13),
|
||||
SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO),
|
||||
SND_PCI_QUIRK(0x2782, 0x1407, "Positivo P15X", ALC269_FIXUP_POSITIVO_P15X_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x2782, 0x1701, "Infinix Y4 Max", ALC269VC_FIXUP_INFINIX_Y4_MAX),
|
||||
SND_PCI_QUIRK(0x2782, 0x1705, "MEDION E15433", ALC269VC_FIXUP_INFINIX_Y4_MAX),
|
||||
SND_PCI_QUIRK(0x2782, 0x1707, "Vaio VJFE-ADL", ALC298_FIXUP_SPK_VOLUME),
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
goto out;
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -706,16 +706,40 @@ static int cs35l56_write_cal(struct cs35l56_private *cs35l56)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cs35l56_dsp_download_and_power_up(struct cs35l56_private *cs35l56,
|
||||
bool load_firmware)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* 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, "wm_adsp_power_up ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cs35l56_reinit_patch(struct cs35l56_private *cs35l56)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Use wm_adsp to load and apply the firmware patch and coefficient files */
|
||||
ret = wm_adsp_power_up(&cs35l56->dsp, true);
|
||||
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, true);
|
||||
if (ret)
|
||||
return;
|
||||
}
|
||||
|
||||
cs35l56_write_cal(cs35l56);
|
||||
|
||||
@@ -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 @@ err:
|
||||
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);
|
||||
|
||||
@@ -38,6 +38,7 @@ struct cs35l56_private {
|
||||
struct snd_soc_component *component;
|
||||
struct regulator_bulk_data supplies[CS35L56_NUM_BULK_SUPPLIES];
|
||||
struct sdw_slave *sdw_peripheral;
|
||||
const char *fallback_fw_suffix;
|
||||
struct work_struct sdw_irq_work;
|
||||
bool sdw_irq_no_unmask;
|
||||
bool soft_resetting;
|
||||
@@ -52,6 +53,8 @@ struct cs35l56_private {
|
||||
bool tdm_mode;
|
||||
bool sysclk_set;
|
||||
u8 old_sdw_clock_scale;
|
||||
u8 sdw_link_num;
|
||||
u8 sdw_unique_id;
|
||||
};
|
||||
|
||||
extern const struct dev_pm_ops cs35l56_pm_ops_i2c_spi;
|
||||
|
||||
@@ -2162,6 +2162,10 @@ static int cs48l32_hw_params(struct snd_pcm_substream *substream,
|
||||
n_slots_multiple = 1;
|
||||
|
||||
sclk_target = snd_soc_tdm_params_to_bclk(params, slotw, n_slots, n_slots_multiple);
|
||||
if (sclk_target < 0) {
|
||||
cs48l32_asp_err(dai, "Invalid parameters\n");
|
||||
return sclk_target;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs48l32_sclk_rates); i++) {
|
||||
if ((cs48l32_sclk_rates[i].freq >= sclk_target) &&
|
||||
|
||||
@@ -1079,8 +1079,7 @@ static void es8326_init(struct snd_soc_component *component)
|
||||
regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00);
|
||||
regmap_write(es8326->regmap, ES8326_INTOUT_IO,
|
||||
es8326->interrupt_clk);
|
||||
regmap_write(es8326->regmap, ES8326_SDINOUT1_IO,
|
||||
(ES8326_IO_DMIC_CLK << ES8326_SDINOUT1_SHIFT));
|
||||
regmap_write(es8326->regmap, ES8326_SDINOUT1_IO, ES8326_IO_INPUT);
|
||||
regmap_write(es8326->regmap, ES8326_SDINOUT23_IO, ES8326_IO_INPUT);
|
||||
|
||||
regmap_write(es8326->regmap, ES8326_ANA_PDN, 0x00);
|
||||
|
||||
@@ -783,16 +783,19 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
|
||||
char **coeff_filename)
|
||||
{
|
||||
const char *system_name = dsp->system_name;
|
||||
const char *asoc_component_prefix = dsp->component->name_prefix;
|
||||
const char *suffix = dsp->component->name_prefix;
|
||||
int ret = 0;
|
||||
|
||||
if (system_name && asoc_component_prefix) {
|
||||
if (dsp->fwf_suffix)
|
||||
suffix = dsp->fwf_suffix;
|
||||
|
||||
if (system_name && suffix) {
|
||||
if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
|
||||
cirrus_dir, system_name,
|
||||
asoc_component_prefix, "wmfw")) {
|
||||
suffix, "wmfw")) {
|
||||
wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
|
||||
cirrus_dir, system_name,
|
||||
asoc_component_prefix, "bin");
|
||||
suffix, "bin");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -801,10 +804,10 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
|
||||
if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
|
||||
cirrus_dir, system_name,
|
||||
NULL, "wmfw")) {
|
||||
if (asoc_component_prefix)
|
||||
if (suffix)
|
||||
wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
|
||||
cirrus_dir, system_name,
|
||||
asoc_component_prefix, "bin");
|
||||
suffix, "bin");
|
||||
|
||||
if (!*coeff_firmware)
|
||||
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,
|
||||
|
||||
/* Check system-specific bin without wmfw before falling back to generic */
|
||||
if (dsp->wmfw_optional && system_name) {
|
||||
if (asoc_component_prefix)
|
||||
if (suffix)
|
||||
wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
|
||||
cirrus_dir, system_name,
|
||||
asoc_component_prefix, "bin");
|
||||
suffix, "bin");
|
||||
|
||||
if (!*coeff_firmware)
|
||||
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,
|
||||
adsp_err(dsp, "Failed to request firmware <%s>%s-%s-%s<-%s<%s>>.wmfw\n",
|
||||
cirrus_dir, dsp->part,
|
||||
dsp->fwf_name ? dsp->fwf_name : dsp->cs_dsp.name,
|
||||
wm_adsp_fw[dsp->fw].file, system_name, asoc_component_prefix);
|
||||
wm_adsp_fw[dsp->fw].file, system_name, suffix);
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
@@ -997,11 +1000,17 @@ int wm_adsp_power_up(struct wm_adsp *dsp, bool load_firmware)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (dsp->bin_mandatory && !coeff_firmware) {
|
||||
ret = -ENOENT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = cs_dsp_power_up(&dsp->cs_dsp,
|
||||
wmfw_firmware, wmfw_filename,
|
||||
coeff_firmware, coeff_filename,
|
||||
wm_adsp_fw_text[dsp->fw]);
|
||||
|
||||
err:
|
||||
wm_adsp_release_firmware_files(dsp,
|
||||
wmfw_firmware, wmfw_filename,
|
||||
coeff_firmware, coeff_filename);
|
||||
|
||||
@@ -29,12 +29,14 @@ struct wm_adsp {
|
||||
const char *part;
|
||||
const char *fwf_name;
|
||||
const char *system_name;
|
||||
const char *fwf_suffix;
|
||||
struct snd_soc_component *component;
|
||||
|
||||
unsigned int sys_config_size;
|
||||
|
||||
int fw;
|
||||
bool wmfw_optional;
|
||||
bool bin_mandatory;
|
||||
|
||||
struct work_struct boot_work;
|
||||
int (*control_add)(struct wm_adsp *dsp, struct cs_dsp_coeff_ctl *cs_ctl);
|
||||
|
||||
@@ -73,7 +73,8 @@ int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_
|
||||
break;
|
||||
default:
|
||||
dev_warn(card->dev,
|
||||
"only -2ch and -4ch are supported for dmic\n");
|
||||
"unsupported number of dmics: %d\n",
|
||||
mach_params.dmic_num);
|
||||
continue;
|
||||
}
|
||||
tplg_dev = TPLG_DEVICE_INTEL_PCH_DMIC;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
@@ -1205,6 +1205,8 @@ static int is_sdca_endpoint_present(struct device *dev,
|
||||
int i;
|
||||
|
||||
dlc = kzalloc(sizeof(*dlc), GFP_KERNEL);
|
||||
if (!dlc)
|
||||
return -ENOMEM;
|
||||
|
||||
adr_end = &adr_dev->endpoints[end_index];
|
||||
dai_info = &codec_info->dais[adr_end->num];
|
||||
|
||||
@@ -40,6 +40,19 @@ struct imx8m_chip_data {
|
||||
struct reset_control *run_stall;
|
||||
};
|
||||
|
||||
static int imx8_shutdown(struct snd_sof_dev *sdev)
|
||||
{
|
||||
/*
|
||||
* Force the DSP to stall. After the firmware image is loaded,
|
||||
* the stall will be removed during run() by a matching
|
||||
* imx_sc_pm_cpu_start() call.
|
||||
*/
|
||||
imx_sc_pm_cpu_start(get_chip_pdata(sdev), IMX_SC_R_DSP, false,
|
||||
RESET_VECTOR_VADDR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* DSP control.
|
||||
*/
|
||||
@@ -281,11 +294,13 @@ static int imx8_ops_init(struct snd_sof_dev *sdev)
|
||||
static const struct imx_chip_ops imx8_chip_ops = {
|
||||
.probe = imx8_probe,
|
||||
.core_kick = imx8_run,
|
||||
.core_shutdown = imx8_shutdown,
|
||||
};
|
||||
|
||||
static const struct imx_chip_ops imx8x_chip_ops = {
|
||||
.probe = imx8_probe,
|
||||
.core_kick = imx8x_run,
|
||||
.core_shutdown = imx8_shutdown,
|
||||
};
|
||||
|
||||
static const struct imx_chip_ops imx8m_chip_ops = {
|
||||
|
||||
@@ -383,6 +383,13 @@ static const struct usbmix_name_map ms_usb_link_map[] = {
|
||||
{ 0 } /* terminator */
|
||||
};
|
||||
|
||||
/* KTMicro USB */
|
||||
static struct usbmix_name_map s31b2_0022_map[] = {
|
||||
{ 23, "Speaker Playback" },
|
||||
{ 18, "Headphone Playback" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* ASUS ROG Zenith II with Realtek ALC1220-VB */
|
||||
static const struct usbmix_name_map asus_zenith_ii_map[] = {
|
||||
{ 19, NULL, 12 }, /* FU, Input Gain Pad - broken response, disabled */
|
||||
@@ -692,6 +699,11 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = {
|
||||
.id = USB_ID(0x045e, 0x083c),
|
||||
.map = ms_usb_link_map,
|
||||
},
|
||||
{
|
||||
/* KTMicro USB */
|
||||
.id = USB_ID(0X31b2, 0x0022),
|
||||
.map = s31b2_0022_map,
|
||||
},
|
||||
{ 0 } /* terminator */
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user