summaryrefslogtreecommitdiff
path: root/sound/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-05-15 20:02:36 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2024-05-15 20:02:36 +0300
commit33e02dc69afbd8f1b85a51d74d72f139ba4ca623 (patch)
tree419637178f5dc6758703143d73eedf484d5b810e /sound/pci
parentd34672777da3ea919e8adb0670ab91ddadf7dea0 (diff)
parentd731b1ed15052580b7b2f40559021012d280f1d9 (diff)
downloadlinux-33e02dc69afbd8f1b85a51d74d72f139ba4ca623.tar.xz
Merge tag 'sound-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "This one became bigger than usual, not in the total size but rather containing lots of small changes all over the places. The majority of changes are about ASoC, especially SOF / Intel stuff, and we see an interesting work for ASoC DAPM graph visualization, while there are many other code cleanup and refactoring, too. Core: - A deadlock fix at device disconnection - A new tool dapm-graph for visualising the DAPM state ASoC: - Large updates throughout the Intel audio drivers - Fixes and clarifications for the DAPM documentation - Cleanups of accessors for driver data, module labelling, and for constification - Modernsation and cleanup work in the Mediatek drivers - Several fixes and features for the DaVinci I2S driver - New drivers for several AMD and Intel platforms, Nuvoton NAU8325, Rockchip RK3308 and Texas Instruments PCM6240 HD-audio: - Cleanup for CONFIG_PM dependencies - Cirrus HD-audio codec fixes and quirks Others: - Series of tree-wide fixes in Makefiles to use *-y - Additions of missing module descriptions - Scarlett2 USB mixer enhancements - A series of legacy emu10k1 fixes and improvements" * tag 'sound-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (603 commits) ALSA: hda/realtek: Drop doubly quirk entry for 103c:8a2e ALSA: hda/realtek - fixed headset Mic not show ASoC: SOF: amd: Fix build error with built-in config ALSA: scarlett2: Increase mixer range to +12dB ALSA: scarlett2: Add S/PDIF source selection controls ALSA: core: Remove superfluous CONFIG_PM ALSA: Fix deadlocks with kctl removals at disconnection ASoC: audio-graph-card2: call of_node_get() before of_get_next_child() ASoC: SOF: amd: Correct spaces in Makefile ASoC: rt715-sdca-sdw: Fix wrong complete waiting in rt715_dev_resume() ASoC: Intel: sof_sdw_rt_amp: use dai parameter ASoC: Intel: sof_sdw: add dai parameter to rtd_init callback ASoC: Intel: sof_sdw: use .controls/.widgets to add controls/widgets ASoC: Intel: sof_sdw: add controls and dapm widgets in codec_info ASoC: Intel: sof_sdw: use generic name for controls/widgets ASoC: Intel: sof_sdw_cs_amp: rename Speakers to Speaker ASoC: Intel: maxim-common: change max98373 data to static ASoC: Intel: sof_sdw: add max98373 dapm routes ASoC: Intel: sof_rt5682: use max_98373_dai_link function ASoC: Intel: sof_nau8825: use max_98373_dai_link function ...
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/Makefile48
-rw-r--r--sound/pci/ali5451/Makefile2
-rw-r--r--sound/pci/asihpi/Makefile2
-rw-r--r--sound/pci/au88x0/Makefile6
-rw-r--r--sound/pci/aw2/Makefile2
-rw-r--r--sound/pci/ca0106/Makefile2
-rw-r--r--sound/pci/ctxfi/Makefile2
-rw-r--r--sound/pci/echoaudio/Makefile28
-rw-r--r--sound/pci/emu10k1/Makefile6
-rw-r--r--sound/pci/emu10k1/emu10k1_callback.c13
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c75
-rw-r--r--sound/pci/emu10k1/emu10k1_patch.c209
-rw-r--r--sound/pci/emu10k1/io.c53
-rw-r--r--sound/pci/emu10k1/memory.c55
-rw-r--r--sound/pci/hda/Kconfig2
-rw-r--r--sound/pci/hda/Makefile52
-rw-r--r--sound/pci/hda/cirrus_scodec_test.c1
-rw-r--r--sound/pci/hda/cs35l41_hda.c416
-rw-r--r--sound/pci/hda/cs35l41_hda.h6
-rw-r--r--sound/pci/hda/cs35l41_hda_property.c24
-rw-r--r--sound/pci/hda/cs35l56_hda.c8
-rw-r--r--sound/pci/hda/hda_codec.c37
-rw-r--r--sound/pci/hda/hda_component.c16
-rw-r--r--sound/pci/hda/hda_component.h7
-rw-r--r--sound/pci/hda/hda_controller.c11
-rw-r--r--sound/pci/hda/hda_controller.h1
-rw-r--r--sound/pci/hda/hda_cs_dsp_ctl.c69
-rw-r--r--sound/pci/hda/hda_generic.c4
-rw-r--r--sound/pci/hda/hda_generic.h2
-rw-r--r--sound/pci/hda/hda_intel.c55
-rw-r--r--sound/pci/hda/hda_intel_trace.h2
-rw-r--r--sound/pci/hda/hda_sysfs.c4
-rw-r--r--sound/pci/hda/patch_analog.c4
-rw-r--r--sound/pci/hda/patch_ca0132.c4
-rw-r--r--sound/pci/hda/patch_cirrus.c4
-rw-r--r--sound/pci/hda/patch_conexant.c4
-rw-r--r--sound/pci/hda/patch_cs8409.c8
-rw-r--r--sound/pci/hda/patch_hdmi.c11
-rw-r--r--sound/pci/hda/patch_realtek.c49
-rw-r--r--sound/pci/hda/patch_sigmatel.c8
-rw-r--r--sound/pci/hda/patch_via.c6
-rw-r--r--sound/pci/ice1712/Makefile6
-rw-r--r--sound/pci/korg1212/Makefile2
-rw-r--r--sound/pci/lx6464es/Makefile2
-rw-r--r--sound/pci/mixart/Makefile2
-rw-r--r--sound/pci/nm256/Makefile2
-rw-r--r--sound/pci/oxygen/Makefile8
-rw-r--r--sound/pci/pcxhr/Makefile2
-rw-r--r--sound/pci/riptide/Makefile2
-rw-r--r--sound/pci/rme9652/Makefile6
-rw-r--r--sound/pci/trident/Makefile2
-rw-r--r--sound/pci/vx222/Makefile2
-rw-r--r--sound/pci/ymfpci/Makefile2
53 files changed, 733 insertions, 623 deletions
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index 04cac7469139..18b673018dfd 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -4,30 +4,30 @@
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
-snd-ad1889-objs := ad1889.o
-snd-als300-objs := als300.o
-snd-als4000-objs := als4000.o
-snd-atiixp-objs := atiixp.o
-snd-atiixp-modem-objs := atiixp_modem.o
-snd-azt3328-objs := azt3328.o
-snd-bt87x-objs := bt87x.o
-snd-cmipci-objs := cmipci.o
-snd-cs4281-objs := cs4281.o
-snd-cs5530-objs := cs5530.o
-snd-ens1370-objs := ens1370.o ak4531_codec.o
-snd-ens1371-objs := ens1371.o
-snd-es1938-objs := es1938.o
-snd-es1968-objs := es1968.o
-snd-fm801-objs := fm801.o
-snd-intel8x0-objs := intel8x0.o
-snd-intel8x0m-objs := intel8x0m.o
-snd-maestro3-objs := maestro3.o
-snd-rme32-objs := rme32.o
-snd-rme96-objs := rme96.o
-snd-sis7019-objs := sis7019.o
-snd-sonicvibes-objs := sonicvibes.o
-snd-via82xx-objs := via82xx.o
-snd-via82xx-modem-objs := via82xx_modem.o
+snd-ad1889-y := ad1889.o
+snd-als300-y := als300.o
+snd-als4000-y := als4000.o
+snd-atiixp-y := atiixp.o
+snd-atiixp-modem-y := atiixp_modem.o
+snd-azt3328-y := azt3328.o
+snd-bt87x-y := bt87x.o
+snd-cmipci-y := cmipci.o
+snd-cs4281-y := cs4281.o
+snd-cs5530-y := cs5530.o
+snd-ens1370-y := ens1370.o ak4531_codec.o
+snd-ens1371-y := ens1371.o
+snd-es1938-y := es1938.o
+snd-es1968-y := es1968.o
+snd-fm801-y := fm801.o
+snd-intel8x0-y := intel8x0.o
+snd-intel8x0m-y := intel8x0m.o
+snd-maestro3-y := maestro3.o
+snd-rme32-y := rme32.o
+snd-rme96-y := rme96.o
+snd-sis7019-y := sis7019.o
+snd-sonicvibes-y := sonicvibes.o
+snd-via82xx-y := via82xx.o
+snd-via82xx-modem-y := via82xx_modem.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_AD1889) += snd-ad1889.o
diff --git a/sound/pci/ali5451/Makefile b/sound/pci/ali5451/Makefile
index 8156198fbaeb..e319a4c1d6b2 100644
--- a/sound/pci/ali5451/Makefile
+++ b/sound/pci/ali5451/Makefile
@@ -4,7 +4,7 @@
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
-snd-ali5451-objs := ali5451.o
+snd-ali5451-y := ali5451.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_ALI5451) += snd-ali5451.o
diff --git a/sound/pci/asihpi/Makefile b/sound/pci/asihpi/Makefile
index 8351f8f5b523..d558a974fa7e 100644
--- a/sound/pci/asihpi/Makefile
+++ b/sound/pci/asihpi/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
-snd-asihpi-objs := asihpi.o hpioctl.o hpimsginit.o\
+snd-asihpi-y := asihpi.o hpioctl.o hpimsginit.o\
hpicmn.o hpifunc.o hpidebug.o hpidspcd.o\
hpios.o hpi6000.o hpi6205.o hpimsgx.o
diff --git a/sound/pci/au88x0/Makefile b/sound/pci/au88x0/Makefile
index 78ab11562f4d..5ec5abdee28d 100644
--- a/sound/pci/au88x0/Makefile
+++ b/sound/pci/au88x0/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
-snd-au8810-objs := au8810.o
-snd-au8820-objs := au8820.o
-snd-au8830-objs := au8830.o
+snd-au8810-y := au8810.o
+snd-au8820-y := au8820.o
+snd-au8830-y := au8830.o
obj-$(CONFIG_SND_AU8810) += snd-au8810.o
obj-$(CONFIG_SND_AU8820) += snd-au8820.o
diff --git a/sound/pci/aw2/Makefile b/sound/pci/aw2/Makefile
index f9045afb4cda..c246f7c7f2bf 100644
--- a/sound/pci/aw2/Makefile
+++ b/sound/pci/aw2/Makefile
@@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
-snd-aw2-objs := aw2-alsa.o aw2-saa7146.o
+snd-aw2-y := aw2-alsa.o aw2-saa7146.o
obj-$(CONFIG_SND_AW2) += snd-aw2.o
diff --git a/sound/pci/ca0106/Makefile b/sound/pci/ca0106/Makefile
index 9e51d3df3ee8..693dc4d80925 100644
--- a/sound/pci/ca0106/Makefile
+++ b/sound/pci/ca0106/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
-snd-ca0106-objs := ca0106_main.o ca0106_mixer.o ca_midi.o
+snd-ca0106-y := ca0106_main.o ca0106_mixer.o ca_midi.o
snd-ca0106-$(CONFIG_SND_PROC_FS) += ca0106_proc.o
obj-$(CONFIG_SND_CA0106) += snd-ca0106.o
diff --git a/sound/pci/ctxfi/Makefile b/sound/pci/ctxfi/Makefile
index 70888706a0af..ff2b1cba3a3c 100644
--- a/sound/pci/ctxfi/Makefile
+++ b/sound/pci/ctxfi/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
-snd-ctxfi-objs := xfi.o ctatc.o ctvmem.o ctpcm.o ctmixer.o ctresource.o \
+snd-ctxfi-y := xfi.o ctatc.o ctvmem.o ctpcm.o ctmixer.o ctresource.o \
ctsrc.o ctamixer.o ctdaio.o ctimap.o cthardware.o cttimer.o \
cthw20k2.o cthw20k1.o
diff --git a/sound/pci/echoaudio/Makefile b/sound/pci/echoaudio/Makefile
index 4865b8fe7434..96667641c7cf 100644
--- a/sound/pci/echoaudio/Makefile
+++ b/sound/pci/echoaudio/Makefile
@@ -4,20 +4,20 @@
# Copyright (c) 2003 by Giuliano Pochini <pochini@shiny.it>
#
-snd-darla20-objs := darla20.o
-snd-gina20-objs := gina20.o
-snd-layla20-objs := layla20.o
-snd-darla24-objs := darla24.o
-snd-gina24-objs := gina24.o
-snd-layla24-objs := layla24.o
-snd-mona-objs := mona.o
-snd-mia-objs := mia.o
-snd-echo3g-objs := echo3g.o
-snd-indigo-objs := indigo.o
-snd-indigoio-objs := indigoio.o
-snd-indigodj-objs := indigodj.o
-snd-indigoiox-objs := indigoiox.o
-snd-indigodjx-objs := indigodjx.o
+snd-darla20-y := darla20.o
+snd-gina20-y := gina20.o
+snd-layla20-y := layla20.o
+snd-darla24-y := darla24.o
+snd-gina24-y := gina24.o
+snd-layla24-y := layla24.o
+snd-mona-y := mona.o
+snd-mia-y := mia.o
+snd-echo3g-y := echo3g.o
+snd-indigo-y := indigo.o
+snd-indigoio-y := indigoio.o
+snd-indigodj-y := indigodj.o
+snd-indigoiox-y := indigoiox.o
+snd-indigodjx-y := indigodjx.o
obj-$(CONFIG_SND_DARLA20) += snd-darla20.o
obj-$(CONFIG_SND_GINA20) += snd-gina20.o
diff --git a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile
index 17d5527be319..1f325abcb3ef 100644
--- a/sound/pci/emu10k1/Makefile
+++ b/sound/pci/emu10k1/Makefile
@@ -4,12 +4,12 @@
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
-snd-emu10k1-objs := emu10k1.o emu10k1_main.o \
+snd-emu10k1-y := emu10k1.o emu10k1_main.o \
irq.o memory.o voice.o emumpu401.o emupcm.o io.o \
emumixer.o emufx.o timer.o p16v.o
snd-emu10k1-$(CONFIG_SND_PROC_FS) += emuproc.o
-snd-emu10k1-synth-objs := emu10k1_synth.o emu10k1_callback.o emu10k1_patch.o
-snd-emu10k1x-objs := emu10k1x.o
+snd-emu10k1-synth-y := emu10k1_synth.o emu10k1_callback.o emu10k1_patch.o
+snd-emu10k1x-y := emu10k1x.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_EMU10K1) += snd-emu10k1.o
diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c
index 941bfbf812ed..ef26e4d3e2a3 100644
--- a/sound/pci/emu10k1/emu10k1_callback.c
+++ b/sound/pci/emu10k1/emu10k1_callback.c
@@ -255,7 +255,7 @@ lookup_voices(struct snd_emux *emu, struct snd_emu10k1 *hw,
/* check if sample is finished playing (non-looping only) */
if (bp != best + V_OFF && bp != best + V_FREE &&
(vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_SINGLESHOT)) {
- val = snd_emu10k1_ptr_read(hw, CCCA_CURRADDR, vp->ch);
+ val = snd_emu10k1_ptr_read(hw, CCCA_CURRADDR, vp->ch) - 64 + 3;
if (val >= vp->reg.loopstart)
bp = best + V_OFF;
}
@@ -310,6 +310,7 @@ start_voice(struct snd_emux_voice *vp)
{
unsigned int temp;
int ch;
+ bool w_16;
u32 psst, dsl, map, ccca, vtarget;
unsigned int addr, mapped_offset;
struct snd_midi_channel *chan;
@@ -321,6 +322,7 @@ start_voice(struct snd_emux_voice *vp)
if (snd_BUG_ON(ch < 0))
return -EINVAL;
chan = vp->chan;
+ w_16 = !(vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS);
emem = (struct snd_emu10k1_memblk *)vp->block;
if (emem == NULL)
@@ -330,7 +332,7 @@ start_voice(struct snd_emux_voice *vp)
/* dev_err(hw->card->devK, "emu: cannot map!\n"); */
return -ENOMEM;
}
- mapped_offset = snd_emu10k1_memblk_offset(emem) >> 1;
+ mapped_offset = snd_emu10k1_memblk_offset(emem) >> w_16;
vp->reg.start += mapped_offset;
vp->reg.end += mapped_offset;
vp->reg.loopstart += mapped_offset;
@@ -362,7 +364,7 @@ start_voice(struct snd_emux_voice *vp)
map = (hw->silent_page.addr << hw->address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
- addr = vp->reg.start;
+ addr = vp->reg.start + 64 - 3;
temp = vp->reg.parm.filterQ;
ccca = (temp << 28) | addr;
if (vp->apitch < 0xe400)
@@ -371,7 +373,7 @@ start_voice(struct snd_emux_voice *vp)
unsigned int shift = (vp->apitch - 0xe000) >> 10;
ccca |= shift << 25;
}
- if (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS)
+ if (!w_16)
ccca |= CCCA_8BITSELECT;
vtarget = (unsigned int)vp->vtarget << 16;
@@ -430,6 +432,9 @@ start_voice(struct snd_emux_voice *vp)
/* Q & current address (Q 4bit value, MSB) */
CCCA, ccca,
+ /* cache */
+ CCR, REG_VAL_PUT(CCR_CACHEINVALIDSIZE, 64),
+
/* reset volume */
VTFT, vtarget | vp->ftarget,
CVCF, vtarget | CVCF_CURRENTFILTER_MASK,
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 8ccc0178360c..5b8a5ba825bd 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -652,52 +652,6 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 *emu)
return 0;
}
-static int snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu,
- const struct firmware *fw_entry)
-{
- int n, i;
- u16 reg;
- u8 value;
- __always_unused u16 write_post;
-
- if (!fw_entry)
- return -EIO;
-
- /* The FPGA is a Xilinx Spartan IIE XC2S50E */
- /* On E-MU 0404b it is a Xilinx Spartan III XC3S50 */
- /* GPIO7 -> FPGA PGMN
- * GPIO6 -> FPGA CCLK
- * GPIO5 -> FPGA DIN
- * FPGA CONFIG OFF -> FPGA PGMN
- */
- spin_lock_irq(&emu->emu_lock);
- outw(0x00, emu->port + A_GPIO); /* Set PGMN low for 100uS. */
- write_post = inw(emu->port + A_GPIO);
- udelay(100);
- outw(0x80, emu->port + A_GPIO); /* Leave bit 7 set during netlist setup. */
- write_post = inw(emu->port + A_GPIO);
- udelay(100); /* Allow FPGA memory to clean */
- for (n = 0; n < fw_entry->size; n++) {
- value = fw_entry->data[n];
- for (i = 0; i < 8; i++) {
- reg = 0x80;
- if (value & 0x1)
- reg = reg | 0x20;
- value = value >> 1;
- outw(reg, emu->port + A_GPIO);
- write_post = inw(emu->port + A_GPIO);
- outw(reg | 0x40, emu->port + A_GPIO);
- write_post = inw(emu->port + A_GPIO);
- }
- }
- /* After programming, set GPIO bit 4 high again. */
- outw(0x10, emu->port + A_GPIO);
- write_post = inw(emu->port + A_GPIO);
- spin_unlock_irq(&emu->emu_lock);
-
- return 0;
-}
-
/* firmware file names, per model, init-fw and dock-fw (optional) */
static const char * const firmware_names[5][2] = {
[EMU_MODEL_EMU1010] = {
@@ -729,7 +683,8 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu, int dock,
return err;
}
- return snd_emu1010_load_firmware_entry(emu, *fw);
+ snd_emu1010_load_firmware_entry(emu, dock, *fw);
+ return 0;
}
static void snd_emu1010_load_dock_firmware(struct snd_emu10k1 *emu)
@@ -744,9 +699,6 @@ static void snd_emu1010_load_dock_firmware(struct snd_emu10k1 *emu)
msleep(200);
dev_info(emu->card->dev, "emu1010: Loading Audio Dock Firmware\n");
- /* Return to Audio Dock programming mode */
- snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG,
- EMU_HANA_FPGA_CONFIG_AUDIODOCK);
err = snd_emu1010_load_firmware(emu, 1, &emu->dock_fw);
if (err < 0)
return;
@@ -864,28 +816,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
snd_emu1010_fpga_lock(emu);
- /* Disable 48Volt power to Audio Dock */
- snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);
-
- /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */
- snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
- dev_dbg(emu->card->dev, "reg1 = 0x%x\n", reg);
- if ((reg & 0x3f) == 0x15) {
- /* FPGA netlist already present so clear it */
- /* Return to programming mode */
-
- snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_HANA);
- }
- snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
- dev_dbg(emu->card->dev, "reg2 = 0x%x\n", reg);
- if ((reg & 0x3f) == 0x15) {
- /* FPGA failed to return to programming mode */
- dev_info(emu->card->dev,
- "emu1010: FPGA failed to return to programming mode\n");
- return -ENODEV;
- }
- dev_info(emu->card->dev, "emu1010: EMU_HANA_ID = 0x%x\n", reg);
-
+ dev_info(emu->card->dev, "emu1010: Loading Hana Firmware\n");
err = snd_emu1010_load_firmware(emu, 0, &emu->firmware);
if (err < 0) {
dev_info(emu->card->dev, "emu1010: Loading Firmware failed\n");
diff --git a/sound/pci/emu10k1/emu10k1_patch.c b/sound/pci/emu10k1/emu10k1_patch.c
index 89890f24509f..dbfa89435ac2 100644
--- a/sound/pci/emu10k1/emu10k1_patch.c
+++ b/sound/pci/emu10k1/emu10k1_patch.c
@@ -16,7 +16,7 @@
#define BLANK_LOOP_START 4
#define BLANK_LOOP_END 8
#define BLANK_LOOP_SIZE 12
-#define BLANK_HEAD_SIZE 32
+#define BLANK_HEAD_SIZE 3
/*
* allocate a sample block and copy data from userspace
@@ -26,56 +26,76 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
struct snd_util_memhdr *hdr,
const void __user *data, long count)
{
+ u8 fill;
+ u32 xor;
+ int shift;
int offset;
int truesize, size, blocksize;
- __maybe_unused int loopsize;
- int loopend, sampleend;
- unsigned int start_addr;
+ int loop_start, loop_end, loop_size, data_end, unroll;
struct snd_emu10k1 *emu;
emu = rec->hw;
if (snd_BUG_ON(!sp || !hdr))
return -EINVAL;
- if (sp->v.size == 0) {
- dev_dbg(emu->card->dev,
- "emu: rom font for sample %d\n", sp->v.sample);
- return 0;
+ if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP | SNDRV_SFNT_SAMPLE_REVERSE_LOOP)) {
+ /* should instead return -ENOTSUPP; but compatibility */
+ printk(KERN_WARNING "Emu10k1 wavetable patch %d with unsupported loop feature\n",
+ sp->v.sample);
}
- /* recalculate address offset */
- sp->v.end -= sp->v.start;
- sp->v.loopstart -= sp->v.start;
- sp->v.loopend -= sp->v.start;
- sp->v.start = 0;
-
- /* some samples have invalid data. the addresses are corrected in voice info */
- sampleend = sp->v.end;
- if (sampleend > sp->v.size)
- sampleend = sp->v.size;
- loopend = sp->v.loopend;
- if (loopend > sampleend)
- loopend = sampleend;
-
- /* be sure loop points start < end */
- if (sp->v.loopstart >= sp->v.loopend)
- swap(sp->v.loopstart, sp->v.loopend);
+ if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS) {
+ shift = 0;
+ fill = 0x80;
+ xor = (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_UNSIGNED) ? 0 : 0x80808080;
+ } else {
+ shift = 1;
+ fill = 0;
+ xor = (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_UNSIGNED) ? 0x80008000 : 0;
+ }
/* compute true data size to be loaded */
truesize = sp->v.size + BLANK_HEAD_SIZE;
- loopsize = 0;
-#if 0 /* not supported */
- if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP))
- loopsize = sp->v.loopend - sp->v.loopstart;
- truesize += loopsize;
-#endif
- if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK)
+ if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK) {
truesize += BLANK_LOOP_SIZE;
+ /* if no blank loop is attached in the sample, add it */
+ if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT) {
+ sp->v.loopstart = sp->v.end + BLANK_LOOP_START;
+ sp->v.loopend = sp->v.end + BLANK_LOOP_END;
+ }
+ }
+
+ loop_start = sp->v.loopstart;
+ loop_end = sp->v.loopend;
+ loop_size = loop_end - loop_start;
+ if (!loop_size)
+ return -EINVAL;
+ data_end = sp->v.end;
+
+ /* recalculate offset */
+ sp->v.start += BLANK_HEAD_SIZE;
+ sp->v.end += BLANK_HEAD_SIZE;
+ sp->v.loopstart += BLANK_HEAD_SIZE;
+ sp->v.loopend += BLANK_HEAD_SIZE;
+
+ // Automatic pre-filling of the cache does not work in the presence
+ // of loops (*), and we don't want to fill it manually, as that is
+ // fiddly and slow. So we unroll the loop until the loop end is
+ // beyond the cache size.
+ // (*) Strictly speaking, a single iteration is supported (that's
+ // how it works when the playback engine runs), but handling this
+ // special case is not worth it.
+ unroll = 0;
+ while (sp->v.loopend < 64) {
+ truesize += loop_size;
+ sp->v.loopstart += loop_size;
+ sp->v.loopend += loop_size;
+ sp->v.end += loop_size;
+ unroll++;
+ }
/* try to allocate a memory block */
- blocksize = truesize;
- if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
- blocksize *= 2;
+ blocksize = truesize << shift;
sp->block = snd_emu10k1_synth_alloc(emu, blocksize);
if (sp->block == NULL) {
dev_dbg(emu->card->dev,
@@ -88,110 +108,43 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
/* write blank samples at head */
offset = 0;
- size = BLANK_HEAD_SIZE;
- if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
- size *= 2;
- if (offset + size > blocksize)
- return -EINVAL;
- snd_emu10k1_synth_bzero(emu, sp->block, offset, size);
- offset += size;
-
- /* copy start->loopend */
- size = loopend;
- if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
- size *= 2;
- if (offset + size > blocksize)
- return -EINVAL;
- if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
- snd_emu10k1_synth_free(emu, sp->block);
- sp->block = NULL;
- return -EFAULT;
- }
+ size = BLANK_HEAD_SIZE << shift;
+ snd_emu10k1_synth_memset(emu, sp->block, offset, size, fill);
offset += size;
- data += size;
-
-#if 0 /* not supported yet */
- /* handle reverse (or bidirectional) loop */
- if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP)) {
- /* copy loop in reverse */
- if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) {
- int woffset;
- unsigned short *wblock = (unsigned short*)block;
- woffset = offset / 2;
- if (offset + loopsize * 2 > blocksize)
- return -EINVAL;
- for (i = 0; i < loopsize; i++)
- wblock[woffset + i] = wblock[woffset - i -1];
- offset += loopsize * 2;
- } else {
- if (offset + loopsize > blocksize)
- return -EINVAL;
- for (i = 0; i < loopsize; i++)
- block[offset + i] = block[offset - i -1];
- offset += loopsize;
- }
- /* modify loop pointers */
- if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_BIDIR_LOOP) {
- sp->v.loopend += loopsize;
- } else {
- sp->v.loopstart += loopsize;
- sp->v.loopend += loopsize;
+ /* copy provided samples */
+ if (unroll && loop_end <= data_end) {
+ size = loop_end << shift;
+ if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size, xor))
+ goto faulty;
+ offset += size;
+
+ data += loop_start << shift;
+ while (--unroll > 0) {
+ size = loop_size << shift;
+ if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size, xor))
+ goto faulty;
+ offset += size;
}
- /* add sample pointer */
- sp->v.end += loopsize;
- }
-#endif
- /* loopend -> sample end */
- size = sp->v.size - loopend;
- if (size < 0)
- return -EINVAL;
- if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
- size *= 2;
- if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
- snd_emu10k1_synth_free(emu, sp->block);
- sp->block = NULL;
- return -EFAULT;
+ size = (data_end - loop_start) << shift;
+ } else {
+ size = data_end << shift;
}
+ if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size, xor))
+ goto faulty;
offset += size;
/* clear rest of samples (if any) */
if (offset < blocksize)
- snd_emu10k1_synth_bzero(emu, sp->block, offset, blocksize - offset);
-
- if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK) {
- /* if no blank loop is attached in the sample, add it */
- if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT) {
- sp->v.loopstart = sp->v.end + BLANK_LOOP_START;
- sp->v.loopend = sp->v.end + BLANK_LOOP_END;
- }
- }
-
-#if 0 /* not supported yet */
- if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_UNSIGNED) {
- /* unsigned -> signed */
- if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) {
- unsigned short *wblock = (unsigned short*)block;
- for (i = 0; i < truesize; i++)
- wblock[i] ^= 0x8000;
- } else {
- for (i = 0; i < truesize; i++)
- block[i] ^= 0x80;
- }
- }
-#endif
-
- /* recalculate offset */
- start_addr = BLANK_HEAD_SIZE * 2;
- if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
- start_addr >>= 1;
- sp->v.start += start_addr;
- sp->v.end += start_addr;
- sp->v.loopstart += start_addr;
- sp->v.loopend += start_addr;
+ snd_emu10k1_synth_memset(emu, sp->block, offset, blocksize - offset, fill);
return 0;
+
+faulty:
+ snd_emu10k1_synth_free(emu, sp->block);
+ sp->block = NULL;
+ return -EFAULT;
}
/*
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index f4a1c2d4b078..b60ab5671e00 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -422,6 +422,59 @@ void snd_emu1010_update_clock(struct snd_emu10k1 *emu)
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, leds);
}
+void snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, int dock,
+ const struct firmware *fw_entry)
+{
+ __always_unused u16 write_post;
+
+ // On E-MU 1010 rev1 the FPGA is a Xilinx Spartan IIE XC2S50E.
+ // On E-MU 0404b it is a Xilinx Spartan III XC3S50.
+ // The wiring is as follows:
+ // GPO7 -> FPGA input & 1K resistor -> FPGA /PGMN <- FPGA output
+ // In normal operation, the active low reset line is held up by
+ // an FPGA output, while the GPO pin performs its duty as control
+ // register access strobe signal. Writing the respective bit to
+ // EMU_HANA_FPGA_CONFIG puts the FPGA output into high-Z mode, at
+ // which point the GPO pin can control the reset line through the
+ // resistor.
+ // GPO6 -> FPGA CCLK & FPGA input
+ // GPO5 -> FPGA DIN (dual function)
+
+ // If the FPGA is already programmed, return it to programming mode
+ snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG,
+ dock ? EMU_HANA_FPGA_CONFIG_AUDIODOCK :
+ EMU_HANA_FPGA_CONFIG_HANA);
+
+ // Assert reset line for 100uS
+ outw(0x00, emu->port + A_GPIO);
+ write_post = inw(emu->port + A_GPIO);
+ udelay(100);
+ outw(0x80, emu->port + A_GPIO);
+ write_post = inw(emu->port + A_GPIO);
+ udelay(100); // Allow FPGA memory to clean
+
+ // Upload the netlist. Keep reset line high!
+ for (int n = 0; n < fw_entry->size; n++) {
+ u8 value = fw_entry->data[n];
+ for (int i = 0; i < 8; i++) {
+ u16 reg = 0x80;
+ if (value & 1)
+ reg |= 0x20;
+ value >>= 1;
+ outw(reg, emu->port + A_GPIO);
+ write_post = inw(emu->port + A_GPIO);
+ outw(reg | 0x40, emu->port + A_GPIO);
+ write_post = inw(emu->port + A_GPIO);
+ }
+ }
+
+ // After programming, set GPIO bit 4 high again.
+ // This appears to be a config word that the rev1 Hana
+ // firmware reads; weird things happen without this.
+ outw(0x10, emu->port + A_GPIO);
+ write_post = inw(emu->port + A_GPIO);
+}
+
void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
{
unsigned long flags;
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 20b07117574b..d29711777161 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -565,15 +565,18 @@ static inline void *offset_ptr(struct snd_emu10k1 *emu, int page, int offset)
}
/*
- * bzero(blk + offset, size)
+ * memset(blk + offset, value, size)
*/
-int snd_emu10k1_synth_bzero(struct snd_emu10k1 *emu, struct snd_util_memblk *blk,
- int offset, int size)
+int snd_emu10k1_synth_memset(struct snd_emu10k1 *emu, struct snd_util_memblk *blk,
+ int offset, int size, u8 value)
{
int page, nextofs, end_offset, temp, temp1;
void *ptr;
struct snd_emu10k1_memblk *p = (struct snd_emu10k1_memblk *)blk;
+ if (snd_BUG_ON(offset + size > p->mem.size))
+ return -EFAULT;
+
offset += blk->offset & (PAGE_SIZE - 1);
end_offset = offset + size;
page = get_aligned_page(offset);
@@ -585,25 +588,55 @@ int snd_emu10k1_synth_bzero(struct snd_emu10k1 *emu, struct snd_util_memblk *blk
temp = temp1;
ptr = offset_ptr(emu, page + p->first_page, offset);
if (ptr)
- memset(ptr, 0, temp);
+ memset(ptr, value, temp);
offset = nextofs;
page++;
} while (offset < end_offset);
return 0;
}
-EXPORT_SYMBOL(snd_emu10k1_synth_bzero);
+EXPORT_SYMBOL(snd_emu10k1_synth_memset);
+
+// Note that the value is assumed to be suitably repetitive.
+static void xor_range(void *ptr, int size, u32 value)
+{
+ if ((long)ptr & 1) {
+ *(u8 *)ptr ^= (u8)value;
+ ptr++;
+ size--;
+ }
+ if (size > 1 && ((long)ptr & 2)) {
+ *(u16 *)ptr ^= (u16)value;
+ ptr += 2;
+ size -= 2;
+ }
+ while (size > 3) {
+ *(u32 *)ptr ^= value;
+ ptr += 4;
+ size -= 4;
+ }
+ if (size > 1) {
+ *(u16 *)ptr ^= (u16)value;
+ ptr += 2;
+ size -= 2;
+ }
+ if (size > 0)
+ *(u8 *)ptr ^= (u8)value;
+}
/*
- * copy_from_user(blk + offset, data, size)
+ * copy_from_user(blk + offset, data, size) ^ xor
*/
int snd_emu10k1_synth_copy_from_user(struct snd_emu10k1 *emu, struct snd_util_memblk *blk,
- int offset, const char __user *data, int size)
+ int offset, const char __user *data, int size, u32 xor)
{
int page, nextofs, end_offset, temp, temp1;
void *ptr;
struct snd_emu10k1_memblk *p = (struct snd_emu10k1_memblk *)blk;
+ if (snd_BUG_ON(offset + size > p->mem.size))
+ return -EFAULT;
+
offset += blk->offset & (PAGE_SIZE - 1);
end_offset = offset + size;
page = get_aligned_page(offset);
@@ -614,8 +647,12 @@ int snd_emu10k1_synth_copy_from_user(struct snd_emu10k1 *emu, struct snd_util_me
if (temp1 < temp)
temp = temp1;
ptr = offset_ptr(emu, page + p->first_page, offset);
- if (ptr && copy_from_user(ptr, data, temp))
- return -EFAULT;
+ if (ptr) {
+ if (copy_from_user(ptr, data, temp))
+ return -EFAULT;
+ if (xor)
+ xor_range(ptr, temp, xor);
+ }
offset = nextofs;
data += temp;
page++;
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index f806636242ee..0da625533afc 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -128,6 +128,7 @@ config SND_HDA_SCODEC_CS35L41_I2C
select SND_SOC_CS35L41_LIB
select SND_HDA_SCODEC_CS35L41
select SND_HDA_CS_DSP_CONTROLS
+ select SND_SOC_CS_AMP_LIB
help
Say Y or M here to include CS35L41 I2C HD-audio side codec support
in snd-hda-intel driver, such as ALC287.
@@ -144,6 +145,7 @@ config SND_HDA_SCODEC_CS35L41_SPI
select SND_SOC_CS35L41_LIB
select SND_HDA_SCODEC_CS35L41
select SND_HDA_CS_DSP_CONTROLS
+ select SND_SOC_CS_AMP_LIB
help
Say Y or M here to include CS35L41 SPI HD-audio side codec support
in snd-hda-intel driver, such as ALC287.
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 13e04e1f65de..058ca0a289e4 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
-snd-hda-intel-objs := hda_intel.o
-snd-hda-tegra-objs := hda_tegra.o
+snd-hda-intel-y := hda_intel.o
+snd-hda-tegra-y := hda_tegra.o
snd-hda-codec-y := hda_bind.o hda_codec.o hda_jack.o hda_auto_parser.o hda_sysfs.o
snd-hda-codec-y += hda_controller.o
@@ -13,32 +13,32 @@ snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
CFLAGS_hda_controller.o := -I$(src)
CFLAGS_hda_intel.o := -I$(src)
-snd-hda-codec-generic-objs := hda_generic.o
-snd-hda-codec-realtek-objs := patch_realtek.o
-snd-hda-codec-cmedia-objs := patch_cmedia.o
-snd-hda-codec-analog-objs := patch_analog.o
-snd-hda-codec-idt-objs := patch_sigmatel.o
-snd-hda-codec-si3054-objs := patch_si3054.o
-snd-hda-codec-cirrus-objs := patch_cirrus.o
-snd-hda-codec-cs8409-objs := patch_cs8409.o patch_cs8409-tables.o
-snd-hda-codec-ca0110-objs := patch_ca0110.o
-snd-hda-codec-ca0132-objs := patch_ca0132.o
-snd-hda-codec-conexant-objs := patch_conexant.o
-snd-hda-codec-via-objs := patch_via.o
-snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o
+snd-hda-codec-generic-y := hda_generic.o
+snd-hda-codec-realtek-y := patch_realtek.o
+snd-hda-codec-cmedia-y := patch_cmedia.o
+snd-hda-codec-analog-y := patch_analog.o
+snd-hda-codec-idt-y := patch_sigmatel.o
+snd-hda-codec-si3054-y := patch_si3054.o
+snd-hda-codec-cirrus-y := patch_cirrus.o
+snd-hda-codec-cs8409-y := patch_cs8409.o patch_cs8409-tables.o
+snd-hda-codec-ca0110-y := patch_ca0110.o
+snd-hda-codec-ca0132-y := patch_ca0132.o
+snd-hda-codec-conexant-y := patch_conexant.o
+snd-hda-codec-via-y := patch_via.o
+snd-hda-codec-hdmi-y := patch_hdmi.o hda_eld.o
# side codecs
-snd-hda-cirrus-scodec-objs := cirrus_scodec.o
-snd-hda-cirrus-scodec-test-objs := cirrus_scodec_test.o
-snd-hda-scodec-cs35l41-objs := cs35l41_hda.o cs35l41_hda_property.o
-snd-hda-scodec-cs35l41-i2c-objs := cs35l41_hda_i2c.o
-snd-hda-scodec-cs35l41-spi-objs := cs35l41_hda_spi.o
-snd-hda-scodec-cs35l56-objs := cs35l56_hda.o
-snd-hda-scodec-cs35l56-i2c-objs := cs35l56_hda_i2c.o
-snd-hda-scodec-cs35l56-spi-objs := cs35l56_hda_spi.o
-snd-hda-cs-dsp-ctls-objs := hda_cs_dsp_ctl.o
-snd-hda-scodec-component-objs := hda_component.o
-snd-hda-scodec-tas2781-i2c-objs := tas2781_hda_i2c.o
+snd-hda-cirrus-scodec-y := cirrus_scodec.o
+snd-hda-cirrus-scodec-test-y := cirrus_scodec_test.o
+snd-hda-scodec-cs35l41-y := cs35l41_hda.o cs35l41_hda_property.o
+snd-hda-scodec-cs35l41-i2c-y := cs35l41_hda_i2c.o
+snd-hda-scodec-cs35l41-spi-y := cs35l41_hda_spi.o
+snd-hda-scodec-cs35l56-y := cs35l56_hda.o
+snd-hda-scodec-cs35l56-i2c-y := cs35l56_hda_i2c.o
+snd-hda-scodec-cs35l56-spi-y := cs35l56_hda_spi.o
+snd-hda-cs-dsp-ctls-y := hda_cs_dsp_ctl.o
+snd-hda-scodec-component-y := hda_component.o
+snd-hda-scodec-tas2781-i2c-y := tas2781_hda_i2c.o
# common driver
obj-$(CONFIG_SND_HDA) := snd-hda-codec.o
diff --git a/sound/pci/hda/cirrus_scodec_test.c b/sound/pci/hda/cirrus_scodec_test.c
index 8ae373676bd1..e925ebe21ccb 100644
--- a/sound/pci/hda/cirrus_scodec_test.c
+++ b/sound/pci/hda/cirrus_scodec_test.c
@@ -366,5 +366,6 @@ static struct kunit_suite cirrus_scodec_test_suite = {
kunit_test_suite(cirrus_scodec_test_suite);
MODULE_IMPORT_NS(SND_HDA_CIRRUS_SCODEC);
+MODULE_DESCRIPTION("KUnit test for the Cirrus side-codec library");
MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
MODULE_LICENSE("GPL");
diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c
index d3fa6e136744..2b0404f6e271 100644
--- a/sound/pci/hda/cs35l41_hda.c
+++ b/sound/pci/hda/cs35l41_hda.c
@@ -22,7 +22,6 @@
#include "hda_cs_dsp_ctl.h"
#include "cs35l41_hda_property.h"
-#define CS35L41_FIRMWARE_ROOT "cirrus/"
#define CS35L41_PART "cs35l41"
#define HALO_STATE_DSP_CTL_NAME "HALO_STATE"
@@ -37,6 +36,42 @@
#define CS35L41_UUID "50d90cdc-3de4-4f18-b528-c7fe3b71f40d"
#define CS35L41_DSM_GET_MUTE 5
#define CS35L41_NOTIFY_EVENT 0x91
+#define CS35L41_TUNING_SIG 0x109A4A35
+
+enum cs35l41_tuning_param_types {
+ TUNING_PARAM_GAIN,
+};
+
+struct cs35l41_tuning_param_hdr {
+ __le32 tuning_index;
+ __le32 type;
+ __le32 size;
+} __packed;
+
+struct cs35l41_tuning_param {
+ struct cs35l41_tuning_param_hdr hdr;
+ union {
+ __le32 gain;
+ };
+} __packed;
+
+struct cs35l41_tuning_params {
+ __le32 signature;
+ __le32 version;
+ __le32 size;
+ __le32 num_entries;
+ u8 data[];
+} __packed;
+
+/* Firmware calibration controls */
+static const struct cirrus_amp_cal_controls cs35l41_calibration_controls = {
+ .alg_id = CAL_DSP_CTL_ALG,
+ .mem_region = CAL_DSP_CTL_TYPE,
+ .ambient = CAL_AMBIENT_DSP_CTL_NAME,
+ .calr = CAL_R_DSP_CTL_NAME,
+ .status = CAL_STATUS_DSP_CTL_NAME,
+ .checksum = CAL_CHECKSUM_DSP_CTL_NAME,
+};
static bool firmware_autostart = 1;
module_param(firmware_autostart, bool, 0444);
@@ -75,7 +110,7 @@ static const struct reg_sequence cs35l41_hda_config_dsp[] = {
{ CS35L41_SP_HIZ_CTRL, 0x00000003 }, // Hi-Z unused/disabled
{ CS35L41_SP_TX_WL, 0x00000018 }, // 24 cycles/slot
{ CS35L41_SP_RX_WL, 0x00000018 }, // 24 cycles/slot
- { CS35L41_DAC_PCM1_SRC, 0x00000032 }, // DACPCM1_SRC = ERR_VOL
+ { CS35L41_DAC_PCM1_SRC, 0x00000032 }, // DACPCM1_SRC = DSP1TX1
{ CS35L41_ASP_TX1_SRC, 0x00000018 }, // ASPTX1 SRC = VMON
{ CS35L41_ASP_TX2_SRC, 0x00000019 }, // ASPTX2 SRC = IMON
{ CS35L41_ASP_TX3_SRC, 0x00000028 }, // ASPTX3 SRC = VPMON
@@ -84,7 +119,7 @@ static const struct reg_sequence cs35l41_hda_config_dsp[] = {
{ CS35L41_DSP1_RX2_SRC, 0x00000008 }, // DSP1RX2 SRC = ASPRX1
{ CS35L41_DSP1_RX3_SRC, 0x00000018 }, // DSP1RX3 SRC = VMON
{ CS35L41_DSP1_RX4_SRC, 0x00000019 }, // DSP1RX4 SRC = IMON
- { CS35L41_DSP1_RX5_SRC, 0x00000029 }, // DSP1RX5 SRC = VBSTMON
+ { CS35L41_DSP1_RX6_SRC, 0x00000029 }, // DSP1RX6 SRC = VBSTMON
};
static const struct reg_sequence cs35l41_hda_unmute[] = {
@@ -92,11 +127,6 @@ static const struct reg_sequence cs35l41_hda_unmute[] = {
{ CS35L41_AMP_GAIN_CTRL, 0x00000084 }, // AMP_GAIN_PCM 4.5 dB
};
-static const struct reg_sequence cs35l41_hda_unmute_dsp[] = {
- { CS35L41_AMP_DIG_VOL_CTRL, 0x00008000 }, // AMP_HPF_PCM_EN = 1, AMP_VOL_PCM 0.0 dB
- { CS35L41_AMP_GAIN_CTRL, 0x00000233 }, // AMP_GAIN_PCM = 17.5dB AMP_GAIN_PDM = 19.5dB
-};
-
static const struct reg_sequence cs35l41_hda_mute[] = {
{ CS35L41_AMP_GAIN_CTRL, 0x00000000 }, // AMP_GAIN_PCM 0.5 dB
{ CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_HPF_PCM_EN = 1, AMP_VOL_PCM Mute
@@ -117,9 +147,30 @@ static const struct cs_dsp_client_ops client_ops = {
.control_remove = hda_cs_dsp_control_remove,
};
+static int cs35l41_request_tuning_param_file(struct cs35l41_hda *cs35l41, char *tuning_filename,
+ const struct firmware **firmware, char **filename,
+ const char *ssid)
+{
+ int ret = 0;
+
+ /* Filename is the same as the tuning file with "cfg" suffix */
+ *filename = kasprintf(GFP_KERNEL, "%scfg", tuning_filename);
+ if (*filename == NULL)
+ return -ENOMEM;
+
+ ret = firmware_request_nowarn(firmware, *filename, cs35l41->dev);
+ if (ret != 0) {
+ dev_dbg(cs35l41->dev, "Failed to request '%s'\n", *filename);
+ kfree(*filename);
+ *filename = NULL;
+ }
+
+ return ret;
+}
+
static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41,
const struct firmware **firmware, char **filename,
- const char *dir, const char *ssid, const char *amp_name,
+ const char *ssid, const char *amp_name,
int spkid, const char *filetype)
{
const char * const dsp_name = cs35l41->cs_dsp.name;
@@ -127,23 +178,23 @@ static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41,
int ret = 0;
if (spkid > -1 && ssid && amp_name)
- *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-spkid%d-%s.%s", dir, CS35L41_PART,
+ *filename = kasprintf(GFP_KERNEL, "cirrus/%s-%s-%s-%s-spkid%d-%s.%s", CS35L41_PART,
dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type],
ssid, spkid, amp_name, filetype);
else if (spkid > -1 && ssid)
- *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-spkid%d.%s", dir, CS35L41_PART,
+ *filename = kasprintf(GFP_KERNEL, "cirrus/%s-%s-%s-%s-spkid%d.%s", CS35L41_PART,
dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type],
ssid, spkid, filetype);
else if (ssid && amp_name)
- *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, CS35L41_PART,
+ *filename = kasprintf(GFP_KERNEL, "cirrus/%s-%s-%s-%s-%s.%s", CS35L41_PART,
dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type],
ssid, amp_name, filetype);
else if (ssid)
- *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s.%s", dir, CS35L41_PART,
+ *filename = kasprintf(GFP_KERNEL, "cirrus/%s-%s-%s-%s.%s", CS35L41_PART,
dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type],
ssid, filetype);
else
- *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, CS35L41_PART,
+ *filename = kasprintf(GFP_KERNEL, "cirrus/%s-%s-%s.%s", CS35L41_PART,
dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type],
filetype);
@@ -184,13 +235,11 @@ static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41,
/* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.wmfw */
ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
- CS35L41_FIRMWARE_ROOT,
cs35l41->acpi_subsystem_id, cs35l41->amp_name,
cs35l41->speaker_id, "wmfw");
if (!ret) {
/* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT,
cs35l41->acpi_subsystem_id, cs35l41->amp_name,
cs35l41->speaker_id, "bin");
if (ret)
@@ -201,12 +250,11 @@ static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41,
/* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */
ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
- CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id,
+ cs35l41->acpi_subsystem_id,
cs35l41->amp_name, -1, "wmfw");
if (!ret) {
/* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT,
cs35l41->acpi_subsystem_id, cs35l41->amp_name,
cs35l41->speaker_id, "bin");
if (ret)
@@ -217,18 +265,17 @@ static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41,
/* try cirrus/part-dspN-fwtype-sub<-spkidN>.wmfw */
ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
- CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id,
+ cs35l41->acpi_subsystem_id,
NULL, cs35l41->speaker_id, "wmfw");
if (!ret) {
/* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT,
cs35l41->acpi_subsystem_id,
cs35l41->amp_name, cs35l41->speaker_id, "bin");
if (ret)
/* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware,
- coeff_filename, CS35L41_FIRMWARE_ROOT,
+ coeff_filename,
cs35l41->acpi_subsystem_id, NULL,
cs35l41->speaker_id, "bin");
if (ret)
@@ -239,18 +286,17 @@ static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41,
/* try cirrus/part-dspN-fwtype-sub.wmfw */
ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
- CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id,
+ cs35l41->acpi_subsystem_id,
NULL, -1, "wmfw");
if (!ret) {
/* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT,
cs35l41->acpi_subsystem_id, cs35l41->amp_name,
cs35l41->speaker_id, "bin");
if (ret)
/* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware,
- coeff_filename, CS35L41_FIRMWARE_ROOT,
+ coeff_filename,
cs35l41->acpi_subsystem_id, NULL,
cs35l41->speaker_id, "bin");
if (ret)
@@ -277,13 +323,13 @@ static int cs35l41_fallback_firmware_file(struct cs35l41_hda *cs35l41,
/* fallback try cirrus/part-dspN-fwtype.wmfw */
ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
- CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "wmfw");
+ NULL, NULL, -1, "wmfw");
if (ret)
goto err;
/* fallback try cirrus/part-dspN-fwtype.bin */
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "bin");
+ NULL, NULL, -1, "bin");
if (ret) {
release_firmware(*wmfw_firmware);
kfree(*wmfw_filename);
@@ -312,12 +358,11 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41,
/* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */
ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
- CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id,
+ cs35l41->acpi_subsystem_id,
cs35l41->amp_name, -1, "wmfw");
if (!ret) {
/* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT,
cs35l41->acpi_subsystem_id, cs35l41->amp_name,
-1, "bin");
if (ret)
@@ -328,18 +373,16 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41,
/* try cirrus/part-dspN-fwtype-sub.wmfw */
ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename,
- CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id,
+ cs35l41->acpi_subsystem_id,
NULL, -1, "wmfw");
if (!ret) {
/* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT,
cs35l41->acpi_subsystem_id,
cs35l41->amp_name, -1, "bin");
if (ret)
/* try cirrus/part-dspN-fwtype-sub.bin */
ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename,
- CS35L41_FIRMWARE_ROOT,
cs35l41->acpi_subsystem_id, NULL, -1,
"bin");
if (ret)
@@ -361,95 +404,162 @@ fallback:
coeff_firmware, coeff_filename);
}
-#if IS_ENABLED(CONFIG_EFI)
-static int cs35l41_apply_calibration(struct cs35l41_hda *cs35l41, __be32 ambient, __be32 r0,
- __be32 status, __be32 checksum)
+
+static void cs35l41_hda_apply_calibration(struct cs35l41_hda *cs35l41)
+{
+ int ret;
+
+ if (!cs35l41->cal_data_valid)
+ return;
+
+ ret = cs_amp_write_cal_coeffs(&cs35l41->cs_dsp, &cs35l41_calibration_controls,
+ &cs35l41->cal_data);
+ if (ret < 0)
+ dev_warn(cs35l41->dev, "Failed to apply calibration: %d\n", ret);
+ else
+ dev_info(cs35l41->dev, "Calibration applied: R0=%d\n", cs35l41->cal_data.calR);
+}
+
+static int cs35l41_read_silicon_uid(struct cs35l41_hda *cs35l41, u64 *uid)
{
+ u32 tmp;
int ret;
- ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_AMBIENT_DSP_CTL_NAME, CAL_DSP_CTL_TYPE,
- CAL_DSP_CTL_ALG, &ambient, 4);
+ ret = regmap_read(cs35l41->regmap, CS35L41_DIE_STS2, &tmp);
if (ret) {
- dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_AMBIENT_DSP_CTL_NAME,
- ret);
+ dev_err(cs35l41->dev, "Cannot obtain CS35L41_DIE_STS2: %d\n", ret);
return ret;
}
- ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_R_DSP_CTL_NAME, CAL_DSP_CTL_TYPE,
- CAL_DSP_CTL_ALG, &r0, 4);
+
+ *uid = tmp;
+ *uid <<= 32;
+
+ ret = regmap_read(cs35l41->regmap, CS35L41_DIE_STS1, &tmp);
if (ret) {
- dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_R_DSP_CTL_NAME, ret);
+ dev_err(cs35l41->dev, "Cannot obtain CS35L41_DIE_STS1: %d\n", ret);
return ret;
}
- ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_STATUS_DSP_CTL_NAME, CAL_DSP_CTL_TYPE,
- CAL_DSP_CTL_ALG, &status, 4);
- if (ret) {
- dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_STATUS_DSP_CTL_NAME,
- ret);
+
+ *uid |= tmp;
+
+ dev_dbg(cs35l41->dev, "UniqueID = %#llx\n", *uid);
+
+ return 0;
+}
+
+static int cs35l41_get_calibration(struct cs35l41_hda *cs35l41)
+{
+ u64 silicon_uid;
+ int ret;
+
+ ret = cs35l41_read_silicon_uid(cs35l41, &silicon_uid);
+ if (ret < 0)
return ret;
- }
- ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_CHECKSUM_DSP_CTL_NAME, CAL_DSP_CTL_TYPE,
- CAL_DSP_CTL_ALG, &checksum, 4);
- if (ret) {
- dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_CHECKSUM_DSP_CTL_NAME,
- ret);
+
+ ret = cs_amp_get_efi_calibration_data(cs35l41->dev, silicon_uid,
+ cs35l41->index,
+ &cs35l41->cal_data);
+
+ /* Only return an error status if probe should be aborted */
+ if ((ret == -ENOENT) || (ret == -EOVERFLOW))
+ return 0;
+
+ if (ret < 0)
return ret;
- }
+
+ cs35l41->cal_data_valid = true;
return 0;
}
-static int cs35l41_save_calibration(struct cs35l41_hda *cs35l41)
+
+static void cs35l41_set_default_tuning_params(struct cs35l41_hda *cs35l41)
{
- static efi_guid_t efi_guid = EFI_GUID(0x02f9af02, 0x7734, 0x4233, 0xb4, 0x3d, 0x93, 0xfe,
- 0x5a, 0xa3, 0x5d, 0xb3);
- static efi_char16_t efi_name[] = L"CirrusSmartAmpCalibrationData";
- const struct cs35l41_amp_efi_data *efi_data;
- const struct cs35l41_amp_cal_data *cl;
- unsigned long data_size = 0;
- efi_status_t status;
- int ret = 0;
- u8 *data = NULL;
- u32 attr;
+ cs35l41->tuning_gain = DEFAULT_AMP_GAIN_PCM;
+}
- /* Get real size of UEFI variable */
- status = efi.get_variable(efi_name, &efi_guid, &attr, &data_size, data);
- if (status == EFI_BUFFER_TOO_SMALL) {
- ret = -ENODEV;
- /* Allocate data buffer of data_size bytes */
- data = vmalloc(data_size);
- if (!data)
- return -ENOMEM;
- /* Get variable contents into buffer */
- status = efi.get_variable(efi_name, &efi_guid, &attr, &data_size, data);
- if (status == EFI_SUCCESS) {
- efi_data = (struct cs35l41_amp_efi_data *)data;
- dev_dbg(cs35l41->dev, "Calibration: Size=%d, Amp Count=%d\n",
- efi_data->size, efi_data->count);
- if (efi_data->count > cs35l41->index) {
- cl = &efi_data->data[cs35l41->index];
- dev_dbg(cs35l41->dev,
- "Calibration: Ambient=%02x, Status=%02x, R0=%d\n",
- cl->calAmbient, cl->calStatus, cl->calR);
-
- /* Calibration can only be applied whilst the DSP is not running */
- ret = cs35l41_apply_calibration(cs35l41,
- cpu_to_be32(cl->calAmbient),
- cpu_to_be32(cl->calR),
- cpu_to_be32(cl->calStatus),
- cpu_to_be32(cl->calR + 1));
- }
+static int cs35l41_read_tuning_params(struct cs35l41_hda *cs35l41, const struct firmware *firmware)
+{
+ struct cs35l41_tuning_params *params;
+ unsigned int offset = 0;
+ unsigned int end;
+ int i;
+
+ params = (void *)&firmware->data[0];
+
+ if (le32_to_cpu(params->size) != firmware->size) {
+ dev_err(cs35l41->dev, "Wrong Size for Tuning Param file. Expected %d got %zu\n",
+ le32_to_cpu(params->size), firmware->size);
+ return -EINVAL;
+ }
+
+ if (le32_to_cpu(params->version) != 1) {
+ dev_err(cs35l41->dev, "Unsupported Tuning Param Version: %d\n",
+ le32_to_cpu(params->version));
+ return -EINVAL;
+ }
+
+ if (le32_to_cpu(params->signature) != CS35L41_TUNING_SIG) {
+ dev_err(cs35l41->dev,
+ "Mismatched Signature for Tuning Param file. Expected %#x got %#x\n",
+ CS35L41_TUNING_SIG, le32_to_cpu(params->signature));
+ return -EINVAL;
+ }
+
+ end = firmware->size - sizeof(struct cs35l41_tuning_params);
+
+ for (i = 0; i < le32_to_cpu(params->num_entries); i++) {
+ struct cs35l41_tuning_param *param;
+
+ if ((offset >= end) || ((offset + sizeof(struct cs35l41_tuning_param_hdr)) >= end))
+ return -EFAULT;
+
+ param = (void *)&params->data[offset];
+ offset += le32_to_cpu(param->hdr.size);
+
+ if (offset > end)
+ return -EFAULT;
+
+ switch (le32_to_cpu(param->hdr.type)) {
+ case TUNING_PARAM_GAIN:
+ cs35l41->tuning_gain = le32_to_cpu(param->gain);
+ dev_dbg(cs35l41->dev, "Applying Gain: %d\n", cs35l41->tuning_gain);
+ break;
+ default:
+ break;
}
- vfree(data);
}
- return ret;
+
+ return 0;
}
-#else
-static int cs35l41_save_calibration(struct cs35l41_hda *cs35l41)
+
+static int cs35l41_load_tuning_params(struct cs35l41_hda *cs35l41, char *tuning_filename)
{
- dev_warn(cs35l41->dev, "Calibration not supported without EFI support.\n");
- return 0;
+ const struct firmware *tuning_param_file = NULL;
+ char *tuning_param_filename = NULL;
+ int ret;
+
+ ret = cs35l41_request_tuning_param_file(cs35l41, tuning_filename, &tuning_param_file,
+ &tuning_param_filename, cs35l41->acpi_subsystem_id);
+ if (ret) {
+ dev_dbg(cs35l41->dev, "Missing Tuning Param for file: %s: %d\n", tuning_filename,
+ ret);
+ return 0;
+ }
+
+ ret = cs35l41_read_tuning_params(cs35l41, tuning_param_file);
+ if (ret) {
+ dev_err(cs35l41->dev, "Error reading Tuning Params from file: %s: %d\n",
+ tuning_param_filename, ret);
+ /* Reset to default Tuning Parameters */
+ cs35l41_set_default_tuning_params(cs35l41);
+ }
+
+ release_firmware(tuning_param_file);
+ kfree(tuning_param_filename);
+
+ return ret;
}
-#endif
static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41)
{
@@ -470,27 +580,35 @@ static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41)
cs35l41->halo_initialized = true;
}
+ cs35l41_set_default_tuning_params(cs35l41);
+
ret = cs35l41_request_firmware_files(cs35l41, &wmfw_firmware, &wmfw_filename,
&coeff_firmware, &coeff_filename);
if (ret < 0)
return ret;
dev_dbg(cs35l41->dev, "Loading WMFW Firmware: %s\n", wmfw_filename);
- if (coeff_filename)
+ if (coeff_filename) {
dev_dbg(cs35l41->dev, "Loading Coefficient File: %s\n", coeff_filename);
- else
+ ret = cs35l41_load_tuning_params(cs35l41, coeff_filename);
+ if (ret)
+ dev_warn(cs35l41->dev, "Unable to load Tuning Parameters: %d\n", ret);
+ } else {
dev_warn(cs35l41->dev, "No Coefficient File available.\n");
+ }
ret = cs_dsp_power_up(dsp, wmfw_firmware, wmfw_filename, coeff_firmware, coeff_filename,
hda_cs_dsp_fw_ids[cs35l41->firmware_type]);
if (ret)
- goto err_release;
+ goto err;
cs35l41_add_controls(cs35l41);
- ret = cs35l41_save_calibration(cs35l41);
+ cs35l41_hda_apply_calibration(cs35l41);
-err_release:
+err:
+ if (ret)
+ cs35l41_set_default_tuning_params(cs35l41);
release_firmware(wmfw_firmware);
release_firmware(coeff_firmware);
kfree(wmfw_filename);
@@ -503,6 +621,7 @@ static void cs35l41_shutdown_dsp(struct cs35l41_hda *cs35l41)
{
struct cs_dsp *dsp = &cs35l41->cs_dsp;
+ cs35l41_set_default_tuning_params(cs35l41);
cs_dsp_stop(dsp);
cs_dsp_power_down(dsp);
dev_dbg(cs35l41->dev, "Unloaded Firmware\n");
@@ -553,6 +672,10 @@ static void cs35l41_hda_play_start(struct device *dev)
if (cs35l41->cs_dsp.running) {
regmap_multi_reg_write(reg, cs35l41_hda_config_dsp,
ARRAY_SIZE(cs35l41_hda_config_dsp));
+ if (cs35l41->hw_cfg.bst_type == CS35L41_INT_BOOST)
+ regmap_write(reg, CS35L41_DSP1_RX5_SRC, CS35L41_INPUT_SRC_VPMON);
+ else
+ regmap_write(reg, CS35L41_DSP1_RX5_SRC, CS35L41_INPUT_SRC_VBSTMON);
regmap_update_bits(reg, CS35L41_PWR_CTRL2,
CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK,
1 << CS35L41_VMON_EN_SHIFT | 1 << CS35L41_IMON_EN_SHIFT);
@@ -570,6 +693,7 @@ static void cs35l41_mute(struct device *dev, bool mute)
{
struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
struct regmap *reg = cs35l41->regmap;
+ unsigned int amp_gain;
dev_dbg(dev, "Mute(%d:%d) Playback Started: %d\n", mute, cs35l41->mute_override,
cs35l41->playback_started);
@@ -581,8 +705,13 @@ static void cs35l41_mute(struct device *dev, bool mute)
} else {
dev_dbg(dev, "Unmuting\n");
if (cs35l41->cs_dsp.running) {
- regmap_multi_reg_write(reg, cs35l41_hda_unmute_dsp,
- ARRAY_SIZE(cs35l41_hda_unmute_dsp));
+ dev_dbg(dev, "Using Tuned Gain: %d\n", cs35l41->tuning_gain);
+ amp_gain = (cs35l41->tuning_gain << CS35L41_AMP_GAIN_PCM_SHIFT) |
+ (DEFAULT_AMP_GAIN_PDM << CS35L41_AMP_GAIN_PDM_SHIFT);
+
+ /* AMP_HPF_PCM_EN = 1, AMP_VOL_PCM 0.0 dB */
+ regmap_write(reg, CS35L41_AMP_DIG_VOL_CTRL, 0x00008000);
+ regmap_write(reg, CS35L41_AMP_GAIN_CTRL, amp_gain);
} else {
regmap_multi_reg_write(reg, cs35l41_hda_unmute,
ARRAY_SIZE(cs35l41_hda_unmute));
@@ -1056,6 +1185,9 @@ static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41)
goto clean_dsp;
}
+ dev_info(cs35l41->dev, "Firmware Loaded - Type: %s, Gain: %d\n",
+ hda_cs_dsp_fw_ids[cs35l41->firmware_type], cs35l41->tuning_gain);
+
return 0;
clean_dsp:
@@ -1461,13 +1593,56 @@ static struct regmap_irq_chip cs35l41_regmap_irq_chip = {
.runtime_pm = true,
};
+static void cs35l41_configure_interrupt(struct cs35l41_hda *cs35l41, int irq_pol)
+{
+ int irq;
+ int ret;
+ int i;
+
+ if (!cs35l41->irq) {
+ dev_warn(cs35l41->dev, "No Interrupt Found");
+ goto err;
+ }
+
+ ret = devm_regmap_add_irq_chip(cs35l41->dev, cs35l41->regmap, cs35l41->irq,
+ IRQF_ONESHOT | IRQF_SHARED | irq_pol,
+ 0, &cs35l41_regmap_irq_chip, &cs35l41->irq_data);
+ if (ret) {
+ dev_dbg(cs35l41->dev, "Unable to add IRQ Chip: %d.", ret);
+ goto err;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(cs35l41_irqs); i++) {
+ irq = regmap_irq_get_virq(cs35l41->irq_data, cs35l41_irqs[i].irq);
+ if (irq < 0) {
+ ret = irq;
+ dev_dbg(cs35l41->dev, "Unable to map IRQ %s: %d.", cs35l41_irqs[i].name,
+ ret);
+ goto err;
+ }
+
+ ret = devm_request_threaded_irq(cs35l41->dev, irq, NULL,
+ cs35l41_irqs[i].handler,
+ IRQF_ONESHOT | IRQF_SHARED | irq_pol,
+ cs35l41_irqs[i].name, cs35l41);
+ if (ret) {
+ dev_dbg(cs35l41->dev, "Unable to allocate IRQ %s:: %d.",
+ cs35l41_irqs[i].name, ret);
+ goto err;
+ }
+ }
+ return;
+err:
+ dev_warn(cs35l41->dev,
+ "IRQ Config Failed. Amp errors may not be recoverable without reboot.");
+}
+
static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41)
{
struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
bool using_irq = false;
- int irq, irq_pol;
+ int irq_pol;
int ret;
- int i;
if (!cs35l41->hw_cfg.valid)
return -EINVAL;
@@ -1510,26 +1685,8 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41)
irq_pol = cs35l41_gpio_config(cs35l41->regmap, hw_cfg);
- if (cs35l41->irq && using_irq) {
- ret = devm_regmap_add_irq_chip(cs35l41->dev, cs35l41->regmap, cs35l41->irq,
- IRQF_ONESHOT | IRQF_SHARED | irq_pol,
- 0, &cs35l41_regmap_irq_chip, &cs35l41->irq_data);
- if (ret)
- return ret;
-
- for (i = 0; i < ARRAY_SIZE(cs35l41_irqs); i++) {
- irq = regmap_irq_get_virq(cs35l41->irq_data, cs35l41_irqs[i].irq);
- if (irq < 0)
- return irq;
-
- ret = devm_request_threaded_irq(cs35l41->dev, irq, NULL,
- cs35l41_irqs[i].handler,
- IRQF_ONESHOT | IRQF_SHARED | irq_pol,
- cs35l41_irqs[i].name, cs35l41);
- if (ret)
- return ret;
- }
- }
+ if (using_irq)
+ cs35l41_configure_interrupt(cs35l41, irq_pol);
return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos);
}
@@ -1808,6 +1965,10 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
if (ret)
goto err;
+ ret = cs35l41_get_calibration(cs35l41);
+ if (ret && ret != -ENOENT)
+ goto err;
+
cs35l41_mute(cs35l41->dev, true);
INIT_WORK(&cs35l41->fw_load_work, cs35l41_fw_load_work);
@@ -1888,6 +2049,7 @@ EXPORT_SYMBOL_NS_GPL(cs35l41_hda_pm_ops, SND_HDA_SCODEC_CS35L41);
MODULE_DESCRIPTION("CS35L41 HDA Driver");
MODULE_IMPORT_NS(SND_HDA_CS_DSP_CONTROLS);
+MODULE_IMPORT_NS(SND_SOC_CS_AMP_LIB);
MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, <tanureal@opensource.cirrus.com>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(FW_CS_DSP);
diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h
index 43d55292b327..b0bebb778462 100644
--- a/sound/pci/hda/cs35l41_hda.h
+++ b/sound/pci/hda/cs35l41_hda.h
@@ -16,11 +16,14 @@
#include <linux/gpio/consumer.h>
#include <linux/device.h>
#include <sound/cs35l41.h>
+#include <sound/cs-amp-lib.h>
#include <linux/firmware/cirrus/cs_dsp.h>
#include <linux/firmware/cirrus/wmfw.h>
#define CS35L41_MAX_ACCEPTABLE_SPI_SPEED_HZ 1000000
+#define DEFAULT_AMP_GAIN_PCM 17 /* 17.5dB Gain */
+#define DEFAULT_AMP_GAIN_PDM 19 /* 19.5dB Gain */
struct cs35l41_amp_cal_data {
u32 calTarget[2];
@@ -83,6 +86,9 @@ struct cs35l41_hda {
bool mute_override;
enum control_bus control_bus;
bool bypass_fw;
+ unsigned int tuning_gain;
+ struct cirrus_amp_cal_data cal_data;
+ bool cal_data_valid;
};
diff --git a/sound/pci/hda/cs35l41_hda_property.c b/sound/pci/hda/cs35l41_hda_property.c
index 8fb688e41414..6a7a6d486916 100644
--- a/sound/pci/hda/cs35l41_hda_property.c
+++ b/sound/pci/hda/cs35l41_hda_property.c
@@ -70,6 +70,8 @@ static const struct cs35l41_config cs35l41_config_table[] = {
{ "103C8C15", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4000, 24 },
{ "103C8C16", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4000, 24 },
{ "103C8C17", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4000, 24 },
+ { "103C8C4D", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
+ { "103C8C4E", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8C4F", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8C50", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8C51", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
@@ -95,6 +97,7 @@ static const struct cs35l41_config cs35l41_config_table[] = {
{ "10431863", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "104318D3", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{ "10431A83", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
+ { "10431B93", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431C9F", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431CAF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431CCF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
@@ -108,10 +111,17 @@ static const struct cs35l41_config cs35l41_config_table[] = {
{ "10431F12", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431F1F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
{ "10431F62", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
+ { "10433A20", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
+ { "10433A30", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
+ { "10433A40", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
+ { "10433A50", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10433A60", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
+ { "17AA3865", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
+ { "17AA3866", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
+ { "17AA386E", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 2, -1, 0, 0, 0 },
{ "17AA386F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
- { "17AA3877", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
- { "17AA3878", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
+ { "17AA3877", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
+ { "17AA3878", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
{ "17AA38A9", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 2, -1, 0, 0, 0 },
{ "17AA38AB", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 2, -1, 0, 0, 0 },
{ "17AA38B4", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
@@ -457,6 +467,8 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CSC3551", "103C8C15", generic_dsd_config },
{ "CSC3551", "103C8C16", generic_dsd_config },
{ "CSC3551", "103C8C17", generic_dsd_config },
+ { "CSC3551", "103C8C4D", generic_dsd_config },
+ { "CSC3551", "103C8C4E", generic_dsd_config },
{ "CSC3551", "103C8C4F", generic_dsd_config },
{ "CSC3551", "103C8C50", generic_dsd_config },
{ "CSC3551", "103C8C51", generic_dsd_config },
@@ -486,6 +498,7 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CSC3551", "10431863", generic_dsd_config },
{ "CSC3551", "104318D3", generic_dsd_config },
{ "CSC3551", "10431A83", generic_dsd_config },
+ { "CSC3551", "10431B93", generic_dsd_config },
{ "CSC3551", "10431C9F", generic_dsd_config },
{ "CSC3551", "10431CAF", generic_dsd_config },
{ "CSC3551", "10431CCF", generic_dsd_config },
@@ -499,7 +512,14 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CSC3551", "10431F12", generic_dsd_config },
{ "CSC3551", "10431F1F", generic_dsd_config },
{ "CSC3551", "10431F62", generic_dsd_config },
+ { "CSC3551", "10433A20", generic_dsd_config },
+ { "CSC3551", "10433A30", generic_dsd_config },
+ { "CSC3551", "10433A40", generic_dsd_config },
+ { "CSC3551", "10433A50", generic_dsd_config },
{ "CSC3551", "10433A60", generic_dsd_config },
+ { "CSC3551", "17AA3865", generic_dsd_config },
+ { "CSC3551", "17AA3866", generic_dsd_config },
+ { "CSC3551", "17AA386E", generic_dsd_config },
{ "CSC3551", "17AA386F", generic_dsd_config },
{ "CSC3551", "17AA3877", generic_dsd_config },
{ "CSC3551", "17AA3878", generic_dsd_config },
diff --git a/sound/pci/hda/cs35l56_hda.c b/sound/pci/hda/cs35l56_hda.c
index 558c1f38fe97..11b0570ff56d 100644
--- a/sound/pci/hda/cs35l56_hda.c
+++ b/sound/pci/hda/cs35l56_hda.c
@@ -732,8 +732,6 @@ static void cs35l56_hda_unbind(struct device *dev, struct device *master, void *
if (cs35l56->base.fw_patched)
cs_dsp_power_down(&cs35l56->cs_dsp);
- cs_dsp_remove(&cs35l56->cs_dsp);
-
if (comps[cs35l56->index].dev == dev)
memset(&comps[cs35l56->index], 0, sizeof(*comps));
@@ -1035,7 +1033,7 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int hid, int id)
ARRAY_SIZE(cs35l56_hda_dai_config));
ret = cs35l56_force_sync_asp1_registers_from_cache(&cs35l56->base);
if (ret)
- goto err;
+ goto dsp_err;
/*
* By default only enable one ASP1TXn, where n=amplifier index,
@@ -1061,6 +1059,8 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int hid, int id)
pm_err:
pm_runtime_disable(cs35l56->base.dev);
+dsp_err:
+ cs_dsp_remove(&cs35l56->cs_dsp);
err:
gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);
@@ -1078,6 +1078,8 @@ void cs35l56_hda_remove(struct device *dev)
component_del(cs35l56->base.dev, &cs35l56_hda_comp_ops);
+ cs_dsp_remove(&cs35l56->cs_dsp);
+
kfree(cs35l56->system_name);
pm_runtime_put_noidle(cs35l56->base.dev);
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 2cac337f5263..325e8f0b99a8 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -616,7 +616,6 @@ void snd_hda_shutup_pins(struct hda_codec *codec)
}
EXPORT_SYMBOL_GPL(snd_hda_shutup_pins);
-#ifdef CONFIG_PM
/* Restore the pin controls cleared previously via snd_hda_shutup_pins() */
static void restore_shutup_pins(struct hda_codec *codec)
{
@@ -634,7 +633,6 @@ static void restore_shutup_pins(struct hda_codec *codec)
}
codec->pins_shutup = 0;
}
-#endif
static void hda_jackpoll_work(struct work_struct *work)
{
@@ -1001,9 +999,7 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
codec->card = card;
codec->addr = codec_addr;
-#ifdef CONFIG_PM
codec->power_jiffies = jiffies;
-#endif
snd_hda_sysfs_init(codec);
@@ -1238,7 +1234,6 @@ static void purify_inactive_streams(struct hda_codec *codec)
}
}
-#ifdef CONFIG_PM
/* clean up all streams; called from suspend */
static void hda_cleanup_all_streams(struct hda_codec *codec)
{
@@ -1250,7 +1245,6 @@ static void hda_cleanup_all_streams(struct hda_codec *codec)
really_cleanup_stream(codec, p);
}
}
-#endif
/*
* amp access functions
@@ -2858,7 +2852,6 @@ static void hda_exec_init_verbs(struct hda_codec *codec)
static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
#endif
-#ifdef CONFIG_PM
/* update the power on/off account with the current jiffies */
static void update_power_acct(struct hda_codec *codec, bool on)
{
@@ -2966,9 +2959,6 @@ static int hda_codec_runtime_resume(struct device *dev)
return 0;
}
-#endif /* CONFIG_PM */
-
-#ifdef CONFIG_PM_SLEEP
static int hda_codec_pm_prepare(struct device *dev)
{
struct hda_codec *codec = dev_to_hda_codec(dev);
@@ -3023,22 +3013,19 @@ static int hda_codec_pm_restore(struct device *dev)
dev->power.power_state = PMSG_RESTORE;
return pm_runtime_force_resume(dev);
}
-#endif /* CONFIG_PM_SLEEP */
/* referred in hda_bind.c */
const struct dev_pm_ops hda_codec_driver_pm = {
-#ifdef CONFIG_PM_SLEEP
- .prepare = hda_codec_pm_prepare,
- .complete = hda_codec_pm_complete,
- .suspend = hda_codec_pm_suspend,
- .resume = hda_codec_pm_resume,
- .freeze = hda_codec_pm_freeze,
- .thaw = hda_codec_pm_thaw,
- .poweroff = hda_codec_pm_suspend,
- .restore = hda_codec_pm_restore,
-#endif /* CONFIG_PM_SLEEP */
- SET_RUNTIME_PM_OPS(hda_codec_runtime_suspend, hda_codec_runtime_resume,
- NULL)
+ .prepare = pm_sleep_ptr(hda_codec_pm_prepare),
+ .complete = pm_sleep_ptr(hda_codec_pm_complete),
+ .suspend = pm_sleep_ptr(hda_codec_pm_suspend),
+ .resume = pm_sleep_ptr(hda_codec_pm_resume),
+ .freeze = pm_sleep_ptr(hda_codec_pm_freeze),
+ .thaw = pm_sleep_ptr(hda_codec_pm_thaw),
+ .poweroff = pm_sleep_ptr(hda_codec_pm_suspend),
+ .restore = pm_sleep_ptr(hda_codec_pm_restore),
+ .runtime_suspend = pm_ptr(hda_codec_runtime_suspend),
+ .runtime_resume = pm_ptr(hda_codec_runtime_resume),
};
/* suspend the codec at shutdown; called from driver's shutdown callback */
@@ -3425,7 +3412,6 @@ int snd_hda_add_new_ctls(struct hda_codec *codec,
}
EXPORT_SYMBOL_GPL(snd_hda_add_new_ctls);
-#ifdef CONFIG_PM
/**
* snd_hda_codec_set_power_save - Configure codec's runtime PM
* @codec: codec device to configure
@@ -3516,7 +3502,6 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
return 0;
}
EXPORT_SYMBOL_GPL(snd_hda_check_amp_list_power);
-#endif
/*
* input MUX helper
@@ -4060,12 +4045,10 @@ void snd_hda_bus_reset_codecs(struct hda_bus *bus)
/* FIXME: maybe a better way needed for forced reset */
if (current_work() != &codec->jackpoll_work.work)
cancel_delayed_work_sync(&codec->jackpoll_work);
-#ifdef CONFIG_PM
if (hda_codec_is_power_on(codec)) {
hda_call_codec_suspend(codec);
hda_call_codec_resume(codec);
}
-#endif
}
}
diff --git a/sound/pci/hda/hda_component.c b/sound/pci/hda/hda_component.c
index cd299d7d84ba..d02589014a3f 100644
--- a/sound/pci/hda/hda_component.c
+++ b/sound/pci/hda/hda_component.c
@@ -123,6 +123,21 @@ static int hda_comp_match_dev_name(struct device *dev, void *data)
return !strcmp(d + n, tmp);
}
+int hda_component_manager_bind(struct hda_codec *cdc,
+ struct hda_component *comps, int count)
+{
+ int i;
+
+ /* Init shared data */
+ for (i = 0; i < count; ++i) {
+ memset(&comps[i], 0, sizeof(comps[i]));
+ comps[i].codec = cdc;
+ }
+
+ return component_bind_all(hda_codec_dev(cdc), comps);
+}
+EXPORT_SYMBOL_NS_GPL(hda_component_manager_bind, SND_HDA_SCODEC_COMPONENT);
+
int hda_component_manager_init(struct hda_codec *cdc,
struct hda_component *comps, int count,
const char *bus, const char *hid,
@@ -143,7 +158,6 @@ int hda_component_manager_init(struct hda_codec *cdc,
sm->hid = hid;
sm->match_str = match_str;
sm->index = i;
- comps[i].codec = cdc;
component_match_add(dev, &match, hda_comp_match_dev_name, sm);
}
diff --git a/sound/pci/hda/hda_component.h b/sound/pci/hda/hda_component.h
index c80a66691b5d..c70b3de68ab2 100644
--- a/sound/pci/hda/hda_component.h
+++ b/sound/pci/hda/hda_component.h
@@ -75,11 +75,8 @@ int hda_component_manager_init(struct hda_codec *cdc,
void hda_component_manager_free(struct hda_codec *cdc,
const struct component_master_ops *ops);
-static inline int hda_component_manager_bind(struct hda_codec *cdc,
- struct hda_component *comps)
-{
- return component_bind_all(hda_codec_dev(cdc), comps);
-}
+int hda_component_manager_bind(struct hda_codec *cdc,
+ struct hda_component *comps, int count);
static inline void hda_component_manager_unbind(struct hda_codec *cdc,
struct hda_component *comps)
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 206306a0eb82..766734dc5be2 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -3,7 +3,7 @@
*
* Implementation of primary alsa driver code base for Intel HD Audio.
*
- * Copyright(c) 2004 Intel Corporation. All rights reserved.
+ * Copyright(c) 2004 Intel Corporation
*
* Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
* PeiSen Hou <pshou@realtek.com.tw>
@@ -914,7 +914,7 @@ static int azx_send_cmd(struct hdac_bus *bus, unsigned int val)
if (chip->disabled)
return 0;
- if (chip->single_cmd)
+ if (chip->single_cmd || bus->use_pio_for_commands)
return azx_single_send_cmd(bus, val);
else
return snd_hdac_bus_send_cmd(bus, val);
@@ -928,7 +928,7 @@ static int azx_get_response(struct hdac_bus *bus, unsigned int addr,
if (chip->disabled)
return 0;
- if (chip->single_cmd)
+ if (chip->single_cmd || bus->use_pio_for_commands)
return azx_single_get_response(bus, addr, res);
else
return azx_rirb_get_response(bus, addr, res);
@@ -1075,11 +1075,9 @@ irqreturn_t azx_interrupt(int irq, void *dev_id)
bool active, handled = false;
int repeat = 0; /* count for avoiding endless loop */
-#ifdef CONFIG_PM
if (azx_has_pm_runtime(chip))
if (!pm_runtime_active(chip->card->dev))
return IRQ_NONE;
-#endif
spin_lock(&bus->reg_lock);
@@ -1188,6 +1186,9 @@ int azx_bus_init(struct azx *chip, const char *model)
if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY)
bus->core.align_bdle_4k = true;
+ if (chip->driver_caps & AZX_DCAPS_PIO_COMMANDS)
+ bus->core.use_pio_for_commands = true;
+
/* enable sync_write flag for stable communication as default */
bus->core.sync_write = 1;
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h
index 8556031bcd68..c2d0109866e6 100644
--- a/sound/pci/hda/hda_controller.h
+++ b/sound/pci/hda/hda_controller.h
@@ -45,6 +45,7 @@
#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */
#define AZX_DCAPS_NO_MSI64 (1 << 29) /* Stick to 32-bit MSIs */
#define AZX_DCAPS_SEPARATE_STREAM_TAG (1 << 30) /* capture and playback use separate stream tag */
+#define AZX_DCAPS_PIO_COMMANDS (1 << 31) /* Use PIO instead of CORB for commands */
enum {
AZX_SNOOP_TYPE_NONE,
diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c
index 463ca06036bf..e6e876998e71 100644
--- a/sound/pci/hda/hda_cs_dsp_ctl.c
+++ b/sound/pci/hda/hda_cs_dsp_ctl.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <sound/soc.h>
+#include <linux/cleanup.h>
#include <linux/firmware/cirrus/cs_dsp.h>
#include <linux/firmware/cirrus/wmfw.h>
#include "hda_cs_dsp_ctl.h"
@@ -51,13 +52,8 @@ static int hda_cs_dsp_coeff_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_v
struct hda_cs_dsp_coeff_ctl *ctl = (struct hda_cs_dsp_coeff_ctl *)snd_kcontrol_chip(kctl);
struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl;
char *p = ucontrol->value.bytes.data;
- int ret = 0;
-
- mutex_lock(&cs_ctl->dsp->pwr_lock);
- ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, p, cs_ctl->len);
- mutex_unlock(&cs_ctl->dsp->pwr_lock);
- return ret;
+ return cs_dsp_coeff_lock_and_write_ctrl(cs_ctl, 0, p, cs_ctl->len);
}
static int hda_cs_dsp_coeff_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
@@ -65,13 +61,8 @@ static int hda_cs_dsp_coeff_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_v
struct hda_cs_dsp_coeff_ctl *ctl = (struct hda_cs_dsp_coeff_ctl *)snd_kcontrol_chip(kctl);
struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl;
char *p = ucontrol->value.bytes.data;
- int ret;
-
- mutex_lock(&cs_ctl->dsp->pwr_lock);
- ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, p, cs_ctl->len);
- mutex_unlock(&cs_ctl->dsp->pwr_lock);
- return ret;
+ return cs_dsp_coeff_lock_and_read_ctrl(cs_ctl, 0, p, cs_ctl->len);
}
static unsigned int wmfw_convert_flags(unsigned int in)
@@ -97,11 +88,23 @@ static unsigned int wmfw_convert_flags(unsigned int in)
return out;
}
-static void hda_cs_dsp_add_kcontrol(struct hda_cs_dsp_coeff_ctl *ctl, const char *name)
+static void hda_cs_dsp_free_kcontrol(struct snd_kcontrol *kctl)
{
+ struct hda_cs_dsp_coeff_ctl *ctl = (struct hda_cs_dsp_coeff_ctl *)snd_kcontrol_chip(kctl);
struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl;
+
+ /* NULL priv to prevent a double-free in hda_cs_dsp_control_remove() */
+ cs_ctl->priv = NULL;
+ kfree(ctl);
+}
+
+static void hda_cs_dsp_add_kcontrol(struct cs_dsp_coeff_ctl *cs_ctl,
+ const struct hda_cs_dsp_ctl_info *info,
+ const char *name)
+{
struct snd_kcontrol_new kcontrol = {0};
struct snd_kcontrol *kctl;
+ struct hda_cs_dsp_coeff_ctl *ctl __free(kfree) = NULL;
int ret = 0;
if (cs_ctl->len > ADSP_MAX_STD_CTRL_SIZE) {
@@ -110,6 +113,13 @@ static void hda_cs_dsp_add_kcontrol(struct hda_cs_dsp_coeff_ctl *ctl, const char
return;
}
+ ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
+ if (!ctl)
+ return;
+
+ ctl->cs_ctl = cs_ctl;
+ ctl->card = info->card;
+
kcontrol.name = name;
kcontrol.info = hda_cs_dsp_coeff_info;
kcontrol.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
@@ -117,20 +127,22 @@ static void hda_cs_dsp_add_kcontrol(struct hda_cs_dsp_coeff_ctl *ctl, const char
kcontrol.get = hda_cs_dsp_coeff_get;
kcontrol.put = hda_cs_dsp_coeff_put;
- /* Save ctl inside private_data, ctl is owned by cs_dsp,
- * and will be freed when cs_dsp removes the control */
kctl = snd_ctl_new1(&kcontrol, (void *)ctl);
if (!kctl)
return;
- ret = snd_ctl_add(ctl->card, kctl);
+ kctl->private_free = hda_cs_dsp_free_kcontrol;
+ ctl->kctl = kctl;
+
+ /* snd_ctl_add() calls our private_free on error, which will kfree(ctl) */
+ cs_ctl->priv = no_free_ptr(ctl);
+ ret = snd_ctl_add(info->card, kctl);
if (ret) {
dev_err(cs_ctl->dsp->dev, "Failed to add KControl %s = %d\n", kcontrol.name, ret);
return;
}
dev_dbg(cs_ctl->dsp->dev, "Added KControl: %s\n", kcontrol.name);
- ctl->kctl = kctl;
}
static void hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl,
@@ -138,7 +150,6 @@ static void hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl,
{
struct cs_dsp *cs_dsp = cs_ctl->dsp;
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
- struct hda_cs_dsp_coeff_ctl *ctl;
const char *region_name;
int ret;
@@ -163,15 +174,7 @@ static void hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl,
" %.*s", cs_ctl->subname_len - skip, cs_ctl->subname + skip);
}
- ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
- if (!ctl)
- return;
-
- ctl->cs_ctl = cs_ctl;
- ctl->card = info->card;
- cs_ctl->priv = ctl;
-
- hda_cs_dsp_add_kcontrol(ctl, name);
+ hda_cs_dsp_add_kcontrol(cs_ctl, info, name);
}
void hda_cs_dsp_add_controls(struct cs_dsp *dsp, const struct hda_cs_dsp_ctl_info *info)
@@ -203,7 +206,9 @@ void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl)
{
struct hda_cs_dsp_coeff_ctl *ctl = cs_ctl->priv;
- kfree(ctl);
+ /* ctl and kctl may already have been removed by ALSA private_free */
+ if (ctl && ctl->kctl)
+ snd_ctl_remove(ctl->card, ctl->kctl);
}
EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_control_remove, SND_HDA_CS_DSP_CONTROLS);
@@ -211,7 +216,6 @@ int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type,
unsigned int alg, const void *buf, size_t len)
{
struct cs_dsp_coeff_ctl *cs_ctl;
- struct hda_cs_dsp_coeff_ctl *ctl;
int ret;
mutex_lock(&dsp->pwr_lock);
@@ -221,13 +225,6 @@ int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type,
if (ret < 0)
return ret;
- if (ret == 0 || (cs_ctl->flags & WMFW_CTL_FLAG_SYS))
- return 0;
-
- ctl = cs_ctl->priv;
-
- snd_ctl_notify(ctl->card, SNDRV_CTL_EVENT_MASK_VALUE, &ctl->kctl->id);
-
return 0;
}
EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_write_ctl, SND_HDA_CS_DSP_CONTROLS);
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index de2a3d08c73c..f64d9dc197a3 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -6021,7 +6021,6 @@ void snd_hda_gen_free(struct hda_codec *codec)
}
EXPORT_SYMBOL_GPL(snd_hda_gen_free);
-#ifdef CONFIG_PM
/**
* snd_hda_gen_check_power_status - check the loopback power save state
* @codec: the HDA codec
@@ -6035,7 +6034,6 @@ int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid)
return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
}
EXPORT_SYMBOL_GPL(snd_hda_gen_check_power_status);
-#endif
/*
@@ -6048,9 +6046,7 @@ static const struct hda_codec_ops generic_patch_ops = {
.init = snd_hda_gen_init,
.free = snd_hda_gen_free,
.unsol_event = snd_hda_jack_unsol_event,
-#ifdef CONFIG_PM
.check_power_status = snd_hda_gen_check_power_status,
-#endif
};
/*
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index a8eea8367629..8f5ecf740c49 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -340,9 +340,7 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec,
struct hda_jack_callback *jack);
void snd_hda_gen_update_outputs(struct hda_codec *codec);
-#ifdef CONFIG_PM
int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid);
-#endif
unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
hda_nid_t nid,
unsigned int power_state);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 1b550c42db09..3500108f6ba3 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -4,7 +4,7 @@
* hda_intel.c - Implementation of primary alsa driver code base
* for Intel HD Audio.
*
- * Copyright(c) 2004 Intel Corporation. All rights reserved.
+ * Copyright(c) 2004 Intel Corporation
*
* Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
* PeiSen Hou <pshou@realtek.com.tw>
@@ -186,8 +186,10 @@ MODULE_PARM_DESC(pm_blacklist, "Enable power-management denylist");
static bool power_save_controller = 1;
module_param(power_save_controller, bool, 0644);
MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
-#else
+#else /* CONFIG_PM */
#define power_save 0
+#define pm_blacklist false
+#define power_save_controller false
#endif /* CONFIG_PM */
static int align_buffer_size = -1;
@@ -289,6 +291,9 @@ enum {
#define AZX_DCAPS_INTEL_BROXTON AZX_DCAPS_INTEL_SKYLAKE
+#define AZX_DCAPS_INTEL_LNL \
+ (AZX_DCAPS_INTEL_SKYLAKE | AZX_DCAPS_PIO_COMMANDS)
+
/* quirks for ATI SB / AMD Hudson */
#define AZX_DCAPS_PRESET_ATI_SB \
(AZX_DCAPS_NO_TCSEL | AZX_DCAPS_POSFIX_LPIB |\
@@ -890,7 +895,6 @@ static void __azx_shutdown_chip(struct azx *chip, bool skip_link_reset)
display_power(chip, false);
}
-#ifdef CONFIG_PM
static DEFINE_MUTEX(card_list_lock);
static LIST_HEAD(card_list);
@@ -916,7 +920,7 @@ static void azx_del_card_list(struct azx *chip)
}
/* trigger power-save check at writing parameter */
-static int param_set_xint(const char *val, const struct kernel_param *kp)
+static int __maybe_unused param_set_xint(const char *val, const struct kernel_param *kp)
{
struct hda_intel *hda;
struct azx *chip;
@@ -987,7 +991,6 @@ static void __azx_runtime_resume(struct azx *chip)
display_power(chip, false);
}
-#ifdef CONFIG_PM_SLEEP
static int azx_prepare(struct device *dev)
{
struct snd_card *card = dev_get_drvdata(dev);
@@ -1046,7 +1049,7 @@ static int azx_suspend(struct device *dev)
return 0;
}
-static int azx_resume(struct device *dev)
+static int __maybe_unused azx_resume(struct device *dev)
{
struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip;
@@ -1097,9 +1100,8 @@ static int azx_thaw_noirq(struct device *dev)
return 0;
}
-#endif /* CONFIG_PM_SLEEP */
-static int azx_runtime_suspend(struct device *dev)
+static int __maybe_unused azx_runtime_suspend(struct device *dev)
{
struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip;
@@ -1116,7 +1118,7 @@ static int azx_runtime_suspend(struct device *dev)
return 0;
}
-static int azx_runtime_resume(struct device *dev)
+static int __maybe_unused azx_runtime_resume(struct device *dev)
{
struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip;
@@ -1133,7 +1135,7 @@ static int azx_runtime_resume(struct device *dev)
return 0;
}
-static int azx_runtime_idle(struct device *dev)
+static int __maybe_unused azx_runtime_idle(struct device *dev)
{
struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip;
@@ -1159,23 +1161,14 @@ static int azx_runtime_idle(struct device *dev)
}
static const struct dev_pm_ops azx_pm = {
- SET_SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume)
-#ifdef CONFIG_PM_SLEEP
- .prepare = azx_prepare,
- .complete = azx_complete,
- .freeze_noirq = azx_freeze_noirq,
- .thaw_noirq = azx_thaw_noirq,
-#endif
+ SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume)
+ .prepare = pm_sleep_ptr(azx_prepare),
+ .complete = pm_sleep_ptr(azx_complete),
+ .freeze_noirq = pm_sleep_ptr(azx_freeze_noirq),
+ .thaw_noirq = pm_sleep_ptr(azx_thaw_noirq),
SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, azx_runtime_idle)
};
-#define AZX_PM_OPS &azx_pm
-#else
-#define azx_add_card_list(chip) /* NOP */
-#define azx_del_card_list(chip) /* NOP */
-#define AZX_PM_OPS NULL
-#endif /* CONFIG_PM */
-
static int azx_probe_continue(struct azx *chip);
@@ -2206,7 +2199,6 @@ out_free:
return err;
}
-#ifdef CONFIG_PM
/* On some boards setting power_save to a non 0 value leads to clicking /
* popping sounds when ever we enter/leave powersaving mode. Ideally we would
* figure out how to avoid these sounds, but that is not always feasible.
@@ -2248,13 +2240,11 @@ static const struct snd_pci_quirk power_save_denylist[] = {
SND_PCI_QUIRK(0x1734, 0x1232, "KONTRON SinglePC", 0),
{}
};
-#endif /* CONFIG_PM */
static void set_default_power_save(struct azx *chip)
{
int val = power_save;
-#ifdef CONFIG_PM
if (pm_blacklist) {
const struct snd_pci_quirk *q;
@@ -2265,7 +2255,6 @@ static void set_default_power_save(struct azx *chip)
val = 0;
}
}
-#endif /* CONFIG_PM */
snd_hda_set_power_save(&chip->bus, val * 1000);
}
@@ -2321,10 +2310,6 @@ static int azx_probe_continue(struct azx *chip)
chip->fw->data);
if (err < 0)
goto out_free;
-#ifndef CONFIG_PM
- release_firmware(chip->fw); /* no longer needed */
- chip->fw = NULL;
-#endif
}
#endif
@@ -2502,8 +2487,10 @@ static const struct pci_device_id azx_ids[] = {
{ PCI_DEVICE_DATA(INTEL, HDA_RPL_M, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
{ PCI_DEVICE_DATA(INTEL, HDA_RPL_PX, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
{ PCI_DEVICE_DATA(INTEL, HDA_MTL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
+ /* Battlemage */
+ { PCI_DEVICE_DATA(INTEL, HDA_BMG, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
/* Lunarlake-P */
- { PCI_DEVICE_DATA(INTEL, HDA_LNL_P, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
+ { PCI_DEVICE_DATA(INTEL, HDA_LNL_P, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_LNL) },
/* Arrow Lake-S */
{ PCI_DEVICE_DATA(INTEL, HDA_ARL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
/* Arrow Lake */
@@ -2765,7 +2752,7 @@ static struct pci_driver azx_driver = {
.remove = azx_remove,
.shutdown = azx_shutdown,
.driver = {
- .pm = AZX_PM_OPS,
+ .pm = &azx_pm,
},
};
diff --git a/sound/pci/hda/hda_intel_trace.h b/sound/pci/hda/hda_intel_trace.h
index 73a7adfa192d..2775fa81a500 100644
--- a/sound/pci/hda/hda_intel_trace.h
+++ b/sound/pci/hda/hda_intel_trace.h
@@ -34,7 +34,6 @@ DEFINE_EVENT(hda_pm, azx_resume,
TP_ARGS(chip)
);
-#ifdef CONFIG_PM
DEFINE_EVENT(hda_pm, azx_runtime_suspend,
TP_PROTO(struct azx *chip),
TP_ARGS(chip)
@@ -44,7 +43,6 @@ DEFINE_EVENT(hda_pm, azx_runtime_resume,
TP_PROTO(struct azx *chip),
TP_ARGS(chip)
);
-#endif
#endif /* _TRACE_HDA_INTEL_H */
diff --git a/sound/pci/hda/hda_sysfs.c b/sound/pci/hda/hda_sysfs.c
index 69ebc37a4d6f..265fd4737893 100644
--- a/sound/pci/hda/hda_sysfs.c
+++ b/sound/pci/hda/hda_sysfs.c
@@ -26,7 +26,6 @@ struct hda_hint {
const char *val; /* contained in the same alloc as key */
};
-#ifdef CONFIG_PM
static ssize_t power_on_acct_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -47,7 +46,6 @@ static ssize_t power_off_acct_show(struct device *dev,
static DEVICE_ATTR_RO(power_on_acct);
static DEVICE_ATTR_RO(power_off_acct);
-#endif /* CONFIG_PM */
#define CODEC_INFO_SHOW(type, field) \
static ssize_t type##_show(struct device *dev, \
@@ -745,10 +743,8 @@ static struct attribute *hda_dev_attrs[] = {
&dev_attr_modelname.attr,
&dev_attr_init_pin_configs.attr,
&dev_attr_driver_pin_configs.attr,
-#ifdef CONFIG_PM
&dev_attr_power_on_acct.attr,
&dev_attr_power_off_acct.attr,
-#endif
#ifdef CONFIG_SND_HDA_RECONFIG
&dev_attr_init_verbs.attr,
&dev_attr_hints.attr,
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 8afe6000f7da..1e9dadcdc51b 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -72,7 +72,6 @@ static int create_beep_ctls(struct hda_codec *codec)
#define create_beep_ctls(codec) 0
#endif
-#ifdef CONFIG_PM
static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
hda_nid_t hp)
{
@@ -118,7 +117,6 @@ static int ad198x_suspend(struct hda_codec *codec)
ad198x_power_eapd(codec);
return 0;
}
-#endif
/* follow EAPD via vmaster hook */
static void ad_vmaster_eapd_hook(void *private_data, int enabled)
@@ -158,10 +156,8 @@ static const struct hda_codec_ops ad198x_auto_patch_ops = {
.init = snd_hda_gen_init,
.free = snd_hda_gen_free,
.unsol_event = snd_hda_jack_unsol_event,
-#ifdef CONFIG_PM
.check_power_status = snd_hda_gen_check_power_status,
.suspend = ad198x_suspend,
-#endif
};
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index aa312441604f..e4673a71551a 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -9682,7 +9682,6 @@ static void dbpro_free(struct hda_codec *codec)
kfree(codec->spec);
}
-#ifdef CONFIG_PM
static int ca0132_suspend(struct hda_codec *codec)
{
struct ca0132_spec *spec = codec->spec;
@@ -9690,7 +9689,6 @@ static int ca0132_suspend(struct hda_codec *codec)
cancel_delayed_work_sync(&spec->unsol_hp_work);
return 0;
}
-#endif
static const struct hda_codec_ops ca0132_patch_ops = {
.build_controls = ca0132_build_controls,
@@ -9698,9 +9696,7 @@ static const struct hda_codec_ops ca0132_patch_ops = {
.init = ca0132_init,
.free = ca0132_free,
.unsol_event = snd_hda_jack_unsol_event,
-#ifdef CONFIG_PM
.suspend = ca0132_suspend,
-#endif
};
static const struct hda_codec_ops dbpro_patch_ops = {
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 6807b4708a17..654724559355 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -1128,7 +1128,6 @@ static int cs421x_parse_auto_config(struct hda_codec *codec)
return 0;
}
-#ifdef CONFIG_PM
/*
* Manage PDREF, when transitioning to D3hot
* (DAC,ADC) -> D3, PDREF=1, AFG->D3
@@ -1153,7 +1152,6 @@ static int cs421x_suspend(struct hda_codec *codec)
return 0;
}
-#endif
static const struct hda_codec_ops cs421x_patch_ops = {
.build_controls = snd_hda_gen_build_controls,
@@ -1161,9 +1159,7 @@ static const struct hda_codec_ops cs421x_patch_ops = {
.init = cs421x_init,
.free = cs_free,
.unsol_event = snd_hda_jack_unsol_event,
-#ifdef CONFIG_PM
.suspend = cs421x_suspend,
-#endif
};
static int patch_cs4210(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index e8209178d87b..17389a3801bd 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -294,13 +294,11 @@ static void cx_jack_unsol_event(struct hda_codec *codec, unsigned int res)
snd_hda_jack_unsol_event(codec, res);
}
-#ifdef CONFIG_PM
static int cx_auto_suspend(struct hda_codec *codec)
{
cx_auto_shutdown(codec);
return 0;
}
-#endif
static const struct hda_codec_ops cx_auto_patch_ops = {
.build_controls = snd_hda_gen_build_controls,
@@ -308,10 +306,8 @@ static const struct hda_codec_ops cx_auto_patch_ops = {
.init = cx_auto_init,
.free = cx_auto_free,
.unsol_event = cx_jack_unsol_event,
-#ifdef CONFIG_PM
.suspend = cx_auto_suspend,
.check_power_status = snd_hda_gen_check_power_status,
-#endif
};
/*
diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c
index e41316e2e983..26f3c31600d7 100644
--- a/sound/pci/hda/patch_cs8409.c
+++ b/sound/pci/hda/patch_cs8409.c
@@ -909,7 +909,6 @@ static void cs42l42_resume(struct sub_codec *cs42l42)
cs42l42_enable_jack_detect(cs42l42);
}
-#ifdef CONFIG_PM
static void cs42l42_suspend(struct sub_codec *cs42l42)
{
struct hda_codec *codec = cs42l42->codec;
@@ -948,7 +947,6 @@ static void cs42l42_suspend(struct sub_codec *cs42l42)
spec->gpio_data &= ~cs42l42->reset_gpio;
snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, spec->gpio_data);
}
-#endif
static void cs8409_free(struct hda_codec *codec)
{
@@ -1003,7 +1001,6 @@ static void cs8409_cs42l42_jack_unsol_event(struct hda_codec *codec, unsigned in
}
}
-#ifdef CONFIG_PM
/* Manage PDREF, when transition to D3hot */
static int cs8409_cs42l42_suspend(struct hda_codec *codec)
{
@@ -1025,7 +1022,6 @@ static int cs8409_cs42l42_suspend(struct hda_codec *codec)
return 0;
}
-#endif
/* Vendor specific HW configuration
* PLL, ASP, I2C, SPI, GPIOs, DMIC etc...
@@ -1080,9 +1076,7 @@ static const struct hda_codec_ops cs8409_cs42l42_patch_ops = {
.init = cs8409_init,
.free = cs8409_free,
.unsol_event = cs8409_cs42l42_jack_unsol_event,
-#ifdef CONFIG_PM
.suspend = cs8409_cs42l42_suspend,
-#endif
};
static int cs8409_cs42l42_exec_verb(struct hdac_device *dev, unsigned int cmd, unsigned int flags,
@@ -1310,9 +1304,7 @@ static const struct hda_codec_ops cs8409_dolphin_patch_ops = {
.init = cs8409_init,
.free = cs8409_free,
.unsol_event = dolphin_jack_unsol_event,
-#ifdef CONFIG_PM
.suspend = cs8409_cs42l42_suspend,
-#endif
};
static int dolphin_exec_verb(struct hdac_device *dev, unsigned int cmd, unsigned int flags,
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 495d63101186..707d203ba652 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -3,7 +3,7 @@
*
* patch_hdmi.c - routines for HDMI/DisplayPort codecs
*
- * Copyright(c) 2008-2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008-2010 Intel Corporation
* Copyright (c) 2006 ATI Technologies Inc.
* Copyright (c) 2008 NVIDIA Corp. All rights reserved.
* Copyright (c) 2008 Wei Ni <wni@nvidia.com>
@@ -2513,7 +2513,6 @@ static void generic_hdmi_free(struct hda_codec *codec)
generic_spec_free(codec);
}
-#ifdef CONFIG_PM
static int generic_hdmi_suspend(struct hda_codec *codec)
{
struct hdmi_spec *spec = codec->spec;
@@ -2540,7 +2539,6 @@ static int generic_hdmi_resume(struct hda_codec *codec)
}
return 0;
}
-#endif
static const struct hda_codec_ops generic_hdmi_patch_ops = {
.init = generic_hdmi_init,
@@ -2548,10 +2546,8 @@ static const struct hda_codec_ops generic_hdmi_patch_ops = {
.build_pcms = generic_hdmi_build_pcms,
.build_controls = generic_hdmi_build_controls,
.unsol_event = hdmi_unsol_event,
-#ifdef CONFIG_PM
.suspend = generic_hdmi_suspend,
.resume = generic_hdmi_resume,
-#endif
};
static const struct hdmi_ops generic_standard_hdmi_ops = {
@@ -2952,7 +2948,6 @@ static void i915_pin_cvt_fixup(struct hda_codec *codec,
}
}
-#ifdef CONFIG_PM
static int i915_adlp_hdmi_suspend(struct hda_codec *codec)
{
struct hdmi_spec *spec = codec->spec;
@@ -3032,7 +3027,6 @@ static int i915_adlp_hdmi_resume(struct hda_codec *codec)
return res;
}
-#endif
/* precondition and allocation for Intel codecs */
static int alloc_intel_hdmi(struct hda_codec *codec)
@@ -3167,10 +3161,8 @@ static int patch_i915_adlp_hdmi(struct hda_codec *codec)
if (spec->silent_stream_type) {
spec->silent_stream_type = SILENT_STREAM_KAE;
-#ifdef CONFIG_PM
codec->patch_ops.resume = i915_adlp_hdmi_resume;
codec->patch_ops.suspend = i915_adlp_hdmi_suspend;
-#endif
}
}
@@ -4642,6 +4634,7 @@ HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi),
HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI", patch_i915_icl_hdmi),
HDA_CODEC_ENTRY(0x8086281c, "Alderlake-P HDMI", patch_i915_adlp_hdmi),
HDA_CODEC_ENTRY(0x8086281d, "Meteor Lake HDMI", patch_i915_adlp_hdmi),
+HDA_CODEC_ENTRY(0x8086281e, "Battlemage HDMI", patch_i915_adlp_hdmi),
HDA_CODEC_ENTRY(0x8086281f, "Raptor Lake P HDMI", patch_i915_adlp_hdmi),
HDA_CODEC_ENTRY(0x80862820, "Lunar Lake HDMI", patch_i915_adlp_hdmi),
HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index b29739bd330b..a696943aec0d 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -109,9 +109,7 @@ struct alc_spec {
/* hooks */
void (*init_hook)(struct hda_codec *codec);
-#ifdef CONFIG_PM
void (*power_hook)(struct hda_codec *codec);
-#endif
void (*shutup)(struct hda_codec *codec);
int init_amp;
@@ -947,7 +945,6 @@ static int alc_init(struct hda_codec *codec)
#define alc_free snd_hda_gen_free
-#ifdef CONFIG_PM
static inline void alc_shutup(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@@ -986,7 +983,6 @@ static int alc_resume(struct hda_codec *codec)
hda_call_check_power_status(codec, 0x01);
return 0;
}
-#endif
/*
*/
@@ -996,11 +992,9 @@ static const struct hda_codec_ops alc_patch_ops = {
.init = alc_init,
.free = alc_free,
.unsol_event = snd_hda_jack_unsol_event,
-#ifdef CONFIG_PM
.resume = alc_resume,
.suspend = alc_suspend,
.check_power_status = snd_hda_gen_check_power_status,
-#endif
};
@@ -4041,7 +4035,6 @@ static void alc5505_dsp_init(struct hda_codec *codec)
#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
#endif
-#ifdef CONFIG_PM
static int alc269_suspend(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@@ -4087,7 +4080,6 @@ static int alc269_resume(struct hda_codec *codec)
return 0;
}
-#endif /* CONFIG_PM */
static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
@@ -6535,6 +6527,20 @@ static void alc295_fixup_chromebook(struct hda_codec *codec,
}
}
+static void alc256_fixup_chromebook(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ struct alc_spec *spec = codec->spec;
+
+ switch (action) {
+ case HDA_FIXUP_ACT_PRE_PROBE:
+ spec->gen.suppress_auto_mute = 1;
+ spec->gen.suppress_auto_mic = 1;
+ spec->en_3kpull_low = false;
+ break;
+ }
+}
+
static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
@@ -6793,7 +6799,7 @@ static int comp_bind(struct device *dev)
struct alc_spec *spec = cdc->spec;
int ret;
- ret = hda_component_manager_bind(cdc, spec->comps);
+ ret = hda_component_manager_bind(cdc, spec->comps, ARRAY_SIZE(spec->comps));
if (ret)
return ret;
@@ -7204,7 +7210,7 @@ static void alc287_alc1318_playback_pcm_hook(struct hda_pcm_stream *hinfo,
}
}
-static void __maybe_unused alc287_s4_power_gpio3_default(struct hda_codec *codec)
+static void alc287_s4_power_gpio3_default(struct hda_codec *codec)
{
if (is_s4_suspend(codec)) {
alc_write_coef_idx(codec, 0x10, 0x8806); /* Change MLK to GPIO3 */
@@ -7219,9 +7225,7 @@ static void alc287_fixup_lenovo_thinkpad_with_alc1318(struct hda_codec *codec,
if (action != HDA_FIXUP_ACT_PRE_PROBE)
return;
-#ifdef CONFIG_PM
spec->power_hook = alc287_s4_power_gpio3_default;
-#endif
spec->gen.pcm_playback_hook = alc287_alc1318_playback_pcm_hook;
}
@@ -7515,6 +7519,7 @@ enum {
ALC285_FIXUP_ASUS_GU605_SPI_2_HEADSET_MIC,
ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1,
ALC287_FIXUP_LENOVO_THKPAD_WH_ALC1318,
+ ALC256_FIXUP_CHROME_BOOK,
};
/* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -9797,6 +9802,12 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC269_FIXUP_THINKPAD_ACPI
},
+ [ALC256_FIXUP_CHROME_BOOK] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc256_fixup_chromebook,
+ .chained = true,
+ .chain_id = ALC225_FIXUP_HEADSET_JACK
+ },
};
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -10103,7 +10114,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8a2c, "HP Envy 16", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8a2d, "HP Envy 16", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8a2e, "HP Envy 16", ALC287_FIXUP_CS35L41_I2C_2),
- SND_PCI_QUIRK(0x103c, 0x8a2e, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8a30, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8a31, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8a6e, "HP EDNA 360", ALC287_FIXUP_CS35L41_I2C_4),
@@ -10148,6 +10158,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8b92, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8b96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
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, 0x8bdd, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8bde, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8bdf, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
@@ -10168,6 +10180,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8c47, "HP EliteBook 840 G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8c48, "HP EliteBook 860 G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8c49, "HP Elite x360 830 2-in-1 G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8c4d, "HP Omen", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x103c, 0x8c4e, "HP Omen", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8c4f, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8c50, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8c51, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
@@ -10282,6 +10296,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1e63, "ASUS H7606W", ALC285_FIXUP_CS35L56_I2C_2),
SND_PCI_QUIRK(0x1043, 0x1e83, "ASUS GA605W", ALC285_FIXUP_CS35L56_I2C_2),
SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
+ SND_PCI_QUIRK(0x1043, 0x1ed3, "ASUS HN7306W", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401),
SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
@@ -10495,7 +10510,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3852, "Lenovo Yoga 7 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
+ SND_PCI_QUIRK(0x17aa, 0x3865, "Lenovo 13X", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x17aa, 0x3866, "Lenovo 13X", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
+ SND_PCI_QUIRK(0x17aa, 0x386e, "Legion Y9000X 2022 IAH7", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x386f, "Legion Pro 7/7i", ALC287_FIXUP_LENOVO_LEGION_7),
SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C),
SND_PCI_QUIRK(0x17aa, 0x3877, "Lenovo Legion 7 Slim 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2),
@@ -10755,6 +10773,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
{.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"},
{.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-headset-jack"},
{.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-chrome-book"},
+ {.id = ALC256_FIXUP_CHROME_BOOK, .name = "alc-2024y-chromebook"},
{.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"},
{.id = ALC298_FIXUP_HUAWEI_MBX_STEREO, .name = "huawei-mbx-stereo"},
{.id = ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE, .name = "alc256-medion-headset"},
@@ -11287,10 +11306,8 @@ static int patch_alc269(struct hda_codec *codec)
codec->power_save_node = 0;
spec->en_3kpull_low = true;
-#ifdef CONFIG_PM
codec->patch_ops.suspend = alc269_suspend;
codec->patch_ops.resume = alc269_resume;
-#endif
spec->shutup = alc_default_shutup;
spec->init_hook = alc_default_init;
@@ -11588,9 +11605,7 @@ static int patch_alc861(struct hda_codec *codec)
if (has_cdefine_beep(codec))
spec->gen.beep_nid = 0x23;
-#ifdef CONFIG_PM
spec->power_hook = alc_power_eapd;
-#endif
alc_pre_init(codec);
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 61258b0aac8d..ae1a34c68c61 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -2154,10 +2154,8 @@ static void stac92hd83xxx_fixup_hp_mic_led(struct hda_codec *codec,
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
spec->mic_mute_led_gpio = 0x08; /* GPIO3 */
-#ifdef CONFIG_PM
/* resetting controller clears GPIO, so we need to keep on */
codec->core.power_caps &= ~AC_PWRST_CLKSTOP;
-#endif
}
}
@@ -4442,7 +4440,6 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer,
#define stac927x_proc_hook NULL
#endif
-#ifdef CONFIG_PM
static int stac_suspend(struct hda_codec *codec)
{
struct sigmatel_spec *spec = codec->spec;
@@ -4456,9 +4453,6 @@ static int stac_suspend(struct hda_codec *codec)
return 0;
}
-#else
-#define stac_suspend NULL
-#endif /* CONFIG_PM */
static const struct hda_codec_ops stac_patch_ops = {
.build_controls = snd_hda_gen_build_controls,
@@ -4466,9 +4460,7 @@ static const struct hda_codec_ops stac_patch_ops = {
.init = stac_init,
.free = stac_free,
.unsol_event = snd_hda_jack_unsol_event,
-#ifdef CONFIG_PM
.suspend = stac_suspend,
-#endif
};
static int alloc_stac_spec(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 2994f85bc1b9..a8ef4bb70dd0 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -379,7 +379,6 @@ static void via_free(struct hda_codec *codec)
snd_hda_gen_free(codec);
}
-#ifdef CONFIG_PM
static int via_suspend(struct hda_codec *codec)
{
struct via_spec *spec = codec->spec;
@@ -400,9 +399,7 @@ static int via_resume(struct hda_codec *codec)
snd_hda_regmap_sync(codec);
return 0;
}
-#endif
-#ifdef CONFIG_PM
static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
{
struct via_spec *spec = codec->spec;
@@ -410,7 +407,6 @@ static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
vt1708_update_hp_work(codec);
return snd_hda_check_amp_list_power(codec, &spec->gen.loopback, nid);
}
-#endif
/*
*/
@@ -423,11 +419,9 @@ static const struct hda_codec_ops via_patch_ops = {
.init = via_init,
.free = via_free,
.unsol_event = snd_hda_jack_unsol_event,
-#ifdef CONFIG_PM
.suspend = via_suspend,
.resume = via_resume,
.check_power_status = via_check_power_status,
-#endif
};
diff --git a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile
index 1196f22a9b45..f406a048374c 100644
--- a/sound/pci/ice1712/Makefile
+++ b/sound/pci/ice1712/Makefile
@@ -4,9 +4,9 @@
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
-snd-ice17xx-ak4xxx-objs := ak4xxx.o
-snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o
-snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o prodigy_hifi.o juli.o phase.o wtm.o se.o maya44.o quartet.o psc724.o wm8766.o wm8776.o
+snd-ice17xx-ak4xxx-y := ak4xxx.o
+snd-ice1712-y := ice1712.o delta.o hoontech.o ews.o
+snd-ice1724-y := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o prodigy_hifi.o juli.o phase.o wtm.o se.o maya44.o quartet.o psc724.o wm8766.o wm8776.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o
diff --git a/sound/pci/korg1212/Makefile b/sound/pci/korg1212/Makefile
index 42eb287c77af..ab0186ffbd58 100644
--- a/sound/pci/korg1212/Makefile
+++ b/sound/pci/korg1212/Makefile
@@ -4,7 +4,7 @@
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
-snd-korg1212-objs := korg1212.o
+snd-korg1212-y := korg1212.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_KORG1212) += snd-korg1212.o
diff --git a/sound/pci/lx6464es/Makefile b/sound/pci/lx6464es/Makefile
index c295f68bac68..2b3047c7a388 100644
--- a/sound/pci/lx6464es/Makefile
+++ b/sound/pci/lx6464es/Makefile
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
-snd-lx6464es-objs := lx6464es.o lx_core.o
+snd-lx6464es-y := lx6464es.o lx_core.o
obj-$(CONFIG_SND_LX6464ES) += snd-lx6464es.o
diff --git a/sound/pci/mixart/Makefile b/sound/pci/mixart/Makefile
index 16cfeb78a0b6..b803e5e72791 100644
--- a/sound/pci/mixart/Makefile
+++ b/sound/pci/mixart/Makefile
@@ -4,6 +4,6 @@
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
-snd-mixart-objs := mixart.o mixart_core.o mixart_hwdep.o mixart_mixer.o
+snd-mixart-y := mixart.o mixart_core.o mixart_hwdep.o mixart_mixer.o
obj-$(CONFIG_SND_MIXART) += snd-mixart.o
diff --git a/sound/pci/nm256/Makefile b/sound/pci/nm256/Makefile
index 3063766ac56b..7d55fe774d20 100644
--- a/sound/pci/nm256/Makefile
+++ b/sound/pci/nm256/Makefile
@@ -4,7 +4,7 @@
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
-snd-nm256-objs := nm256.o
+snd-nm256-y := nm256.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_NM256) += snd-nm256.o
diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile
index 0dfc4f840992..cc0c24694750 100644
--- a/sound/pci/oxygen/Makefile
+++ b/sound/pci/oxygen/Makefile
@@ -1,8 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
-snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o
-snd-oxygen-objs := oxygen.o xonar_dg_mixer.o xonar_dg.o
-snd-se6x-objs := se6x.o
-snd-virtuoso-objs := virtuoso.o xonar_lib.o \
+snd-oxygen-lib-y := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o
+snd-oxygen-y := oxygen.o xonar_dg_mixer.o xonar_dg.o
+snd-se6x-y := se6x.o
+snd-virtuoso-y := virtuoso.o xonar_lib.o \
xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o
obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o
diff --git a/sound/pci/pcxhr/Makefile b/sound/pci/pcxhr/Makefile
index 5993d86cfb5d..0ea1e5ccb56f 100644
--- a/sound/pci/pcxhr/Makefile
+++ b/sound/pci/pcxhr/Makefile
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
-snd-pcxhr-objs := pcxhr.o pcxhr_hwdep.o pcxhr_mixer.o pcxhr_core.o pcxhr_mix22.o
+snd-pcxhr-y := pcxhr.o pcxhr_hwdep.o pcxhr_mixer.o pcxhr_core.o pcxhr_mix22.o
obj-$(CONFIG_SND_PCXHR) += snd-pcxhr.o
diff --git a/sound/pci/riptide/Makefile b/sound/pci/riptide/Makefile
index 9a505bae243e..9b4e9595859a 100644
--- a/sound/pci/riptide/Makefile
+++ b/sound/pci/riptide/Makefile
@@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
-snd-riptide-objs := riptide.o
+snd-riptide-y := riptide.o
obj-$(CONFIG_SND_RIPTIDE) += snd-riptide.o
diff --git a/sound/pci/rme9652/Makefile b/sound/pci/rme9652/Makefile
index a3351447ddc0..cc99ae892211 100644
--- a/sound/pci/rme9652/Makefile
+++ b/sound/pci/rme9652/Makefile
@@ -4,9 +4,9 @@
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
-snd-rme9652-objs := rme9652.o
-snd-hdsp-objs := hdsp.o
-snd-hdspm-objs := hdspm.o
+snd-rme9652-y := rme9652.o
+snd-hdsp-y := hdsp.o
+snd-hdspm-y := hdspm.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_RME9652) += snd-rme9652.o
diff --git a/sound/pci/trident/Makefile b/sound/pci/trident/Makefile
index e8975bc37fcb..476d16abcfc9 100644
--- a/sound/pci/trident/Makefile
+++ b/sound/pci/trident/Makefile
@@ -4,7 +4,7 @@
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
-snd-trident-objs := trident.o trident_main.o trident_memory.o
+snd-trident-y := trident.o trident_main.o trident_memory.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_TRIDENT) += snd-trident.o
diff --git a/sound/pci/vx222/Makefile b/sound/pci/vx222/Makefile
index dda900e45385..6889137eb438 100644
--- a/sound/pci/vx222/Makefile
+++ b/sound/pci/vx222/Makefile
@@ -4,6 +4,6 @@
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
-snd-vx222-objs := vx222.o vx222_ops.o
+snd-vx222-y := vx222.o vx222_ops.o
obj-$(CONFIG_SND_VX222) += snd-vx222.o
diff --git a/sound/pci/ymfpci/Makefile b/sound/pci/ymfpci/Makefile
index 40a1d83e1a9e..2d7856403371 100644
--- a/sound/pci/ymfpci/Makefile
+++ b/sound/pci/ymfpci/Makefile
@@ -4,7 +4,7 @@
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
-snd-ymfpci-objs := ymfpci.o ymfpci_main.o
+snd-ymfpci-y := ymfpci.o ymfpci_main.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_YMFPCI) += snd-ymfpci.o