aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt7
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt2
-rw-r--r--MAINTAINERS13
-rw-r--r--arch/arm/mach-tegra/Kconfig3
-rw-r--r--arch/arm/mach-tegra/board-harmony.c7
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h (renamed from arch/arm/mach-tegra/include/mach/harmony_audio.h)5
-rw-r--r--drivers/media/radio/Kconfig15
-rw-r--r--drivers/media/radio/Makefile1
-rw-r--r--drivers/media/radio/radio-maestro.c452
-rw-r--r--drivers/staging/intel_sst/intel_sst_drv_interface.c1
-rw-r--r--drivers/staging/intel_sst/intelmid.c4
-rw-r--r--include/linux/mfd/wm8994/pdata.h49
-rw-r--r--include/sound/ak4641.h26
-rw-r--r--include/sound/control.h1
-rw-r--r--include/sound/max98095.h54
-rw-r--r--include/sound/soc-dapm.h80
-rw-r--r--include/sound/soc.h32
-rw-r--r--include/sound/tea575x-tuner.h26
-rw-r--r--include/sound/tlv320dac33-plat.h2
-rw-r--r--include/sound/tpa6130a2-plat.h2
-rw-r--r--include/sound/wm8915.h55
-rw-r--r--include/sound/wm8962.h22
-rw-r--r--sound/core/control.c64
-rw-r--r--sound/core/init.c2
-rw-r--r--sound/core/pcm_lib.c14
-rw-r--r--sound/firewire/Kconfig11
-rw-r--r--sound/firewire/Makefile2
-rw-r--r--sound/firewire/isight.c755
-rw-r--r--sound/firewire/iso-resources.c5
-rw-r--r--sound/firewire/packets-buffer.c2
-rw-r--r--sound/i2c/other/Makefile2
-rw-r--r--sound/i2c/other/tea575x-tuner.c153
-rw-r--r--sound/oss/Kconfig4
-rw-r--r--sound/oss/Makefile1
-rw-r--r--sound/oss/ac97_codec.c1203
-rw-r--r--sound/oss/au1550_ac97.c2147
-rw-r--r--sound/pci/Kconfig27
-rw-r--r--sound/pci/Makefile1
-rw-r--r--sound/pci/asihpi/asihpi.c328
-rw-r--r--sound/pci/asihpi/hpi6000.c39
-rw-r--r--sound/pci/asihpi/hpi6205.c95
-rw-r--r--sound/pci/asihpi/hpi_internal.h19
-rw-r--r--sound/pci/asihpi/hpicmn.c10
-rw-r--r--sound/pci/asihpi/hpicmn.h2
-rw-r--r--sound/pci/asihpi/hpifunc.c27
-rw-r--r--sound/pci/asihpi/hpimsgx.c31
-rw-r--r--sound/pci/asihpi/hpioctl.c63
-rw-r--r--sound/pci/au88x0/au8810.h2
-rw-r--r--sound/pci/au88x0/au8820.h2
-rw-r--r--sound/pci/au88x0/au8830.h2
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c13
-rw-r--r--sound/pci/emu10k1/emufx.c5
-rw-r--r--sound/pci/emu10k1/emumixer.c10
-rw-r--r--sound/pci/es1968.c78
-rw-r--r--sound/pci/fm801.c371
-rw-r--r--sound/pci/hda/hda_codec.c97
-rw-r--r--sound/pci/hda/hda_codec.h4
-rw-r--r--sound/pci/hda/hda_intel.c38
-rw-r--r--sound/pci/hda/hda_local.h16
-rw-r--r--sound/pci/hda/patch_analog.c345
-rw-r--r--sound/pci/hda/patch_ca0110.c16
-rw-r--r--sound/pci/hda/patch_cirrus.c52
-rw-r--r--sound/pci/hda/patch_cmedia.c40
-rw-r--r--sound/pci/hda/patch_conexant.c1085
-rw-r--r--sound/pci/hda/patch_hdmi.c39
-rw-r--r--sound/pci/hda/patch_realtek.c3681
-rw-r--r--sound/pci/hda/patch_si3054.c11
-rw-r--r--sound/pci/hda/patch_sigmatel.c431
-rw-r--r--sound/pci/hda/patch_via.c1526
-rw-r--r--sound/pci/intel8x0m.c4
-rw-r--r--sound/pci/lola/Makefile4
-rw-r--r--sound/pci/lola/lola.c791
-rw-r--r--sound/pci/lola/lola.h527
-rw-r--r--sound/pci/lola/lola_clock.c323
-rw-r--r--sound/pci/lola/lola_mixer.c839
-rw-r--r--sound/pci/lola/lola_pcm.c706
-rw-r--r--sound/pci/lola/lola_proc.c222
-rw-r--r--sound/ppc/tumbler.c2
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c2
-rw-r--r--sound/soc/au1x/db1200.c2
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c13
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c166
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c42
-rw-r--r--sound/soc/blackfin/bf5xx-ad193x.c56
-rw-r--r--sound/soc/blackfin/bf5xx-ad1980.c45
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c42
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c23
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c172
-rw-r--r--sound/soc/blackfin/bf5xx-sport.c159
-rw-r--r--sound/soc/blackfin/bf5xx-sport.h16
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c42
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.c23
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.c110
-rw-r--r--sound/soc/codecs/88pm860x-codec.c2
-rw-r--r--sound/soc/codecs/Kconfig20
-rw-r--r--sound/soc/codecs/Makefile10
-rw-r--r--sound/soc/codecs/ad193x.c23
-rw-r--r--sound/soc/codecs/ad1980.c2
-rw-r--r--sound/soc/codecs/ad73311.c2
-rw-r--r--sound/soc/codecs/ak4535.c19
-rw-r--r--sound/soc/codecs/ak4641.c664
-rw-r--r--sound/soc/codecs/ak4641.h47
-rw-r--r--sound/soc/codecs/ak4671.c18
-rw-r--r--sound/soc/codecs/cx20442.c18
-rw-r--r--sound/soc/codecs/dmic.c26
-rw-r--r--sound/soc/codecs/jz4740.c18
-rw-r--r--sound/soc/codecs/max98088.c87
-rw-r--r--sound/soc/codecs/max98088.h13
-rw-r--r--sound/soc/codecs/max98095.c2396
-rw-r--r--sound/soc/codecs/max98095.h299
-rw-r--r--sound/soc/codecs/sn95031.c17
-rw-r--r--sound/soc/codecs/spdif_transciever.c8
-rw-r--r--sound/soc/codecs/ssm2602.c464
-rw-r--r--sound/soc/codecs/ssm2602.h6
-rw-r--r--sound/soc/codecs/tlv320aic23.c19
-rw-r--r--sound/soc/codecs/tlv320aic3x.c3
-rw-r--r--sound/soc/codecs/tlv320dac33.c17
-rw-r--r--sound/soc/codecs/tlv320dac33.h2
-rw-r--r--sound/soc/codecs/tpa6130a2.c4
-rw-r--r--sound/soc/codecs/tpa6130a2.h2
-rw-r--r--sound/soc/codecs/twl6040.c6
-rw-r--r--sound/soc/codecs/wm1250-ev1.c108
-rw-r--r--sound/soc/codecs/wm8711.c18
-rw-r--r--sound/soc/codecs/wm8728.c18
-rw-r--r--sound/soc/codecs/wm8731.c22
-rw-r--r--sound/soc/codecs/wm8903.c44
-rw-r--r--sound/soc/codecs/wm8915.c2931
-rw-r--r--sound/soc/codecs/wm8915.h3717
-rw-r--r--sound/soc/codecs/wm8958-dsp2.c1051
-rw-r--r--sound/soc/codecs/wm8962.c63
-rw-r--r--sound/soc/codecs/wm8993.c3
-rw-r--r--sound/soc/codecs/wm8994.c395
-rw-r--r--sound/soc/codecs/wm8994.h97
-rw-r--r--sound/soc/codecs/wm8995.c4
-rw-r--r--sound/soc/codecs/wm9705.c18
-rw-r--r--sound/soc/codecs/wm9712.c18
-rw-r--r--sound/soc/codecs/wm9713.c19
-rw-r--r--sound/soc/codecs/wm_hubs.c24
-rw-r--r--sound/soc/davinci/davinci-mcasp.c2
-rw-r--r--sound/soc/imx/imx-ssi.c6
-rw-r--r--sound/soc/jz4740/qi_lb60.c46
-rw-r--r--sound/soc/mid-x86/sst_platform.c4
-rw-r--r--sound/soc/omap/omap-mcbsp.c6
-rw-r--r--sound/soc/omap/omap-mcbsp.h2
-rw-r--r--sound/soc/omap/omap-pcm.c7
-rw-r--r--sound/soc/omap/omap-pcm.h2
-rw-r--r--sound/soc/omap/rx51.c2
-rw-r--r--sound/soc/pxa/Kconfig9
-rw-r--r--sound/soc/pxa/Makefile2
-rw-r--r--sound/soc/pxa/corgi.c2
-rw-r--r--sound/soc/pxa/hx4700.c255
-rw-r--r--sound/soc/pxa/poodle.c2
-rw-r--r--sound/soc/pxa/spitz.c41
-rw-r--r--sound/soc/samsung/Kconfig15
-rw-r--r--sound/soc/samsung/Makefile4
-rw-r--r--sound/soc/samsung/goni_wm8994.c1
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c1
-rw-r--r--sound/soc/samsung/smdk_wm8580pcm.c206
-rw-r--r--sound/soc/samsung/speyside.c332
-rw-r--r--sound/soc/sh/fsi.c188
-rw-r--r--sound/soc/soc-cache.c612
-rw-r--r--sound/soc/soc-core.c191
-rw-r--r--sound/soc/soc-dapm.c611
-rw-r--r--sound/soc/soc-jack.c2
-rw-r--r--sound/soc/soc-utils.c53
-rw-r--r--sound/soc/tegra/Kconfig38
-rw-r--r--sound/soc/tegra/Makefile14
-rw-r--r--sound/soc/tegra/harmony.c394
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.c9
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.h2
-rw-r--r--sound/soc/tegra/tegra_i2s.c2
-rw-r--r--sound/soc/tegra/tegra_wm8903.c475
-rw-r--r--sound/soc/tegra/trimslice.c228
-rw-r--r--sound/usb/6fire/control.c105
-rw-r--r--sound/usb/6fire/control.h17
-rw-r--r--sound/usb/6fire/firmware.c73
-rw-r--r--sound/usb/6fire/pcm.c97
-rw-r--r--sound/usb/Kconfig10
-rw-r--r--sound/usb/clock.c11
-rw-r--r--sound/usb/debug.h2
-rw-r--r--sound/usb/format.c1
-rw-r--r--sound/usb/mixer.c10
-rw-r--r--sound/usb/mixer_quirks.c12
-rw-r--r--sound/usb/quirks-table.h47
-rw-r--r--sound/usb/quirks.c1
185 files changed, 24459 insertions, 10516 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 9822afb6313c..89757012c7ff 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -1230,6 +1230,13 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1230 This module supports multiple cards. 1230 This module supports multiple cards.
1231 The driver requires the firmware loader support on kernel. 1231 The driver requires the firmware loader support on kernel.
1232 1232
1233 Module snd-lola
1234 ---------------
1235
1236 Module for Digigram Lola PCI-e boards
1237
1238 This module supports multiple cards.
1239
1233 Module snd-lx6464es 1240 Module snd-lx6464es
1234 ------------------- 1241 -------------------
1235 1242
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index 0caf77e59be4..d70c93bdcadf 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -94,7 +94,7 @@ ALC662/663/272
94 3stack-dig 3-stack (2-channel) with SPDIF 94 3stack-dig 3-stack (2-channel) with SPDIF
95 3stack-6ch 3-stack (6-channel) 95 3stack-6ch 3-stack (6-channel)
96 3stack-6ch-dig 3-stack (6-channel) with SPDIF 96 3stack-6ch-dig 3-stack (6-channel) with SPDIF
97 6stack-dig 6-stack with SPDIF 97 5stack-dig 5-stack with SPDIF
98 lenovo-101e Lenovo laptop 98 lenovo-101e Lenovo laptop
99 eeepc-p701 ASUS Eeepc P701 99 eeepc-p701 ASUS Eeepc P701
100 eeepc-ep20 ASUS Eeepc EP20 100 eeepc-ep20 ASUS Eeepc EP20
diff --git a/MAINTAINERS b/MAINTAINERS
index 49a0bf3a5b97..0c916367ae7c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4269,6 +4269,13 @@ M: Tim Hockin <thockin@hockin.org>
4269S: Maintained 4269S: Maintained
4270F: drivers/net/natsemi.c 4270F: drivers/net/natsemi.c
4271 4271
4272NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER
4273M: Daniel Mack <zonque@gmail.com>
4274S: Maintained
4275L: alsa-devel@alsa-project.org
4276W: http://www.native-instruments.com
4277F: sound/usb/caiaq/
4278
4272NCP FILESYSTEM 4279NCP FILESYSTEM
4273M: Petr Vandrovec <petr@vandrovec.name> 4280M: Petr Vandrovec <petr@vandrovec.name>
4274S: Odd Fixes 4281S: Odd Fixes
@@ -5868,7 +5875,7 @@ F: include/sound/
5868F: sound/ 5875F: sound/
5869 5876
5870SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC) 5877SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC)
5871M: Liam Girdwood <lrg@slimlogic.co.uk> 5878M: Liam Girdwood <lrg@ti.com>
5872M: Mark Brown <broonie@opensource.wolfsonmicro.com> 5879M: Mark Brown <broonie@opensource.wolfsonmicro.com>
5873T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git 5880T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git
5874L: alsa-devel@alsa-project.org (moderated for non-subscribers) 5881L: alsa-devel@alsa-project.org (moderated for non-subscribers)
@@ -6119,7 +6126,7 @@ F: drivers/mmc/host/tifm_sd.c
6119F: include/linux/tifm.h 6126F: include/linux/tifm.h
6120 6127
6121TI TWL4030 SERIES SOC CODEC DRIVER 6128TI TWL4030 SERIES SOC CODEC DRIVER
6122M: Peter Ujfalusi <peter.ujfalusi@nokia.com> 6129M: Peter Ujfalusi <peter.ujfalusi@ti.com>
6123L: alsa-devel@alsa-project.org (moderated for non-subscribers) 6130L: alsa-devel@alsa-project.org (moderated for non-subscribers)
6124S: Maintained 6131S: Maintained
6125F: sound/soc/codecs/twl4030* 6132F: sound/soc/codecs/twl4030*
@@ -6763,7 +6770,7 @@ F: drivers/scsi/vmw_pvscsi.c
6763F: drivers/scsi/vmw_pvscsi.h 6770F: drivers/scsi/vmw_pvscsi.h
6764 6771
6765VOLTAGE AND CURRENT REGULATOR FRAMEWORK 6772VOLTAGE AND CURRENT REGULATOR FRAMEWORK
6766M: Liam Girdwood <lrg@slimlogic.co.uk> 6773M: Liam Girdwood <lrg@ti.com>
6767M: Mark Brown <broonie@opensource.wolfsonmicro.com> 6774M: Mark Brown <broonie@opensource.wolfsonmicro.com>
6768W: http://opensource.wolfsonmicro.com/node/15 6775W: http://opensource.wolfsonmicro.com/node/15
6769W: http://www.slimlogic.co.uk/?p=48 6776W: http://www.slimlogic.co.uk/?p=48
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 3cdeffc97b44..5ec1846aa1d0 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -27,12 +27,14 @@ comment "Tegra board type"
27 27
28config MACH_HARMONY 28config MACH_HARMONY
29 bool "Harmony board" 29 bool "Harmony board"
30 select MACH_HAS_SND_SOC_TEGRA_WM8903
30 help 31 help
31 Support for nVidia Harmony development platform 32 Support for nVidia Harmony development platform
32 33
33config MACH_KAEN 34config MACH_KAEN
34 bool "Kaen board" 35 bool "Kaen board"
35 select MACH_SEABOARD 36 select MACH_SEABOARD
37 select MACH_HAS_SND_SOC_TEGRA_WM8903
36 help 38 help
37 Support for the Kaen version of Seaboard 39 Support for the Kaen version of Seaboard
38 40
@@ -43,6 +45,7 @@ config MACH_PAZ00
43 45
44config MACH_SEABOARD 46config MACH_SEABOARD
45 bool "Seaboard board" 47 bool "Seaboard board"
48 select MACH_HAS_SND_SOC_TEGRA_WM8903
46 help 49 help
47 Support for nVidia Seaboard development platform. It will 50 Support for nVidia Seaboard development platform. It will
48 also be included for some of the derivative boards that 51 also be included for some of the derivative boards that
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index 75c918a86a31..30e18bc60647 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -34,7 +34,7 @@
34#include <asm/mach/time.h> 34#include <asm/mach/time.h>
35#include <asm/setup.h> 35#include <asm/setup.h>
36 36
37#include <mach/harmony_audio.h> 37#include <mach/tegra_wm8903_pdata.h>
38#include <mach/iomap.h> 38#include <mach/iomap.h>
39#include <mach/irqs.h> 39#include <mach/irqs.h>
40#include <mach/sdhci.h> 40#include <mach/sdhci.h>
@@ -67,15 +67,16 @@ static struct platform_device debug_uart = {
67 }, 67 },
68}; 68};
69 69
70static struct harmony_audio_platform_data harmony_audio_pdata = { 70static struct tegra_wm8903_platform_data harmony_audio_pdata = {
71 .gpio_spkr_en = TEGRA_GPIO_SPKR_EN, 71 .gpio_spkr_en = TEGRA_GPIO_SPKR_EN,
72 .gpio_hp_det = TEGRA_GPIO_HP_DET, 72 .gpio_hp_det = TEGRA_GPIO_HP_DET,
73 .gpio_hp_mute = -1,
73 .gpio_int_mic_en = TEGRA_GPIO_INT_MIC_EN, 74 .gpio_int_mic_en = TEGRA_GPIO_INT_MIC_EN,
74 .gpio_ext_mic_en = TEGRA_GPIO_EXT_MIC_EN, 75 .gpio_ext_mic_en = TEGRA_GPIO_EXT_MIC_EN,
75}; 76};
76 77
77static struct platform_device harmony_audio_device = { 78static struct platform_device harmony_audio_device = {
78 .name = "tegra-snd-harmony", 79 .name = "tegra-snd-wm8903",
79 .id = 0, 80 .id = 0,
80 .dev = { 81 .dev = {
81 .platform_data = &harmony_audio_pdata, 82 .platform_data = &harmony_audio_pdata,
diff --git a/arch/arm/mach-tegra/include/mach/harmony_audio.h b/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
index af086500ab7d..9d293344a7ff 100644
--- a/arch/arm/mach-tegra/include/mach/harmony_audio.h
+++ b/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/mach-tegra/include/mach/harmony_audio.h 2 * arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
3 * 3 *
4 * Copyright 2011 NVIDIA, Inc. 4 * Copyright 2011 NVIDIA, Inc.
5 * 5 *
@@ -14,9 +14,10 @@
14 * 14 *
15 */ 15 */
16 16
17struct harmony_audio_platform_data { 17struct tegra_wm8903_platform_data {
18 int gpio_spkr_en; 18 int gpio_spkr_en;
19 int gpio_hp_det; 19 int gpio_hp_det;
20 int gpio_hp_mute;
20 int gpio_int_mic_en; 21 int gpio_int_mic_en;
21 int gpio_ext_mic_en; 22 int gpio_ext_mic_en;
22}; 23};
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 299994c3aa74..e4c97fd6f05a 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -166,21 +166,6 @@ config RADIO_MAXIRADIO
166 To compile this driver as a module, choose M here: the 166 To compile this driver as a module, choose M here: the
167 module will be called radio-maxiradio. 167 module will be called radio-maxiradio.
168 168
169config RADIO_MAESTRO
170 tristate "Maestro on board radio"
171 depends on VIDEO_V4L2 && PCI
172 ---help---
173 Say Y here to directly support the on-board radio tuner on the
174 Maestro 2 or 2E sound card.
175
176 In order to control your radio card, you will need to use programs
177 that are compatible with the Video For Linux API. Information on
178 this API and pointers to "v4l" programs may be found at
179 <file:Documentation/video4linux/API.html>.
180
181 To compile this driver as a module, choose M here: the
182 module will be called radio-maestro.
183
184config RADIO_MIROPCM20 169config RADIO_MIROPCM20
185 tristate "miroSOUND PCM20 radio" 170 tristate "miroSOUND PCM20 radio"
186 depends on ISA && VIDEO_V4L2 && SND 171 depends on ISA && VIDEO_V4L2 && SND
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 2faa33371986..f484a6e04eb2 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -16,7 +16,6 @@ obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
16obj-$(CONFIG_RADIO_TRUST) += radio-trust.o 16obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
17obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o 17obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
18obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o 18obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o
19obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
20obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o 19obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
21obj-$(CONFIG_USB_DSBR) += dsbr100.o 20obj-$(CONFIG_USB_DSBR) += dsbr100.o
22obj-$(CONFIG_RADIO_SI470X) += si470x/ 21obj-$(CONFIG_RADIO_SI470X) += si470x/
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
deleted file mode 100644
index 6af61bfeb178..000000000000
--- a/drivers/media/radio/radio-maestro.c
+++ /dev/null
@@ -1,452 +0,0 @@
1/* Maestro PCI sound card radio driver for Linux support
2 * (c) 2000 A. Tlalka, atlka@pg.gda.pl
3 * Notes on the hardware
4 *
5 * + Frequency control is done digitally
6 * + No volume control - only mute/unmute - you have to use Aux line volume
7 * control on Maestro card to set the volume
8 * + Radio status (tuned/not_tuned and stereo/mono) is valid some time after
9 * frequency setting (>100ms) and only when the radio is unmuted.
10 * version 0.02
11 * + io port is automatically detected - only the first radio is used
12 * version 0.03
13 * + thread access locking additions
14 * version 0.04
15 * + code improvements
16 * + VIDEO_TUNER_LOW is permanent
17 *
18 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
19 */
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/ioport.h>
24#include <linux/delay.h>
25#include <linux/version.h> /* for KERNEL_VERSION MACRO */
26#include <linux/pci.h>
27#include <linux/videodev2.h>
28#include <linux/io.h>
29#include <linux/slab.h>
30#include <media/v4l2-device.h>
31#include <media/v4l2-ioctl.h>
32
33MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl");
34MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
35MODULE_LICENSE("GPL");
36
37static int radio_nr = -1;
38module_param(radio_nr, int, 0);
39
40#define RADIO_VERSION KERNEL_VERSION(0, 0, 6)
41#define DRIVER_VERSION "0.06"
42
43#define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */
44
45#define IO_MASK 4 /* mask register offset from GPIO_DATA
46 bits 1=unmask write to given bit */
47#define IO_DIR 8 /* direction register offset from GPIO_DATA
48 bits 0/1=read/write direction */
49
50#define GPIO6 0x0040 /* mask bits for GPIO lines */
51#define GPIO7 0x0080
52#define GPIO8 0x0100
53#define GPIO9 0x0200
54
55#define STR_DATA GPIO6 /* radio TEA5757 pins and GPIO bits */
56#define STR_CLK GPIO7
57#define STR_WREN GPIO8
58#define STR_MOST GPIO9
59
60#define FREQ_LO 50*16000
61#define FREQ_HI 150*16000
62
63#define FREQ_IF 171200 /* 10.7*16000 */
64#define FREQ_STEP 200 /* 12.5*16 */
65
66#define FREQ2BITS(x) ((((unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1))\
67 /(FREQ_STEP<<2))<<2) /* (x==fmhz*16*1000) -> bits */
68
69#define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF)
70
71struct maestro {
72 struct v4l2_device v4l2_dev;
73 struct video_device vdev;
74 struct pci_dev *pdev;
75 struct mutex lock;
76
77 u16 io; /* base of Maestro card radio io (GPIO_DATA)*/
78 u16 muted; /* VIDEO_AUDIO_MUTE */
79 u16 stereo; /* VIDEO_TUNER_STEREO_ON */
80 u16 tuned; /* signal strength (0 or 0xffff) */
81};
82
83static inline struct maestro *to_maestro(struct v4l2_device *v4l2_dev)
84{
85 return container_of(v4l2_dev, struct maestro, v4l2_dev);
86}
87
88static u32 radio_bits_get(struct maestro *dev)
89{
90 u16 io = dev->io, l, rdata;
91 u32 data = 0;
92 u16 omask;
93
94 omask = inw(io + IO_MASK);
95 outw(~(STR_CLK | STR_WREN), io + IO_MASK);
96 outw(0, io);
97 udelay(16);
98
99 for (l = 24; l--;) {
100 outw(STR_CLK, io); /* HI state */
101 udelay(2);
102 if (!l)
103 dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff;
104 outw(0, io); /* LO state */
105 udelay(2);
106 data <<= 1; /* shift data */
107 rdata = inw(io);
108 if (!l)
109 dev->stereo = (rdata & STR_MOST) ? 0 : 1;
110 else if (rdata & STR_DATA)
111 data++;
112 udelay(2);
113 }
114
115 if (dev->muted)
116 outw(STR_WREN, io);
117
118 udelay(4);
119 outw(omask, io + IO_MASK);
120
121 return data & 0x3ffe;
122}
123
124static void radio_bits_set(struct maestro *dev, u32 data)
125{
126 u16 io = dev->io, l, bits;
127 u16 omask, odir;
128
129 omask = inw(io + IO_MASK);
130 odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
131 outw(odir | STR_DATA, io + IO_DIR);
132 outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
133 udelay(16);
134 for (l = 25; l; l--) {
135 bits = ((data >> 18) & STR_DATA) | STR_WREN;
136 data <<= 1; /* shift data */
137 outw(bits, io); /* start strobe */
138 udelay(2);
139 outw(bits | STR_CLK, io); /* HI level */
140 udelay(2);
141 outw(bits, io); /* LO level */
142 udelay(4);
143 }
144
145 if (!dev->muted)
146 outw(0, io);
147
148 udelay(4);
149 outw(omask, io + IO_MASK);
150 outw(odir, io + IO_DIR);
151 msleep(125);
152}
153
154static int vidioc_querycap(struct file *file, void *priv,
155 struct v4l2_capability *v)
156{
157 struct maestro *dev = video_drvdata(file);
158
159 strlcpy(v->driver, "radio-maestro", sizeof(v->driver));
160 strlcpy(v->card, "Maestro Radio", sizeof(v->card));
161 snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev));
162 v->version = RADIO_VERSION;
163 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
164 return 0;
165}
166
167static int vidioc_g_tuner(struct file *file, void *priv,
168 struct v4l2_tuner *v)
169{
170 struct maestro *dev = video_drvdata(file);
171
172 if (v->index > 0)
173 return -EINVAL;
174
175 mutex_lock(&dev->lock);
176 radio_bits_get(dev);
177
178 strlcpy(v->name, "FM", sizeof(v->name));
179 v->type = V4L2_TUNER_RADIO;
180 v->rangelow = FREQ_LO;
181 v->rangehigh = FREQ_HI;
182 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
183 v->capability = V4L2_TUNER_CAP_LOW;
184 if (dev->stereo)
185 v->audmode = V4L2_TUNER_MODE_STEREO;
186 else
187 v->audmode = V4L2_TUNER_MODE_MONO;
188 v->signal = dev->tuned;
189 mutex_unlock(&dev->lock);
190 return 0;
191}
192
193static int vidioc_s_tuner(struct file *file, void *priv,
194 struct v4l2_tuner *v)
195{
196 return v->index ? -EINVAL : 0;
197}
198
199static int vidioc_s_frequency(struct file *file, void *priv,
200 struct v4l2_frequency *f)
201{
202 struct maestro *dev = video_drvdata(file);
203
204 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
205 return -EINVAL;
206 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
207 return -EINVAL;
208 mutex_lock(&dev->lock);
209 radio_bits_set(dev, FREQ2BITS(f->frequency));
210 mutex_unlock(&dev->lock);
211 return 0;
212}
213
214static int vidioc_g_frequency(struct file *file, void *priv,
215 struct v4l2_frequency *f)
216{
217 struct maestro *dev = video_drvdata(file);
218
219 if (f->tuner != 0)
220 return -EINVAL;
221 f->type = V4L2_TUNER_RADIO;
222 mutex_lock(&dev->lock);
223 f->frequency = BITS2FREQ(radio_bits_get(dev));
224 mutex_unlock(&dev->lock);
225 return 0;
226}
227
228static int vidioc_queryctrl(struct file *file, void *priv,
229 struct v4l2_queryctrl *qc)
230{
231 switch (qc->id) {
232 case V4L2_CID_AUDIO_MUTE:
233 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
234 }
235 return -EINVAL;
236}
237
238static int vidioc_g_ctrl(struct file *file, void *priv,
239 struct v4l2_control *ctrl)
240{
241 struct maestro *dev = video_drvdata(file);
242
243 switch (ctrl->id) {
244 case V4L2_CID_AUDIO_MUTE:
245 ctrl->value = dev->muted;
246 return 0;
247 }
248 return -EINVAL;
249}
250
251static int vidioc_s_ctrl(struct file *file, void *priv,
252 struct v4l2_control *ctrl)
253{
254 struct maestro *dev = video_drvdata(file);
255 u16 io = dev->io;
256 u16 omask;
257
258 switch (ctrl->id) {
259 case V4L2_CID_AUDIO_MUTE:
260 mutex_lock(&dev->lock);
261 omask = inw(io + IO_MASK);
262 outw(~STR_WREN, io + IO_MASK);
263 dev->muted = ctrl->value;
264 outw(dev->muted ? STR_WREN : 0, io);
265 udelay(4);
266 outw(omask, io + IO_MASK);
267 msleep(125);
268 mutex_unlock(&dev->lock);
269 return 0;
270 }
271 return -EINVAL;
272}
273
274static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
275{
276 *i = 0;
277 return 0;
278}
279
280static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
281{
282 return i ? -EINVAL : 0;
283}
284
285static int vidioc_g_audio(struct file *file, void *priv,
286 struct v4l2_audio *a)
287{
288 a->index = 0;
289 strlcpy(a->name, "Radio", sizeof(a->name));
290 a->capability = V4L2_AUDCAP_STEREO;
291 return 0;
292}
293
294static int vidioc_s_audio(struct file *file, void *priv,
295 struct v4l2_audio *a)
296{
297 return a->index ? -EINVAL : 0;
298}
299
300static const struct v4l2_file_operations maestro_fops = {
301 .owner = THIS_MODULE,
302 .unlocked_ioctl = video_ioctl2,
303};
304
305static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
306 .vidioc_querycap = vidioc_querycap,
307 .vidioc_g_tuner = vidioc_g_tuner,
308 .vidioc_s_tuner = vidioc_s_tuner,
309 .vidioc_g_audio = vidioc_g_audio,
310 .vidioc_s_audio = vidioc_s_audio,
311 .vidioc_g_input = vidioc_g_input,
312 .vidioc_s_input = vidioc_s_input,
313 .vidioc_g_frequency = vidioc_g_frequency,
314 .vidioc_s_frequency = vidioc_s_frequency,
315 .vidioc_queryctrl = vidioc_queryctrl,
316 .vidioc_g_ctrl = vidioc_g_ctrl,
317 .vidioc_s_ctrl = vidioc_s_ctrl,
318};
319
320static u16 __devinit radio_power_on(struct maestro *dev)
321{
322 register u16 io = dev->io;
323 register u32 ofreq;
324 u16 omask, odir;
325
326 omask = inw(io + IO_MASK);
327 odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
328 outw(odir & ~STR_WREN, io + IO_DIR);
329 dev->muted = inw(io) & STR_WREN ? 0 : 1;
330 outw(odir, io + IO_DIR);
331 outw(~(STR_WREN | STR_CLK), io + IO_MASK);
332 outw(dev->muted ? 0 : STR_WREN, io);
333 udelay(16);
334 outw(omask, io + IO_MASK);
335 ofreq = radio_bits_get(dev);
336
337 if ((ofreq < FREQ2BITS(FREQ_LO)) || (ofreq > FREQ2BITS(FREQ_HI)))
338 ofreq = FREQ2BITS(FREQ_LO);
339 radio_bits_set(dev, ofreq);
340
341 return (ofreq == radio_bits_get(dev));
342}
343
344static int __devinit maestro_probe(struct pci_dev *pdev,
345 const struct pci_device_id *ent)
346{
347 struct maestro *dev;
348 struct v4l2_device *v4l2_dev;
349 int retval;
350
351 retval = pci_enable_device(pdev);
352 if (retval) {
353 dev_err(&pdev->dev, "enabling pci device failed!\n");
354 goto err;
355 }
356
357 retval = -ENOMEM;
358
359 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
360 if (dev == NULL) {
361 dev_err(&pdev->dev, "not enough memory\n");
362 goto err;
363 }
364
365 v4l2_dev = &dev->v4l2_dev;
366 mutex_init(&dev->lock);
367 dev->pdev = pdev;
368
369 strlcpy(v4l2_dev->name, "maestro", sizeof(v4l2_dev->name));
370
371 retval = v4l2_device_register(&pdev->dev, v4l2_dev);
372 if (retval < 0) {
373 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
374 goto errfr;
375 }
376
377 dev->io = pci_resource_start(pdev, 0) + GPIO_DATA;
378
379 strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
380 dev->vdev.v4l2_dev = v4l2_dev;
381 dev->vdev.fops = &maestro_fops;
382 dev->vdev.ioctl_ops = &maestro_ioctl_ops;
383 dev->vdev.release = video_device_release_empty;
384 video_set_drvdata(&dev->vdev, dev);
385
386 if (!radio_power_on(dev)) {
387 retval = -EIO;
388 goto errfr1;
389 }
390
391 retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr);
392 if (retval) {
393 v4l2_err(v4l2_dev, "can't register video device!\n");
394 goto errfr1;
395 }
396
397 v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n");
398
399 return 0;
400errfr1:
401 v4l2_device_unregister(v4l2_dev);
402errfr:
403 kfree(dev);
404err:
405 return retval;
406
407}
408
409static void __devexit maestro_remove(struct pci_dev *pdev)
410{
411 struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
412 struct maestro *dev = to_maestro(v4l2_dev);
413
414 video_unregister_device(&dev->vdev);
415 v4l2_device_unregister(&dev->v4l2_dev);
416}
417
418static struct pci_device_id maestro_r_pci_tbl[] = {
419 { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968),
420 .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
421 .class_mask = 0xffff00 },
422 { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978),
423 .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
424 .class_mask = 0xffff00 },
425 { 0 }
426};
427MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl);
428
429static struct pci_driver maestro_r_driver = {
430 .name = "maestro_radio",
431 .id_table = maestro_r_pci_tbl,
432 .probe = maestro_probe,
433 .remove = __devexit_p(maestro_remove),
434};
435
436static int __init maestro_radio_init(void)
437{
438 int retval = pci_register_driver(&maestro_r_driver);
439
440 if (retval)
441 printk(KERN_ERR "error during registration pci driver\n");
442
443 return retval;
444}
445
446static void __exit maestro_radio_exit(void)
447{
448 pci_unregister_driver(&maestro_r_driver);
449}
450
451module_init(maestro_radio_init);
452module_exit(maestro_radio_exit);
diff --git a/drivers/staging/intel_sst/intel_sst_drv_interface.c b/drivers/staging/intel_sst/intel_sst_drv_interface.c
index e9c182108243..971588ce26d3 100644
--- a/drivers/staging/intel_sst/intel_sst_drv_interface.c
+++ b/drivers/staging/intel_sst/intel_sst_drv_interface.c
@@ -508,7 +508,6 @@ int register_sst_card(struct intel_sst_card_ops *card)
508 sst_drv_ctx->pmic_state = SND_MAD_INIT_DONE; 508 sst_drv_ctx->pmic_state = SND_MAD_INIT_DONE;
509 sst_drv_ctx->rx_time_slot_status = 0; /*default AMIC*/ 509 sst_drv_ctx->rx_time_slot_status = 0; /*default AMIC*/
510 card->pcm_control = sst_pmic_ops.pcm_control; 510 card->pcm_control = sst_pmic_ops.pcm_control;
511 sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT;
512 return 0; 511 return 0;
513 } else { 512 } else {
514 pr_err("strcmp fail %s\n", card->module_name); 513 pr_err("strcmp fail %s\n", card->module_name);
diff --git a/drivers/staging/intel_sst/intelmid.c b/drivers/staging/intel_sst/intelmid.c
index d207636a7b6d..ebb6d03552c4 100644
--- a/drivers/staging/intel_sst/intelmid.c
+++ b/drivers/staging/intel_sst/intelmid.c
@@ -32,6 +32,7 @@
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/interrupt.h> 33#include <linux/interrupt.h>
34#include <linux/sched.h> 34#include <linux/sched.h>
35#include <linux/firmware.h>
35#include <sound/control.h> 36#include <sound/control.h>
36#include <asm/mrst.h> 37#include <asm/mrst.h>
37#include <sound/pcm.h> 38#include <sound/pcm.h>
@@ -40,6 +41,8 @@
40#include <sound/initval.h> 41#include <sound/initval.h>
41#include "intel_sst.h" 42#include "intel_sst.h"
42#include "intel_sst_ioctl.h" 43#include "intel_sst_ioctl.h"
44#include "intel_sst_fw_ipc.h"
45#include "intel_sst_common.h"
43#include "intelmid_snd_control.h" 46#include "intelmid_snd_control.h"
44#include "intelmid.h" 47#include "intelmid.h"
45 48
@@ -802,6 +805,7 @@ static int __devinit snd_intelmad_sst_register(
802 pr_err("sst card registration failed\n"); 805 pr_err("sst card registration failed\n");
803 return ret_val; 806 return ret_val;
804 } 807 }
808 sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT;
805 809
806 sst_card_vendor_id = intelmaddata->sstdrv_ops->vendor_id; 810 sst_card_vendor_id = intelmaddata->sstdrv_ops->vendor_id;
807 intelmaddata->pmic_status = PMIC_UNINIT; 811 intelmaddata->pmic_status = PMIC_UNINIT;
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
index 466b1c777aff..d12f8d635a81 100644
--- a/include/linux/mfd/wm8994/pdata.h
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -32,6 +32,10 @@ struct wm8994_ldo_pdata {
32#define WM8994_EQ_REGS 20 32#define WM8994_EQ_REGS 20
33#define WM8958_MBC_CUTOFF_REGS 20 33#define WM8958_MBC_CUTOFF_REGS 20
34#define WM8958_MBC_COEFF_REGS 48 34#define WM8958_MBC_COEFF_REGS 48
35#define WM8958_MBC_COMBINED_REGS 56
36#define WM8958_VSS_HPF_REGS 2
37#define WM8958_VSS_REGS 148
38#define WM8958_ENH_EQ_REGS 32
35 39
36/** 40/**
37 * DRC configurations are specified with a label and a set of register 41 * DRC configurations are specified with a label and a set of register
@@ -71,6 +75,42 @@ struct wm8958_mbc_cfg {
71 const char *name; 75 const char *name;
72 u16 cutoff_regs[WM8958_MBC_CUTOFF_REGS]; 76 u16 cutoff_regs[WM8958_MBC_CUTOFF_REGS];
73 u16 coeff_regs[WM8958_MBC_COEFF_REGS]; 77 u16 coeff_regs[WM8958_MBC_COEFF_REGS];
78
79 /* Coefficient layout when using MBC+VSS firmware */
80 u16 combined_regs[WM8958_MBC_COMBINED_REGS];
81};
82
83/**
84 * VSS HPF configurations are specified with a label and two values to
85 * write. Configurations are expected to be generated using the
86 * multiband compressor configuration panel in WISCE - see
87 * http://www.wolfsonmicro.com/wisce/
88 */
89struct wm8958_vss_hpf_cfg {
90 const char *name;
91 u16 regs[WM8958_VSS_HPF_REGS];
92};
93
94/**
95 * VSS configurations are specified with a label and array of values
96 * to write. Configurations are expected to be generated using the
97 * multiband compressor configuration panel in WISCE - see
98 * http://www.wolfsonmicro.com/wisce/
99 */
100struct wm8958_vss_cfg {
101 const char *name;
102 u16 regs[WM8958_VSS_REGS];
103};
104
105/**
106 * Enhanced EQ configurations are specified with a label and array of
107 * values to write. Configurations are expected to be generated using
108 * the multiband compressor configuration panel in WISCE - see
109 * http://www.wolfsonmicro.com/wisce/
110 */
111struct wm8958_enh_eq_cfg {
112 const char *name;
113 u16 regs[WM8958_ENH_EQ_REGS];
74}; 114};
75 115
76struct wm8994_pdata { 116struct wm8994_pdata {
@@ -95,6 +135,15 @@ struct wm8994_pdata {
95 int num_mbc_cfgs; 135 int num_mbc_cfgs;
96 struct wm8958_mbc_cfg *mbc_cfgs; 136 struct wm8958_mbc_cfg *mbc_cfgs;
97 137
138 int num_vss_cfgs;
139 struct wm8958_vss_cfg *vss_cfgs;
140
141 int num_vss_hpf_cfgs;
142 struct wm8958_vss_hpf_cfg *vss_hpf_cfgs;
143
144 int num_enh_eq_cfgs;
145 struct wm8958_enh_eq_cfg *enh_eq_cfgs;
146
98 /* LINEOUT can be differential or single ended */ 147 /* LINEOUT can be differential or single ended */
99 unsigned int lineout1_diff:1; 148 unsigned int lineout1_diff:1;
100 unsigned int lineout2_diff:1; 149 unsigned int lineout2_diff:1;
diff --git a/include/sound/ak4641.h b/include/sound/ak4641.h
new file mode 100644
index 000000000000..96d1991c811d
--- /dev/null
+++ b/include/sound/ak4641.h
@@ -0,0 +1,26 @@
1/*
2 * AK4641 ALSA SoC Codec driver
3 *
4 * Copyright 2009 Philipp Zabel
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __AK4641_H
12#define __AK4641_H
13
14/**
15 * struct ak4641_platform_data - platform specific AK4641 configuration
16 * @gpio_power: GPIO to control external power to AK4641
17 * @gpio_npdn: GPIO connected to AK4641 nPDN pin
18 *
19 * Both GPIO parameters are optional.
20 */
21struct ak4641_platform_data {
22 int gpio_power;
23 int gpio_npdn;
24};
25
26#endif /* __AK4641_H */
diff --git a/include/sound/control.h b/include/sound/control.h
index 404acb859cee..1a94a216ed99 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -113,6 +113,7 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new * kcontrolnew, v
113void snd_ctl_free_one(struct snd_kcontrol * kcontrol); 113void snd_ctl_free_one(struct snd_kcontrol * kcontrol);
114int snd_ctl_add(struct snd_card * card, struct snd_kcontrol * kcontrol); 114int snd_ctl_add(struct snd_card * card, struct snd_kcontrol * kcontrol);
115int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol); 115int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol);
116int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace);
116int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id); 117int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
117int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id); 118int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
118int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, 119int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id,
diff --git a/include/sound/max98095.h b/include/sound/max98095.h
new file mode 100644
index 000000000000..7513a42dd4aa
--- /dev/null
+++ b/include/sound/max98095.h
@@ -0,0 +1,54 @@
1/*
2 * Platform data for MAX98095
3 *
4 * Copyright 2011 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#ifndef __SOUND_MAX98095_PDATA_H__
14#define __SOUND_MAX98095_PDATA_H__
15
16/* Equalizer filter response configuration */
17struct max98095_eq_cfg {
18 const char *name;
19 unsigned int rate;
20 u16 band1[5];
21 u16 band2[5];
22 u16 band3[5];
23 u16 band4[5];
24 u16 band5[5];
25};
26
27/* Biquad filter response configuration */
28struct max98095_biquad_cfg {
29 const char *name;
30 unsigned int rate;
31 u16 band1[5];
32 u16 band2[5];
33};
34
35/* codec platform data */
36struct max98095_pdata {
37
38 /* Equalizers for DAI1 and DAI2 */
39 struct max98095_eq_cfg *eq_cfg;
40 unsigned int eq_cfgcnt;
41
42 /* Biquad filter for DAI1 and DAI2 */
43 struct max98095_biquad_cfg *bq_cfg;
44 unsigned int bq_cfgcnt;
45
46 /* Analog/digital microphone configuration:
47 * 0 = analog microphone input (normal setting)
48 * 1 = digital microphone input
49 */
50 unsigned int digmic_left_mode:1;
51 unsigned int digmic_right_mode:1;
52};
53
54#endif
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index f72c1039a6fb..c46e7d89561d 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -24,7 +24,7 @@
24 * SoC dynamic audio power management 24 * SoC dynamic audio power management
25 * 25 *
26 * We can have up to 4 power domains 26 * We can have up to 4 power domains
27 * 1. Codec domain - VREF, VMID 27 * 1. Codec domain - VREF, VMID
28 * Usually controlled at codec probe/remove, although can be set 28 * Usually controlled at codec probe/remove, although can be set
29 * at stream time if power is not needed for sidetone, etc. 29 * at stream time if power is not needed for sidetone, etc.
30 * 2. Platform/Machine domain - physically connected inputs and outputs 30 * 2. Platform/Machine domain - physically connected inputs and outputs
@@ -39,30 +39,30 @@
39 39
40/* codec domain */ 40/* codec domain */
41#define SND_SOC_DAPM_VMID(wname) \ 41#define SND_SOC_DAPM_VMID(wname) \
42{ .id = snd_soc_dapm_vmid, .name = wname, .kcontrols = NULL, \ 42{ .id = snd_soc_dapm_vmid, .name = wname, .kcontrol_news = NULL, \
43 .num_kcontrols = 0} 43 .num_kcontrols = 0}
44 44
45/* platform domain */ 45/* platform domain */
46#define SND_SOC_DAPM_INPUT(wname) \ 46#define SND_SOC_DAPM_INPUT(wname) \
47{ .id = snd_soc_dapm_input, .name = wname, .kcontrols = NULL, \ 47{ .id = snd_soc_dapm_input, .name = wname, .kcontrol_news = NULL, \
48 .num_kcontrols = 0, .reg = SND_SOC_NOPM } 48 .num_kcontrols = 0, .reg = SND_SOC_NOPM }
49#define SND_SOC_DAPM_OUTPUT(wname) \ 49#define SND_SOC_DAPM_OUTPUT(wname) \
50{ .id = snd_soc_dapm_output, .name = wname, .kcontrols = NULL, \ 50{ .id = snd_soc_dapm_output, .name = wname, .kcontrol_news = NULL, \
51 .num_kcontrols = 0, .reg = SND_SOC_NOPM } 51 .num_kcontrols = 0, .reg = SND_SOC_NOPM }
52#define SND_SOC_DAPM_MIC(wname, wevent) \ 52#define SND_SOC_DAPM_MIC(wname, wevent) \
53{ .id = snd_soc_dapm_mic, .name = wname, .kcontrols = NULL, \ 53{ .id = snd_soc_dapm_mic, .name = wname, .kcontrol_news = NULL, \
54 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ 54 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
55 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD} 55 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}
56#define SND_SOC_DAPM_HP(wname, wevent) \ 56#define SND_SOC_DAPM_HP(wname, wevent) \
57{ .id = snd_soc_dapm_hp, .name = wname, .kcontrols = NULL, \ 57{ .id = snd_soc_dapm_hp, .name = wname, .kcontrol_news = NULL, \
58 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ 58 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
59 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD} 59 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}
60#define SND_SOC_DAPM_SPK(wname, wevent) \ 60#define SND_SOC_DAPM_SPK(wname, wevent) \
61{ .id = snd_soc_dapm_spk, .name = wname, .kcontrols = NULL, \ 61{ .id = snd_soc_dapm_spk, .name = wname, .kcontrol_news = NULL, \
62 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ 62 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
63 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD} 63 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}
64#define SND_SOC_DAPM_LINE(wname, wevent) \ 64#define SND_SOC_DAPM_LINE(wname, wevent) \
65{ .id = snd_soc_dapm_line, .name = wname, .kcontrols = NULL, \ 65{ .id = snd_soc_dapm_line, .name = wname, .kcontrol_news = NULL, \
66 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ 66 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
67 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD} 67 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}
68 68
@@ -70,91 +70,91 @@
70#define SND_SOC_DAPM_PGA(wname, wreg, wshift, winvert,\ 70#define SND_SOC_DAPM_PGA(wname, wreg, wshift, winvert,\
71 wcontrols, wncontrols) \ 71 wcontrols, wncontrols) \
72{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \ 72{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \
73 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols} 73 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = wncontrols}
74#define SND_SOC_DAPM_OUT_DRV(wname, wreg, wshift, winvert,\ 74#define SND_SOC_DAPM_OUT_DRV(wname, wreg, wshift, winvert,\
75 wcontrols, wncontrols) \ 75 wcontrols, wncontrols) \
76{ .id = snd_soc_dapm_out_drv, .name = wname, .reg = wreg, .shift = wshift, \ 76{ .id = snd_soc_dapm_out_drv, .name = wname, .reg = wreg, .shift = wshift, \
77 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols} 77 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = wncontrols}
78#define SND_SOC_DAPM_MIXER(wname, wreg, wshift, winvert, \ 78#define SND_SOC_DAPM_MIXER(wname, wreg, wshift, winvert, \
79 wcontrols, wncontrols)\ 79 wcontrols, wncontrols)\
80{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ 80{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \
81 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols} 81 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = wncontrols}
82#define SND_SOC_DAPM_MIXER_NAMED_CTL(wname, wreg, wshift, winvert, \ 82#define SND_SOC_DAPM_MIXER_NAMED_CTL(wname, wreg, wshift, winvert, \
83 wcontrols, wncontrols)\ 83 wcontrols, wncontrols)\
84{ .id = snd_soc_dapm_mixer_named_ctl, .name = wname, .reg = wreg, \ 84{ .id = snd_soc_dapm_mixer_named_ctl, .name = wname, .reg = wreg, \
85 .shift = wshift, .invert = winvert, .kcontrols = wcontrols, \ 85 .shift = wshift, .invert = winvert, .kcontrol_news = wcontrols, \
86 .num_kcontrols = wncontrols} 86 .num_kcontrols = wncontrols}
87#define SND_SOC_DAPM_MICBIAS(wname, wreg, wshift, winvert) \ 87#define SND_SOC_DAPM_MICBIAS(wname, wreg, wshift, winvert) \
88{ .id = snd_soc_dapm_micbias, .name = wname, .reg = wreg, .shift = wshift, \ 88{ .id = snd_soc_dapm_micbias, .name = wname, .reg = wreg, .shift = wshift, \
89 .invert = winvert, .kcontrols = NULL, .num_kcontrols = 0} 89 .invert = winvert, .kcontrol_news = NULL, .num_kcontrols = 0}
90#define SND_SOC_DAPM_SWITCH(wname, wreg, wshift, winvert, wcontrols) \ 90#define SND_SOC_DAPM_SWITCH(wname, wreg, wshift, winvert, wcontrols) \
91{ .id = snd_soc_dapm_switch, .name = wname, .reg = wreg, .shift = wshift, \ 91{ .id = snd_soc_dapm_switch, .name = wname, .reg = wreg, .shift = wshift, \
92 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1} 92 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = 1}
93#define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \ 93#define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \
94{ .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, .shift = wshift, \ 94{ .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, .shift = wshift, \
95 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1} 95 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = 1}
96#define SND_SOC_DAPM_VIRT_MUX(wname, wreg, wshift, winvert, wcontrols) \ 96#define SND_SOC_DAPM_VIRT_MUX(wname, wreg, wshift, winvert, wcontrols) \
97{ .id = snd_soc_dapm_virt_mux, .name = wname, .reg = wreg, .shift = wshift, \ 97{ .id = snd_soc_dapm_virt_mux, .name = wname, .reg = wreg, .shift = wshift, \
98 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1} 98 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = 1}
99#define SND_SOC_DAPM_VALUE_MUX(wname, wreg, wshift, winvert, wcontrols) \ 99#define SND_SOC_DAPM_VALUE_MUX(wname, wreg, wshift, winvert, wcontrols) \
100{ .id = snd_soc_dapm_value_mux, .name = wname, .reg = wreg, \ 100{ .id = snd_soc_dapm_value_mux, .name = wname, .reg = wreg, \
101 .shift = wshift, .invert = winvert, .kcontrols = wcontrols, \ 101 .shift = wshift, .invert = winvert, .kcontrol_news = wcontrols, \
102 .num_kcontrols = 1} 102 .num_kcontrols = 1}
103 103
104/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */ 104/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
105#define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\ 105#define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\
106 wcontrols) \ 106 wcontrols) \
107{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \ 107{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \
108 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)} 108 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}
109#define SOC_MIXER_ARRAY(wname, wreg, wshift, winvert, \ 109#define SOC_MIXER_ARRAY(wname, wreg, wshift, winvert, \
110 wcontrols)\ 110 wcontrols)\
111{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ 111{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \
112 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)} 112 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}
113#define SOC_MIXER_NAMED_CTL_ARRAY(wname, wreg, wshift, winvert, \ 113#define SOC_MIXER_NAMED_CTL_ARRAY(wname, wreg, wshift, winvert, \
114 wcontrols)\ 114 wcontrols)\
115{ .id = snd_soc_dapm_mixer_named_ctl, .name = wname, .reg = wreg, \ 115{ .id = snd_soc_dapm_mixer_named_ctl, .name = wname, .reg = wreg, \
116 .shift = wshift, .invert = winvert, .kcontrols = wcontrols, \ 116 .shift = wshift, .invert = winvert, .kcontrol_news = wcontrols, \
117 .num_kcontrols = ARRAY_SIZE(wcontrols)} 117 .num_kcontrols = ARRAY_SIZE(wcontrols)}
118 118
119/* path domain with event - event handler must return 0 for success */ 119/* path domain with event - event handler must return 0 for success */
120#define SND_SOC_DAPM_PGA_E(wname, wreg, wshift, winvert, wcontrols, \ 120#define SND_SOC_DAPM_PGA_E(wname, wreg, wshift, winvert, wcontrols, \
121 wncontrols, wevent, wflags) \ 121 wncontrols, wevent, wflags) \
122{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \ 122{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \
123 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \ 123 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = wncontrols, \
124 .event = wevent, .event_flags = wflags} 124 .event = wevent, .event_flags = wflags}
125#define SND_SOC_DAPM_OUT_DRV_E(wname, wreg, wshift, winvert, wcontrols, \ 125#define SND_SOC_DAPM_OUT_DRV_E(wname, wreg, wshift, winvert, wcontrols, \
126 wncontrols, wevent, wflags) \ 126 wncontrols, wevent, wflags) \
127{ .id = snd_soc_dapm_out_drv, .name = wname, .reg = wreg, .shift = wshift, \ 127{ .id = snd_soc_dapm_out_drv, .name = wname, .reg = wreg, .shift = wshift, \
128 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \ 128 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = wncontrols, \
129 .event = wevent, .event_flags = wflags} 129 .event = wevent, .event_flags = wflags}
130#define SND_SOC_DAPM_MIXER_E(wname, wreg, wshift, winvert, wcontrols, \ 130#define SND_SOC_DAPM_MIXER_E(wname, wreg, wshift, winvert, wcontrols, \
131 wncontrols, wevent, wflags) \ 131 wncontrols, wevent, wflags) \
132{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ 132{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \
133 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \ 133 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = wncontrols, \
134 .event = wevent, .event_flags = wflags} 134 .event = wevent, .event_flags = wflags}
135#define SND_SOC_DAPM_MIXER_NAMED_CTL_E(wname, wreg, wshift, winvert, \ 135#define SND_SOC_DAPM_MIXER_NAMED_CTL_E(wname, wreg, wshift, winvert, \
136 wcontrols, wncontrols, wevent, wflags) \ 136 wcontrols, wncontrols, wevent, wflags) \
137{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ 137{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \
138 .invert = winvert, .kcontrols = wcontrols, \ 138 .invert = winvert, .kcontrol_news = wcontrols, \
139 .num_kcontrols = wncontrols, .event = wevent, .event_flags = wflags} 139 .num_kcontrols = wncontrols, .event = wevent, .event_flags = wflags}
140#define SND_SOC_DAPM_MICBIAS_E(wname, wreg, wshift, winvert, wevent, wflags) \ 140#define SND_SOC_DAPM_MICBIAS_E(wname, wreg, wshift, winvert, wevent, wflags) \
141{ .id = snd_soc_dapm_micbias, .name = wname, .reg = wreg, .shift = wshift, \ 141{ .id = snd_soc_dapm_micbias, .name = wname, .reg = wreg, .shift = wshift, \
142 .invert = winvert, .kcontrols = NULL, .num_kcontrols = 0, \ 142 .invert = winvert, .kcontrol_news = NULL, .num_kcontrols = 0, \
143 .event = wevent, .event_flags = wflags} 143 .event = wevent, .event_flags = wflags}
144#define SND_SOC_DAPM_SWITCH_E(wname, wreg, wshift, winvert, wcontrols, \ 144#define SND_SOC_DAPM_SWITCH_E(wname, wreg, wshift, winvert, wcontrols, \
145 wevent, wflags) \ 145 wevent, wflags) \
146{ .id = snd_soc_dapm_switch, .name = wname, .reg = wreg, .shift = wshift, \ 146{ .id = snd_soc_dapm_switch, .name = wname, .reg = wreg, .shift = wshift, \
147 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \ 147 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = 1, \
148 .event = wevent, .event_flags = wflags} 148 .event = wevent, .event_flags = wflags}
149#define SND_SOC_DAPM_MUX_E(wname, wreg, wshift, winvert, wcontrols, \ 149#define SND_SOC_DAPM_MUX_E(wname, wreg, wshift, winvert, wcontrols, \
150 wevent, wflags) \ 150 wevent, wflags) \
151{ .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, .shift = wshift, \ 151{ .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, .shift = wshift, \
152 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \ 152 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = 1, \
153 .event = wevent, .event_flags = wflags} 153 .event = wevent, .event_flags = wflags}
154#define SND_SOC_DAPM_VIRT_MUX_E(wname, wreg, wshift, winvert, wcontrols, \ 154#define SND_SOC_DAPM_VIRT_MUX_E(wname, wreg, wshift, winvert, wcontrols, \
155 wevent, wflags) \ 155 wevent, wflags) \
156{ .id = snd_soc_dapm_virt_mux, .name = wname, .reg = wreg, .shift = wshift, \ 156{ .id = snd_soc_dapm_virt_mux, .name = wname, .reg = wreg, .shift = wshift, \
157 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \ 157 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = 1, \
158 .event = wevent, .event_flags = wflags} 158 .event = wevent, .event_flags = wflags}
159 159
160/* additional sequencing control within an event type */ 160/* additional sequencing control within an event type */
@@ -173,26 +173,26 @@
173#define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \ 173#define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
174 wevent, wflags) \ 174 wevent, wflags) \
175{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \ 175{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \
176 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \ 176 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \
177 .event = wevent, .event_flags = wflags} 177 .event = wevent, .event_flags = wflags}
178#define SOC_MIXER_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \ 178#define SOC_MIXER_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
179 wevent, wflags) \ 179 wevent, wflags) \
180{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ 180{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \
181 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \ 181 .invert = winvert, .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \
182 .event = wevent, .event_flags = wflags} 182 .event = wevent, .event_flags = wflags}
183#define SOC_MIXER_NAMED_CTL_E_ARRAY(wname, wreg, wshift, winvert, \ 183#define SOC_MIXER_NAMED_CTL_E_ARRAY(wname, wreg, wshift, winvert, \
184 wcontrols, wevent, wflags) \ 184 wcontrols, wevent, wflags) \
185{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ 185{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \
186 .invert = winvert, .kcontrols = wcontrols, \ 186 .invert = winvert, .kcontrol_news = wcontrols, \
187 .num_kcontrols = ARRAY_SIZE(wcontrols), .event = wevent, .event_flags = wflags} 187 .num_kcontrols = ARRAY_SIZE(wcontrols), .event = wevent, .event_flags = wflags}
188 188
189/* events that are pre and post DAPM */ 189/* events that are pre and post DAPM */
190#define SND_SOC_DAPM_PRE(wname, wevent) \ 190#define SND_SOC_DAPM_PRE(wname, wevent) \
191{ .id = snd_soc_dapm_pre, .name = wname, .kcontrols = NULL, \ 191{ .id = snd_soc_dapm_pre, .name = wname, .kcontrol_news = NULL, \
192 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ 192 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
193 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD} 193 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD}
194#define SND_SOC_DAPM_POST(wname, wevent) \ 194#define SND_SOC_DAPM_POST(wname, wevent) \
195{ .id = snd_soc_dapm_post, .name = wname, .kcontrols = NULL, \ 195{ .id = snd_soc_dapm_post, .name = wname, .kcontrol_news = NULL, \
196 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ 196 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
197 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD} 197 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD}
198 198
@@ -232,7 +232,7 @@
232 232
233/* generic widgets */ 233/* generic widgets */
234#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \ 234#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
235{ .id = wid, .name = wname, .kcontrols = NULL, .num_kcontrols = 0, \ 235{ .id = wid, .name = wname, .kcontrol_news = NULL, .num_kcontrols = 0, \
236 .reg = -((wreg) + 1), .shift = wshift, .mask = wmask, \ 236 .reg = -((wreg) + 1), .shift = wshift, .mask = wmask, \
237 .on_val = won_val, .off_val = woff_val, .event = dapm_reg_event, \ 237 .on_val = won_val, .off_val = woff_val, .event = dapm_reg_event, \
238 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD} 238 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}
@@ -356,7 +356,8 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card);
356 356
357/* dapm sys fs - used by the core */ 357/* dapm sys fs - used by the core */
358int snd_soc_dapm_sys_add(struct device *dev); 358int snd_soc_dapm_sys_add(struct device *dev);
359void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm); 359void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
360 struct dentry *parent);
360 361
361/* dapm audio pin control and status */ 362/* dapm audio pin control and status */
362int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, 363int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm,
@@ -472,7 +473,8 @@ struct snd_soc_dapm_widget {
472 473
473 /* kcontrols that relate to this widget */ 474 /* kcontrols that relate to this widget */
474 int num_kcontrols; 475 int num_kcontrols;
475 const struct snd_kcontrol_new *kcontrols; 476 const struct snd_kcontrol_new *kcontrol_news;
477 struct snd_kcontrol **kcontrols;
476 478
477 /* widget input and outputs */ 479 /* widget input and outputs */
478 struct list_head sources; 480 struct list_head sources;
@@ -516,4 +518,10 @@ struct snd_soc_dapm_context {
516#endif 518#endif
517}; 519};
518 520
521/* A list of widgets associated with an object, typically a snd_kcontrol */
522struct snd_soc_dapm_widget_list {
523 int num_widgets;
524 struct snd_soc_dapm_widget *widgets[0];
525};
526
519#endif 527#endif
diff --git a/include/sound/soc.h b/include/sound/soc.h
index bfa4836ea107..f1de3e0c75bc 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -248,7 +248,7 @@ typedef int (*hw_write_t)(void *,const char* ,int);
248extern struct snd_ac97_bus_ops soc_ac97_ops; 248extern struct snd_ac97_bus_ops soc_ac97_ops;
249 249
250enum snd_soc_control_type { 250enum snd_soc_control_type {
251 SND_SOC_CUSTOM, 251 SND_SOC_CUSTOM = 1,
252 SND_SOC_I2C, 252 SND_SOC_I2C,
253 SND_SOC_SPI, 253 SND_SOC_SPI,
254}; 254};
@@ -278,6 +278,10 @@ int snd_soc_register_codec(struct device *dev,
278void snd_soc_unregister_codec(struct device *dev); 278void snd_soc_unregister_codec(struct device *dev);
279int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, 279int snd_soc_codec_volatile_register(struct snd_soc_codec *codec,
280 unsigned int reg); 280 unsigned int reg);
281int snd_soc_codec_readable_register(struct snd_soc_codec *codec,
282 unsigned int reg);
283int snd_soc_codec_writable_register(struct snd_soc_codec *codec,
284 unsigned int reg);
281int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, 285int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
282 int addr_bits, int data_bits, 286 int addr_bits, int data_bits,
283 enum snd_soc_control_type control); 287 enum snd_soc_control_type control);
@@ -292,6 +296,8 @@ int snd_soc_default_volatile_register(struct snd_soc_codec *codec,
292 unsigned int reg); 296 unsigned int reg);
293int snd_soc_default_readable_register(struct snd_soc_codec *codec, 297int snd_soc_default_readable_register(struct snd_soc_codec *codec,
294 unsigned int reg); 298 unsigned int reg);
299int snd_soc_default_writable_register(struct snd_soc_codec *codec,
300 unsigned int reg);
295 301
296/* Utility functions to get clock rates from various things */ 302/* Utility functions to get clock rates from various things */
297int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); 303int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
@@ -523,6 +529,7 @@ struct snd_soc_codec {
523 size_t reg_size; /* reg_cache_size * reg_word_size */ 529 size_t reg_size; /* reg_cache_size * reg_word_size */
524 int (*volatile_register)(struct snd_soc_codec *, unsigned int); 530 int (*volatile_register)(struct snd_soc_codec *, unsigned int);
525 int (*readable_register)(struct snd_soc_codec *, unsigned int); 531 int (*readable_register)(struct snd_soc_codec *, unsigned int);
532 int (*writable_register)(struct snd_soc_codec *, unsigned int);
526 533
527 /* runtime */ 534 /* runtime */
528 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ 535 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
@@ -539,10 +546,12 @@ struct snd_soc_codec {
539 546
540 /* codec IO */ 547 /* codec IO */
541 void *control_data; /* codec control (i2c/3wire) data */ 548 void *control_data; /* codec control (i2c/3wire) data */
549 enum snd_soc_control_type control_type;
542 hw_write_t hw_write; 550 hw_write_t hw_write;
543 unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int); 551 unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
544 unsigned int (*read)(struct snd_soc_codec *, unsigned int); 552 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
545 int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); 553 int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
554 int (*bulk_write_raw)(struct snd_soc_codec *, unsigned int, const void *, size_t);
546 void *reg_cache; 555 void *reg_cache;
547 const void *reg_def_copy; 556 const void *reg_def_copy;
548 const struct snd_soc_cache_ops *cache_ops; 557 const struct snd_soc_cache_ops *cache_ops;
@@ -568,7 +577,9 @@ struct snd_soc_codec_driver {
568 pm_message_t state); 577 pm_message_t state);
569 int (*resume)(struct snd_soc_codec *); 578 int (*resume)(struct snd_soc_codec *);
570 579
571 /* Default DAPM setup, added after probe() is run */ 580 /* Default control and setup, added after probe() is run */
581 const struct snd_kcontrol_new *controls;
582 int num_controls;
572 const struct snd_soc_dapm_widget *dapm_widgets; 583 const struct snd_soc_dapm_widget *dapm_widgets;
573 int num_dapm_widgets; 584 int num_dapm_widgets;
574 const struct snd_soc_dapm_route *dapm_routes; 585 const struct snd_soc_dapm_route *dapm_routes;
@@ -587,6 +598,7 @@ struct snd_soc_codec_driver {
587 size_t, unsigned int); 598 size_t, unsigned int);
588 int (*volatile_register)(struct snd_soc_codec *, unsigned int); 599 int (*volatile_register)(struct snd_soc_codec *, unsigned int);
589 int (*readable_register)(struct snd_soc_codec *, unsigned int); 600 int (*readable_register)(struct snd_soc_codec *, unsigned int);
601 int (*writable_register)(struct snd_soc_codec *, unsigned int);
590 short reg_cache_size; 602 short reg_cache_size;
591 short reg_cache_step; 603 short reg_cache_step;
592 short reg_word_size; 604 short reg_word_size;
@@ -690,6 +702,8 @@ struct snd_soc_aux_dev {
690/* SoC card */ 702/* SoC card */
691struct snd_soc_card { 703struct snd_soc_card {
692 const char *name; 704 const char *name;
705 const char *long_name;
706 const char *driver_name;
693 struct device *dev; 707 struct device *dev;
694 struct snd_card *snd_card; 708 struct snd_card *snd_card;
695 struct module *owner; 709 struct module *owner;
@@ -737,12 +751,15 @@ struct snd_soc_card {
737 struct snd_soc_pcm_runtime *rtd_aux; 751 struct snd_soc_pcm_runtime *rtd_aux;
738 int num_aux_rtd; 752 int num_aux_rtd;
739 753
754 const struct snd_kcontrol_new *controls;
755 int num_controls;
756
740 /* 757 /*
741 * Card-specific routes and widgets. 758 * Card-specific routes and widgets.
742 */ 759 */
743 struct snd_soc_dapm_widget *dapm_widgets; 760 const struct snd_soc_dapm_widget *dapm_widgets;
744 int num_dapm_widgets; 761 int num_dapm_widgets;
745 struct snd_soc_dapm_route *dapm_routes; 762 const struct snd_soc_dapm_route *dapm_routes;
746 int num_dapm_routes; 763 int num_dapm_routes;
747 764
748 struct work_struct deferred_resume_work; 765 struct work_struct deferred_resume_work;
@@ -805,7 +822,7 @@ struct soc_enum {
805 unsigned char shift_r; 822 unsigned char shift_r;
806 unsigned int max; 823 unsigned int max;
807 unsigned int mask; 824 unsigned int mask;
808 const char **texts; 825 const char * const *texts;
809 const unsigned int *values; 826 const unsigned int *values;
810 void *dapm; 827 void *dapm;
811}; 828};
@@ -814,6 +831,8 @@ struct soc_enum {
814unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg); 831unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
815unsigned int snd_soc_write(struct snd_soc_codec *codec, 832unsigned int snd_soc_write(struct snd_soc_codec *codec,
816 unsigned int reg, unsigned int val); 833 unsigned int reg, unsigned int val);
834unsigned int snd_soc_bulk_write_raw(struct snd_soc_codec *codec,
835 unsigned int reg, const void *data, size_t len);
817 836
818/* device driver data */ 837/* device driver data */
819 838
@@ -871,6 +890,9 @@ static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
871 INIT_LIST_HEAD(&card->dapm_list); 890 INIT_LIST_HEAD(&card->dapm_list);
872} 891}
873 892
893int snd_soc_util_init(void);
894void snd_soc_util_exit(void);
895
874#include <sound/soc-dai.h> 896#include <sound/soc-dai.h>
875 897
876#ifdef CONFIG_DEBUG_FS 898#ifdef CONFIG_DEBUG_FS
diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h
index 5718a02d3afb..d2ea112fc20f 100644
--- a/include/sound/tea575x-tuner.h
+++ b/include/sound/tea575x-tuner.h
@@ -26,29 +26,37 @@
26#include <media/v4l2-dev.h> 26#include <media/v4l2-dev.h>
27#include <media/v4l2-ioctl.h> 27#include <media/v4l2-ioctl.h>
28 28
29#define TEA575X_FMIF 10700
30
31#define TEA575X_DATA (1 << 0)
32#define TEA575X_CLK (1 << 1)
33#define TEA575X_WREN (1 << 2)
34#define TEA575X_MOST (1 << 3)
35
29struct snd_tea575x; 36struct snd_tea575x;
30 37
31struct snd_tea575x_ops { 38struct snd_tea575x_ops {
32 void (*write)(struct snd_tea575x *tea, unsigned int val); 39 void (*set_pins)(struct snd_tea575x *tea, u8 pins);
33 unsigned int (*read)(struct snd_tea575x *tea); 40 u8 (*get_pins)(struct snd_tea575x *tea);
34 void (*mute)(struct snd_tea575x *tea, unsigned int mute); 41 void (*set_direction)(struct snd_tea575x *tea, bool output);
35}; 42};
36 43
37struct snd_tea575x { 44struct snd_tea575x {
38 struct snd_card *card;
39 struct video_device *vd; /* video device */ 45 struct video_device *vd; /* video device */
40 int dev_nr; /* requested device number + 1 */ 46 bool tea5759; /* 5759 chip is present */
41 int tea5759; /* 5759 chip is present */ 47 bool mute; /* Device is muted? */
42 int mute; /* Device is muted? */ 48 bool stereo; /* receiving stereo */
43 unsigned int freq_fixup; /* crystal onboard */ 49 bool tuned; /* tuned to a station */
44 unsigned int val; /* hw value */ 50 unsigned int val; /* hw value */
45 unsigned long freq; /* frequency */ 51 unsigned long freq; /* frequency */
46 unsigned long in_use; /* set if the device is in use */ 52 unsigned long in_use; /* set if the device is in use */
47 struct snd_tea575x_ops *ops; 53 struct snd_tea575x_ops *ops;
48 void *private_data; 54 void *private_data;
55 u8 card[32];
56 u8 bus_info[32];
49}; 57};
50 58
51void snd_tea575x_init(struct snd_tea575x *tea); 59int snd_tea575x_init(struct snd_tea575x *tea);
52void snd_tea575x_exit(struct snd_tea575x *tea); 60void snd_tea575x_exit(struct snd_tea575x *tea);
53 61
54#endif /* __SOUND_TEA575X_TUNER_H */ 62#endif /* __SOUND_TEA575X_TUNER_H */
diff --git a/include/sound/tlv320dac33-plat.h b/include/sound/tlv320dac33-plat.h
index 6c6649656798..0b94192a8cdf 100644
--- a/include/sound/tlv320dac33-plat.h
+++ b/include/sound/tlv320dac33-plat.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Platform header for Texas Instruments TLV320DAC33 codec driver 2 * Platform header for Texas Instruments TLV320DAC33 codec driver
3 * 3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> 4 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
5 * 5 *
6 * Copyright: (C) 2009 Nokia Corporation 6 * Copyright: (C) 2009 Nokia Corporation
7 * 7 *
diff --git a/include/sound/tpa6130a2-plat.h b/include/sound/tpa6130a2-plat.h
index e29fde6b5cbe..89beccb57edd 100644
--- a/include/sound/tpa6130a2-plat.h
+++ b/include/sound/tpa6130a2-plat.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) Nokia Corporation 4 * Copyright (C) Nokia Corporation
5 * 5 *
6 * Written by Peter Ujfalusi <peter.ujfalusi@nokia.com> 6 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
diff --git a/include/sound/wm8915.h b/include/sound/wm8915.h
new file mode 100644
index 000000000000..5817d762f6f3
--- /dev/null
+++ b/include/sound/wm8915.h
@@ -0,0 +1,55 @@
1/*
2 * linux/sound/wm8915.h -- Platform data for WM8915
3 *
4 * Copyright 2011 Wolfson Microelectronics. PLC.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __LINUX_SND_WM8903_H
12#define __LINUX_SND_WM8903_H
13
14enum wm8915_inmode {
15 WM8915_DIFFERRENTIAL_1 = 0, /* IN1xP - IN1xN */
16 WM8915_INVERTING = 1, /* IN1xN */
17 WM8915_NON_INVERTING = 2, /* IN1xP */
18 WM8915_DIFFERENTIAL_2 = 3, /* IN2xP - IN2xP */
19};
20
21/**
22 * ReTune Mobile configurations are specified with a label, sample
23 * rate and set of values to write (the enable bits will be ignored).
24 *
25 * Configurations are expected to be generated using the ReTune Mobile
26 * control panel in WISCE - see http://www.wolfsonmicro.com/wisce/
27 */
28struct wm8915_retune_mobile_config {
29 const char *name;
30 int rate;
31 u16 regs[20];
32};
33
34#define WM8915_SET_DEFAULT 0x10000
35
36struct wm8915_pdata {
37 int irq_flags; /** Set IRQ trigger flags; default active low */
38
39 int ldo_ena; /** GPIO for LDO1; -1 for none */
40
41 int micdet_def; /** Default MICDET_SRC/HP1FB_SRC/MICD_BIAS */
42
43 enum wm8915_inmode inl_mode;
44 enum wm8915_inmode inr_mode;
45
46 u32 spkmute_seq; /** Value for register 0x802 */
47
48 int gpio_base;
49 u32 gpio_default[5];
50
51 int num_retune_mobile_cfgs;
52 struct wm8915_retune_mobile_config *retune_mobile_cfgs;
53};
54
55#endif
diff --git a/include/sound/wm8962.h b/include/sound/wm8962.h
index 2b5306c503fb..1750bed7c2f6 100644
--- a/include/sound/wm8962.h
+++ b/include/sound/wm8962.h
@@ -14,6 +14,28 @@
14/* Use to set GPIO default values to zero */ 14/* Use to set GPIO default values to zero */
15#define WM8962_GPIO_SET 0x10000 15#define WM8962_GPIO_SET 0x10000
16 16
17#define WM8962_GPIO_FN_CLKOUT 0
18#define WM8962_GPIO_FN_LOGIC 1
19#define WM8962_GPIO_FN_SDOUT 2
20#define WM8962_GPIO_FN_IRQ 3
21#define WM8962_GPIO_FN_THERMAL 4
22#define WM8962_GPIO_FN_PLL2_LOCK 6
23#define WM8962_GPIO_FN_PLL3_LOCK 7
24#define WM8962_GPIO_FN_FLL_LOCK 9
25#define WM8962_GPIO_FN_DRC_ACT 10
26#define WM8962_GPIO_FN_WSEQ_DONE 11
27#define WM8962_GPIO_FN_ALC_NG_ACT 12
28#define WM8962_GPIO_FN_ALC_PEAK_LIMIT 13
29#define WM8962_GPIO_FN_ALC_SATURATION 14
30#define WM8962_GPIO_FN_ALC_LEVEL_THR 15
31#define WM8962_GPIO_FN_ALC_LEVEL_LOCK 16
32#define WM8962_GPIO_FN_FIFO_ERR 17
33#define WM8962_GPIO_FN_OPCLK 18
34#define WM8962_GPIO_FN_DMICCLK 19
35#define WM8962_GPIO_FN_DMICDAT 20
36#define WM8962_GPIO_FN_MICD 21
37#define WM8962_GPIO_FN_MICSCD 22
38
17struct wm8962_pdata { 39struct wm8962_pdata {
18 int gpio_base; 40 int gpio_base;
19 u32 gpio_init[WM8962_MAX_GPIO]; 41 u32 gpio_init[WM8962_MAX_GPIO];
diff --git a/sound/core/control.c b/sound/core/control.c
index a08ad57c49b6..5d98194bcad5 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -366,6 +366,70 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
366EXPORT_SYMBOL(snd_ctl_add); 366EXPORT_SYMBOL(snd_ctl_add);
367 367
368/** 368/**
369 * snd_ctl_replace - replace the control instance of the card
370 * @card: the card instance
371 * @kcontrol: the control instance to replace
372 * @add_on_replace: add the control if not already added
373 *
374 * Replaces the given control. If the given control does not exist
375 * and the add_on_replace flag is set, the control is added. If the
376 * control exists, it is destroyed first.
377 *
378 * Returns zero if successful, or a negative error code on failure.
379 *
380 * It frees automatically the control which cannot be added or replaced.
381 */
382int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol,
383 bool add_on_replace)
384{
385 struct snd_ctl_elem_id id;
386 unsigned int idx;
387 struct snd_kcontrol *old;
388 int ret;
389
390 if (!kcontrol)
391 return -EINVAL;
392 if (snd_BUG_ON(!card || !kcontrol->info)) {
393 ret = -EINVAL;
394 goto error;
395 }
396 id = kcontrol->id;
397 down_write(&card->controls_rwsem);
398 old = snd_ctl_find_id(card, &id);
399 if (!old) {
400 if (add_on_replace)
401 goto add;
402 up_write(&card->controls_rwsem);
403 ret = -EINVAL;
404 goto error;
405 }
406 ret = snd_ctl_remove(card, old);
407 if (ret < 0) {
408 up_write(&card->controls_rwsem);
409 goto error;
410 }
411add:
412 if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
413 up_write(&card->controls_rwsem);
414 ret = -ENOMEM;
415 goto error;
416 }
417 list_add_tail(&kcontrol->list, &card->controls);
418 card->controls_count += kcontrol->count;
419 kcontrol->id.numid = card->last_numid + 1;
420 card->last_numid += kcontrol->count;
421 up_write(&card->controls_rwsem);
422 for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
423 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
424 return 0;
425
426error:
427 snd_ctl_free_one(kcontrol);
428 return ret;
429}
430EXPORT_SYMBOL(snd_ctl_replace);
431
432/**
369 * snd_ctl_remove - remove the control from the card and release it 433 * snd_ctl_remove - remove the control from the card and release it
370 * @card: the card instance 434 * @card: the card instance
371 * @kcontrol: the control instance to remove 435 * @kcontrol: the control instance to remove
diff --git a/sound/core/init.c b/sound/core/init.c
index a0080aa45ae9..30ecad41403c 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -514,7 +514,7 @@ static void snd_card_set_id_no_lock(struct snd_card *card, const char *nid)
514 id = card->id; 514 id = card->id;
515 515
516 if (*id == '\0') 516 if (*id == '\0')
517 strcpy(id, "default"); 517 strcpy(id, "Default");
518 518
519 while (1) { 519 while (1) {
520 if (loops-- == 0) { 520 if (loops-- == 0) {
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 64449cb8f873..abfeff1611ce 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -189,6 +189,7 @@ static void xrun(struct snd_pcm_substream *substream)
189#define XRUN_LOG_CNT 10 189#define XRUN_LOG_CNT 10
190 190
191struct hwptr_log_entry { 191struct hwptr_log_entry {
192 unsigned int in_interrupt;
192 unsigned long jiffies; 193 unsigned long jiffies;
193 snd_pcm_uframes_t pos; 194 snd_pcm_uframes_t pos;
194 snd_pcm_uframes_t period_size; 195 snd_pcm_uframes_t period_size;
@@ -204,7 +205,7 @@ struct snd_pcm_hwptr_log {
204}; 205};
205 206
206static void xrun_log(struct snd_pcm_substream *substream, 207static void xrun_log(struct snd_pcm_substream *substream,
207 snd_pcm_uframes_t pos) 208 snd_pcm_uframes_t pos, int in_interrupt)
208{ 209{
209 struct snd_pcm_runtime *runtime = substream->runtime; 210 struct snd_pcm_runtime *runtime = substream->runtime;
210 struct snd_pcm_hwptr_log *log = runtime->hwptr_log; 211 struct snd_pcm_hwptr_log *log = runtime->hwptr_log;
@@ -220,6 +221,7 @@ static void xrun_log(struct snd_pcm_substream *substream,
220 return; 221 return;
221 } 222 }
222 entry = &log->entries[log->idx]; 223 entry = &log->entries[log->idx];
224 entry->in_interrupt = in_interrupt;
223 entry->jiffies = jiffies; 225 entry->jiffies = jiffies;
224 entry->pos = pos; 226 entry->pos = pos;
225 entry->period_size = runtime->period_size; 227 entry->period_size = runtime->period_size;
@@ -246,9 +248,11 @@ static void xrun_log_show(struct snd_pcm_substream *substream)
246 entry = &log->entries[idx]; 248 entry = &log->entries[idx];
247 if (entry->period_size == 0) 249 if (entry->period_size == 0)
248 break; 250 break;
249 snd_printd("hwptr log: %s: j=%lu, pos=%ld/%ld/%ld, " 251 snd_printd("hwptr log: %s: %sj=%lu, pos=%ld/%ld/%ld, "
250 "hwptr=%ld/%ld\n", 252 "hwptr=%ld/%ld\n",
251 name, entry->jiffies, (unsigned long)entry->pos, 253 name, entry->in_interrupt ? "[Q] " : "",
254 entry->jiffies,
255 (unsigned long)entry->pos,
252 (unsigned long)entry->period_size, 256 (unsigned long)entry->period_size,
253 (unsigned long)entry->buffer_size, 257 (unsigned long)entry->buffer_size,
254 (unsigned long)entry->old_hw_ptr, 258 (unsigned long)entry->old_hw_ptr,
@@ -262,7 +266,7 @@ static void xrun_log_show(struct snd_pcm_substream *substream)
262#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */ 266#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */
263 267
264#define hw_ptr_error(substream, fmt, args...) do { } while (0) 268#define hw_ptr_error(substream, fmt, args...) do { } while (0)
265#define xrun_log(substream, pos) do { } while (0) 269#define xrun_log(substream, pos, in_interrupt) do { } while (0)
266#define xrun_log_show(substream) do { } while (0) 270#define xrun_log_show(substream) do { } while (0)
267 271
268#endif 272#endif
@@ -326,7 +330,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
326 } 330 }
327 pos -= pos % runtime->min_align; 331 pos -= pos % runtime->min_align;
328 if (xrun_debug(substream, XRUN_DEBUG_LOG)) 332 if (xrun_debug(substream, XRUN_DEBUG_LOG))
329 xrun_log(substream, pos); 333 xrun_log(substream, pos, in_interrupt);
330 hw_base = runtime->hw_ptr_base; 334 hw_base = runtime->hw_ptr_base;
331 new_hw_ptr = hw_base + pos; 335 new_hw_ptr = hw_base + pos;
332 if (in_interrupt) { 336 if (in_interrupt) {
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig
index e486f48660fb..26071489970b 100644
--- a/sound/firewire/Kconfig
+++ b/sound/firewire/Kconfig
@@ -22,4 +22,15 @@ config SND_FIREWIRE_SPEAKERS
22 To compile this driver as a module, choose M here: the module 22 To compile this driver as a module, choose M here: the module
23 will be called snd-firewire-speakers. 23 will be called snd-firewire-speakers.
24 24
25config SND_ISIGHT
26 tristate "Apple iSight microphone"
27 select SND_PCM
28 select SND_FIREWIRE_LIB
29 help
30 Say Y here to include support for the front and rear microphones
31 of the Apple iSight web camera.
32
33 To compile this driver as a module, choose M here: the module
34 will be called snd-isight.
35
25endif # SND_FIREWIRE 36endif # SND_FIREWIRE
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile
index e5b1634d9ad4..d71ed8935f76 100644
--- a/sound/firewire/Makefile
+++ b/sound/firewire/Makefile
@@ -1,6 +1,8 @@
1snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \ 1snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \
2 fcp.o cmp.o amdtp.o 2 fcp.o cmp.o amdtp.o
3snd-firewire-speakers-objs := speakers.o 3snd-firewire-speakers-objs := speakers.o
4snd-isight-objs := isight.o
4 5
5obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o 6obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o
6obj-$(CONFIG_SND_FIREWIRE_SPEAKERS) += snd-firewire-speakers.o 7obj-$(CONFIG_SND_FIREWIRE_SPEAKERS) += snd-firewire-speakers.o
8obj-$(CONFIG_SND_ISIGHT) += snd-isight.o
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c
new file mode 100644
index 000000000000..86ee16ca365e
--- /dev/null
+++ b/sound/firewire/isight.c
@@ -0,0 +1,755 @@
1/*
2 * Apple iSight audio driver
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
6 */
7
8#include <asm/byteorder.h>
9#include <linux/delay.h>
10#include <linux/device.h>
11#include <linux/firewire.h>
12#include <linux/firewire-constants.h>
13#include <linux/module.h>
14#include <linux/mod_devicetable.h>
15#include <linux/mutex.h>
16#include <linux/string.h>
17#include <sound/control.h>
18#include <sound/core.h>
19#include <sound/initval.h>
20#include <sound/pcm.h>
21#include <sound/tlv.h>
22#include "lib.h"
23#include "iso-resources.h"
24#include "packets-buffer.h"
25
26#define OUI_APPLE 0x000a27
27#define MODEL_APPLE_ISIGHT 0x000008
28#define SW_ISIGHT_AUDIO 0x000010
29
30#define REG_AUDIO_ENABLE 0x000
31#define AUDIO_ENABLE 0x80000000
32#define REG_DEF_AUDIO_GAIN 0x204
33#define REG_GAIN_RAW_START 0x210
34#define REG_GAIN_RAW_END 0x214
35#define REG_GAIN_DB_START 0x218
36#define REG_GAIN_DB_END 0x21c
37#define REG_SAMPLE_RATE_INQUIRY 0x280
38#define REG_ISO_TX_CONFIG 0x300
39#define SPEED_SHIFT 16
40#define REG_SAMPLE_RATE 0x400
41#define RATE_48000 0x80000000
42#define REG_GAIN 0x500
43#define REG_MUTE 0x504
44
45#define MAX_FRAMES_PER_PACKET 475
46
47#define QUEUE_LENGTH 20
48
49struct isight {
50 struct snd_card *card;
51 struct fw_unit *unit;
52 struct fw_device *device;
53 u64 audio_base;
54 struct fw_address_handler iris_handler;
55 struct snd_pcm_substream *pcm;
56 struct mutex mutex;
57 struct iso_packets_buffer buffer;
58 struct fw_iso_resources resources;
59 struct fw_iso_context *context;
60 bool pcm_active;
61 bool pcm_running;
62 bool first_packet;
63 int packet_index;
64 u32 total_samples;
65 unsigned int buffer_pointer;
66 unsigned int period_counter;
67 s32 gain_min, gain_max;
68 unsigned int gain_tlv[4];
69};
70
71struct audio_payload {
72 __be32 sample_count;
73 __be32 signature;
74 __be32 sample_total;
75 __be32 reserved;
76 __be16 samples[2 * MAX_FRAMES_PER_PACKET];
77};
78
79MODULE_DESCRIPTION("iSight audio driver");
80MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
81MODULE_LICENSE("GPL v2");
82
83static struct fw_iso_packet audio_packet = {
84 .payload_length = sizeof(struct audio_payload),
85 .interrupt = 1,
86 .header_length = 4,
87};
88
89static void isight_update_pointers(struct isight *isight, unsigned int count)
90{
91 struct snd_pcm_runtime *runtime = isight->pcm->runtime;
92 unsigned int ptr;
93
94 smp_wmb(); /* update buffer data before buffer pointer */
95
96 ptr = isight->buffer_pointer;
97 ptr += count;
98 if (ptr >= runtime->buffer_size)
99 ptr -= runtime->buffer_size;
100 ACCESS_ONCE(isight->buffer_pointer) = ptr;
101
102 isight->period_counter += count;
103 if (isight->period_counter >= runtime->period_size) {
104 isight->period_counter -= runtime->period_size;
105 snd_pcm_period_elapsed(isight->pcm);
106 }
107}
108
109static void isight_samples(struct isight *isight,
110 const __be16 *samples, unsigned int count)
111{
112 struct snd_pcm_runtime *runtime;
113 unsigned int count1;
114
115 if (!ACCESS_ONCE(isight->pcm_running))
116 return;
117
118 runtime = isight->pcm->runtime;
119 if (isight->buffer_pointer + count <= runtime->buffer_size) {
120 memcpy(runtime->dma_area + isight->buffer_pointer * 4,
121 samples, count * 4);
122 } else {
123 count1 = runtime->buffer_size - isight->buffer_pointer;
124 memcpy(runtime->dma_area + isight->buffer_pointer * 4,
125 samples, count1 * 4);
126 samples += count1 * 2;
127 memcpy(runtime->dma_area, samples, (count - count1) * 4);
128 }
129
130 isight_update_pointers(isight, count);
131}
132
133static void isight_pcm_abort(struct isight *isight)
134{
135 unsigned long flags;
136
137 if (ACCESS_ONCE(isight->pcm_active)) {
138 snd_pcm_stream_lock_irqsave(isight->pcm, flags);
139 if (snd_pcm_running(isight->pcm))
140 snd_pcm_stop(isight->pcm, SNDRV_PCM_STATE_XRUN);
141 snd_pcm_stream_unlock_irqrestore(isight->pcm, flags);
142 }
143}
144
145static void isight_dropped_samples(struct isight *isight, unsigned int total)
146{
147 struct snd_pcm_runtime *runtime;
148 u32 dropped;
149 unsigned int count1;
150
151 if (!ACCESS_ONCE(isight->pcm_running))
152 return;
153
154 runtime = isight->pcm->runtime;
155 dropped = total - isight->total_samples;
156 if (dropped < runtime->buffer_size) {
157 if (isight->buffer_pointer + dropped <= runtime->buffer_size) {
158 memset(runtime->dma_area + isight->buffer_pointer * 4,
159 0, dropped * 4);
160 } else {
161 count1 = runtime->buffer_size - isight->buffer_pointer;
162 memset(runtime->dma_area + isight->buffer_pointer * 4,
163 0, count1 * 4);
164 memset(runtime->dma_area, 0, (dropped - count1) * 4);
165 }
166 isight_update_pointers(isight, dropped);
167 } else {
168 isight_pcm_abort(isight);
169 }
170}
171
172static void isight_packet(struct fw_iso_context *context, u32 cycle,
173 size_t header_length, void *header, void *data)
174{
175 struct isight *isight = data;
176 const struct audio_payload *payload;
177 unsigned int index, length, count, total;
178 int err;
179
180 if (isight->packet_index < 0)
181 return;
182 index = isight->packet_index;
183 payload = isight->buffer.packets[index].buffer;
184 length = be32_to_cpup(header) >> 16;
185
186 if (likely(length >= 16 &&
187 payload->signature == cpu_to_be32(0x73676874/*"sght"*/))) {
188 count = be32_to_cpu(payload->sample_count);
189 if (likely(count <= (length - 16) / 4)) {
190 total = be32_to_cpu(payload->sample_total);
191 if (unlikely(total != isight->total_samples)) {
192 if (!isight->first_packet)
193 isight_dropped_samples(isight, total);
194 isight->first_packet = false;
195 isight->total_samples = total;
196 }
197
198 isight_samples(isight, payload->samples, count);
199 isight->total_samples += count;
200 }
201 }
202
203 err = fw_iso_context_queue(isight->context, &audio_packet,
204 &isight->buffer.iso_buffer,
205 isight->buffer.packets[index].offset);
206 if (err < 0) {
207 dev_err(&isight->unit->device, "queueing error: %d\n", err);
208 isight_pcm_abort(isight);
209 isight->packet_index = -1;
210 return;
211 }
212
213 if (++index >= QUEUE_LENGTH)
214 index = 0;
215 isight->packet_index = index;
216}
217
218static int isight_connect(struct isight *isight)
219{
220 int ch, err, rcode, errors = 0;
221 __be32 value;
222
223retry_after_bus_reset:
224 ch = fw_iso_resources_allocate(&isight->resources,
225 sizeof(struct audio_payload),
226 isight->device->max_speed);
227 if (ch < 0) {
228 err = ch;
229 goto error;
230 }
231
232 value = cpu_to_be32(ch | (isight->device->max_speed << SPEED_SHIFT));
233 for (;;) {
234 rcode = fw_run_transaction(
235 isight->device->card,
236 TCODE_WRITE_QUADLET_REQUEST,
237 isight->device->node_id,
238 isight->resources.generation,
239 isight->device->max_speed,
240 isight->audio_base + REG_ISO_TX_CONFIG,
241 &value, 4);
242 if (rcode == RCODE_COMPLETE) {
243 return 0;
244 } else if (rcode == RCODE_GENERATION) {
245 fw_iso_resources_free(&isight->resources);
246 goto retry_after_bus_reset;
247 } else if (rcode_is_permanent_error(rcode) || ++errors >= 3) {
248 err = -EIO;
249 goto err_resources;
250 }
251 msleep(5);
252 }
253
254err_resources:
255 fw_iso_resources_free(&isight->resources);
256error:
257 return err;
258}
259
260static int isight_open(struct snd_pcm_substream *substream)
261{
262 static const struct snd_pcm_hardware hardware = {
263 .info = SNDRV_PCM_INFO_MMAP |
264 SNDRV_PCM_INFO_MMAP_VALID |
265 SNDRV_PCM_INFO_BATCH |
266 SNDRV_PCM_INFO_INTERLEAVED |
267 SNDRV_PCM_INFO_BLOCK_TRANSFER,
268 .formats = SNDRV_PCM_FMTBIT_S16_BE,
269 .rates = SNDRV_PCM_RATE_48000,
270 .rate_min = 48000,
271 .rate_max = 48000,
272 .channels_min = 2,
273 .channels_max = 2,
274 .buffer_bytes_max = 4 * 1024 * 1024,
275 .period_bytes_min = MAX_FRAMES_PER_PACKET * 4,
276 .period_bytes_max = 1024 * 1024,
277 .periods_min = 2,
278 .periods_max = UINT_MAX,
279 };
280 struct isight *isight = substream->private_data;
281
282 substream->runtime->hw = hardware;
283
284 return iso_packets_buffer_init(&isight->buffer, isight->unit,
285 QUEUE_LENGTH,
286 sizeof(struct audio_payload),
287 DMA_FROM_DEVICE);
288}
289
290static int isight_close(struct snd_pcm_substream *substream)
291{
292 struct isight *isight = substream->private_data;
293
294 iso_packets_buffer_destroy(&isight->buffer, isight->unit);
295
296 return 0;
297}
298
299static int isight_hw_params(struct snd_pcm_substream *substream,
300 struct snd_pcm_hw_params *hw_params)
301{
302 struct isight *isight = substream->private_data;
303 int err;
304
305 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
306 params_buffer_bytes(hw_params));
307 if (err < 0)
308 return err;
309
310 ACCESS_ONCE(isight->pcm_active) = true;
311
312 return 0;
313}
314
315static int reg_read(struct isight *isight, int offset, __be32 *value)
316{
317 return snd_fw_transaction(isight->unit, TCODE_READ_QUADLET_REQUEST,
318 isight->audio_base + offset, value, 4);
319}
320
321static int reg_write(struct isight *isight, int offset, __be32 value)
322{
323 return snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST,
324 isight->audio_base + offset, &value, 4);
325}
326
327static void isight_stop_streaming(struct isight *isight)
328{
329 if (!isight->context)
330 return;
331
332 fw_iso_context_stop(isight->context);
333 fw_iso_context_destroy(isight->context);
334 isight->context = NULL;
335 fw_iso_resources_free(&isight->resources);
336 reg_write(isight, REG_AUDIO_ENABLE, 0);
337}
338
339static int isight_hw_free(struct snd_pcm_substream *substream)
340{
341 struct isight *isight = substream->private_data;
342
343 ACCESS_ONCE(isight->pcm_active) = false;
344
345 mutex_lock(&isight->mutex);
346 isight_stop_streaming(isight);
347 mutex_unlock(&isight->mutex);
348
349 return snd_pcm_lib_free_vmalloc_buffer(substream);
350}
351
352static int isight_start_streaming(struct isight *isight)
353{
354 unsigned int i;
355 int err;
356
357 if (isight->context) {
358 if (isight->packet_index < 0)
359 isight_stop_streaming(isight);
360 else
361 return 0;
362 }
363
364 err = reg_write(isight, REG_SAMPLE_RATE, cpu_to_be32(RATE_48000));
365 if (err < 0)
366 goto error;
367
368 err = isight_connect(isight);
369 if (err < 0)
370 goto error;
371
372 err = reg_write(isight, REG_AUDIO_ENABLE, cpu_to_be32(AUDIO_ENABLE));
373 if (err < 0)
374 goto err_resources;
375
376 isight->context = fw_iso_context_create(isight->device->card,
377 FW_ISO_CONTEXT_RECEIVE,
378 isight->resources.channel,
379 isight->device->max_speed,
380 4, isight_packet, isight);
381 if (IS_ERR(isight->context)) {
382 err = PTR_ERR(isight->context);
383 isight->context = NULL;
384 goto err_resources;
385 }
386
387 for (i = 0; i < QUEUE_LENGTH; ++i) {
388 err = fw_iso_context_queue(isight->context, &audio_packet,
389 &isight->buffer.iso_buffer,
390 isight->buffer.packets[i].offset);
391 if (err < 0)
392 goto err_context;
393 }
394
395 isight->first_packet = true;
396 isight->packet_index = 0;
397
398 err = fw_iso_context_start(isight->context, -1, 0,
399 FW_ISO_CONTEXT_MATCH_ALL_TAGS/*?*/);
400 if (err < 0)
401 goto err_context;
402
403 return 0;
404
405err_context:
406 fw_iso_context_destroy(isight->context);
407 isight->context = NULL;
408err_resources:
409 fw_iso_resources_free(&isight->resources);
410 reg_write(isight, REG_AUDIO_ENABLE, 0);
411error:
412 return err;
413}
414
415static int isight_prepare(struct snd_pcm_substream *substream)
416{
417 struct isight *isight = substream->private_data;
418 int err;
419
420 isight->buffer_pointer = 0;
421 isight->period_counter = 0;
422
423 mutex_lock(&isight->mutex);
424 err = isight_start_streaming(isight);
425 mutex_unlock(&isight->mutex);
426
427 return err;
428}
429
430static int isight_trigger(struct snd_pcm_substream *substream, int cmd)
431{
432 struct isight *isight = substream->private_data;
433
434 switch (cmd) {
435 case SNDRV_PCM_TRIGGER_START:
436 ACCESS_ONCE(isight->pcm_running) = true;
437 break;
438 case SNDRV_PCM_TRIGGER_STOP:
439 ACCESS_ONCE(isight->pcm_running) = false;
440 break;
441 default:
442 return -EINVAL;
443 }
444 return 0;
445}
446
447static snd_pcm_uframes_t isight_pointer(struct snd_pcm_substream *substream)
448{
449 struct isight *isight = substream->private_data;
450
451 return ACCESS_ONCE(isight->buffer_pointer);
452}
453
454static int isight_create_pcm(struct isight *isight)
455{
456 static struct snd_pcm_ops ops = {
457 .open = isight_open,
458 .close = isight_close,
459 .ioctl = snd_pcm_lib_ioctl,
460 .hw_params = isight_hw_params,
461 .hw_free = isight_hw_free,
462 .prepare = isight_prepare,
463 .trigger = isight_trigger,
464 .pointer = isight_pointer,
465 .page = snd_pcm_lib_get_vmalloc_page,
466 .mmap = snd_pcm_lib_mmap_vmalloc,
467 };
468 struct snd_pcm *pcm;
469 int err;
470
471 err = snd_pcm_new(isight->card, "iSight", 0, 0, 1, &pcm);
472 if (err < 0)
473 return err;
474 pcm->private_data = isight;
475 strcpy(pcm->name, "iSight");
476 isight->pcm = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
477 isight->pcm->ops = &ops;
478
479 return 0;
480}
481
482static int isight_gain_info(struct snd_kcontrol *ctl,
483 struct snd_ctl_elem_info *info)
484{
485 struct isight *isight = ctl->private_data;
486
487 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
488 info->count = 1;
489 info->value.integer.min = isight->gain_min;
490 info->value.integer.max = isight->gain_max;
491
492 return 0;
493}
494
495static int isight_gain_get(struct snd_kcontrol *ctl,
496 struct snd_ctl_elem_value *value)
497{
498 struct isight *isight = ctl->private_data;
499 __be32 gain;
500 int err;
501
502 err = reg_read(isight, REG_GAIN, &gain);
503 if (err < 0)
504 return err;
505
506 value->value.integer.value[0] = (s32)be32_to_cpu(gain);
507
508 return 0;
509}
510
511static int isight_gain_put(struct snd_kcontrol *ctl,
512 struct snd_ctl_elem_value *value)
513{
514 struct isight *isight = ctl->private_data;
515
516 if (value->value.integer.value[0] < isight->gain_min ||
517 value->value.integer.value[0] > isight->gain_max)
518 return -EINVAL;
519
520 return reg_write(isight, REG_GAIN,
521 cpu_to_be32(value->value.integer.value[0]));
522}
523
524static int isight_mute_get(struct snd_kcontrol *ctl,
525 struct snd_ctl_elem_value *value)
526{
527 struct isight *isight = ctl->private_data;
528 __be32 mute;
529 int err;
530
531 err = reg_read(isight, REG_MUTE, &mute);
532 if (err < 0)
533 return err;
534
535 value->value.integer.value[0] = !mute;
536
537 return 0;
538}
539
540static int isight_mute_put(struct snd_kcontrol *ctl,
541 struct snd_ctl_elem_value *value)
542{
543 struct isight *isight = ctl->private_data;
544
545 return reg_write(isight, REG_MUTE,
546 (__force __be32)!value->value.integer.value[0]);
547}
548
549static int isight_create_mixer(struct isight *isight)
550{
551 static const struct snd_kcontrol_new gain_control = {
552 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
553 .name = "Mic Capture Volume",
554 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
555 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
556 .info = isight_gain_info,
557 .get = isight_gain_get,
558 .put = isight_gain_put,
559 };
560 static const struct snd_kcontrol_new mute_control = {
561 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
562 .name = "Mic Capture Switch",
563 .info = snd_ctl_boolean_mono_info,
564 .get = isight_mute_get,
565 .put = isight_mute_put,
566 };
567 __be32 value;
568 struct snd_kcontrol *ctl;
569 int err;
570
571 err = reg_read(isight, REG_GAIN_RAW_START, &value);
572 if (err < 0)
573 return err;
574 isight->gain_min = be32_to_cpu(value);
575
576 err = reg_read(isight, REG_GAIN_RAW_END, &value);
577 if (err < 0)
578 return err;
579 isight->gain_max = be32_to_cpu(value);
580
581 isight->gain_tlv[0] = SNDRV_CTL_TLVT_DB_MINMAX;
582 isight->gain_tlv[1] = 2 * sizeof(unsigned int);
583
584 err = reg_read(isight, REG_GAIN_DB_START, &value);
585 if (err < 0)
586 return err;
587 isight->gain_tlv[2] = (s32)be32_to_cpu(value) * 100;
588
589 err = reg_read(isight, REG_GAIN_DB_END, &value);
590 if (err < 0)
591 return err;
592 isight->gain_tlv[3] = (s32)be32_to_cpu(value) * 100;
593
594 ctl = snd_ctl_new1(&gain_control, isight);
595 if (ctl)
596 ctl->tlv.p = isight->gain_tlv;
597 err = snd_ctl_add(isight->card, ctl);
598 if (err < 0)
599 return err;
600
601 err = snd_ctl_add(isight->card, snd_ctl_new1(&mute_control, isight));
602 if (err < 0)
603 return err;
604
605 return 0;
606}
607
608static void isight_card_free(struct snd_card *card)
609{
610 struct isight *isight = card->private_data;
611
612 fw_iso_resources_destroy(&isight->resources);
613 fw_unit_put(isight->unit);
614 fw_device_put(isight->device);
615 mutex_destroy(&isight->mutex);
616}
617
618static u64 get_unit_base(struct fw_unit *unit)
619{
620 struct fw_csr_iterator i;
621 int key, value;
622
623 fw_csr_iterator_init(&i, unit->directory);
624 while (fw_csr_iterator_next(&i, &key, &value))
625 if (key == CSR_OFFSET)
626 return CSR_REGISTER_BASE + value * 4;
627 return 0;
628}
629
630static int isight_probe(struct device *unit_dev)
631{
632 struct fw_unit *unit = fw_unit(unit_dev);
633 struct fw_device *fw_dev = fw_parent_device(unit);
634 struct snd_card *card;
635 struct isight *isight;
636 int err;
637
638 err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*isight), &card);
639 if (err < 0)
640 return err;
641 snd_card_set_dev(card, unit_dev);
642
643 isight = card->private_data;
644 isight->card = card;
645 mutex_init(&isight->mutex);
646 isight->unit = fw_unit_get(unit);
647 isight->device = fw_device_get(fw_dev);
648 isight->audio_base = get_unit_base(unit);
649 if (!isight->audio_base) {
650 dev_err(&unit->device, "audio unit base not found\n");
651 err = -ENXIO;
652 goto err_unit;
653 }
654 fw_iso_resources_init(&isight->resources, unit);
655
656 card->private_free = isight_card_free;
657
658 strcpy(card->driver, "iSight");
659 strcpy(card->shortname, "Apple iSight");
660 snprintf(card->longname, sizeof(card->longname),
661 "Apple iSight (GUID %08x%08x) at %s, S%d",
662 fw_dev->config_rom[3], fw_dev->config_rom[4],
663 dev_name(&unit->device), 100 << fw_dev->max_speed);
664 strcpy(card->mixername, "iSight");
665
666 err = isight_create_pcm(isight);
667 if (err < 0)
668 goto error;
669
670 err = isight_create_mixer(isight);
671 if (err < 0)
672 goto error;
673
674 err = snd_card_register(card);
675 if (err < 0)
676 goto error;
677
678 dev_set_drvdata(unit_dev, isight);
679
680 return 0;
681
682err_unit:
683 fw_unit_put(isight->unit);
684 fw_device_put(isight->device);
685 mutex_destroy(&isight->mutex);
686error:
687 snd_card_free(card);
688 return err;
689}
690
691static int isight_remove(struct device *dev)
692{
693 struct isight *isight = dev_get_drvdata(dev);
694
695 isight_pcm_abort(isight);
696
697 snd_card_disconnect(isight->card);
698
699 mutex_lock(&isight->mutex);
700 isight_stop_streaming(isight);
701 mutex_unlock(&isight->mutex);
702
703 snd_card_free_when_closed(isight->card);
704
705 return 0;
706}
707
708static void isight_bus_reset(struct fw_unit *unit)
709{
710 struct isight *isight = dev_get_drvdata(&unit->device);
711
712 if (fw_iso_resources_update(&isight->resources) < 0) {
713 isight_pcm_abort(isight);
714
715 mutex_lock(&isight->mutex);
716 isight_stop_streaming(isight);
717 mutex_unlock(&isight->mutex);
718 }
719}
720
721static const struct ieee1394_device_id isight_id_table[] = {
722 {
723 .match_flags = IEEE1394_MATCH_SPECIFIER_ID |
724 IEEE1394_MATCH_VERSION,
725 .specifier_id = OUI_APPLE,
726 .version = SW_ISIGHT_AUDIO,
727 },
728 { }
729};
730MODULE_DEVICE_TABLE(ieee1394, isight_id_table);
731
732static struct fw_driver isight_driver = {
733 .driver = {
734 .owner = THIS_MODULE,
735 .name = KBUILD_MODNAME,
736 .bus = &fw_bus_type,
737 .probe = isight_probe,
738 .remove = isight_remove,
739 },
740 .update = isight_bus_reset,
741 .id_table = isight_id_table,
742};
743
744static int __init alsa_isight_init(void)
745{
746 return driver_register(&isight_driver.driver);
747}
748
749static void __exit alsa_isight_exit(void)
750{
751 driver_unregister(&isight_driver.driver);
752}
753
754module_init(alsa_isight_init);
755module_exit(alsa_isight_exit);
diff --git a/sound/firewire/iso-resources.c b/sound/firewire/iso-resources.c
index bb9c0c1fb529..ffe20b877e9f 100644
--- a/sound/firewire/iso-resources.c
+++ b/sound/firewire/iso-resources.c
@@ -31,6 +31,7 @@ int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit)
31 31
32 return 0; 32 return 0;
33} 33}
34EXPORT_SYMBOL(fw_iso_resources_init);
34 35
35/** 36/**
36 * fw_iso_resources_destroy - destroy a resource manager 37 * fw_iso_resources_destroy - destroy a resource manager
@@ -42,6 +43,7 @@ void fw_iso_resources_destroy(struct fw_iso_resources *r)
42 mutex_destroy(&r->mutex); 43 mutex_destroy(&r->mutex);
43 fw_unit_put(r->unit); 44 fw_unit_put(r->unit);
44} 45}
46EXPORT_SYMBOL(fw_iso_resources_destroy);
45 47
46static unsigned int packet_bandwidth(unsigned int max_payload_bytes, int speed) 48static unsigned int packet_bandwidth(unsigned int max_payload_bytes, int speed)
47{ 49{
@@ -146,6 +148,7 @@ retry_after_bus_reset:
146 148
147 return channel; 149 return channel;
148} 150}
151EXPORT_SYMBOL(fw_iso_resources_allocate);
149 152
150/** 153/**
151 * fw_iso_resources_update - update resource allocations after a bus reset 154 * fw_iso_resources_update - update resource allocations after a bus reset
@@ -197,6 +200,7 @@ int fw_iso_resources_update(struct fw_iso_resources *r)
197 200
198 return channel; 201 return channel;
199} 202}
203EXPORT_SYMBOL(fw_iso_resources_update);
200 204
201/** 205/**
202 * fw_iso_resources_free - frees allocated resources 206 * fw_iso_resources_free - frees allocated resources
@@ -224,3 +228,4 @@ void fw_iso_resources_free(struct fw_iso_resources *r)
224 228
225 mutex_unlock(&r->mutex); 229 mutex_unlock(&r->mutex);
226} 230}
231EXPORT_SYMBOL(fw_iso_resources_free);
diff --git a/sound/firewire/packets-buffer.c b/sound/firewire/packets-buffer.c
index 1e20e60ba6a6..3c61ca2e6152 100644
--- a/sound/firewire/packets-buffer.c
+++ b/sound/firewire/packets-buffer.c
@@ -60,6 +60,7 @@ err_packets:
60error: 60error:
61 return err; 61 return err;
62} 62}
63EXPORT_SYMBOL(iso_packets_buffer_init);
63 64
64/** 65/**
65 * iso_packets_buffer_destroy - frees packet buffer resources 66 * iso_packets_buffer_destroy - frees packet buffer resources
@@ -72,3 +73,4 @@ void iso_packets_buffer_destroy(struct iso_packets_buffer *b,
72 fw_iso_buffer_destroy(&b->iso_buffer, fw_parent_device(unit)->card); 73 fw_iso_buffer_destroy(&b->iso_buffer, fw_parent_device(unit)->card);
73 kfree(b->packets); 74 kfree(b->packets);
74} 75}
76EXPORT_SYMBOL(iso_packets_buffer_destroy);
diff --git a/sound/i2c/other/Makefile b/sound/i2c/other/Makefile
index 2dad40f3f622..c95d8f1aae87 100644
--- a/sound/i2c/other/Makefile
+++ b/sound/i2c/other/Makefile
@@ -14,4 +14,4 @@ snd-tea575x-tuner-objs := tea575x-tuner.o
14obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o 14obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o
15obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o 15obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o
16obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o 16obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o
17obj-$(CONFIG_SND_FM801_TEA575X) += snd-tea575x-tuner.o 17obj-$(CONFIG_SND_TEA575X) += snd-tea575x-tuner.o
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index ee538f1ae846..4831800239d3 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -37,8 +37,8 @@ static int radio_nr = -1;
37module_param(radio_nr, int, 0); 37module_param(radio_nr, int, 0);
38 38
39#define RADIO_VERSION KERNEL_VERSION(0, 0, 2) 39#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
40#define FREQ_LO (87 * 16000) 40#define FREQ_LO (50UL * 16000)
41#define FREQ_HI (108 * 16000) 41#define FREQ_HI (150UL * 16000)
42 42
43/* 43/*
44 * definitions 44 * definitions
@@ -77,27 +77,95 @@ static struct v4l2_queryctrl radio_qctrl[] = {
77 * lowlevel part 77 * lowlevel part
78 */ 78 */
79 79
80static void snd_tea575x_write(struct snd_tea575x *tea, unsigned int val)
81{
82 u16 l;
83 u8 data;
84
85 tea->ops->set_direction(tea, 1);
86 udelay(16);
87
88 for (l = 25; l > 0; l--) {
89 data = (val >> 24) & TEA575X_DATA;
90 val <<= 1; /* shift data */
91 tea->ops->set_pins(tea, data | TEA575X_WREN);
92 udelay(2);
93 tea->ops->set_pins(tea, data | TEA575X_WREN | TEA575X_CLK);
94 udelay(2);
95 tea->ops->set_pins(tea, data | TEA575X_WREN);
96 udelay(2);
97 }
98
99 if (!tea->mute)
100 tea->ops->set_pins(tea, 0);
101}
102
103static unsigned int snd_tea575x_read(struct snd_tea575x *tea)
104{
105 u16 l, rdata;
106 u32 data = 0;
107
108 tea->ops->set_direction(tea, 0);
109 tea->ops->set_pins(tea, 0);
110 udelay(16);
111
112 for (l = 24; l--;) {
113 tea->ops->set_pins(tea, TEA575X_CLK);
114 udelay(2);
115 if (!l)
116 tea->tuned = tea->ops->get_pins(tea) & TEA575X_MOST ? 0 : 1;
117 tea->ops->set_pins(tea, 0);
118 udelay(2);
119 data <<= 1; /* shift data */
120 rdata = tea->ops->get_pins(tea);
121 if (!l)
122 tea->stereo = (rdata & TEA575X_MOST) ? 0 : 1;
123 if (rdata & TEA575X_DATA)
124 data++;
125 udelay(2);
126 }
127
128 if (tea->mute)
129 tea->ops->set_pins(tea, TEA575X_WREN);
130
131 return data;
132}
133
134static void snd_tea575x_get_freq(struct snd_tea575x *tea)
135{
136 unsigned long freq;
137
138 freq = snd_tea575x_read(tea) & TEA575X_BIT_FREQ_MASK;
139 /* freq *= 12.5 */
140 freq *= 125;
141 freq /= 10;
142 /* crystal fixup */
143 if (tea->tea5759)
144 freq += TEA575X_FMIF;
145 else
146 freq -= TEA575X_FMIF;
147
148 tea->freq = freq * 16; /* from kHz */
149}
150
80static void snd_tea575x_set_freq(struct snd_tea575x *tea) 151static void snd_tea575x_set_freq(struct snd_tea575x *tea)
81{ 152{
82 unsigned long freq; 153 unsigned long freq;
83 154
84 freq = tea->freq / 16; /* to kHz */ 155 freq = clamp(tea->freq, FREQ_LO, FREQ_HI);
85 if (freq > 108000) 156 freq /= 16; /* to kHz */
86 freq = 108000;
87 if (freq < 87000)
88 freq = 87000;
89 /* crystal fixup */ 157 /* crystal fixup */
90 if (tea->tea5759) 158 if (tea->tea5759)
91 freq -= tea->freq_fixup; 159 freq -= TEA575X_FMIF;
92 else 160 else
93 freq += tea->freq_fixup; 161 freq += TEA575X_FMIF;
94 /* freq /= 12.5 */ 162 /* freq /= 12.5 */
95 freq *= 10; 163 freq *= 10;
96 freq /= 125; 164 freq /= 125;
97 165
98 tea->val &= ~TEA575X_BIT_FREQ_MASK; 166 tea->val &= ~TEA575X_BIT_FREQ_MASK;
99 tea->val |= freq & TEA575X_BIT_FREQ_MASK; 167 tea->val |= freq & TEA575X_BIT_FREQ_MASK;
100 tea->ops->write(tea, tea->val); 168 snd_tea575x_write(tea, tea->val);
101} 169}
102 170
103/* 171/*
@@ -109,29 +177,34 @@ static int vidioc_querycap(struct file *file, void *priv,
109{ 177{
110 struct snd_tea575x *tea = video_drvdata(file); 178 struct snd_tea575x *tea = video_drvdata(file);
111 179
112 strcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757");
113 strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver)); 180 strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver));
114 strlcpy(v->card, "Maestro Radio", sizeof(v->card)); 181 strlcpy(v->card, tea->card, sizeof(v->card));
115 sprintf(v->bus_info, "PCI"); 182 strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card));
183 strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info));
116 v->version = RADIO_VERSION; 184 v->version = RADIO_VERSION;
117 v->capabilities = V4L2_CAP_TUNER; 185 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
118 return 0; 186 return 0;
119} 187}
120 188
121static int vidioc_g_tuner(struct file *file, void *priv, 189static int vidioc_g_tuner(struct file *file, void *priv,
122 struct v4l2_tuner *v) 190 struct v4l2_tuner *v)
123{ 191{
192 struct snd_tea575x *tea = video_drvdata(file);
193
124 if (v->index > 0) 194 if (v->index > 0)
125 return -EINVAL; 195 return -EINVAL;
126 196
197 snd_tea575x_read(tea);
198
127 strcpy(v->name, "FM"); 199 strcpy(v->name, "FM");
128 v->type = V4L2_TUNER_RADIO; 200 v->type = V4L2_TUNER_RADIO;
201 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
129 v->rangelow = FREQ_LO; 202 v->rangelow = FREQ_LO;
130 v->rangehigh = FREQ_HI; 203 v->rangehigh = FREQ_HI;
131 v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; 204 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
132 v->capability = V4L2_TUNER_CAP_LOW; 205 v->audmode = tea->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO;
133 v->audmode = V4L2_TUNER_MODE_MONO; 206 v->signal = tea->tuned ? 0xffff : 0;
134 v->signal = 0xffff; 207
135 return 0; 208 return 0;
136} 209}
137 210
@@ -148,7 +221,10 @@ static int vidioc_g_frequency(struct file *file, void *priv,
148{ 221{
149 struct snd_tea575x *tea = video_drvdata(file); 222 struct snd_tea575x *tea = video_drvdata(file);
150 223
224 if (f->tuner != 0)
225 return -EINVAL;
151 f->type = V4L2_TUNER_RADIO; 226 f->type = V4L2_TUNER_RADIO;
227 snd_tea575x_get_freq(tea);
152 f->frequency = tea->freq; 228 f->frequency = tea->freq;
153 return 0; 229 return 0;
154} 230}
@@ -158,6 +234,9 @@ static int vidioc_s_frequency(struct file *file, void *priv,
158{ 234{
159 struct snd_tea575x *tea = video_drvdata(file); 235 struct snd_tea575x *tea = video_drvdata(file);
160 236
237 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
238 return -EINVAL;
239
161 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) 240 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
162 return -EINVAL; 241 return -EINVAL;
163 242
@@ -209,10 +288,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
209 288
210 switch (ctrl->id) { 289 switch (ctrl->id) {
211 case V4L2_CID_AUDIO_MUTE: 290 case V4L2_CID_AUDIO_MUTE:
212 if (tea->ops->mute) { 291 ctrl->value = tea->mute;
213 ctrl->value = tea->mute; 292 return 0;
214 return 0;
215 }
216 } 293 }
217 return -EINVAL; 294 return -EINVAL;
218} 295}
@@ -224,11 +301,11 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
224 301
225 switch (ctrl->id) { 302 switch (ctrl->id) {
226 case V4L2_CID_AUDIO_MUTE: 303 case V4L2_CID_AUDIO_MUTE:
227 if (tea->ops->mute) { 304 if (tea->mute != ctrl->value) {
228 tea->ops->mute(tea, ctrl->value);
229 tea->mute = ctrl->value; 305 tea->mute = ctrl->value;
230 return 0; 306 snd_tea575x_set_freq(tea);
231 } 307 }
308 return 0;
232 } 309 }
233 return -EINVAL; 310 return -EINVAL;
234} 311}
@@ -293,18 +370,16 @@ static struct video_device tea575x_radio = {
293/* 370/*
294 * initialize all the tea575x chips 371 * initialize all the tea575x chips
295 */ 372 */
296void snd_tea575x_init(struct snd_tea575x *tea) 373int snd_tea575x_init(struct snd_tea575x *tea)
297{ 374{
298 int retval; 375 int retval;
299 unsigned int val;
300 struct video_device *tea575x_radio_inst; 376 struct video_device *tea575x_radio_inst;
301 377
302 val = tea->ops->read(tea); 378 tea->mute = 1;
303 if (val == 0x1ffffff || val == 0) { 379
304 snd_printk(KERN_ERR 380 snd_tea575x_write(tea, 0x55AA);
305 "tea575x-tuner: Cannot find TEA575x chip\n"); 381 if (snd_tea575x_read(tea) != 0x55AA)
306 return; 382 return -ENODEV;
307 }
308 383
309 tea->in_use = 0; 384 tea->in_use = 0;
310 tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40; 385 tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40;
@@ -313,7 +388,7 @@ void snd_tea575x_init(struct snd_tea575x *tea)
313 tea575x_radio_inst = video_device_alloc(); 388 tea575x_radio_inst = video_device_alloc();
314 if (tea575x_radio_inst == NULL) { 389 if (tea575x_radio_inst == NULL) {
315 printk(KERN_ERR "tea575x-tuner: not enough memory\n"); 390 printk(KERN_ERR "tea575x-tuner: not enough memory\n");
316 return; 391 return -ENOMEM;
317 } 392 }
318 393
319 memcpy(tea575x_radio_inst, &tea575x_radio, sizeof(tea575x_radio)); 394 memcpy(tea575x_radio_inst, &tea575x_radio, sizeof(tea575x_radio));
@@ -328,17 +403,13 @@ void snd_tea575x_init(struct snd_tea575x *tea)
328 if (retval) { 403 if (retval) {
329 printk(KERN_ERR "tea575x-tuner: can't register video device!\n"); 404 printk(KERN_ERR "tea575x-tuner: can't register video device!\n");
330 kfree(tea575x_radio_inst); 405 kfree(tea575x_radio_inst);
331 return; 406 return retval;
332 } 407 }
333 408
334 snd_tea575x_set_freq(tea); 409 snd_tea575x_set_freq(tea);
335
336 /* mute on init */
337 if (tea->ops->mute) {
338 tea->ops->mute(tea, 1);
339 tea->mute = 1;
340 }
341 tea->vd = tea575x_radio_inst; 410 tea->vd = tea575x_radio_inst;
411
412 return 0;
342} 413}
343 414
344void snd_tea575x_exit(struct snd_tea575x *tea) 415void snd_tea575x_exit(struct snd_tea575x *tea)
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 76c090218073..6c93e051f9ae 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -22,10 +22,6 @@ config SOUND_VWSND
22 <file:Documentation/sound/oss/vwsnd> for more info on this driver's 22 <file:Documentation/sound/oss/vwsnd> for more info on this driver's
23 capabilities. 23 capabilities.
24 24
25config SOUND_AU1550_AC97
26 tristate "Au1550/Au1200 AC97 Sound"
27 depends on SOC_AU1550 || SOC_AU1200
28
29config SOUND_MSNDCLAS 25config SOUND_MSNDCLAS
30 tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey" 26 tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey"
31 depends on (m || !STANDALONE) && ISA 27 depends on (m || !STANDALONE) && ISA
diff --git a/sound/oss/Makefile b/sound/oss/Makefile
index 90ffb99c6b17..77f21b68bf0f 100644
--- a/sound/oss/Makefile
+++ b/sound/oss/Makefile
@@ -25,7 +25,6 @@ obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o
25obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o 25obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o
26obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o 26obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o
27obj-$(CONFIG_SOUND_VWSND) += vwsnd.o 27obj-$(CONFIG_SOUND_VWSND) += vwsnd.o
28obj-$(CONFIG_SOUND_AU1550_AC97) += au1550_ac97.o ac97_codec.o
29obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o 28obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o
30 29
31obj-$(CONFIG_DMASOUND) += dmasound/ 30obj-$(CONFIG_DMASOUND) += dmasound/
diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c
deleted file mode 100644
index 0cd23d94888f..000000000000
--- a/sound/oss/ac97_codec.c
+++ /dev/null
@@ -1,1203 +0,0 @@
1/*
2 * ac97_codec.c: Generic AC97 mixer/modem module
3 *
4 * Derived from ac97 mixer in maestro and trident driver.
5 *
6 * Copyright 2000 Silicon Integrated System Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 **************************************************************************
23 *
24 * The Intel Audio Codec '97 specification is available at:
25 * http://download.intel.com/support/motherboards/desktop/sb/ac97_r23.pdf
26 *
27 **************************************************************************
28 *
29 * History
30 * May 02, 2003 Liam Girdwood <lrg@slimlogic.co.uk>
31 * Removed non existent WM9700
32 * Added support for WM9705, WM9708, WM9709, WM9710, WM9711
33 * WM9712 and WM9717
34 * Mar 28, 2002 Randolph Bentson <bentson@holmsjoen.com>
35 * corrections to support WM9707 in ViewPad 1000
36 * v0.4 Mar 15 2000 Ollie Lho
37 * dual codecs support verified with 4 channels output
38 * v0.3 Feb 22 2000 Ollie Lho
39 * bug fix for record mask setting
40 * v0.2 Feb 10 2000 Ollie Lho
41 * add ac97_read_proc for /proc/driver/{vendor}/ac97
42 * v0.1 Jan 14 2000 Ollie Lho <ollie@sis.com.tw>
43 * Isolated from trident.c to support multiple ac97 codec
44 */
45#include <linux/module.h>
46#include <linux/kernel.h>
47#include <linux/slab.h>
48#include <linux/string.h>
49#include <linux/errno.h>
50#include <linux/bitops.h>
51#include <linux/delay.h>
52#include <linux/pci.h>
53#include <linux/ac97_codec.h>
54#include <asm/uaccess.h>
55#include <linux/mutex.h>
56
57#define CODEC_ID_BUFSZ 14
58
59static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel);
60static void ac97_write_mixer(struct ac97_codec *codec, int oss_channel,
61 unsigned int left, unsigned int right);
62static void ac97_set_mixer(struct ac97_codec *codec, unsigned int oss_mixer, unsigned int val );
63static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask);
64static int ac97_mixer_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned long arg);
65
66static int ac97_init_mixer(struct ac97_codec *codec);
67
68static int wolfson_init03(struct ac97_codec * codec);
69static int wolfson_init04(struct ac97_codec * codec);
70static int wolfson_init05(struct ac97_codec * codec);
71static int wolfson_init11(struct ac97_codec * codec);
72static int wolfson_init13(struct ac97_codec * codec);
73static int tritech_init(struct ac97_codec * codec);
74static int tritech_maestro_init(struct ac97_codec * codec);
75static int sigmatel_9708_init(struct ac97_codec *codec);
76static int sigmatel_9721_init(struct ac97_codec *codec);
77static int sigmatel_9744_init(struct ac97_codec *codec);
78static int ad1886_init(struct ac97_codec *codec);
79static int eapd_control(struct ac97_codec *codec, int);
80static int crystal_digital_control(struct ac97_codec *codec, int slots, int rate, int mode);
81static int cmedia_init(struct ac97_codec * codec);
82static int cmedia_digital_control(struct ac97_codec *codec, int slots, int rate, int mode);
83static int generic_digital_control(struct ac97_codec *codec, int slots, int rate, int mode);
84
85
86/*
87 * AC97 operations.
88 *
89 * If you are adding a codec then you should be able to use
90 * eapd_ops - any codec that supports EAPD amp control (most)
91 * null_ops - any ancient codec that supports nothing
92 *
93 * The three functions are
94 * init - used for non AC97 standard initialisation
95 * amplifier - used to do amplifier control (1=on 0=off)
96 * digital - switch to digital modes (0 = analog)
97 *
98 * Not all codecs support all features, not all drivers use all the
99 * operations yet
100 */
101
102static struct ac97_ops null_ops = { NULL, NULL, NULL };
103static struct ac97_ops default_ops = { NULL, eapd_control, NULL };
104static struct ac97_ops default_digital_ops = { NULL, eapd_control, generic_digital_control};
105static struct ac97_ops wolfson_ops03 = { wolfson_init03, NULL, NULL };
106static struct ac97_ops wolfson_ops04 = { wolfson_init04, NULL, NULL };
107static struct ac97_ops wolfson_ops05 = { wolfson_init05, NULL, NULL };
108static struct ac97_ops wolfson_ops11 = { wolfson_init11, NULL, NULL };
109static struct ac97_ops wolfson_ops13 = { wolfson_init13, NULL, NULL };
110static struct ac97_ops tritech_ops = { tritech_init, NULL, NULL };
111static struct ac97_ops tritech_m_ops = { tritech_maestro_init, NULL, NULL };
112static struct ac97_ops sigmatel_9708_ops = { sigmatel_9708_init, NULL, NULL };
113static struct ac97_ops sigmatel_9721_ops = { sigmatel_9721_init, NULL, NULL };
114static struct ac97_ops sigmatel_9744_ops = { sigmatel_9744_init, NULL, NULL };
115static struct ac97_ops crystal_digital_ops = { NULL, eapd_control, crystal_digital_control };
116static struct ac97_ops ad1886_ops = { ad1886_init, eapd_control, NULL };
117static struct ac97_ops cmedia_ops = { NULL, eapd_control, NULL};
118static struct ac97_ops cmedia_digital_ops = { cmedia_init, eapd_control, cmedia_digital_control};
119
120/* sorted by vendor/device id */
121static const struct {
122 u32 id;
123 char *name;
124 struct ac97_ops *ops;
125 int flags;
126} ac97_codec_ids[] = {
127 {0x41445303, "Analog Devices AD1819", &null_ops},
128 {0x41445340, "Analog Devices AD1881", &null_ops},
129 {0x41445348, "Analog Devices AD1881A", &null_ops},
130 {0x41445360, "Analog Devices AD1885", &default_ops},
131 {0x41445361, "Analog Devices AD1886", &ad1886_ops},
132 {0x41445370, "Analog Devices AD1981", &null_ops},
133 {0x41445372, "Analog Devices AD1981A", &null_ops},
134 {0x41445374, "Analog Devices AD1981B", &null_ops},
135 {0x41445460, "Analog Devices AD1885", &default_ops},
136 {0x41445461, "Analog Devices AD1886", &ad1886_ops},
137 {0x414B4D00, "Asahi Kasei AK4540", &null_ops},
138 {0x414B4D01, "Asahi Kasei AK4542", &null_ops},
139 {0x414B4D02, "Asahi Kasei AK4543", &null_ops},
140 {0x414C4326, "ALC100P", &null_ops},
141 {0x414C4710, "ALC200/200P", &null_ops},
142 {0x414C4720, "ALC650", &default_digital_ops},
143 {0x434D4941, "CMedia", &cmedia_ops, AC97_NO_PCM_VOLUME },
144 {0x434D4942, "CMedia", &cmedia_ops, AC97_NO_PCM_VOLUME },
145 {0x434D4961, "CMedia", &cmedia_digital_ops, AC97_NO_PCM_VOLUME },
146 {0x43525900, "Cirrus Logic CS4297", &default_ops},
147 {0x43525903, "Cirrus Logic CS4297", &default_ops},
148 {0x43525913, "Cirrus Logic CS4297A rev A", &default_ops},
149 {0x43525914, "Cirrus Logic CS4297A rev B", &default_ops},
150 {0x43525923, "Cirrus Logic CS4298", &null_ops},
151 {0x4352592B, "Cirrus Logic CS4294", &null_ops},
152 {0x4352592D, "Cirrus Logic CS4294", &null_ops},
153 {0x43525931, "Cirrus Logic CS4299 rev A", &crystal_digital_ops},
154 {0x43525933, "Cirrus Logic CS4299 rev C", &crystal_digital_ops},
155 {0x43525934, "Cirrus Logic CS4299 rev D", &crystal_digital_ops},
156 {0x43585430, "CXT48", &default_ops, AC97_DELUDED_MODEM },
157 {0x43585442, "CXT66", &default_ops, AC97_DELUDED_MODEM },
158 {0x44543031, "Diamond Technology DT0893", &default_ops},
159 {0x45838308, "ESS Allegro ES1988", &null_ops},
160 {0x49434511, "ICE1232", &null_ops}, /* I hope --jk */
161 {0x4e534331, "National Semiconductor LM4549", &null_ops},
162 {0x53494c22, "Silicon Laboratory Si3036", &null_ops},
163 {0x53494c23, "Silicon Laboratory Si3038", &null_ops},
164 {0x545200FF, "TriTech TR?????", &tritech_m_ops},
165 {0x54524102, "TriTech TR28022", &null_ops},
166 {0x54524103, "TriTech TR28023", &null_ops},
167 {0x54524106, "TriTech TR28026", &null_ops},
168 {0x54524108, "TriTech TR28028", &tritech_ops},
169 {0x54524123, "TriTech TR A5", &null_ops},
170 {0x574D4C03, "Wolfson WM9703/07/08/17", &wolfson_ops03},
171 {0x574D4C04, "Wolfson WM9704M/WM9704Q", &wolfson_ops04},
172 {0x574D4C05, "Wolfson WM9705/WM9710", &wolfson_ops05},
173 {0x574D4C09, "Wolfson WM9709", &null_ops},
174 {0x574D4C12, "Wolfson WM9711/9712", &wolfson_ops11},
175 {0x574D4C13, "Wolfson WM9713", &wolfson_ops13, AC97_DEFAULT_POWER_OFF},
176 {0x83847600, "SigmaTel STAC????", &null_ops},
177 {0x83847604, "SigmaTel STAC9701/3/4/5", &null_ops},
178 {0x83847605, "SigmaTel STAC9704", &null_ops},
179 {0x83847608, "SigmaTel STAC9708", &sigmatel_9708_ops},
180 {0x83847609, "SigmaTel STAC9721/23", &sigmatel_9721_ops},
181 {0x83847644, "SigmaTel STAC9744/45", &sigmatel_9744_ops},
182 {0x83847652, "SigmaTel STAC9752/53", &default_ops},
183 {0x83847656, "SigmaTel STAC9756/57", &sigmatel_9744_ops},
184 {0x83847666, "SigmaTel STAC9750T", &sigmatel_9744_ops},
185 {0x83847684, "SigmaTel STAC9783/84?", &null_ops},
186 {0x57454301, "Winbond 83971D", &null_ops},
187};
188
189/* this table has default mixer values for all OSS mixers. */
190static struct mixer_defaults {
191 int mixer;
192 unsigned int value;
193} mixer_defaults[SOUND_MIXER_NRDEVICES] = {
194 /* all values 0 -> 100 in bytes */
195 {SOUND_MIXER_VOLUME, 0x4343},
196 {SOUND_MIXER_BASS, 0x4343},
197 {SOUND_MIXER_TREBLE, 0x4343},
198 {SOUND_MIXER_PCM, 0x4343},
199 {SOUND_MIXER_SPEAKER, 0x4343},
200 {SOUND_MIXER_LINE, 0x4343},
201 {SOUND_MIXER_MIC, 0x0000},
202 {SOUND_MIXER_CD, 0x4343},
203 {SOUND_MIXER_ALTPCM, 0x4343},
204 {SOUND_MIXER_IGAIN, 0x4343},
205 {SOUND_MIXER_LINE1, 0x4343},
206 {SOUND_MIXER_PHONEIN, 0x4343},
207 {SOUND_MIXER_PHONEOUT, 0x4343},
208 {SOUND_MIXER_VIDEO, 0x4343},
209 {-1,0}
210};
211
212/* table to scale scale from OSS mixer value to AC97 mixer register value */
213static struct ac97_mixer_hw {
214 unsigned char offset;
215 int scale;
216} ac97_hw[SOUND_MIXER_NRDEVICES]= {
217 [SOUND_MIXER_VOLUME] = {AC97_MASTER_VOL_STEREO,64},
218 [SOUND_MIXER_BASS] = {AC97_MASTER_TONE, 16},
219 [SOUND_MIXER_TREBLE] = {AC97_MASTER_TONE, 16},
220 [SOUND_MIXER_PCM] = {AC97_PCMOUT_VOL, 32},
221 [SOUND_MIXER_SPEAKER] = {AC97_PCBEEP_VOL, 16},
222 [SOUND_MIXER_LINE] = {AC97_LINEIN_VOL, 32},
223 [SOUND_MIXER_MIC] = {AC97_MIC_VOL, 32},
224 [SOUND_MIXER_CD] = {AC97_CD_VOL, 32},
225 [SOUND_MIXER_ALTPCM] = {AC97_HEADPHONE_VOL, 64},
226 [SOUND_MIXER_IGAIN] = {AC97_RECORD_GAIN, 16},
227 [SOUND_MIXER_LINE1] = {AC97_AUX_VOL, 32},
228 [SOUND_MIXER_PHONEIN] = {AC97_PHONE_VOL, 32},
229 [SOUND_MIXER_PHONEOUT] = {AC97_MASTER_VOL_MONO, 64},
230 [SOUND_MIXER_VIDEO] = {AC97_VIDEO_VOL, 32},
231};
232
233/* the following tables allow us to go from OSS <-> ac97 quickly. */
234enum ac97_recsettings {
235 AC97_REC_MIC=0,
236 AC97_REC_CD,
237 AC97_REC_VIDEO,
238 AC97_REC_AUX,
239 AC97_REC_LINE,
240 AC97_REC_STEREO, /* combination of all enabled outputs.. */
241 AC97_REC_MONO, /*.. or the mono equivalent */
242 AC97_REC_PHONE
243};
244
245static const unsigned int ac97_rm2oss[] = {
246 [AC97_REC_MIC] = SOUND_MIXER_MIC,
247 [AC97_REC_CD] = SOUND_MIXER_CD,
248 [AC97_REC_VIDEO] = SOUND_MIXER_VIDEO,
249 [AC97_REC_AUX] = SOUND_MIXER_LINE1,
250 [AC97_REC_LINE] = SOUND_MIXER_LINE,
251 [AC97_REC_STEREO]= SOUND_MIXER_IGAIN,
252 [AC97_REC_PHONE] = SOUND_MIXER_PHONEIN
253};
254
255/* indexed by bit position */
256static const unsigned int ac97_oss_rm[] = {
257 [SOUND_MIXER_MIC] = AC97_REC_MIC,
258 [SOUND_MIXER_CD] = AC97_REC_CD,
259 [SOUND_MIXER_VIDEO] = AC97_REC_VIDEO,
260 [SOUND_MIXER_LINE1] = AC97_REC_AUX,
261 [SOUND_MIXER_LINE] = AC97_REC_LINE,
262 [SOUND_MIXER_IGAIN] = AC97_REC_STEREO,
263 [SOUND_MIXER_PHONEIN] = AC97_REC_PHONE
264};
265
266static LIST_HEAD(codecs);
267static LIST_HEAD(codec_drivers);
268static DEFINE_MUTEX(codec_mutex);
269
270/* reads the given OSS mixer from the ac97 the caller must have insured that the ac97 knows
271 about that given mixer, and should be holding a spinlock for the card */
272static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel)
273{
274 u16 val;
275 int ret = 0;
276 int scale;
277 struct ac97_mixer_hw *mh = &ac97_hw[oss_channel];
278
279 val = codec->codec_read(codec , mh->offset);
280
281 if (val & AC97_MUTE) {
282 ret = 0;
283 } else if (AC97_STEREO_MASK & (1 << oss_channel)) {
284 /* nice stereo mixers .. */
285 int left,right;
286
287 left = (val >> 8) & 0x7f;
288 right = val & 0x7f;
289
290 if (oss_channel == SOUND_MIXER_IGAIN) {
291 right = (right * 100) / mh->scale;
292 left = (left * 100) / mh->scale;
293 } else {
294 /* these may have 5 or 6 bit resolution */
295 if(oss_channel == SOUND_MIXER_VOLUME || oss_channel == SOUND_MIXER_ALTPCM)
296 scale = (1 << codec->bit_resolution);
297 else
298 scale = mh->scale;
299
300 right = 100 - ((right * 100) / scale);
301 left = 100 - ((left * 100) / scale);
302 }
303 ret = left | (right << 8);
304 } else if (oss_channel == SOUND_MIXER_SPEAKER) {
305 ret = 100 - ((((val & 0x1e)>>1) * 100) / mh->scale);
306 } else if (oss_channel == SOUND_MIXER_PHONEIN) {
307 ret = 100 - (((val & 0x1f) * 100) / mh->scale);
308 } else if (oss_channel == SOUND_MIXER_PHONEOUT) {
309 scale = (1 << codec->bit_resolution);
310 ret = 100 - (((val & 0x1f) * 100) / scale);
311 } else if (oss_channel == SOUND_MIXER_MIC) {
312 ret = 100 - (((val & 0x1f) * 100) / mh->scale);
313 /* the low bit is optional in the tone sliders and masking
314 it lets us avoid the 0xf 'bypass'.. */
315 } else if (oss_channel == SOUND_MIXER_BASS) {
316 ret = 100 - ((((val >> 8) & 0xe) * 100) / mh->scale);
317 } else if (oss_channel == SOUND_MIXER_TREBLE) {
318 ret = 100 - (((val & 0xe) * 100) / mh->scale);
319 }
320
321#ifdef DEBUG
322 printk("ac97_codec: read OSS mixer %2d (%s ac97 register 0x%02x), "
323 "0x%04x -> 0x%04x\n",
324 oss_channel, codec->id ? "Secondary" : "Primary",
325 mh->offset, val, ret);
326#endif
327
328 return ret;
329}
330
331/* write the OSS encoded volume to the given OSS encoded mixer, again caller's job to
332 make sure all is well in arg land, call with spinlock held */
333static void ac97_write_mixer(struct ac97_codec *codec, int oss_channel,
334 unsigned int left, unsigned int right)
335{
336 u16 val = 0;
337 int scale;
338 struct ac97_mixer_hw *mh = &ac97_hw[oss_channel];
339
340#ifdef DEBUG
341 printk("ac97_codec: wrote OSS mixer %2d (%s ac97 register 0x%02x), "
342 "left vol:%2d, right vol:%2d:",
343 oss_channel, codec->id ? "Secondary" : "Primary",
344 mh->offset, left, right);
345#endif
346
347 if (AC97_STEREO_MASK & (1 << oss_channel)) {
348 /* stereo mixers */
349 if (left == 0 && right == 0) {
350 val = AC97_MUTE;
351 } else {
352 if (oss_channel == SOUND_MIXER_IGAIN) {
353 right = (right * mh->scale) / 100;
354 left = (left * mh->scale) / 100;
355 if (right >= mh->scale)
356 right = mh->scale-1;
357 if (left >= mh->scale)
358 left = mh->scale-1;
359 } else {
360 /* these may have 5 or 6 bit resolution */
361 if (oss_channel == SOUND_MIXER_VOLUME ||
362 oss_channel == SOUND_MIXER_ALTPCM)
363 scale = (1 << codec->bit_resolution);
364 else
365 scale = mh->scale;
366
367 right = ((100 - right) * scale) / 100;
368 left = ((100 - left) * scale) / 100;
369 if (right >= scale)
370 right = scale-1;
371 if (left >= scale)
372 left = scale-1;
373 }
374 val = (left << 8) | right;
375 }
376 } else if (oss_channel == SOUND_MIXER_BASS) {
377 val = codec->codec_read(codec , mh->offset) & ~0x0f00;
378 left = ((100 - left) * mh->scale) / 100;
379 if (left >= mh->scale)
380 left = mh->scale-1;
381 val |= (left << 8) & 0x0e00;
382 } else if (oss_channel == SOUND_MIXER_TREBLE) {
383 val = codec->codec_read(codec , mh->offset) & ~0x000f;
384 left = ((100 - left) * mh->scale) / 100;
385 if (left >= mh->scale)
386 left = mh->scale-1;
387 val |= left & 0x000e;
388 } else if(left == 0) {
389 val = AC97_MUTE;
390 } else if (oss_channel == SOUND_MIXER_SPEAKER) {
391 left = ((100 - left) * mh->scale) / 100;
392 if (left >= mh->scale)
393 left = mh->scale-1;
394 val = left << 1;
395 } else if (oss_channel == SOUND_MIXER_PHONEIN) {
396 left = ((100 - left) * mh->scale) / 100;
397 if (left >= mh->scale)
398 left = mh->scale-1;
399 val = left;
400 } else if (oss_channel == SOUND_MIXER_PHONEOUT) {
401 scale = (1 << codec->bit_resolution);
402 left = ((100 - left) * scale) / 100;
403 if (left >= mh->scale)
404 left = mh->scale-1;
405 val = left;
406 } else if (oss_channel == SOUND_MIXER_MIC) {
407 val = codec->codec_read(codec , mh->offset) & ~0x801f;
408 left = ((100 - left) * mh->scale) / 100;
409 if (left >= mh->scale)
410 left = mh->scale-1;
411 val |= left;
412 /* the low bit is optional in the tone sliders and masking
413 it lets us avoid the 0xf 'bypass'.. */
414 }
415#ifdef DEBUG
416 printk(" 0x%04x", val);
417#endif
418
419 codec->codec_write(codec, mh->offset, val);
420
421#ifdef DEBUG
422 val = codec->codec_read(codec, mh->offset);
423 printk(" -> 0x%04x\n", val);
424#endif
425}
426
427/* a thin wrapper for write_mixer */
428static void ac97_set_mixer(struct ac97_codec *codec, unsigned int oss_mixer, unsigned int val )
429{
430 unsigned int left,right;
431
432 /* cleanse input a little */
433 right = ((val >> 8) & 0xff) ;
434 left = (val & 0xff) ;
435
436 if (right > 100) right = 100;
437 if (left > 100) left = 100;
438
439 codec->mixer_state[oss_mixer] = (right << 8) | left;
440 codec->write_mixer(codec, oss_mixer, left, right);
441}
442
443/* read or write the recmask, the ac97 can really have left and right recording
444 inputs independently set, but OSS doesn't seem to want us to express that to
445 the user. the caller guarantees that we have a supported bit set, and they
446 must be holding the card's spinlock */
447static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask)
448{
449 unsigned int val;
450
451 if (rw) {
452 /* read it from the card */
453 val = codec->codec_read(codec, AC97_RECORD_SELECT);
454#ifdef DEBUG
455 printk("ac97_codec: ac97 recmask to set to 0x%04x\n", val);
456#endif
457 return (1 << ac97_rm2oss[val & 0x07]);
458 }
459
460 /* else, write the first set in the mask as the
461 output */
462 /* clear out current set value first (AC97 supports only 1 input!) */
463 val = (1 << ac97_rm2oss[codec->codec_read(codec, AC97_RECORD_SELECT) & 0x07]);
464 if (mask != val)
465 mask &= ~val;
466
467 val = ffs(mask);
468 val = ac97_oss_rm[val-1];
469 val |= val << 8; /* set both channels */
470
471#ifdef DEBUG
472 printk("ac97_codec: setting ac97 recmask to 0x%04x\n", val);
473#endif
474
475 codec->codec_write(codec, AC97_RECORD_SELECT, val);
476
477 return 0;
478};
479
480static int ac97_mixer_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned long arg)
481{
482 int i, val = 0;
483
484 if (cmd == SOUND_MIXER_INFO) {
485 mixer_info info;
486 memset(&info, 0, sizeof(info));
487 strlcpy(info.id, codec->name, sizeof(info.id));
488 strlcpy(info.name, codec->name, sizeof(info.name));
489 info.modify_counter = codec->modcnt;
490 if (copy_to_user((void __user *)arg, &info, sizeof(info)))
491 return -EFAULT;
492 return 0;
493 }
494 if (cmd == SOUND_OLD_MIXER_INFO) {
495 _old_mixer_info info;
496 memset(&info, 0, sizeof(info));
497 strlcpy(info.id, codec->name, sizeof(info.id));
498 strlcpy(info.name, codec->name, sizeof(info.name));
499 if (copy_to_user((void __user *)arg, &info, sizeof(info)))
500 return -EFAULT;
501 return 0;
502 }
503
504 if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
505 return -EINVAL;
506
507 if (cmd == OSS_GETVERSION)
508 return put_user(SOUND_VERSION, (int __user *)arg);
509
510 if (_SIOC_DIR(cmd) == _SIOC_READ) {
511 switch (_IOC_NR(cmd)) {
512 case SOUND_MIXER_RECSRC: /* give them the current record source */
513 if (!codec->recmask_io) {
514 val = 0;
515 } else {
516 val = codec->recmask_io(codec, 1, 0);
517 }
518 break;
519
520 case SOUND_MIXER_DEVMASK: /* give them the supported mixers */
521 val = codec->supported_mixers;
522 break;
523
524 case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
525 val = codec->record_sources;
526 break;
527
528 case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
529 val = codec->stereo_mixers;
530 break;
531
532 case SOUND_MIXER_CAPS:
533 val = SOUND_CAP_EXCL_INPUT;
534 break;
535
536 default: /* read a specific mixer */
537 i = _IOC_NR(cmd);
538
539 if (!supported_mixer(codec, i))
540 return -EINVAL;
541
542 /* do we ever want to touch the hardware? */
543 /* val = codec->read_mixer(codec, i); */
544 val = codec->mixer_state[i];
545 break;
546 }
547 return put_user(val, (int __user *)arg);
548 }
549
550 if (_SIOC_DIR(cmd) == (_SIOC_WRITE|_SIOC_READ)) {
551 codec->modcnt++;
552 if (get_user(val, (int __user *)arg))
553 return -EFAULT;
554
555 switch (_IOC_NR(cmd)) {
556 case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
557 if (!codec->recmask_io) return -EINVAL;
558 if (!val) return 0;
559 if (!(val &= codec->record_sources)) return -EINVAL;
560
561 codec->recmask_io(codec, 0, val);
562
563 return 0;
564 default: /* write a specific mixer */
565 i = _IOC_NR(cmd);
566
567 if (!supported_mixer(codec, i))
568 return -EINVAL;
569
570 ac97_set_mixer(codec, i, val);
571
572 return 0;
573 }
574 }
575 return -EINVAL;
576}
577
578/**
579 * codec_id - Turn id1/id2 into a PnP string
580 * @id1: Vendor ID1
581 * @id2: Vendor ID2
582 * @buf: CODEC_ID_BUFSZ byte buffer
583 *
584 * Fills buf with a zero terminated PnP ident string for the id1/id2
585 * pair. For convenience the return is the passed in buffer pointer.
586 */
587
588static char *codec_id(u16 id1, u16 id2, char *buf)
589{
590 if(id1&0x8080) {
591 snprintf(buf, CODEC_ID_BUFSZ, "0x%04x:0x%04x", id1, id2);
592 } else {
593 buf[0] = (id1 >> 8);
594 buf[1] = (id1 & 0xFF);
595 buf[2] = (id2 >> 8);
596 snprintf(buf+3, CODEC_ID_BUFSZ - 3, "%d", id2&0xFF);
597 }
598 return buf;
599}
600
601/**
602 * ac97_check_modem - Check if the Codec is a modem
603 * @codec: codec to check
604 *
605 * Return true if the device is an AC97 1.0 or AC97 2.0 modem
606 */
607
608static int ac97_check_modem(struct ac97_codec *codec)
609{
610 /* Check for an AC97 1.0 soft modem (ID1) */
611 if(codec->codec_read(codec, AC97_RESET) & 2)
612 return 1;
613 /* Check for an AC97 2.x soft modem */
614 codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0L);
615 if(codec->codec_read(codec, AC97_EXTENDED_MODEM_ID) & 1)
616 return 1;
617 return 0;
618}
619
620
621/**
622 * ac97_alloc_codec - Allocate an AC97 codec
623 *
624 * Returns a new AC97 codec structure. AC97 codecs may become
625 * refcounted soon so this interface is needed. Returns with
626 * one reference taken.
627 */
628
629struct ac97_codec *ac97_alloc_codec(void)
630{
631 struct ac97_codec *codec = kzalloc(sizeof(struct ac97_codec), GFP_KERNEL);
632 if(!codec)
633 return NULL;
634
635 spin_lock_init(&codec->lock);
636 INIT_LIST_HEAD(&codec->list);
637 return codec;
638}
639
640EXPORT_SYMBOL(ac97_alloc_codec);
641
642/**
643 * ac97_release_codec - Release an AC97 codec
644 * @codec: codec to release
645 *
646 * Release an allocated AC97 codec. This will be refcounted in
647 * time but for the moment is trivial. Calls the unregister
648 * handler if the codec is now defunct.
649 */
650
651void ac97_release_codec(struct ac97_codec *codec)
652{
653 /* Remove from the list first, we don't want to be
654 "rediscovered" */
655 mutex_lock(&codec_mutex);
656 list_del(&codec->list);
657 mutex_unlock(&codec_mutex);
658 /*
659 * The driver needs to deal with internal
660 * locking to avoid accidents here.
661 */
662 if(codec->driver)
663 codec->driver->remove(codec, codec->driver);
664 kfree(codec);
665}
666
667EXPORT_SYMBOL(ac97_release_codec);
668
669/**
670 * ac97_probe_codec - Initialize and setup AC97-compatible codec
671 * @codec: (in/out) Kernel info for a single AC97 codec
672 *
673 * Reset the AC97 codec, then initialize the mixer and
674 * the rest of the @codec structure.
675 *
676 * The codec_read and codec_write fields of @codec are
677 * required to be setup and working when this function
678 * is called. All other fields are set by this function.
679 *
680 * codec_wait field of @codec can optionally be provided
681 * when calling this function. If codec_wait is not %NULL,
682 * this function will call codec_wait any time it is
683 * necessary to wait for the audio chip to reach the
684 * codec-ready state. If codec_wait is %NULL, then
685 * the default behavior is to call schedule_timeout.
686 * Currently codec_wait is used to wait for AC97 codec
687 * reset to complete.
688 *
689 * Some codecs will power down when a register reset is
690 * performed. We now check for such codecs.
691 *
692 * Returns 1 (true) on success, or 0 (false) on failure.
693 */
694
695int ac97_probe_codec(struct ac97_codec *codec)
696{
697 u16 id1, id2;
698 u16 audio;
699 int i;
700 char cidbuf[CODEC_ID_BUFSZ];
701 u16 f;
702 struct list_head *l;
703 struct ac97_driver *d;
704
705 /* wait for codec-ready state */
706 if (codec->codec_wait)
707 codec->codec_wait(codec);
708 else
709 udelay(10);
710
711 /* will the codec power down if register reset ? */
712 id1 = codec->codec_read(codec, AC97_VENDOR_ID1);
713 id2 = codec->codec_read(codec, AC97_VENDOR_ID2);
714 codec->name = NULL;
715 codec->codec_ops = &null_ops;
716 for (i = 0; i < ARRAY_SIZE(ac97_codec_ids); i++) {
717 if (ac97_codec_ids[i].id == ((id1 << 16) | id2)) {
718 codec->type = ac97_codec_ids[i].id;
719 codec->name = ac97_codec_ids[i].name;
720 codec->codec_ops = ac97_codec_ids[i].ops;
721 codec->flags = ac97_codec_ids[i].flags;
722 break;
723 }
724 }
725
726 codec->model = (id1 << 16) | id2;
727 if ((codec->flags & AC97_DEFAULT_POWER_OFF) == 0) {
728 /* reset codec and wait for the ready bit before we continue */
729 codec->codec_write(codec, AC97_RESET, 0L);
730 if (codec->codec_wait)
731 codec->codec_wait(codec);
732 else
733 udelay(10);
734 }
735
736 /* probing AC97 codec, AC97 2.0 says that bit 15 of register 0x00 (reset) should
737 * be read zero.
738 *
739 * FIXME: is the following comment outdated? -jgarzik
740 * Probing of AC97 in this way is not reliable, it is not even SAFE !!
741 */
742 if ((audio = codec->codec_read(codec, AC97_RESET)) & 0x8000) {
743 printk(KERN_ERR "ac97_codec: %s ac97 codec not present\n",
744 (codec->id & 0x2) ? (codec->id&1 ? "4th" : "Tertiary")
745 : (codec->id&1 ? "Secondary": "Primary"));
746 return 0;
747 }
748
749 /* probe for Modem Codec */
750 codec->modem = ac97_check_modem(codec);
751
752 /* enable SPDIF */
753 f = codec->codec_read(codec, AC97_EXTENDED_STATUS);
754 if((codec->codec_ops == &null_ops) && (f & 4))
755 codec->codec_ops = &default_digital_ops;
756
757 /* A device which thinks its a modem but isn't */
758 if(codec->flags & AC97_DELUDED_MODEM)
759 codec->modem = 0;
760
761 if (codec->name == NULL)
762 codec->name = "Unknown";
763 printk(KERN_INFO "ac97_codec: AC97 %s codec, id: %s (%s)\n",
764 codec->modem ? "Modem" : (audio ? "Audio" : ""),
765 codec_id(id1, id2, cidbuf), codec->name);
766
767 if(!ac97_init_mixer(codec))
768 return 0;
769
770 /*
771 * Attach last so the caller can override the mixer
772 * callbacks.
773 */
774
775 mutex_lock(&codec_mutex);
776 list_add(&codec->list, &codecs);
777
778 list_for_each(l, &codec_drivers) {
779 d = list_entry(l, struct ac97_driver, list);
780 if ((codec->model ^ d->codec_id) & d->codec_mask)
781 continue;
782 if(d->probe(codec, d) == 0)
783 {
784 codec->driver = d;
785 break;
786 }
787 }
788
789 mutex_unlock(&codec_mutex);
790 return 1;
791}
792
793static int ac97_init_mixer(struct ac97_codec *codec)
794{
795 u16 cap;
796 int i;
797
798 cap = codec->codec_read(codec, AC97_RESET);
799
800 /* mixer masks */
801 codec->supported_mixers = AC97_SUPPORTED_MASK;
802 codec->stereo_mixers = AC97_STEREO_MASK;
803 codec->record_sources = AC97_RECORD_MASK;
804 if (!(cap & 0x04))
805 codec->supported_mixers &= ~(SOUND_MASK_BASS|SOUND_MASK_TREBLE);
806 if (!(cap & 0x10))
807 codec->supported_mixers &= ~SOUND_MASK_ALTPCM;
808
809
810 /* detect bit resolution */
811 codec->codec_write(codec, AC97_MASTER_VOL_STEREO, 0x2020);
812 if(codec->codec_read(codec, AC97_MASTER_VOL_STEREO) == 0x2020)
813 codec->bit_resolution = 6;
814 else
815 codec->bit_resolution = 5;
816
817 /* generic OSS to AC97 wrapper */
818 codec->read_mixer = ac97_read_mixer;
819 codec->write_mixer = ac97_write_mixer;
820 codec->recmask_io = ac97_recmask_io;
821 codec->mixer_ioctl = ac97_mixer_ioctl;
822
823 /* initialize mixer channel volumes */
824 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
825 struct mixer_defaults *md = &mixer_defaults[i];
826 if (md->mixer == -1)
827 break;
828 if (!supported_mixer(codec, md->mixer))
829 continue;
830 ac97_set_mixer(codec, md->mixer, md->value);
831 }
832
833 /* codec specific initialization for 4-6 channel output or secondary codec stuff */
834 if (codec->codec_ops->init != NULL) {
835 codec->codec_ops->init(codec);
836 }
837
838 /*
839 * Volume is MUTE only on this device. We have to initialise
840 * it but its useless beyond that.
841 */
842 if(codec->flags & AC97_NO_PCM_VOLUME)
843 {
844 codec->supported_mixers &= ~SOUND_MASK_PCM;
845 printk(KERN_WARNING "AC97 codec does not have proper volume support.\n");
846 }
847 return 1;
848}
849
850#define AC97_SIGMATEL_ANALOG 0x6c /* Analog Special */
851#define AC97_SIGMATEL_DAC2INVERT 0x6e
852#define AC97_SIGMATEL_BIAS1 0x70
853#define AC97_SIGMATEL_BIAS2 0x72
854#define AC97_SIGMATEL_MULTICHN 0x74 /* Multi-Channel programming */
855#define AC97_SIGMATEL_CIC1 0x76
856#define AC97_SIGMATEL_CIC2 0x78
857
858
859static int sigmatel_9708_init(struct ac97_codec * codec)
860{
861 u16 codec72, codec6c;
862
863 codec72 = codec->codec_read(codec, AC97_SIGMATEL_BIAS2) & 0x8000;
864 codec6c = codec->codec_read(codec, AC97_SIGMATEL_ANALOG);
865
866 if ((codec72==0) && (codec6c==0)) {
867 codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);
868 codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x1000);
869 codec->codec_write(codec, AC97_SIGMATEL_BIAS1, 0xabba);
870 codec->codec_write(codec, AC97_SIGMATEL_BIAS2, 0x0007);
871 } else if ((codec72==0x8000) && (codec6c==0)) {
872 codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);
873 codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x1001);
874 codec->codec_write(codec, AC97_SIGMATEL_DAC2INVERT, 0x0008);
875 } else if ((codec72==0x8000) && (codec6c==0x0080)) {
876 /* nothing */
877 }
878 codec->codec_write(codec, AC97_SIGMATEL_MULTICHN, 0x0000);
879 return 0;
880}
881
882
883static int sigmatel_9721_init(struct ac97_codec * codec)
884{
885 /* Only set up secondary codec */
886 if (codec->id == 0)
887 return 0;
888
889 codec->codec_write(codec, AC97_SURROUND_MASTER, 0L);
890
891 /* initialize SigmaTel STAC9721/23 as secondary codec, decoding AC link
892 sloc 3,4 = 0x01, slot 7,8 = 0x00, */
893 codec->codec_write(codec, AC97_SIGMATEL_MULTICHN, 0x00);
894
895 /* we don't have the crystal when we are on an AMR card, so use
896 BIT_CLK as our clock source. Write the magic word ABBA and read
897 back to enable register 0x78 */
898 codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);
899 codec->codec_read(codec, AC97_SIGMATEL_CIC1);
900
901 /* sync all the clocks*/
902 codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x3802);
903
904 return 0;
905}
906
907
908static int sigmatel_9744_init(struct ac97_codec * codec)
909{
910 // patch for SigmaTel
911 codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);
912 codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x0000); // is this correct? --jk
913 codec->codec_write(codec, AC97_SIGMATEL_BIAS1, 0xabba);
914 codec->codec_write(codec, AC97_SIGMATEL_BIAS2, 0x0002);
915 codec->codec_write(codec, AC97_SIGMATEL_MULTICHN, 0x0000);
916 return 0;
917}
918
919static int cmedia_init(struct ac97_codec *codec)
920{
921 /* Initialise the CMedia 9739 */
922 /*
923 We could set various options here
924 Register 0x20 bit 0x100 sets mic as center bass
925 Also do multi_channel_ctrl &=~0x3000 |=0x1000
926
927 For now we set up the GPIO and PC beep
928 */
929
930 u16 v;
931
932 /* MIC */
933 codec->codec_write(codec, 0x64, 0x3000);
934 v = codec->codec_read(codec, 0x64);
935 v &= ~0x8000;
936 codec->codec_write(codec, 0x64, v);
937 codec->codec_write(codec, 0x70, 0x0100);
938 codec->codec_write(codec, 0x72, 0x0020);
939 return 0;
940}
941
942#define AC97_WM97XX_FMIXER_VOL 0x72
943#define AC97_WM97XX_RMIXER_VOL 0x74
944#define AC97_WM97XX_TEST 0x5a
945#define AC97_WM9704_RPCM_VOL 0x70
946#define AC97_WM9711_OUT3VOL 0x16
947
948static int wolfson_init03(struct ac97_codec * codec)
949{
950 /* this is known to work for the ViewSonic ViewPad 1000 */
951 codec->codec_write(codec, AC97_WM97XX_FMIXER_VOL, 0x0808);
952 codec->codec_write(codec, AC97_GENERAL_PURPOSE, 0x8000);
953 return 0;
954}
955
956static int wolfson_init04(struct ac97_codec * codec)
957{
958 codec->codec_write(codec, AC97_WM97XX_FMIXER_VOL, 0x0808);
959 codec->codec_write(codec, AC97_WM97XX_RMIXER_VOL, 0x0808);
960
961 // patch for DVD noise
962 codec->codec_write(codec, AC97_WM97XX_TEST, 0x0200);
963
964 // init vol as PCM vol
965 codec->codec_write(codec, AC97_WM9704_RPCM_VOL,
966 codec->codec_read(codec, AC97_PCMOUT_VOL));
967
968 /* set rear surround volume */
969 codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0000);
970 return 0;
971}
972
973/* WM9705, WM9710 */
974static int wolfson_init05(struct ac97_codec * codec)
975{
976 /* set front mixer volume */
977 codec->codec_write(codec, AC97_WM97XX_FMIXER_VOL, 0x0808);
978 return 0;
979}
980
981/* WM9711, WM9712 */
982static int wolfson_init11(struct ac97_codec * codec)
983{
984 /* stop pop's during suspend/resume */
985 codec->codec_write(codec, AC97_WM97XX_TEST,
986 codec->codec_read(codec, AC97_WM97XX_TEST) & 0xffbf);
987
988 /* set out3 volume */
989 codec->codec_write(codec, AC97_WM9711_OUT3VOL, 0x0808);
990 return 0;
991}
992
993/* WM9713 */
994static int wolfson_init13(struct ac97_codec * codec)
995{
996 codec->codec_write(codec, AC97_RECORD_GAIN, 0x00a0);
997 codec->codec_write(codec, AC97_POWER_CONTROL, 0x0000);
998 codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0xDA00);
999 codec->codec_write(codec, AC97_EXTEND_MODEM_STAT, 0x3810);
1000 codec->codec_write(codec, AC97_PHONE_VOL, 0x0808);
1001 codec->codec_write(codec, AC97_PCBEEP_VOL, 0x0808);
1002
1003 return 0;
1004}
1005
1006static int tritech_init(struct ac97_codec * codec)
1007{
1008 codec->codec_write(codec, 0x26, 0x0300);
1009 codec->codec_write(codec, 0x26, 0x0000);
1010 codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0000);
1011 codec->codec_write(codec, AC97_RESERVED_3A, 0x0000);
1012 return 0;
1013}
1014
1015
1016/* copied from drivers/sound/maestro.c */
1017static int tritech_maestro_init(struct ac97_codec * codec)
1018{
1019 /* no idea what this does */
1020 codec->codec_write(codec, 0x2A, 0x0001);
1021 codec->codec_write(codec, 0x2C, 0x0000);
1022 codec->codec_write(codec, 0x2C, 0XFFFF);
1023 return 0;
1024}
1025
1026
1027
1028/*
1029 * Presario700 workaround
1030 * for Jack Sense/SPDIF Register mis-setting causing
1031 * no audible output
1032 * by Santiago Nullo 04/05/2002
1033 */
1034
1035#define AC97_AD1886_JACK_SENSE 0x72
1036
1037static int ad1886_init(struct ac97_codec * codec)
1038{
1039 /* from AD1886 Specs */
1040 codec->codec_write(codec, AC97_AD1886_JACK_SENSE, 0x0010);
1041 return 0;
1042}
1043
1044
1045
1046
1047/*
1048 * This is basically standard AC97. It should work as a default for
1049 * almost all modern codecs. Note that some cards wire EAPD *backwards*
1050 * That side of it is up to the card driver not us to cope with.
1051 *
1052 */
1053
1054static int eapd_control(struct ac97_codec * codec, int on)
1055{
1056 if(on)
1057 codec->codec_write(codec, AC97_POWER_CONTROL,
1058 codec->codec_read(codec, AC97_POWER_CONTROL)|0x8000);
1059 else
1060 codec->codec_write(codec, AC97_POWER_CONTROL,
1061 codec->codec_read(codec, AC97_POWER_CONTROL)&~0x8000);
1062 return 0;
1063}
1064
1065static int generic_digital_control(struct ac97_codec *codec, int slots, int rate, int mode)
1066{
1067 u16 reg;
1068
1069 reg = codec->codec_read(codec, AC97_SPDIF_CONTROL);
1070
1071 switch(rate)
1072 {
1073 /* Off by default */
1074 default:
1075 case 0:
1076 reg = codec->codec_read(codec, AC97_EXTENDED_STATUS);
1077 codec->codec_write(codec, AC97_EXTENDED_STATUS, (reg & ~AC97_EA_SPDIF));
1078 if(rate == 0)
1079 return 0;
1080 return -EINVAL;
1081 case 1:
1082 reg = (reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_48K;
1083 break;
1084 case 2:
1085 reg = (reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_44K;
1086 break;
1087 case 3:
1088 reg = (reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_32K;
1089 break;
1090 }
1091
1092 reg &= ~AC97_SC_CC_MASK;
1093 reg |= (mode & AUDIO_CCMASK) << 6;
1094
1095 if(mode & AUDIO_DIGITAL)
1096 reg |= 2;
1097 if(mode & AUDIO_PRO)
1098 reg |= 1;
1099 if(mode & AUDIO_DRS)
1100 reg |= 0x4000;
1101
1102 codec->codec_write(codec, AC97_SPDIF_CONTROL, reg);
1103
1104 reg = codec->codec_read(codec, AC97_EXTENDED_STATUS);
1105 reg &= (AC97_EA_SLOT_MASK);
1106 reg |= AC97_EA_VRA | AC97_EA_SPDIF | slots;
1107 codec->codec_write(codec, AC97_EXTENDED_STATUS, reg);
1108
1109 reg = codec->codec_read(codec, AC97_EXTENDED_STATUS);
1110 if(!(reg & 0x0400))
1111 {
1112 codec->codec_write(codec, AC97_EXTENDED_STATUS, reg & ~ AC97_EA_SPDIF);
1113 return -EINVAL;
1114 }
1115 return 0;
1116}
1117
1118/*
1119 * Crystal digital audio control (CS4299)
1120 */
1121
1122static int crystal_digital_control(struct ac97_codec *codec, int slots, int rate, int mode)
1123{
1124 u16 cv;
1125
1126 if(mode & AUDIO_DIGITAL)
1127 return -EINVAL;
1128
1129 switch(rate)
1130 {
1131 case 0: cv = 0x0; break; /* SPEN off */
1132 case 48000: cv = 0x8004; break; /* 48KHz digital */
1133 case 44100: cv = 0x8104; break; /* 44.1KHz digital */
1134 case 32768: /* 32Khz */
1135 default:
1136 return -EINVAL;
1137 }
1138 codec->codec_write(codec, 0x68, cv);
1139 return 0;
1140}
1141
1142/*
1143 * CMedia digital audio control
1144 * Needs more work.
1145 */
1146
1147static int cmedia_digital_control(struct ac97_codec *codec, int slots, int rate, int mode)
1148{
1149 u16 cv;
1150
1151 if(mode & AUDIO_DIGITAL)
1152 return -EINVAL;
1153
1154 switch(rate)
1155 {
1156 case 0: cv = 0x0001; break; /* SPEN off */
1157 case 48000: cv = 0x0009; break; /* 48KHz digital */
1158 default:
1159 return -EINVAL;
1160 }
1161 codec->codec_write(codec, 0x2A, 0x05c4);
1162 codec->codec_write(codec, 0x6C, cv);
1163
1164 /* Switch on mix to surround */
1165 cv = codec->codec_read(codec, 0x64);
1166 cv &= ~0x0200;
1167 if(mode)
1168 cv |= 0x0200;
1169 codec->codec_write(codec, 0x64, cv);
1170 return 0;
1171}
1172
1173
1174/* copied from drivers/sound/maestro.c */
1175#if 0 /* there has been 1 person on the planet with a pt101 that we
1176 know of. If they care, they can put this back in :) */
1177static int pt101_init(struct ac97_codec * codec)
1178{
1179 printk(KERN_INFO "ac97_codec: PT101 Codec detected, initializing but _not_ installing mixer device.\n");
1180 /* who knows.. */
1181 codec->codec_write(codec, 0x2A, 0x0001);
1182 codec->codec_write(codec, 0x2C, 0x0000);
1183 codec->codec_write(codec, 0x2C, 0xFFFF);
1184 codec->codec_write(codec, 0x10, 0x9F1F);
1185 codec->codec_write(codec, 0x12, 0x0808);
1186 codec->codec_write(codec, 0x14, 0x9F1F);
1187 codec->codec_write(codec, 0x16, 0x9F1F);
1188 codec->codec_write(codec, 0x18, 0x0404);
1189 codec->codec_write(codec, 0x1A, 0x0000);
1190 codec->codec_write(codec, 0x1C, 0x0000);
1191 codec->codec_write(codec, 0x02, 0x0404);
1192 codec->codec_write(codec, 0x04, 0x0808);
1193 codec->codec_write(codec, 0x0C, 0x801F);
1194 codec->codec_write(codec, 0x0E, 0x801F);
1195 return 0;
1196}
1197#endif
1198
1199
1200EXPORT_SYMBOL(ac97_probe_codec);
1201
1202MODULE_LICENSE("GPL");
1203
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
deleted file mode 100644
index a8f626d99c5b..000000000000
--- a/sound/oss/au1550_ac97.c
+++ /dev/null
@@ -1,2147 +0,0 @@
1/*
2 * au1550_ac97.c -- Sound driver for Alchemy Au1550 MIPS Internet Edge
3 * Processor.
4 *
5 * Copyright 2004 Embedded Edge, LLC
6 * dan@embeddededge.com
7 *
8 * Mostly copied from the au1000.c driver and some from the
9 * PowerMac dbdma driver.
10 * We assume the processor can do memory coherent DMA.
11 *
12 * Ported to 2.6 by Matt Porter <mporter@kernel.crashing.org>
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version.
18 *
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
22 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 */
35
36#undef DEBUG
37
38#include <linux/module.h>
39#include <linux/string.h>
40#include <linux/ioport.h>
41#include <linux/sched.h>
42#include <linux/delay.h>
43#include <linux/sound.h>
44#include <linux/slab.h>
45#include <linux/soundcard.h>
46#include <linux/init.h>
47#include <linux/interrupt.h>
48#include <linux/kernel.h>
49#include <linux/poll.h>
50#include <linux/bitops.h>
51#include <linux/spinlock.h>
52#include <linux/ac97_codec.h>
53#include <linux/mutex.h>
54
55#include <asm/io.h>
56#include <asm/uaccess.h>
57#include <asm/hardirq.h>
58#include <asm/mach-au1x00/au1xxx_psc.h>
59#include <asm/mach-au1x00/au1xxx_dbdma.h>
60#include <asm/mach-au1x00/au1xxx.h>
61
62#undef OSS_DOCUMENTED_MIXER_SEMANTICS
63
64/* misc stuff */
65#define POLL_COUNT 0x50000
66#define AC97_EXT_DACS (AC97_EXTID_SDAC | AC97_EXTID_CDAC | AC97_EXTID_LDAC)
67
68/* The number of DBDMA ring descriptors to allocate. No sense making
69 * this too large....if you can't keep up with a few you aren't likely
70 * to be able to with lots of them, either.
71 */
72#define NUM_DBDMA_DESCRIPTORS 4
73
74#define err(format, arg...) printk(KERN_ERR format "\n" , ## arg)
75
76/* Boot options
77 * 0 = no VRA, 1 = use VRA if codec supports it
78 */
79static DEFINE_MUTEX(au1550_ac97_mutex);
80static int vra = 1;
81module_param(vra, bool, 0);
82MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it");
83
84static struct au1550_state {
85 /* soundcore stuff */
86 int dev_audio;
87
88 struct ac97_codec *codec;
89 unsigned codec_base_caps; /* AC'97 reg 00h, "Reset Register" */
90 unsigned codec_ext_caps; /* AC'97 reg 28h, "Extended Audio ID" */
91 int no_vra; /* do not use VRA */
92
93 spinlock_t lock;
94 struct mutex open_mutex;
95 struct mutex sem;
96 fmode_t open_mode;
97 wait_queue_head_t open_wait;
98
99 struct dmabuf {
100 u32 dmanr;
101 unsigned sample_rate;
102 unsigned src_factor;
103 unsigned sample_size;
104 int num_channels;
105 int dma_bytes_per_sample;
106 int user_bytes_per_sample;
107 int cnt_factor;
108
109 void *rawbuf;
110 unsigned buforder;
111 unsigned numfrag;
112 unsigned fragshift;
113 void *nextIn;
114 void *nextOut;
115 int count;
116 unsigned total_bytes;
117 unsigned error;
118 wait_queue_head_t wait;
119
120 /* redundant, but makes calculations easier */
121 unsigned fragsize;
122 unsigned dma_fragsize;
123 unsigned dmasize;
124 unsigned dma_qcount;
125
126 /* OSS stuff */
127 unsigned mapped:1;
128 unsigned ready:1;
129 unsigned stopped:1;
130 unsigned ossfragshift;
131 int ossmaxfrags;
132 unsigned subdivision;
133 } dma_dac, dma_adc;
134} au1550_state;
135
136static unsigned
137ld2(unsigned int x)
138{
139 unsigned r = 0;
140
141 if (x >= 0x10000) {
142 x >>= 16;
143 r += 16;
144 }
145 if (x >= 0x100) {
146 x >>= 8;
147 r += 8;
148 }
149 if (x >= 0x10) {
150 x >>= 4;
151 r += 4;
152 }
153 if (x >= 4) {
154 x >>= 2;
155 r += 2;
156 }
157 if (x >= 2)
158 r++;
159 return r;
160}
161
162static void
163au1550_delay(int msec)
164{
165 if (in_interrupt())
166 return;
167
168 schedule_timeout_uninterruptible(msecs_to_jiffies(msec));
169}
170
171static u16
172rdcodec(struct ac97_codec *codec, u8 addr)
173{
174 struct au1550_state *s = codec->private_data;
175 unsigned long flags;
176 u32 cmd, val;
177 u16 data;
178 int i;
179
180 spin_lock_irqsave(&s->lock, flags);
181
182 for (i = 0; i < POLL_COUNT; i++) {
183 val = au_readl(PSC_AC97STAT);
184 au_sync();
185 if (!(val & PSC_AC97STAT_CP))
186 break;
187 }
188 if (i == POLL_COUNT)
189 err("rdcodec: codec cmd pending expired!");
190
191 cmd = (u32)PSC_AC97CDC_INDX(addr);
192 cmd |= PSC_AC97CDC_RD; /* read command */
193 au_writel(cmd, PSC_AC97CDC);
194 au_sync();
195
196 /* now wait for the data
197 */
198 for (i = 0; i < POLL_COUNT; i++) {
199 val = au_readl(PSC_AC97STAT);
200 au_sync();
201 if (!(val & PSC_AC97STAT_CP))
202 break;
203 }
204 if (i == POLL_COUNT) {
205 err("rdcodec: read poll expired!");
206 data = 0;
207 goto out;
208 }
209
210 /* wait for command done?
211 */
212 for (i = 0; i < POLL_COUNT; i++) {
213 val = au_readl(PSC_AC97EVNT);
214 au_sync();
215 if (val & PSC_AC97EVNT_CD)
216 break;
217 }
218 if (i == POLL_COUNT) {
219 err("rdcodec: read cmdwait expired!");
220 data = 0;
221 goto out;
222 }
223
224 data = au_readl(PSC_AC97CDC) & 0xffff;
225 au_sync();
226
227 /* Clear command done event.
228 */
229 au_writel(PSC_AC97EVNT_CD, PSC_AC97EVNT);
230 au_sync();
231
232 out:
233 spin_unlock_irqrestore(&s->lock, flags);
234
235 return data;
236}
237
238
239static void
240wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
241{
242 struct au1550_state *s = codec->private_data;
243 unsigned long flags;
244 u32 cmd, val;
245 int i;
246
247 spin_lock_irqsave(&s->lock, flags);
248
249 for (i = 0; i < POLL_COUNT; i++) {
250 val = au_readl(PSC_AC97STAT);
251 au_sync();
252 if (!(val & PSC_AC97STAT_CP))
253 break;
254 }
255 if (i == POLL_COUNT)
256 err("wrcodec: codec cmd pending expired!");
257
258 cmd = (u32)PSC_AC97CDC_INDX(addr);
259 cmd |= (u32)data;
260 au_writel(cmd, PSC_AC97CDC);
261 au_sync();
262
263 for (i = 0; i < POLL_COUNT; i++) {
264 val = au_readl(PSC_AC97STAT);
265 au_sync();
266 if (!(val & PSC_AC97STAT_CP))
267 break;
268 }
269 if (i == POLL_COUNT)
270 err("wrcodec: codec cmd pending expired!");
271
272 for (i = 0; i < POLL_COUNT; i++) {
273 val = au_readl(PSC_AC97EVNT);
274 au_sync();
275 if (val & PSC_AC97EVNT_CD)
276 break;
277 }
278 if (i == POLL_COUNT)
279 err("wrcodec: read cmdwait expired!");
280
281 /* Clear command done event.
282 */
283 au_writel(PSC_AC97EVNT_CD, PSC_AC97EVNT);
284 au_sync();
285
286 spin_unlock_irqrestore(&s->lock, flags);
287}
288
289static void
290waitcodec(struct ac97_codec *codec)
291{
292 u16 temp;
293 u32 val;
294 int i;
295
296 /* codec_wait is used to wait for a ready state after
297 * an AC97C_RESET.
298 */
299 au1550_delay(10);
300
301 /* first poll the CODEC_READY tag bit
302 */
303 for (i = 0; i < POLL_COUNT; i++) {
304 val = au_readl(PSC_AC97STAT);
305 au_sync();
306 if (val & PSC_AC97STAT_CR)
307 break;
308 }
309 if (i == POLL_COUNT) {
310 err("waitcodec: CODEC_READY poll expired!");
311 return;
312 }
313
314 /* get AC'97 powerdown control/status register
315 */
316 temp = rdcodec(codec, AC97_POWER_CONTROL);
317
318 /* If anything is powered down, power'em up
319 */
320 if (temp & 0x7f00) {
321 /* Power on
322 */
323 wrcodec(codec, AC97_POWER_CONTROL, 0);
324 au1550_delay(100);
325
326 /* Reread
327 */
328 temp = rdcodec(codec, AC97_POWER_CONTROL);
329 }
330
331 /* Check if Codec REF,ANL,DAC,ADC ready
332 */
333 if ((temp & 0x7f0f) != 0x000f)
334 err("codec reg 26 status (0x%x) not ready!!", temp);
335}
336
337/* stop the ADC before calling */
338static void
339set_adc_rate(struct au1550_state *s, unsigned rate)
340{
341 struct dmabuf *adc = &s->dma_adc;
342 struct dmabuf *dac = &s->dma_dac;
343 unsigned adc_rate, dac_rate;
344 u16 ac97_extstat;
345
346 if (s->no_vra) {
347 /* calc SRC factor
348 */
349 adc->src_factor = ((96000 / rate) + 1) >> 1;
350 adc->sample_rate = 48000 / adc->src_factor;
351 return;
352 }
353
354 adc->src_factor = 1;
355
356 ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
357
358 rate = rate > 48000 ? 48000 : rate;
359
360 /* enable VRA
361 */
362 wrcodec(s->codec, AC97_EXTENDED_STATUS,
363 ac97_extstat | AC97_EXTSTAT_VRA);
364
365 /* now write the sample rate
366 */
367 wrcodec(s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate);
368
369 /* read it back for actual supported rate
370 */
371 adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
372
373 pr_debug("set_adc_rate: set to %d Hz\n", adc_rate);
374
375 /* some codec's don't allow unequal DAC and ADC rates, in which case
376 * writing one rate reg actually changes both.
377 */
378 dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
379 if (dac->num_channels > 2)
380 wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate);
381 if (dac->num_channels > 4)
382 wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate);
383
384 adc->sample_rate = adc_rate;
385 dac->sample_rate = dac_rate;
386}
387
388/* stop the DAC before calling */
389static void
390set_dac_rate(struct au1550_state *s, unsigned rate)
391{
392 struct dmabuf *dac = &s->dma_dac;
393 struct dmabuf *adc = &s->dma_adc;
394 unsigned adc_rate, dac_rate;
395 u16 ac97_extstat;
396
397 if (s->no_vra) {
398 /* calc SRC factor
399 */
400 dac->src_factor = ((96000 / rate) + 1) >> 1;
401 dac->sample_rate = 48000 / dac->src_factor;
402 return;
403 }
404
405 dac->src_factor = 1;
406
407 ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
408
409 rate = rate > 48000 ? 48000 : rate;
410
411 /* enable VRA
412 */
413 wrcodec(s->codec, AC97_EXTENDED_STATUS,
414 ac97_extstat | AC97_EXTSTAT_VRA);
415
416 /* now write the sample rate
417 */
418 wrcodec(s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate);
419
420 /* I don't support different sample rates for multichannel,
421 * so make these channels the same.
422 */
423 if (dac->num_channels > 2)
424 wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate);
425 if (dac->num_channels > 4)
426 wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate);
427 /* read it back for actual supported rate
428 */
429 dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
430
431 pr_debug("set_dac_rate: set to %d Hz\n", dac_rate);
432
433 /* some codec's don't allow unequal DAC and ADC rates, in which case
434 * writing one rate reg actually changes both.
435 */
436 adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
437
438 dac->sample_rate = dac_rate;
439 adc->sample_rate = adc_rate;
440}
441
442static void
443stop_dac(struct au1550_state *s)
444{
445 struct dmabuf *db = &s->dma_dac;
446 u32 stat;
447 unsigned long flags;
448
449 if (db->stopped)
450 return;
451
452 spin_lock_irqsave(&s->lock, flags);
453
454 au_writel(PSC_AC97PCR_TP, PSC_AC97PCR);
455 au_sync();
456
457 /* Wait for Transmit Busy to show disabled.
458 */
459 do {
460 stat = au_readl(PSC_AC97STAT);
461 au_sync();
462 } while ((stat & PSC_AC97STAT_TB) != 0);
463
464 au1xxx_dbdma_reset(db->dmanr);
465
466 db->stopped = 1;
467
468 spin_unlock_irqrestore(&s->lock, flags);
469}
470
471static void
472stop_adc(struct au1550_state *s)
473{
474 struct dmabuf *db = &s->dma_adc;
475 unsigned long flags;
476 u32 stat;
477
478 if (db->stopped)
479 return;
480
481 spin_lock_irqsave(&s->lock, flags);
482
483 au_writel(PSC_AC97PCR_RP, PSC_AC97PCR);
484 au_sync();
485
486 /* Wait for Receive Busy to show disabled.
487 */
488 do {
489 stat = au_readl(PSC_AC97STAT);
490 au_sync();
491 } while ((stat & PSC_AC97STAT_RB) != 0);
492
493 au1xxx_dbdma_reset(db->dmanr);
494
495 db->stopped = 1;
496
497 spin_unlock_irqrestore(&s->lock, flags);
498}
499
500
501static void
502set_xmit_slots(int num_channels)
503{
504 u32 ac97_config, stat;
505
506 ac97_config = au_readl(PSC_AC97CFG);
507 au_sync();
508 ac97_config &= ~(PSC_AC97CFG_TXSLOT_MASK | PSC_AC97CFG_DE_ENABLE);
509 au_writel(ac97_config, PSC_AC97CFG);
510 au_sync();
511
512 switch (num_channels) {
513 case 6: /* stereo with surround and center/LFE,
514 * slots 3,4,6,7,8,9
515 */
516 ac97_config |= PSC_AC97CFG_TXSLOT_ENA(6);
517 ac97_config |= PSC_AC97CFG_TXSLOT_ENA(9);
518
519 case 4: /* stereo with surround, slots 3,4,7,8 */
520 ac97_config |= PSC_AC97CFG_TXSLOT_ENA(7);
521 ac97_config |= PSC_AC97CFG_TXSLOT_ENA(8);
522
523 case 2: /* stereo, slots 3,4 */
524 case 1: /* mono */
525 ac97_config |= PSC_AC97CFG_TXSLOT_ENA(3);
526 ac97_config |= PSC_AC97CFG_TXSLOT_ENA(4);
527 }
528
529 au_writel(ac97_config, PSC_AC97CFG);
530 au_sync();
531
532 ac97_config |= PSC_AC97CFG_DE_ENABLE;
533 au_writel(ac97_config, PSC_AC97CFG);
534 au_sync();
535
536 /* Wait for Device ready.
537 */
538 do {
539 stat = au_readl(PSC_AC97STAT);
540 au_sync();
541 } while ((stat & PSC_AC97STAT_DR) == 0);
542}
543
544static void
545set_recv_slots(int num_channels)
546{
547 u32 ac97_config, stat;
548
549 ac97_config = au_readl(PSC_AC97CFG);
550 au_sync();
551 ac97_config &= ~(PSC_AC97CFG_RXSLOT_MASK | PSC_AC97CFG_DE_ENABLE);
552 au_writel(ac97_config, PSC_AC97CFG);
553 au_sync();
554
555 /* Always enable slots 3 and 4 (stereo). Slot 6 is
556 * optional Mic ADC, which we don't support yet.
557 */
558 ac97_config |= PSC_AC97CFG_RXSLOT_ENA(3);
559 ac97_config |= PSC_AC97CFG_RXSLOT_ENA(4);
560
561 au_writel(ac97_config, PSC_AC97CFG);
562 au_sync();
563
564 ac97_config |= PSC_AC97CFG_DE_ENABLE;
565 au_writel(ac97_config, PSC_AC97CFG);
566 au_sync();
567
568 /* Wait for Device ready.
569 */
570 do {
571 stat = au_readl(PSC_AC97STAT);
572 au_sync();
573 } while ((stat & PSC_AC97STAT_DR) == 0);
574}
575
576/* Hold spinlock for both start_dac() and start_adc() calls */
577static void
578start_dac(struct au1550_state *s)
579{
580 struct dmabuf *db = &s->dma_dac;
581
582 if (!db->stopped)
583 return;
584
585 set_xmit_slots(db->num_channels);
586 au_writel(PSC_AC97PCR_TC, PSC_AC97PCR);
587 au_sync();
588 au_writel(PSC_AC97PCR_TS, PSC_AC97PCR);
589 au_sync();
590
591 au1xxx_dbdma_start(db->dmanr);
592
593 db->stopped = 0;
594}
595
596static void
597start_adc(struct au1550_state *s)
598{
599 struct dmabuf *db = &s->dma_adc;
600 int i;
601
602 if (!db->stopped)
603 return;
604
605 /* Put two buffers on the ring to get things started.
606 */
607 for (i=0; i<2; i++) {
608 au1xxx_dbdma_put_dest(db->dmanr, virt_to_phys(db->nextIn),
609 db->dma_fragsize, DDMA_FLAGS_IE);
610
611 db->nextIn += db->dma_fragsize;
612 if (db->nextIn >= db->rawbuf + db->dmasize)
613 db->nextIn -= db->dmasize;
614 }
615
616 set_recv_slots(db->num_channels);
617 au1xxx_dbdma_start(db->dmanr);
618 au_writel(PSC_AC97PCR_RC, PSC_AC97PCR);
619 au_sync();
620 au_writel(PSC_AC97PCR_RS, PSC_AC97PCR);
621 au_sync();
622
623 db->stopped = 0;
624}
625
626static int
627prog_dmabuf(struct au1550_state *s, struct dmabuf *db)
628{
629 unsigned user_bytes_per_sec;
630 unsigned bufs;
631 unsigned rate = db->sample_rate;
632
633 if (!db->rawbuf) {
634 db->ready = db->mapped = 0;
635 db->buforder = 5; /* 32 * PAGE_SIZE */
636 db->rawbuf = kmalloc((PAGE_SIZE << db->buforder), GFP_KERNEL);
637 if (!db->rawbuf)
638 return -ENOMEM;
639 }
640
641 db->cnt_factor = 1;
642 if (db->sample_size == 8)
643 db->cnt_factor *= 2;
644 if (db->num_channels == 1)
645 db->cnt_factor *= 2;
646 db->cnt_factor *= db->src_factor;
647
648 db->count = 0;
649 db->dma_qcount = 0;
650 db->nextIn = db->nextOut = db->rawbuf;
651
652 db->user_bytes_per_sample = (db->sample_size>>3) * db->num_channels;
653 db->dma_bytes_per_sample = 2 * ((db->num_channels == 1) ?
654 2 : db->num_channels);
655
656 user_bytes_per_sec = rate * db->user_bytes_per_sample;
657 bufs = PAGE_SIZE << db->buforder;
658 if (db->ossfragshift) {
659 if ((1000 << db->ossfragshift) < user_bytes_per_sec)
660 db->fragshift = ld2(user_bytes_per_sec/1000);
661 else
662 db->fragshift = db->ossfragshift;
663 } else {
664 db->fragshift = ld2(user_bytes_per_sec / 100 /
665 (db->subdivision ? db->subdivision : 1));
666 if (db->fragshift < 3)
667 db->fragshift = 3;
668 }
669
670 db->fragsize = 1 << db->fragshift;
671 db->dma_fragsize = db->fragsize * db->cnt_factor;
672 db->numfrag = bufs / db->dma_fragsize;
673
674 while (db->numfrag < 4 && db->fragshift > 3) {
675 db->fragshift--;
676 db->fragsize = 1 << db->fragshift;
677 db->dma_fragsize = db->fragsize * db->cnt_factor;
678 db->numfrag = bufs / db->dma_fragsize;
679 }
680
681 if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
682 db->numfrag = db->ossmaxfrags;
683
684 db->dmasize = db->dma_fragsize * db->numfrag;
685 memset(db->rawbuf, 0, bufs);
686
687 pr_debug("prog_dmabuf: rate=%d, samplesize=%d, channels=%d\n",
688 rate, db->sample_size, db->num_channels);
689 pr_debug("prog_dmabuf: fragsize=%d, cnt_factor=%d, dma_fragsize=%d\n",
690 db->fragsize, db->cnt_factor, db->dma_fragsize);
691 pr_debug("prog_dmabuf: numfrag=%d, dmasize=%d\n", db->numfrag, db->dmasize);
692
693 db->ready = 1;
694 return 0;
695}
696
697static int
698prog_dmabuf_adc(struct au1550_state *s)
699{
700 stop_adc(s);
701 return prog_dmabuf(s, &s->dma_adc);
702
703}
704
705static int
706prog_dmabuf_dac(struct au1550_state *s)
707{
708 stop_dac(s);
709 return prog_dmabuf(s, &s->dma_dac);
710}
711
712
713static void dac_dma_interrupt(int irq, void *dev_id)
714{
715 struct au1550_state *s = (struct au1550_state *) dev_id;
716 struct dmabuf *db = &s->dma_dac;
717 u32 ac97c_stat;
718
719 spin_lock(&s->lock);
720
721 ac97c_stat = au_readl(PSC_AC97STAT);
722 if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE))
723 pr_debug("AC97C status = 0x%08x\n", ac97c_stat);
724 db->dma_qcount--;
725
726 if (db->count >= db->fragsize) {
727 if (au1xxx_dbdma_put_source(db->dmanr,
728 virt_to_phys(db->nextOut), db->fragsize,
729 DDMA_FLAGS_IE) == 0) {
730 err("qcount < 2 and no ring room!");
731 }
732 db->nextOut += db->fragsize;
733 if (db->nextOut >= db->rawbuf + db->dmasize)
734 db->nextOut -= db->dmasize;
735 db->count -= db->fragsize;
736 db->total_bytes += db->dma_fragsize;
737 db->dma_qcount++;
738 }
739
740 /* wake up anybody listening */
741 if (waitqueue_active(&db->wait))
742 wake_up(&db->wait);
743
744 spin_unlock(&s->lock);
745}
746
747
748static void adc_dma_interrupt(int irq, void *dev_id)
749{
750 struct au1550_state *s = (struct au1550_state *)dev_id;
751 struct dmabuf *dp = &s->dma_adc;
752 u32 obytes;
753 char *obuf;
754
755 spin_lock(&s->lock);
756
757 /* Pull the buffer from the dma queue.
758 */
759 au1xxx_dbdma_get_dest(dp->dmanr, (void *)(&obuf), &obytes);
760
761 if ((dp->count + obytes) > dp->dmasize) {
762 /* Overrun. Stop ADC and log the error
763 */
764 spin_unlock(&s->lock);
765 stop_adc(s);
766 dp->error++;
767 err("adc overrun");
768 return;
769 }
770
771 /* Put a new empty buffer on the destination DMA.
772 */
773 au1xxx_dbdma_put_dest(dp->dmanr, virt_to_phys(dp->nextIn),
774 dp->dma_fragsize, DDMA_FLAGS_IE);
775
776 dp->nextIn += dp->dma_fragsize;
777 if (dp->nextIn >= dp->rawbuf + dp->dmasize)
778 dp->nextIn -= dp->dmasize;
779
780 dp->count += obytes;
781 dp->total_bytes += obytes;
782
783 /* wake up anybody listening
784 */
785 if (waitqueue_active(&dp->wait))
786 wake_up(&dp->wait);
787
788 spin_unlock(&s->lock);
789}
790
791static loff_t
792au1550_llseek(struct file *file, loff_t offset, int origin)
793{
794 return -ESPIPE;
795}
796
797
798static int
799au1550_open_mixdev(struct inode *inode, struct file *file)
800{
801 mutex_lock(&au1550_ac97_mutex);
802 file->private_data = &au1550_state;
803 mutex_unlock(&au1550_ac97_mutex);
804 return 0;
805}
806
807static int
808au1550_release_mixdev(struct inode *inode, struct file *file)
809{
810 return 0;
811}
812
813static int
814mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
815 unsigned long arg)
816{
817 return codec->mixer_ioctl(codec, cmd, arg);
818}
819
820static long
821au1550_ioctl_mixdev(struct file *file, unsigned int cmd, unsigned long arg)
822{
823 struct au1550_state *s = file->private_data;
824 struct ac97_codec *codec = s->codec;
825 int ret;
826
827 mutex_lock(&au1550_ac97_mutex);
828 ret = mixdev_ioctl(codec, cmd, arg);
829 mutex_unlock(&au1550_ac97_mutex);
830
831 return ret;
832}
833
834static /*const */ struct file_operations au1550_mixer_fops = {
835 .owner = THIS_MODULE,
836 .llseek = au1550_llseek,
837 .unlocked_ioctl = au1550_ioctl_mixdev,
838 .open = au1550_open_mixdev,
839 .release = au1550_release_mixdev,
840};
841
842static int
843drain_dac(struct au1550_state *s, int nonblock)
844{
845 unsigned long flags;
846 int count, tmo;
847
848 if (s->dma_dac.mapped || !s->dma_dac.ready || s->dma_dac.stopped)
849 return 0;
850
851 for (;;) {
852 spin_lock_irqsave(&s->lock, flags);
853 count = s->dma_dac.count;
854 spin_unlock_irqrestore(&s->lock, flags);
855 if (count <= s->dma_dac.fragsize)
856 break;
857 if (signal_pending(current))
858 break;
859 if (nonblock)
860 return -EBUSY;
861 tmo = 1000 * count / (s->no_vra ?
862 48000 : s->dma_dac.sample_rate);
863 tmo /= s->dma_dac.dma_bytes_per_sample;
864 au1550_delay(tmo);
865 }
866 if (signal_pending(current))
867 return -ERESTARTSYS;
868 return 0;
869}
870
871static inline u8 S16_TO_U8(s16 ch)
872{
873 return (u8) (ch >> 8) + 0x80;
874}
875static inline s16 U8_TO_S16(u8 ch)
876{
877 return (s16) (ch - 0x80) << 8;
878}
879
880/*
881 * Translates user samples to dma buffer suitable for AC'97 DAC data:
882 * If mono, copy left channel to right channel in dma buffer.
883 * If 8 bit samples, cvt to 16-bit before writing to dma buffer.
884 * If interpolating (no VRA), duplicate every audio frame src_factor times.
885 */
886static int
887translate_from_user(struct dmabuf *db, char* dmabuf, char* userbuf,
888 int dmacount)
889{
890 int sample, i;
891 int interp_bytes_per_sample;
892 int num_samples;
893 int mono = (db->num_channels == 1);
894 char usersample[12];
895 s16 ch, dmasample[6];
896
897 if (db->sample_size == 16 && !mono && db->src_factor == 1) {
898 /* no translation necessary, just copy
899 */
900 if (copy_from_user(dmabuf, userbuf, dmacount))
901 return -EFAULT;
902 return dmacount;
903 }
904
905 interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
906 num_samples = dmacount / interp_bytes_per_sample;
907
908 for (sample = 0; sample < num_samples; sample++) {
909 if (copy_from_user(usersample, userbuf,
910 db->user_bytes_per_sample)) {
911 return -EFAULT;
912 }
913
914 for (i = 0; i < db->num_channels; i++) {
915 if (db->sample_size == 8)
916 ch = U8_TO_S16(usersample[i]);
917 else
918 ch = *((s16 *) (&usersample[i * 2]));
919 dmasample[i] = ch;
920 if (mono)
921 dmasample[i + 1] = ch; /* right channel */
922 }
923
924 /* duplicate every audio frame src_factor times
925 */
926 for (i = 0; i < db->src_factor; i++)
927 memcpy(dmabuf, dmasample, db->dma_bytes_per_sample);
928
929 userbuf += db->user_bytes_per_sample;
930 dmabuf += interp_bytes_per_sample;
931 }
932
933 return num_samples * interp_bytes_per_sample;
934}
935
936/*
937 * Translates AC'97 ADC samples to user buffer:
938 * If mono, send only left channel to user buffer.
939 * If 8 bit samples, cvt from 16 to 8 bit before writing to user buffer.
940 * If decimating (no VRA), skip over src_factor audio frames.
941 */
942static int
943translate_to_user(struct dmabuf *db, char* userbuf, char* dmabuf,
944 int dmacount)
945{
946 int sample, i;
947 int interp_bytes_per_sample;
948 int num_samples;
949 int mono = (db->num_channels == 1);
950 char usersample[12];
951
952 if (db->sample_size == 16 && !mono && db->src_factor == 1) {
953 /* no translation necessary, just copy
954 */
955 if (copy_to_user(userbuf, dmabuf, dmacount))
956 return -EFAULT;
957 return dmacount;
958 }
959
960 interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
961 num_samples = dmacount / interp_bytes_per_sample;
962
963 for (sample = 0; sample < num_samples; sample++) {
964 for (i = 0; i < db->num_channels; i++) {
965 if (db->sample_size == 8)
966 usersample[i] =
967 S16_TO_U8(*((s16 *) (&dmabuf[i * 2])));
968 else
969 *((s16 *) (&usersample[i * 2])) =
970 *((s16 *) (&dmabuf[i * 2]));
971 }
972
973 if (copy_to_user(userbuf, usersample,
974 db->user_bytes_per_sample)) {
975 return -EFAULT;
976 }
977
978 userbuf += db->user_bytes_per_sample;
979 dmabuf += interp_bytes_per_sample;
980 }
981
982 return num_samples * interp_bytes_per_sample;
983}
984
985/*
986 * Copy audio data to/from user buffer from/to dma buffer, taking care
987 * that we wrap when reading/writing the dma buffer. Returns actual byte
988 * count written to or read from the dma buffer.
989 */
990static int
991copy_dmabuf_user(struct dmabuf *db, char* userbuf, int count, int to_user)
992{
993 char *bufptr = to_user ? db->nextOut : db->nextIn;
994 char *bufend = db->rawbuf + db->dmasize;
995 int cnt, ret;
996
997 if (bufptr + count > bufend) {
998 int partial = (int) (bufend - bufptr);
999 if (to_user) {
1000 if ((cnt = translate_to_user(db, userbuf,
1001 bufptr, partial)) < 0)
1002 return cnt;
1003 ret = cnt;
1004 if ((cnt = translate_to_user(db, userbuf + partial,
1005 db->rawbuf,
1006 count - partial)) < 0)
1007 return cnt;
1008 ret += cnt;
1009 } else {
1010 if ((cnt = translate_from_user(db, bufptr, userbuf,
1011 partial)) < 0)
1012 return cnt;
1013 ret = cnt;
1014 if ((cnt = translate_from_user(db, db->rawbuf,
1015 userbuf + partial,
1016 count - partial)) < 0)
1017 return cnt;
1018 ret += cnt;
1019 }
1020 } else {
1021 if (to_user)
1022 ret = translate_to_user(db, userbuf, bufptr, count);
1023 else
1024 ret = translate_from_user(db, bufptr, userbuf, count);
1025 }
1026
1027 return ret;
1028}
1029
1030
1031static ssize_t
1032au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
1033{
1034 struct au1550_state *s = file->private_data;
1035 struct dmabuf *db = &s->dma_adc;
1036 DECLARE_WAITQUEUE(wait, current);
1037 ssize_t ret;
1038 unsigned long flags;
1039 int cnt, usercnt, avail;
1040
1041 if (db->mapped)
1042 return -ENXIO;
1043 if (!access_ok(VERIFY_WRITE, buffer, count))
1044 return -EFAULT;
1045 ret = 0;
1046
1047 count *= db->cnt_factor;
1048
1049 mutex_lock(&s->sem);
1050 add_wait_queue(&db->wait, &wait);
1051
1052 while (count > 0) {
1053 /* wait for samples in ADC dma buffer
1054 */
1055 do {
1056 spin_lock_irqsave(&s->lock, flags);
1057 if (db->stopped)
1058 start_adc(s);
1059 avail = db->count;
1060 if (avail <= 0)
1061 __set_current_state(TASK_INTERRUPTIBLE);
1062 spin_unlock_irqrestore(&s->lock, flags);
1063 if (avail <= 0) {
1064 if (file->f_flags & O_NONBLOCK) {
1065 if (!ret)
1066 ret = -EAGAIN;
1067 goto out;
1068 }
1069 mutex_unlock(&s->sem);
1070 schedule();
1071 if (signal_pending(current)) {
1072 if (!ret)
1073 ret = -ERESTARTSYS;
1074 goto out2;
1075 }
1076 mutex_lock(&s->sem);
1077 }
1078 } while (avail <= 0);
1079
1080 /* copy from nextOut to user
1081 */
1082 if ((cnt = copy_dmabuf_user(db, buffer,
1083 count > avail ?
1084 avail : count, 1)) < 0) {
1085 if (!ret)
1086 ret = -EFAULT;
1087 goto out;
1088 }
1089
1090 spin_lock_irqsave(&s->lock, flags);
1091 db->count -= cnt;
1092 db->nextOut += cnt;
1093 if (db->nextOut >= db->rawbuf + db->dmasize)
1094 db->nextOut -= db->dmasize;
1095 spin_unlock_irqrestore(&s->lock, flags);
1096
1097 count -= cnt;
1098 usercnt = cnt / db->cnt_factor;
1099 buffer += usercnt;
1100 ret += usercnt;
1101 } /* while (count > 0) */
1102
1103out:
1104 mutex_unlock(&s->sem);
1105out2:
1106 remove_wait_queue(&db->wait, &wait);
1107 set_current_state(TASK_RUNNING);
1108 return ret;
1109}
1110
1111static ssize_t
1112au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
1113{
1114 struct au1550_state *s = file->private_data;
1115 struct dmabuf *db = &s->dma_dac;
1116 DECLARE_WAITQUEUE(wait, current);
1117 ssize_t ret = 0;
1118 unsigned long flags;
1119 int cnt, usercnt, avail;
1120
1121 pr_debug("write: count=%d\n", count);
1122
1123 if (db->mapped)
1124 return -ENXIO;
1125 if (!access_ok(VERIFY_READ, buffer, count))
1126 return -EFAULT;
1127
1128 count *= db->cnt_factor;
1129
1130 mutex_lock(&s->sem);
1131 add_wait_queue(&db->wait, &wait);
1132
1133 while (count > 0) {
1134 /* wait for space in playback buffer
1135 */
1136 do {
1137 spin_lock_irqsave(&s->lock, flags);
1138 avail = (int) db->dmasize - db->count;
1139 if (avail <= 0)
1140 __set_current_state(TASK_INTERRUPTIBLE);
1141 spin_unlock_irqrestore(&s->lock, flags);
1142 if (avail <= 0) {
1143 if (file->f_flags & O_NONBLOCK) {
1144 if (!ret)
1145 ret = -EAGAIN;
1146 goto out;
1147 }
1148 mutex_unlock(&s->sem);
1149 schedule();
1150 if (signal_pending(current)) {
1151 if (!ret)
1152 ret = -ERESTARTSYS;
1153 goto out2;
1154 }
1155 mutex_lock(&s->sem);
1156 }
1157 } while (avail <= 0);
1158
1159 /* copy from user to nextIn
1160 */
1161 if ((cnt = copy_dmabuf_user(db, (char *) buffer,
1162 count > avail ?
1163 avail : count, 0)) < 0) {
1164 if (!ret)
1165 ret = -EFAULT;
1166 goto out;
1167 }
1168
1169 spin_lock_irqsave(&s->lock, flags);
1170 db->count += cnt;
1171 db->nextIn += cnt;
1172 if (db->nextIn >= db->rawbuf + db->dmasize)
1173 db->nextIn -= db->dmasize;
1174
1175 /* If the data is available, we want to keep two buffers
1176 * on the dma queue. If the queue count reaches zero,
1177 * we know the dma has stopped.
1178 */
1179 while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) {
1180 if (au1xxx_dbdma_put_source(db->dmanr,
1181 virt_to_phys(db->nextOut), db->fragsize,
1182 DDMA_FLAGS_IE) == 0) {
1183 err("qcount < 2 and no ring room!");
1184 }
1185 db->nextOut += db->fragsize;
1186 if (db->nextOut >= db->rawbuf + db->dmasize)
1187 db->nextOut -= db->dmasize;
1188 db->total_bytes += db->dma_fragsize;
1189 if (db->dma_qcount == 0)
1190 start_dac(s);
1191 db->dma_qcount++;
1192 }
1193 spin_unlock_irqrestore(&s->lock, flags);
1194
1195 count -= cnt;
1196 usercnt = cnt / db->cnt_factor;
1197 buffer += usercnt;
1198 ret += usercnt;
1199 } /* while (count > 0) */
1200
1201out:
1202 mutex_unlock(&s->sem);
1203out2:
1204 remove_wait_queue(&db->wait, &wait);
1205 set_current_state(TASK_RUNNING);
1206 return ret;
1207}
1208
1209
1210/* No kernel lock - we have our own spinlock */
1211static unsigned int
1212au1550_poll(struct file *file, struct poll_table_struct *wait)
1213{
1214 struct au1550_state *s = file->private_data;
1215 unsigned long flags;
1216 unsigned int mask = 0;
1217
1218 if (file->f_mode & FMODE_WRITE) {
1219 if (!s->dma_dac.ready)
1220 return 0;
1221 poll_wait(file, &s->dma_dac.wait, wait);
1222 }
1223 if (file->f_mode & FMODE_READ) {
1224 if (!s->dma_adc.ready)
1225 return 0;
1226 poll_wait(file, &s->dma_adc.wait, wait);
1227 }
1228
1229 spin_lock_irqsave(&s->lock, flags);
1230
1231 if (file->f_mode & FMODE_READ) {
1232 if (s->dma_adc.count >= (signed)s->dma_adc.dma_fragsize)
1233 mask |= POLLIN | POLLRDNORM;
1234 }
1235 if (file->f_mode & FMODE_WRITE) {
1236 if (s->dma_dac.mapped) {
1237 if (s->dma_dac.count >=
1238 (signed)s->dma_dac.dma_fragsize)
1239 mask |= POLLOUT | POLLWRNORM;
1240 } else {
1241 if ((signed) s->dma_dac.dmasize >=
1242 s->dma_dac.count + (signed)s->dma_dac.dma_fragsize)
1243 mask |= POLLOUT | POLLWRNORM;
1244 }
1245 }
1246 spin_unlock_irqrestore(&s->lock, flags);
1247 return mask;
1248}
1249
1250static int
1251au1550_mmap(struct file *file, struct vm_area_struct *vma)
1252{
1253 struct au1550_state *s = file->private_data;
1254 struct dmabuf *db;
1255 unsigned long size;
1256 int ret = 0;
1257
1258 mutex_lock(&au1550_ac97_mutex);
1259 mutex_lock(&s->sem);
1260 if (vma->vm_flags & VM_WRITE)
1261 db = &s->dma_dac;
1262 else if (vma->vm_flags & VM_READ)
1263 db = &s->dma_adc;
1264 else {
1265 ret = -EINVAL;
1266 goto out;
1267 }
1268 if (vma->vm_pgoff != 0) {
1269 ret = -EINVAL;
1270 goto out;
1271 }
1272 size = vma->vm_end - vma->vm_start;
1273 if (size > (PAGE_SIZE << db->buforder)) {
1274 ret = -EINVAL;
1275 goto out;
1276 }
1277 if (remap_pfn_range(vma, vma->vm_start, page_to_pfn(virt_to_page(db->rawbuf)),
1278 size, vma->vm_page_prot)) {
1279 ret = -EAGAIN;
1280 goto out;
1281 }
1282 vma->vm_flags &= ~VM_IO;
1283 db->mapped = 1;
1284out:
1285 mutex_unlock(&s->sem);
1286 mutex_unlock(&au1550_ac97_mutex);
1287 return ret;
1288}
1289
1290#ifdef DEBUG
1291static struct ioctl_str_t {
1292 unsigned int cmd;
1293 const char *str;
1294} ioctl_str[] = {
1295 {SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
1296 {SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
1297 {SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
1298 {SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
1299 {SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
1300 {SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
1301 {SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
1302 {SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
1303 {SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
1304 {SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
1305 {SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
1306 {SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
1307 {SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
1308 {SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
1309 {SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
1310 {SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
1311 {SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
1312 {SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
1313 {SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
1314 {SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
1315 {SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
1316 {SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
1317 {SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
1318 {SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
1319 {SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
1320 {SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
1321 {SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
1322 {SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
1323 {SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
1324 {OSS_GETVERSION, "OSS_GETVERSION"},
1325 {SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
1326 {SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
1327 {SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
1328 {SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
1329};
1330#endif
1331
1332static int
1333dma_count_done(struct dmabuf *db)
1334{
1335 if (db->stopped)
1336 return 0;
1337
1338 return db->dma_fragsize - au1xxx_get_dma_residue(db->dmanr);
1339}
1340
1341
1342static int
1343au1550_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1344{
1345 struct au1550_state *s = file->private_data;
1346 unsigned long flags;
1347 audio_buf_info abinfo;
1348 count_info cinfo;
1349 int count;
1350 int val, mapped, ret, diff;
1351
1352 mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
1353 ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
1354
1355#ifdef DEBUG
1356 for (count = 0; count < ARRAY_SIZE(ioctl_str); count++) {
1357 if (ioctl_str[count].cmd == cmd)
1358 break;
1359 }
1360 if (count < ARRAY_SIZE(ioctl_str))
1361 pr_debug("ioctl %s, arg=0x%lxn", ioctl_str[count].str, arg);
1362 else
1363 pr_debug("ioctl 0x%x unknown, arg=0x%lx\n", cmd, arg);
1364#endif
1365
1366 switch (cmd) {
1367 case OSS_GETVERSION:
1368 return put_user(SOUND_VERSION, (int *) arg);
1369
1370 case SNDCTL_DSP_SYNC:
1371 if (file->f_mode & FMODE_WRITE)
1372 return drain_dac(s, file->f_flags & O_NONBLOCK);
1373 return 0;
1374
1375 case SNDCTL_DSP_SETDUPLEX:
1376 return 0;
1377
1378 case SNDCTL_DSP_GETCAPS:
1379 return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
1380 DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
1381
1382 case SNDCTL_DSP_RESET:
1383 if (file->f_mode & FMODE_WRITE) {
1384 stop_dac(s);
1385 synchronize_irq();
1386 s->dma_dac.count = s->dma_dac.total_bytes = 0;
1387 s->dma_dac.nextIn = s->dma_dac.nextOut =
1388 s->dma_dac.rawbuf;
1389 }
1390 if (file->f_mode & FMODE_READ) {
1391 stop_adc(s);
1392 synchronize_irq();
1393 s->dma_adc.count = s->dma_adc.total_bytes = 0;
1394 s->dma_adc.nextIn = s->dma_adc.nextOut =
1395 s->dma_adc.rawbuf;
1396 }
1397 return 0;
1398
1399 case SNDCTL_DSP_SPEED:
1400 if (get_user(val, (int *) arg))
1401 return -EFAULT;
1402 if (val >= 0) {
1403 if (file->f_mode & FMODE_READ) {
1404 stop_adc(s);
1405 set_adc_rate(s, val);
1406 }
1407 if (file->f_mode & FMODE_WRITE) {
1408 stop_dac(s);
1409 set_dac_rate(s, val);
1410 }
1411 if (s->open_mode & FMODE_READ)
1412 if ((ret = prog_dmabuf_adc(s)))
1413 return ret;
1414 if (s->open_mode & FMODE_WRITE)
1415 if ((ret = prog_dmabuf_dac(s)))
1416 return ret;
1417 }
1418 return put_user((file->f_mode & FMODE_READ) ?
1419 s->dma_adc.sample_rate :
1420 s->dma_dac.sample_rate,
1421 (int *)arg);
1422
1423 case SNDCTL_DSP_STEREO:
1424 if (get_user(val, (int *) arg))
1425 return -EFAULT;
1426 if (file->f_mode & FMODE_READ) {
1427 stop_adc(s);
1428 s->dma_adc.num_channels = val ? 2 : 1;
1429 if ((ret = prog_dmabuf_adc(s)))
1430 return ret;
1431 }
1432 if (file->f_mode & FMODE_WRITE) {
1433 stop_dac(s);
1434 s->dma_dac.num_channels = val ? 2 : 1;
1435 if (s->codec_ext_caps & AC97_EXT_DACS) {
1436 /* disable surround and center/lfe in AC'97
1437 */
1438 u16 ext_stat = rdcodec(s->codec,
1439 AC97_EXTENDED_STATUS);
1440 wrcodec(s->codec, AC97_EXTENDED_STATUS,
1441 ext_stat | (AC97_EXTSTAT_PRI |
1442 AC97_EXTSTAT_PRJ |
1443 AC97_EXTSTAT_PRK));
1444 }
1445 if ((ret = prog_dmabuf_dac(s)))
1446 return ret;
1447 }
1448 return 0;
1449
1450 case SNDCTL_DSP_CHANNELS:
1451 if (get_user(val, (int *) arg))
1452 return -EFAULT;
1453 if (val != 0) {
1454 if (file->f_mode & FMODE_READ) {
1455 if (val < 0 || val > 2)
1456 return -EINVAL;
1457 stop_adc(s);
1458 s->dma_adc.num_channels = val;
1459 if ((ret = prog_dmabuf_adc(s)))
1460 return ret;
1461 }
1462 if (file->f_mode & FMODE_WRITE) {
1463 switch (val) {
1464 case 1:
1465 case 2:
1466 break;
1467 case 3:
1468 case 5:
1469 return -EINVAL;
1470 case 4:
1471 if (!(s->codec_ext_caps &
1472 AC97_EXTID_SDAC))
1473 return -EINVAL;
1474 break;
1475 case 6:
1476 if ((s->codec_ext_caps &
1477 AC97_EXT_DACS) != AC97_EXT_DACS)
1478 return -EINVAL;
1479 break;
1480 default:
1481 return -EINVAL;
1482 }
1483
1484 stop_dac(s);
1485 if (val <= 2 &&
1486 (s->codec_ext_caps & AC97_EXT_DACS)) {
1487 /* disable surround and center/lfe
1488 * channels in AC'97
1489 */
1490 u16 ext_stat =
1491 rdcodec(s->codec,
1492 AC97_EXTENDED_STATUS);
1493 wrcodec(s->codec,
1494 AC97_EXTENDED_STATUS,
1495 ext_stat | (AC97_EXTSTAT_PRI |
1496 AC97_EXTSTAT_PRJ |
1497 AC97_EXTSTAT_PRK));
1498 } else if (val >= 4) {
1499 /* enable surround, center/lfe
1500 * channels in AC'97
1501 */
1502 u16 ext_stat =
1503 rdcodec(s->codec,
1504 AC97_EXTENDED_STATUS);
1505 ext_stat &= ~AC97_EXTSTAT_PRJ;
1506 if (val == 6)
1507 ext_stat &=
1508 ~(AC97_EXTSTAT_PRI |
1509 AC97_EXTSTAT_PRK);
1510 wrcodec(s->codec,
1511 AC97_EXTENDED_STATUS,
1512 ext_stat);
1513 }
1514
1515 s->dma_dac.num_channels = val;
1516 if ((ret = prog_dmabuf_dac(s)))
1517 return ret;
1518 }
1519 }
1520 return put_user(val, (int *) arg);
1521
1522 case SNDCTL_DSP_GETFMTS: /* Returns a mask */
1523 return put_user(AFMT_S16_LE | AFMT_U8, (int *) arg);
1524
1525 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
1526 if (get_user(val, (int *) arg))
1527 return -EFAULT;
1528 if (val != AFMT_QUERY) {
1529 if (file->f_mode & FMODE_READ) {
1530 stop_adc(s);
1531 if (val == AFMT_S16_LE)
1532 s->dma_adc.sample_size = 16;
1533 else {
1534 val = AFMT_U8;
1535 s->dma_adc.sample_size = 8;
1536 }
1537 if ((ret = prog_dmabuf_adc(s)))
1538 return ret;
1539 }
1540 if (file->f_mode & FMODE_WRITE) {
1541 stop_dac(s);
1542 if (val == AFMT_S16_LE)
1543 s->dma_dac.sample_size = 16;
1544 else {
1545 val = AFMT_U8;
1546 s->dma_dac.sample_size = 8;
1547 }
1548 if ((ret = prog_dmabuf_dac(s)))
1549 return ret;
1550 }
1551 } else {
1552 if (file->f_mode & FMODE_READ)
1553 val = (s->dma_adc.sample_size == 16) ?
1554 AFMT_S16_LE : AFMT_U8;
1555 else
1556 val = (s->dma_dac.sample_size == 16) ?
1557 AFMT_S16_LE : AFMT_U8;
1558 }
1559 return put_user(val, (int *) arg);
1560
1561 case SNDCTL_DSP_POST:
1562 return 0;
1563
1564 case SNDCTL_DSP_GETTRIGGER:
1565 val = 0;
1566 spin_lock_irqsave(&s->lock, flags);
1567 if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
1568 val |= PCM_ENABLE_INPUT;
1569 if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
1570 val |= PCM_ENABLE_OUTPUT;
1571 spin_unlock_irqrestore(&s->lock, flags);
1572 return put_user(val, (int *) arg);
1573
1574 case SNDCTL_DSP_SETTRIGGER:
1575 if (get_user(val, (int *) arg))
1576 return -EFAULT;
1577 if (file->f_mode & FMODE_READ) {
1578 if (val & PCM_ENABLE_INPUT) {
1579 spin_lock_irqsave(&s->lock, flags);
1580 start_adc(s);
1581 spin_unlock_irqrestore(&s->lock, flags);
1582 } else
1583 stop_adc(s);
1584 }
1585 if (file->f_mode & FMODE_WRITE) {
1586 if (val & PCM_ENABLE_OUTPUT) {
1587 spin_lock_irqsave(&s->lock, flags);
1588 start_dac(s);
1589 spin_unlock_irqrestore(&s->lock, flags);
1590 } else
1591 stop_dac(s);
1592 }
1593 return 0;
1594
1595 case SNDCTL_DSP_GETOSPACE:
1596 if (!(file->f_mode & FMODE_WRITE))
1597 return -EINVAL;
1598 abinfo.fragsize = s->dma_dac.fragsize;
1599 spin_lock_irqsave(&s->lock, flags);
1600 count = s->dma_dac.count;
1601 count -= dma_count_done(&s->dma_dac);
1602 spin_unlock_irqrestore(&s->lock, flags);
1603 if (count < 0)
1604 count = 0;
1605 abinfo.bytes = (s->dma_dac.dmasize - count) /
1606 s->dma_dac.cnt_factor;
1607 abinfo.fragstotal = s->dma_dac.numfrag;
1608 abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
1609 pr_debug("ioctl SNDCTL_DSP_GETOSPACE: bytes=%d, fragments=%d\n", abinfo.bytes, abinfo.fragments);
1610 return copy_to_user((void *) arg, &abinfo,
1611 sizeof(abinfo)) ? -EFAULT : 0;
1612
1613 case SNDCTL_DSP_GETISPACE:
1614 if (!(file->f_mode & FMODE_READ))
1615 return -EINVAL;
1616 abinfo.fragsize = s->dma_adc.fragsize;
1617 spin_lock_irqsave(&s->lock, flags);
1618 count = s->dma_adc.count;
1619 count += dma_count_done(&s->dma_adc);
1620 spin_unlock_irqrestore(&s->lock, flags);
1621 if (count < 0)
1622 count = 0;
1623 abinfo.bytes = count / s->dma_adc.cnt_factor;
1624 abinfo.fragstotal = s->dma_adc.numfrag;
1625 abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
1626 return copy_to_user((void *) arg, &abinfo,
1627 sizeof(abinfo)) ? -EFAULT : 0;
1628
1629 case SNDCTL_DSP_NONBLOCK:
1630 spin_lock(&file->f_lock);
1631 file->f_flags |= O_NONBLOCK;
1632 spin_unlock(&file->f_lock);
1633 return 0;
1634
1635 case SNDCTL_DSP_GETODELAY:
1636 if (!(file->f_mode & FMODE_WRITE))
1637 return -EINVAL;
1638 spin_lock_irqsave(&s->lock, flags);
1639 count = s->dma_dac.count;
1640 count -= dma_count_done(&s->dma_dac);
1641 spin_unlock_irqrestore(&s->lock, flags);
1642 if (count < 0)
1643 count = 0;
1644 count /= s->dma_dac.cnt_factor;
1645 return put_user(count, (int *) arg);
1646
1647 case SNDCTL_DSP_GETIPTR:
1648 if (!(file->f_mode & FMODE_READ))
1649 return -EINVAL;
1650 spin_lock_irqsave(&s->lock, flags);
1651 cinfo.bytes = s->dma_adc.total_bytes;
1652 count = s->dma_adc.count;
1653 if (!s->dma_adc.stopped) {
1654 diff = dma_count_done(&s->dma_adc);
1655 count += diff;
1656 cinfo.bytes += diff;
1657 cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) + diff -
1658 virt_to_phys(s->dma_adc.rawbuf);
1659 } else
1660 cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) -
1661 virt_to_phys(s->dma_adc.rawbuf);
1662 if (s->dma_adc.mapped)
1663 s->dma_adc.count &= (s->dma_adc.dma_fragsize-1);
1664 spin_unlock_irqrestore(&s->lock, flags);
1665 if (count < 0)
1666 count = 0;
1667 cinfo.blocks = count >> s->dma_adc.fragshift;
1668 return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
1669
1670 case SNDCTL_DSP_GETOPTR:
1671 if (!(file->f_mode & FMODE_READ))
1672 return -EINVAL;
1673 spin_lock_irqsave(&s->lock, flags);
1674 cinfo.bytes = s->dma_dac.total_bytes;
1675 count = s->dma_dac.count;
1676 if (!s->dma_dac.stopped) {
1677 diff = dma_count_done(&s->dma_dac);
1678 count -= diff;
1679 cinfo.bytes += diff;
1680 cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) + diff -
1681 virt_to_phys(s->dma_dac.rawbuf);
1682 } else
1683 cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) -
1684 virt_to_phys(s->dma_dac.rawbuf);
1685 if (s->dma_dac.mapped)
1686 s->dma_dac.count &= (s->dma_dac.dma_fragsize-1);
1687 spin_unlock_irqrestore(&s->lock, flags);
1688 if (count < 0)
1689 count = 0;
1690 cinfo.blocks = count >> s->dma_dac.fragshift;
1691 return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
1692
1693 case SNDCTL_DSP_GETBLKSIZE:
1694 if (file->f_mode & FMODE_WRITE)
1695 return put_user(s->dma_dac.fragsize, (int *) arg);
1696 else
1697 return put_user(s->dma_adc.fragsize, (int *) arg);
1698
1699 case SNDCTL_DSP_SETFRAGMENT:
1700 if (get_user(val, (int *) arg))
1701 return -EFAULT;
1702 if (file->f_mode & FMODE_READ) {
1703 stop_adc(s);
1704 s->dma_adc.ossfragshift = val & 0xffff;
1705 s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
1706 if (s->dma_adc.ossfragshift < 4)
1707 s->dma_adc.ossfragshift = 4;
1708 if (s->dma_adc.ossfragshift > 15)
1709 s->dma_adc.ossfragshift = 15;
1710 if (s->dma_adc.ossmaxfrags < 4)
1711 s->dma_adc.ossmaxfrags = 4;
1712 if ((ret = prog_dmabuf_adc(s)))
1713 return ret;
1714 }
1715 if (file->f_mode & FMODE_WRITE) {
1716 stop_dac(s);
1717 s->dma_dac.ossfragshift = val & 0xffff;
1718 s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
1719 if (s->dma_dac.ossfragshift < 4)
1720 s->dma_dac.ossfragshift = 4;
1721 if (s->dma_dac.ossfragshift > 15)
1722 s->dma_dac.ossfragshift = 15;
1723 if (s->dma_dac.ossmaxfrags < 4)
1724 s->dma_dac.ossmaxfrags = 4;
1725 if ((ret = prog_dmabuf_dac(s)))
1726 return ret;
1727 }
1728 return 0;
1729
1730 case SNDCTL_DSP_SUBDIVIDE:
1731 if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
1732 (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
1733 return -EINVAL;
1734 if (get_user(val, (int *) arg))
1735 return -EFAULT;
1736 if (val != 1 && val != 2 && val != 4)
1737 return -EINVAL;
1738 if (file->f_mode & FMODE_READ) {
1739 stop_adc(s);
1740 s->dma_adc.subdivision = val;
1741 if ((ret = prog_dmabuf_adc(s)))
1742 return ret;
1743 }
1744 if (file->f_mode & FMODE_WRITE) {
1745 stop_dac(s);
1746 s->dma_dac.subdivision = val;
1747 if ((ret = prog_dmabuf_dac(s)))
1748 return ret;
1749 }
1750 return 0;
1751
1752 case SOUND_PCM_READ_RATE:
1753 return put_user((file->f_mode & FMODE_READ) ?
1754 s->dma_adc.sample_rate :
1755 s->dma_dac.sample_rate,
1756 (int *)arg);
1757
1758 case SOUND_PCM_READ_CHANNELS:
1759 if (file->f_mode & FMODE_READ)
1760 return put_user(s->dma_adc.num_channels, (int *)arg);
1761 else
1762 return put_user(s->dma_dac.num_channels, (int *)arg);
1763
1764 case SOUND_PCM_READ_BITS:
1765 if (file->f_mode & FMODE_READ)
1766 return put_user(s->dma_adc.sample_size, (int *)arg);
1767 else
1768 return put_user(s->dma_dac.sample_size, (int *)arg);
1769
1770 case SOUND_PCM_WRITE_FILTER:
1771 case SNDCTL_DSP_SETSYNCRO:
1772 case SOUND_PCM_READ_FILTER:
1773 return -EINVAL;
1774 }
1775
1776 return mixdev_ioctl(s->codec, cmd, arg);
1777}
1778
1779static long
1780au1550_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1781{
1782 int ret;
1783
1784 mutex_lock(&au1550_ac97_mutex);
1785 ret = au1550_ioctl(file, cmd, arg);
1786 mutex_unlock(&au1550_ac97_mutex);
1787
1788 return ret;
1789}
1790
1791static int
1792au1550_open(struct inode *inode, struct file *file)
1793{
1794 int minor = MINOR(inode->i_rdev);
1795 DECLARE_WAITQUEUE(wait, current);
1796 struct au1550_state *s = &au1550_state;
1797 int ret;
1798
1799#ifdef DEBUG
1800 if (file->f_flags & O_NONBLOCK)
1801 pr_debug("open: non-blocking\n");
1802 else
1803 pr_debug("open: blocking\n");
1804#endif
1805
1806 file->private_data = s;
1807 mutex_lock(&au1550_ac97_mutex);
1808 /* wait for device to become free */
1809 mutex_lock(&s->open_mutex);
1810 while (s->open_mode & file->f_mode) {
1811 ret = -EBUSY;
1812 if (file->f_flags & O_NONBLOCK)
1813 goto out;
1814 add_wait_queue(&s->open_wait, &wait);
1815 __set_current_state(TASK_INTERRUPTIBLE);
1816 mutex_unlock(&s->open_mutex);
1817 schedule();
1818 remove_wait_queue(&s->open_wait, &wait);
1819 set_current_state(TASK_RUNNING);
1820 ret = -ERESTARTSYS;
1821 if (signal_pending(current))
1822 goto out2;
1823 mutex_lock(&s->open_mutex);
1824 }
1825
1826 stop_dac(s);
1827 stop_adc(s);
1828
1829 if (file->f_mode & FMODE_READ) {
1830 s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
1831 s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
1832 s->dma_adc.num_channels = 1;
1833 s->dma_adc.sample_size = 8;
1834 set_adc_rate(s, 8000);
1835 if ((minor & 0xf) == SND_DEV_DSP16)
1836 s->dma_adc.sample_size = 16;
1837 }
1838
1839 if (file->f_mode & FMODE_WRITE) {
1840 s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
1841 s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
1842 s->dma_dac.num_channels = 1;
1843 s->dma_dac.sample_size = 8;
1844 set_dac_rate(s, 8000);
1845 if ((minor & 0xf) == SND_DEV_DSP16)
1846 s->dma_dac.sample_size = 16;
1847 }
1848
1849 if (file->f_mode & FMODE_READ) {
1850 if ((ret = prog_dmabuf_adc(s)))
1851 goto out;
1852 }
1853 if (file->f_mode & FMODE_WRITE) {
1854 if ((ret = prog_dmabuf_dac(s)))
1855 goto out;
1856 }
1857
1858 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
1859 mutex_init(&s->sem);
1860 ret = 0;
1861out:
1862 mutex_unlock(&s->open_mutex);
1863out2:
1864 mutex_unlock(&au1550_ac97_mutex);
1865 return ret;
1866}
1867
1868static int
1869au1550_release(struct inode *inode, struct file *file)
1870{
1871 struct au1550_state *s = file->private_data;
1872
1873 mutex_lock(&au1550_ac97_mutex);
1874
1875 if (file->f_mode & FMODE_WRITE) {
1876 mutex_unlock(&au1550_ac97_mutex);
1877 drain_dac(s, file->f_flags & O_NONBLOCK);
1878 mutex_lock(&au1550_ac97_mutex);
1879 }
1880
1881 mutex_lock(&s->open_mutex);
1882 if (file->f_mode & FMODE_WRITE) {
1883 stop_dac(s);
1884 kfree(s->dma_dac.rawbuf);
1885 s->dma_dac.rawbuf = NULL;
1886 }
1887 if (file->f_mode & FMODE_READ) {
1888 stop_adc(s);
1889 kfree(s->dma_adc.rawbuf);
1890 s->dma_adc.rawbuf = NULL;
1891 }
1892 s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
1893 mutex_unlock(&s->open_mutex);
1894 wake_up(&s->open_wait);
1895 mutex_unlock(&au1550_ac97_mutex);
1896 return 0;
1897}
1898
1899static /*const */ struct file_operations au1550_audio_fops = {
1900 .owner = THIS_MODULE,
1901 .llseek = au1550_llseek,
1902 .read = au1550_read,
1903 .write = au1550_write,
1904 .poll = au1550_poll,
1905 .unlocked_ioctl = au1550_unlocked_ioctl,
1906 .mmap = au1550_mmap,
1907 .open = au1550_open,
1908 .release = au1550_release,
1909};
1910
1911MODULE_AUTHOR("Advanced Micro Devices (AMD), dan@embeddededge.com");
1912MODULE_DESCRIPTION("Au1550 AC97 Audio Driver");
1913MODULE_LICENSE("GPL");
1914
1915
1916static int __devinit
1917au1550_probe(void)
1918{
1919 struct au1550_state *s = &au1550_state;
1920 int val;
1921
1922 memset(s, 0, sizeof(struct au1550_state));
1923
1924 init_waitqueue_head(&s->dma_adc.wait);
1925 init_waitqueue_head(&s->dma_dac.wait);
1926 init_waitqueue_head(&s->open_wait);
1927 mutex_init(&s->open_mutex);
1928 spin_lock_init(&s->lock);
1929
1930 s->codec = ac97_alloc_codec();
1931 if(s->codec == NULL) {
1932 err("Out of memory");
1933 return -1;
1934 }
1935 s->codec->private_data = s;
1936 s->codec->id = 0;
1937 s->codec->codec_read = rdcodec;
1938 s->codec->codec_write = wrcodec;
1939 s->codec->codec_wait = waitcodec;
1940
1941 if (!request_mem_region(CPHYSADDR(AC97_PSC_SEL),
1942 0x30, "Au1550 AC97")) {
1943 err("AC'97 ports in use");
1944 }
1945
1946 /* Allocate the DMA Channels
1947 */
1948 if ((s->dma_dac.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_MEM_CHAN,
1949 DBDMA_AC97_TX_CHAN, dac_dma_interrupt, (void *)s)) == 0) {
1950 err("Can't get DAC DMA");
1951 goto err_dma1;
1952 }
1953 au1xxx_dbdma_set_devwidth(s->dma_dac.dmanr, 16);
1954 if (au1xxx_dbdma_ring_alloc(s->dma_dac.dmanr,
1955 NUM_DBDMA_DESCRIPTORS) == 0) {
1956 err("Can't get DAC DMA descriptors");
1957 goto err_dma1;
1958 }
1959
1960 if ((s->dma_adc.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_AC97_RX_CHAN,
1961 DBDMA_MEM_CHAN, adc_dma_interrupt, (void *)s)) == 0) {
1962 err("Can't get ADC DMA");
1963 goto err_dma2;
1964 }
1965 au1xxx_dbdma_set_devwidth(s->dma_adc.dmanr, 16);
1966 if (au1xxx_dbdma_ring_alloc(s->dma_adc.dmanr,
1967 NUM_DBDMA_DESCRIPTORS) == 0) {
1968 err("Can't get ADC DMA descriptors");
1969 goto err_dma2;
1970 }
1971
1972 pr_info("DAC: DMA%d, ADC: DMA%d", DBDMA_AC97_TX_CHAN, DBDMA_AC97_RX_CHAN);
1973
1974 /* register devices */
1975
1976 if ((s->dev_audio = register_sound_dsp(&au1550_audio_fops, -1)) < 0)
1977 goto err_dev1;
1978 if ((s->codec->dev_mixer =
1979 register_sound_mixer(&au1550_mixer_fops, -1)) < 0)
1980 goto err_dev2;
1981
1982 /* The GPIO for the appropriate PSC was configured by the
1983 * board specific start up.
1984 *
1985 * configure PSC for AC'97
1986 */
1987 au_writel(0, AC97_PSC_CTRL); /* Disable PSC */
1988 au_sync();
1989 au_writel((PSC_SEL_CLK_SERCLK | PSC_SEL_PS_AC97MODE), AC97_PSC_SEL);
1990 au_sync();
1991
1992 /* cold reset the AC'97
1993 */
1994 au_writel(PSC_AC97RST_RST, PSC_AC97RST);
1995 au_sync();
1996 au1550_delay(10);
1997 au_writel(0, PSC_AC97RST);
1998 au_sync();
1999
2000 /* need to delay around 500msec(bleech) to give
2001 some CODECs enough time to wakeup */
2002 au1550_delay(500);
2003
2004 /* warm reset the AC'97 to start the bitclk
2005 */
2006 au_writel(PSC_AC97RST_SNC, PSC_AC97RST);
2007 au_sync();
2008 udelay(100);
2009 au_writel(0, PSC_AC97RST);
2010 au_sync();
2011
2012 /* Enable PSC
2013 */
2014 au_writel(PSC_CTRL_ENABLE, AC97_PSC_CTRL);
2015 au_sync();
2016
2017 /* Wait for PSC ready.
2018 */
2019 do {
2020 val = au_readl(PSC_AC97STAT);
2021 au_sync();
2022 } while ((val & PSC_AC97STAT_SR) == 0);
2023
2024 /* Configure AC97 controller.
2025 * Deep FIFO, 16-bit sample, DMA, make sure DMA matches fifo size.
2026 */
2027 val = PSC_AC97CFG_SET_LEN(16);
2028 val |= PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8;
2029
2030 /* Enable device so we can at least
2031 * talk over the AC-link.
2032 */
2033 au_writel(val, PSC_AC97CFG);
2034 au_writel(PSC_AC97MSK_ALLMASK, PSC_AC97MSK);
2035 au_sync();
2036 val |= PSC_AC97CFG_DE_ENABLE;
2037 au_writel(val, PSC_AC97CFG);
2038 au_sync();
2039
2040 /* Wait for Device ready.
2041 */
2042 do {
2043 val = au_readl(PSC_AC97STAT);
2044 au_sync();
2045 } while ((val & PSC_AC97STAT_DR) == 0);
2046
2047 /* codec init */
2048 if (!ac97_probe_codec(s->codec))
2049 goto err_dev3;
2050
2051 s->codec_base_caps = rdcodec(s->codec, AC97_RESET);
2052 s->codec_ext_caps = rdcodec(s->codec, AC97_EXTENDED_ID);
2053 pr_info("AC'97 Base/Extended ID = %04x/%04x",
2054 s->codec_base_caps, s->codec_ext_caps);
2055
2056 if (!(s->codec_ext_caps & AC97_EXTID_VRA)) {
2057 /* codec does not support VRA
2058 */
2059 s->no_vra = 1;
2060 } else if (!vra) {
2061 /* Boot option says disable VRA
2062 */
2063 u16 ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
2064 wrcodec(s->codec, AC97_EXTENDED_STATUS,
2065 ac97_extstat & ~AC97_EXTSTAT_VRA);
2066 s->no_vra = 1;
2067 }
2068 if (s->no_vra)
2069 pr_info("no VRA, interpolating and decimating");
2070
2071 /* set mic to be the recording source */
2072 val = SOUND_MASK_MIC;
2073 mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC,
2074 (unsigned long) &val);
2075
2076 return 0;
2077
2078 err_dev3:
2079 unregister_sound_mixer(s->codec->dev_mixer);
2080 err_dev2:
2081 unregister_sound_dsp(s->dev_audio);
2082 err_dev1:
2083 au1xxx_dbdma_chan_free(s->dma_adc.dmanr);
2084 err_dma2:
2085 au1xxx_dbdma_chan_free(s->dma_dac.dmanr);
2086 err_dma1:
2087 release_mem_region(CPHYSADDR(AC97_PSC_SEL), 0x30);
2088
2089 ac97_release_codec(s->codec);
2090 return -1;
2091}
2092
2093static void __devinit
2094au1550_remove(void)
2095{
2096 struct au1550_state *s = &au1550_state;
2097
2098 if (!s)
2099 return;
2100 synchronize_irq();
2101 au1xxx_dbdma_chan_free(s->dma_adc.dmanr);
2102 au1xxx_dbdma_chan_free(s->dma_dac.dmanr);
2103 release_mem_region(CPHYSADDR(AC97_PSC_SEL), 0x30);
2104 unregister_sound_dsp(s->dev_audio);
2105 unregister_sound_mixer(s->codec->dev_mixer);
2106 ac97_release_codec(s->codec);
2107}
2108
2109static int __init
2110init_au1550(void)
2111{
2112 return au1550_probe();
2113}
2114
2115static void __exit
2116cleanup_au1550(void)
2117{
2118 au1550_remove();
2119}
2120
2121module_init(init_au1550);
2122module_exit(cleanup_au1550);
2123
2124#ifndef MODULE
2125
2126static int __init
2127au1550_setup(char *options)
2128{
2129 char *this_opt;
2130
2131 if (!options || !*options)
2132 return 0;
2133
2134 while ((this_opt = strsep(&options, ","))) {
2135 if (!*this_opt)
2136 continue;
2137 if (!strncmp(this_opt, "vra", 3)) {
2138 vra = 1;
2139 }
2140 }
2141
2142 return 1;
2143}
2144
2145__setup("au1550_audio=", au1550_setup);
2146
2147#endif /* MODULE */
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 389cd7931668..e90d103e177e 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -534,6 +534,14 @@ config SND_ES1968_INPUT
534 If you say N the buttons will directly control the master volume. 534 If you say N the buttons will directly control the master volume.
535 It is recommended to say Y. 535 It is recommended to say Y.
536 536
537config SND_ES1968_RADIO
538 bool "Enable TEA5757 radio tuner support for es1968"
539 depends on SND_ES1968
540 depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_ES1968
541 help
542 Say Y here to include support for TEA5757 radio tuner integrated on
543 some MediaForte cards (e.g. SF64-PCE2).
544
537config SND_FM801 545config SND_FM801
538 tristate "ForteMedia FM801" 546 tristate "ForteMedia FM801"
539 select SND_OPL3_LIB 547 select SND_OPL3_LIB
@@ -552,13 +560,13 @@ config SND_FM801_TEA575X_BOOL
552 depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801 560 depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801
553 help 561 help
554 Say Y here to include support for soundcards based on the ForteMedia 562 Say Y here to include support for soundcards based on the ForteMedia
555 FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media 563 FM801 chip with a TEA5757 tuner (MediaForte SF256-PCS, SF256-PCP and
556 Forte SF256-PCS-02) into the snd-fm801 driver. 564 SF64-PCR) into the snd-fm801 driver.
557 565
558config SND_FM801_TEA575X 566config SND_TEA575X
559 tristate 567 tristate
560 depends on SND_FM801_TEA575X_BOOL 568 depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO
561 default SND_FM801 569 default SND_FM801 || SND_ES1968
562 570
563source "sound/pci/hda/Kconfig" 571source "sound/pci/hda/Kconfig"
564 572
@@ -658,6 +666,15 @@ config SND_KORG1212
658 To compile this driver as a module, choose M here: the module 666 To compile this driver as a module, choose M here: the module
659 will be called snd-korg1212. 667 will be called snd-korg1212.
660 668
669config SND_LOLA
670 tristate "Digigram Lola"
671 select SND_PCM
672 help
673 Say Y to include support for Digigram Lola boards.
674
675 To compile this driver as a module, choose M here: the module
676 will be called snd-lola.
677
661config SND_LX6464ES 678config SND_LX6464ES
662 tristate "Digigram LX6464ES" 679 tristate "Digigram LX6464ES"
663 select SND_PCM 680 select SND_PCM
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index 9cf4348ec137..54fe325e3aa5 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_SND) += \
64 ca0106/ \ 64 ca0106/ \
65 cs46xx/ \ 65 cs46xx/ \
66 cs5535audio/ \ 66 cs5535audio/ \
67 lola/ \
67 lx6464es/ \ 68 lx6464es/ \
68 echoaudio/ \ 69 echoaudio/ \
69 emu10k1/ \ 70 emu10k1/ \
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index f8ccc9677c6f..2ca6f4f85b41 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -42,10 +42,29 @@
42#include <sound/tlv.h> 42#include <sound/tlv.h>
43#include <sound/hwdep.h> 43#include <sound/hwdep.h>
44 44
45
45MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
46MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); 47MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
47MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); 48MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
48 49
50#if defined CONFIG_SND_DEBUG
51/* copied from pcm_lib.c, hope later patch will make that version public
52and this copy can be removed */
53static void pcm_debug_name(struct snd_pcm_substream *substream,
54 char *name, size_t len)
55{
56 snprintf(name, len, "pcmC%dD%d%c:%d",
57 substream->pcm->card->number,
58 substream->pcm->device,
59 substream->stream ? 'c' : 'p',
60 substream->number);
61}
62#define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name))
63#else
64#define pcm_debug_name(s, n, l) do { } while (0)
65#define DEBUG_NAME(name, substream) do { } while (0)
66#endif
67
49#if defined CONFIG_SND_DEBUG_VERBOSE 68#if defined CONFIG_SND_DEBUG_VERBOSE
50/** 69/**
51 * snd_printddd - very verbose debug printk 70 * snd_printddd - very verbose debug printk
@@ -58,7 +77,7 @@ MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
58#define snd_printddd(format, args...) \ 77#define snd_printddd(format, args...) \
59 __snd_printk(3, __FILE__, __LINE__, format, ##args) 78 __snd_printk(3, __FILE__, __LINE__, format, ##args)
60#else 79#else
61#define snd_printddd(format, args...) do { } while (0) 80#define snd_printddd(format, args...) do { } while (0)
62#endif 81#endif
63 82
64static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ 83static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */
@@ -101,13 +120,6 @@ static int adapter_fs = DEFAULT_SAMPLERATE;
101#define PERIOD_BYTES_MIN 2048 120#define PERIOD_BYTES_MIN 2048
102#define BUFFER_BYTES_MAX (512 * 1024) 121#define BUFFER_BYTES_MAX (512 * 1024)
103 122
104/* convert stream to character */
105#define SCHR(s) ((s == SNDRV_PCM_STREAM_PLAYBACK) ? 'P' : 'C')
106
107/*#define TIMER_MILLISECONDS 20
108#define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000)
109*/
110
111#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7) 123#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
112 124
113struct clk_source { 125struct clk_source {
@@ -136,7 +148,7 @@ struct snd_card_asihpi {
136 u32 h_mixer; 148 u32 h_mixer;
137 struct clk_cache cc; 149 struct clk_cache cc;
138 150
139 u16 support_mmap; 151 u16 can_dma;
140 u16 support_grouping; 152 u16 support_grouping;
141 u16 support_mrx; 153 u16 support_mrx;
142 u16 update_interval_frames; 154 u16 update_interval_frames;
@@ -155,6 +167,7 @@ struct snd_card_asihpi_pcm {
155 unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */ 167 unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */
156 unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */ 168 unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */
157 unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */ 169 unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */
170 unsigned int drained_count;
158 struct snd_pcm_substream *substream; 171 struct snd_pcm_substream *substream;
159 u32 h_stream; 172 u32 h_stream;
160 struct hpi_format format; 173 struct hpi_format format;
@@ -288,19 +301,26 @@ static u16 handle_error(u16 err, int line, char *filename)
288#define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__) 301#define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
289 302
290/***************************** GENERAL PCM ****************/ 303/***************************** GENERAL PCM ****************/
291static void print_hwparams(struct snd_pcm_hw_params *p) 304
305static void print_hwparams(struct snd_pcm_substream *substream,
306 struct snd_pcm_hw_params *p)
292{ 307{
293 snd_printd("HWPARAMS \n"); 308 DEBUG_NAME(substream, name);
294 snd_printd("samplerate %d \n", params_rate(p)); 309 snd_printd("%s HWPARAMS\n", name);
295 snd_printd("Channels %d \n", params_channels(p)); 310 snd_printd(" samplerate %d Hz\n", params_rate(p));
296 snd_printd("Format %d \n", params_format(p)); 311 snd_printd(" channels %d\n", params_channels(p));
297 snd_printd("subformat %d \n", params_subformat(p)); 312 snd_printd(" format %d\n", params_format(p));
298 snd_printd("Buffer bytes %d \n", params_buffer_bytes(p)); 313 snd_printd(" subformat %d\n", params_subformat(p));
299 snd_printd("Period bytes %d \n", params_period_bytes(p)); 314 snd_printd(" buffer %d B\n", params_buffer_bytes(p));
300 snd_printd("access %d \n", params_access(p)); 315 snd_printd(" period %d B\n", params_period_bytes(p));
301 snd_printd("period_size %d \n", params_period_size(p)); 316 snd_printd(" access %d\n", params_access(p));
302 snd_printd("periods %d \n", params_periods(p)); 317 snd_printd(" period_size %d\n", params_period_size(p));
303 snd_printd("buffer_size %d \n", params_buffer_size(p)); 318 snd_printd(" periods %d\n", params_periods(p));
319 snd_printd(" buffer_size %d\n", params_buffer_size(p));
320 snd_printd(" %d B/s\n", params_rate(p) *
321 params_channels(p) *
322 snd_pcm_format_width(params_format(p)) / 8);
323
304} 324}
305 325
306static snd_pcm_format_t hpi_to_alsa_formats[] = { 326static snd_pcm_format_t hpi_to_alsa_formats[] = {
@@ -451,7 +471,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
451 int width; 471 int width;
452 unsigned int bytes_per_sec; 472 unsigned int bytes_per_sec;
453 473
454 print_hwparams(params); 474 print_hwparams(substream, params);
455 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); 475 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
456 if (err < 0) 476 if (err < 0)
457 return err; 477 return err;
@@ -459,10 +479,6 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
459 if (err) 479 if (err)
460 return err; 480 return err;
461 481
462 snd_printdd("format %d, %d chans, %d_hz\n",
463 format, params_channels(params),
464 params_rate(params));
465
466 hpi_handle_error(hpi_format_create(&dpcm->format, 482 hpi_handle_error(hpi_format_create(&dpcm->format,
467 params_channels(params), 483 params_channels(params),
468 format, params_rate(params), 0, 0)); 484 format, params_rate(params), 0, 0));
@@ -477,8 +493,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
477 } 493 }
478 494
479 dpcm->hpi_buffer_attached = 0; 495 dpcm->hpi_buffer_attached = 0;
480 if (card->support_mmap) { 496 if (card->can_dma) {
481
482 err = hpi_stream_host_buffer_attach(dpcm->h_stream, 497 err = hpi_stream_host_buffer_attach(dpcm->h_stream,
483 params_buffer_bytes(params), runtime->dma_addr); 498 params_buffer_bytes(params), runtime->dma_addr);
484 if (err == 0) { 499 if (err == 0) {
@@ -509,8 +524,6 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
509 dpcm->bytes_per_sec = bytes_per_sec; 524 dpcm->bytes_per_sec = bytes_per_sec;
510 dpcm->buffer_bytes = params_buffer_bytes(params); 525 dpcm->buffer_bytes = params_buffer_bytes(params);
511 dpcm->period_bytes = params_period_bytes(params); 526 dpcm->period_bytes = params_period_bytes(params);
512 snd_printdd("buffer_bytes=%d, period_bytes=%d, bps=%d\n",
513 dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec);
514 527
515 return 0; 528 return 0;
516} 529}
@@ -564,9 +577,10 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
564 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); 577 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
565 struct snd_pcm_substream *s; 578 struct snd_pcm_substream *s;
566 u16 e; 579 u16 e;
580 DEBUG_NAME(substream, name);
581
582 snd_printdd("%s trigger\n", name);
567 583
568 snd_printdd("%c%d trigger\n",
569 SCHR(substream->stream), substream->number);
570 switch (cmd) { 584 switch (cmd) {
571 case SNDRV_PCM_TRIGGER_START: 585 case SNDRV_PCM_TRIGGER_START:
572 snd_pcm_group_for_each_entry(s, substream) { 586 snd_pcm_group_for_each_entry(s, substream) {
@@ -580,8 +594,8 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
580 if (substream->stream != s->stream) 594 if (substream->stream != s->stream)
581 continue; 595 continue;
582 596
583 if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) && 597 ds->drained_count = 0;
584 (card->support_mmap)) { 598 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
585 /* How do I know how much valid data is present 599 /* How do I know how much valid data is present
586 * in buffer? Must be at least one period! 600 * in buffer? Must be at least one period!
587 * Guessing 2 periods, but if 601 * Guessing 2 periods, but if
@@ -599,9 +613,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
599 } 613 }
600 614
601 if (card->support_grouping) { 615 if (card->support_grouping) {
602 snd_printdd("\t%c%d group\n", 616 snd_printdd("%d group\n", s->number);
603 SCHR(s->stream),
604 s->number);
605 e = hpi_stream_group_add( 617 e = hpi_stream_group_add(
606 dpcm->h_stream, 618 dpcm->h_stream,
607 ds->h_stream); 619 ds->h_stream);
@@ -618,7 +630,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
618 /* start the master stream */ 630 /* start the master stream */
619 snd_card_asihpi_pcm_timer_start(substream); 631 snd_card_asihpi_pcm_timer_start(substream);
620 if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || 632 if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ||
621 !card->support_mmap) 633 !card->can_dma)
622 hpi_handle_error(hpi_stream_start(dpcm->h_stream)); 634 hpi_handle_error(hpi_stream_start(dpcm->h_stream));
623 break; 635 break;
624 636
@@ -636,9 +648,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
636 s->runtime->status->state = SNDRV_PCM_STATE_SETUP; 648 s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
637 649
638 if (card->support_grouping) { 650 if (card->support_grouping) {
639 snd_printdd("\t%c%d group\n", 651 snd_printdd("%d group\n", s->number);
640 SCHR(s->stream),
641 s->number);
642 snd_pcm_trigger_done(s, substream); 652 snd_pcm_trigger_done(s, substream);
643 } else 653 } else
644 break; 654 break;
@@ -732,9 +742,9 @@ static void snd_card_asihpi_timer_function(unsigned long data)
732 int loops = 0; 742 int loops = 0;
733 u16 state; 743 u16 state;
734 u32 buffer_size, bytes_avail, samples_played, on_card_bytes; 744 u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
745 DEBUG_NAME(substream, name);
735 746
736 snd_printdd("%c%d snd_card_asihpi_timer_function\n", 747 snd_printdd("%s snd_card_asihpi_timer_function\n", name);
737 SCHR(substream->stream), substream->number);
738 748
739 /* find minimum newdata and buffer pos in group */ 749 /* find minimum newdata and buffer pos in group */
740 snd_pcm_group_for_each_entry(s, substream) { 750 snd_pcm_group_for_each_entry(s, substream) {
@@ -756,6 +766,9 @@ static void snd_card_asihpi_timer_function(unsigned long data)
756 /* number of bytes in on-card buffer */ 766 /* number of bytes in on-card buffer */
757 runtime->delay = on_card_bytes; 767 runtime->delay = on_card_bytes;
758 768
769 if (!card->can_dma)
770 on_card_bytes = bytes_avail;
771
759 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { 772 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
760 pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail; 773 pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
761 if (state == HPI_STATE_STOPPED) { 774 if (state == HPI_STATE_STOPPED) {
@@ -763,12 +776,18 @@ static void snd_card_asihpi_timer_function(unsigned long data)
763 (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { 776 (on_card_bytes < ds->pcm_buf_host_rw_ofs)) {
764 hpi_handle_error(hpi_stream_start(ds->h_stream)); 777 hpi_handle_error(hpi_stream_start(ds->h_stream));
765 snd_printdd("P%d start\n", s->number); 778 snd_printdd("P%d start\n", s->number);
779 ds->drained_count = 0;
766 } 780 }
767 } else if (state == HPI_STATE_DRAINED) { 781 } else if (state == HPI_STATE_DRAINED) {
768 snd_printd(KERN_WARNING "P%d drained\n", 782 snd_printd(KERN_WARNING "P%d drained\n",
769 s->number); 783 s->number);
770 /*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); 784 ds->drained_count++;
771 continue; */ 785 if (ds->drained_count > 2) {
786 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
787 continue;
788 }
789 } else {
790 ds->drained_count = 0;
772 } 791 }
773 } else 792 } else
774 pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs; 793 pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
@@ -786,16 +805,18 @@ static void snd_card_asihpi_timer_function(unsigned long data)
786 newdata); 805 newdata);
787 } 806 }
788 807
789 snd_printdd("hw_ptr x%04lX, appl_ptr x%04lX\n", 808 snd_printdd("hw_ptr 0x%04lX, appl_ptr 0x%04lX\n",
790 (unsigned long)frames_to_bytes(runtime, 809 (unsigned long)frames_to_bytes(runtime,
791 runtime->status->hw_ptr), 810 runtime->status->hw_ptr),
792 (unsigned long)frames_to_bytes(runtime, 811 (unsigned long)frames_to_bytes(runtime,
793 runtime->control->appl_ptr)); 812 runtime->control->appl_ptr));
794 813
795 snd_printdd("%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X," 814 snd_printdd("%d S=%d, "
796 " aux=x%04X space=x%04X\n", 815 "rw=0x%04X, dma=0x%04X, left=0x%04X, "
797 loops, SCHR(s->stream), s->number, 816 "aux=0x%04X space=0x%04X\n",
798 state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail, 817 s->number, state,
818 ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs,
819 (int)bytes_avail,
799 (int)on_card_bytes, buffer_size-bytes_avail); 820 (int)on_card_bytes, buffer_size-bytes_avail);
800 loops++; 821 loops++;
801 } 822 }
@@ -814,7 +835,7 @@ static void snd_card_asihpi_timer_function(unsigned long data)
814 835
815 next_jiffies = max(next_jiffies, 1U); 836 next_jiffies = max(next_jiffies, 1U);
816 dpcm->timer.expires = jiffies + next_jiffies; 837 dpcm->timer.expires = jiffies + next_jiffies;
817 snd_printdd("jif %d buf pos x%04X newdata x%04X xfer x%04X\n", 838 snd_printdd("jif %d buf pos 0x%04X newdata 0x%04X xfer 0x%04X\n",
818 next_jiffies, pcm_buf_dma_ofs, newdata, xfercount); 839 next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);
819 840
820 snd_pcm_group_for_each_entry(s, substream) { 841 snd_pcm_group_for_each_entry(s, substream) {
@@ -826,30 +847,63 @@ static void snd_card_asihpi_timer_function(unsigned long data)
826 847
827 ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs; 848 ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
828 849
829 if (xfercount && (on_card_bytes <= ds->period_bytes)) { 850 if (xfercount &&
830 if (card->support_mmap) { 851 /* Limit use of on card fifo for playback */
831 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { 852 ((on_card_bytes <= ds->period_bytes) ||
832 snd_printddd("P%d write x%04x\n", 853 (s->stream == SNDRV_PCM_STREAM_CAPTURE)))
854
855 {
856
857 unsigned int buf_ofs = ds->pcm_buf_host_rw_ofs % ds->buffer_bytes;
858 unsigned int xfer1, xfer2;
859 char *pd = &s->runtime->dma_area[buf_ofs];
860
861 if (card->can_dma) { /* buffer wrap is handled at lower level */
862 xfer1 = xfercount;
863 xfer2 = 0;
864 } else {
865 xfer1 = min(xfercount, ds->buffer_bytes - buf_ofs);
866 xfer2 = xfercount - xfer1;
867 }
868
869 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
870 snd_printddd("P%d write1 0x%04X 0x%04X\n",
871 s->number, xfer1, buf_ofs);
872 hpi_handle_error(
873 hpi_outstream_write_buf(
874 ds->h_stream, pd, xfer1,
875 &ds->format));
876
877 if (xfer2) {
878 pd = s->runtime->dma_area;
879
880 snd_printddd("P%d write2 0x%04X 0x%04X\n",
833 s->number, 881 s->number,
834 ds->period_bytes); 882 xfercount - xfer1, buf_ofs);
835 hpi_handle_error( 883 hpi_handle_error(
836 hpi_outstream_write_buf( 884 hpi_outstream_write_buf(
837 ds->h_stream, 885 ds->h_stream, pd,
838 &s->runtime-> 886 xfercount - xfer1,
839 dma_area[0],
840 xfercount,
841 &ds->format)); 887 &ds->format));
842 } else { 888 }
843 snd_printddd("C%d read x%04x\n", 889 } else {
844 s->number, 890 snd_printddd("C%d read1 0x%04x\n",
845 xfercount); 891 s->number, xfer1);
892 hpi_handle_error(
893 hpi_instream_read_buf(
894 ds->h_stream,
895 pd, xfer1));
896 if (xfer2) {
897 pd = s->runtime->dma_area;
898 snd_printddd("C%d read2 0x%04x\n",
899 s->number, xfer2);
846 hpi_handle_error( 900 hpi_handle_error(
847 hpi_instream_read_buf( 901 hpi_instream_read_buf(
848 ds->h_stream, 902 ds->h_stream,
849 NULL, xfercount)); 903 pd, xfer2));
850 } 904 }
851 ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount; 905 }
852 } /* else R/W will be handled by read/write callbacks */ 906 ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount;
853 ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs; 907 ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs;
854 snd_pcm_period_elapsed(s); 908 snd_pcm_period_elapsed(s);
855 } 909 }
@@ -863,7 +917,7 @@ static void snd_card_asihpi_timer_function(unsigned long data)
863static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, 917static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
864 unsigned int cmd, void *arg) 918 unsigned int cmd, void *arg)
865{ 919{
866 snd_printdd(KERN_INFO "Playback ioctl %d\n", cmd); 920 snd_printddd(KERN_INFO "P%d ioctl %d\n", substream->number, cmd);
867 return snd_pcm_lib_ioctl(substream, cmd, arg); 921 return snd_pcm_lib_ioctl(substream, cmd, arg);
868} 922}
869 923
@@ -873,7 +927,7 @@ static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
873 struct snd_pcm_runtime *runtime = substream->runtime; 927 struct snd_pcm_runtime *runtime = substream->runtime;
874 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 928 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
875 929
876 snd_printdd("playback prepare %d\n", substream->number); 930 snd_printdd("P%d prepare\n", substream->number);
877 931
878 hpi_handle_error(hpi_outstream_reset(dpcm->h_stream)); 932 hpi_handle_error(hpi_outstream_reset(dpcm->h_stream));
879 dpcm->pcm_buf_host_rw_ofs = 0; 933 dpcm->pcm_buf_host_rw_ofs = 0;
@@ -890,7 +944,7 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
890 snd_pcm_uframes_t ptr; 944 snd_pcm_uframes_t ptr;
891 945
892 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); 946 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
893 snd_printddd("playback_pointer=x%04lx\n", (unsigned long)ptr); 947 snd_printddd("P%d pointer = 0x%04lx\n", substream->number, (unsigned long)ptr);
894 return ptr; 948 return ptr;
895} 949}
896 950
@@ -986,11 +1040,9 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
986 SNDRV_PCM_INFO_DOUBLE | 1040 SNDRV_PCM_INFO_DOUBLE |
987 SNDRV_PCM_INFO_BATCH | 1041 SNDRV_PCM_INFO_BATCH |
988 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1042 SNDRV_PCM_INFO_BLOCK_TRANSFER |
989 SNDRV_PCM_INFO_PAUSE; 1043 SNDRV_PCM_INFO_PAUSE |
990 1044 SNDRV_PCM_INFO_MMAP |
991 if (card->support_mmap) 1045 SNDRV_PCM_INFO_MMAP_VALID;
992 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_MMAP |
993 SNDRV_PCM_INFO_MMAP_VALID;
994 1046
995 if (card->support_grouping) 1047 if (card->support_grouping)
996 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START; 1048 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
@@ -998,7 +1050,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
998 /* struct is copied, so can create initializer dynamically */ 1050 /* struct is copied, so can create initializer dynamically */
999 runtime->hw = snd_card_asihpi_playback; 1051 runtime->hw = snd_card_asihpi_playback;
1000 1052
1001 if (card->support_mmap) 1053 if (card->can_dma)
1002 err = snd_pcm_hw_constraint_pow2(runtime, 0, 1054 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1003 SNDRV_PCM_HW_PARAM_BUFFER_BYTES); 1055 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1004 if (err < 0) 1056 if (err < 0)
@@ -1028,58 +1080,6 @@ static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1028 return 0; 1080 return 0;
1029} 1081}
1030 1082
1031static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,
1032 int channel,
1033 snd_pcm_uframes_t pos,
1034 void __user *src,
1035 snd_pcm_uframes_t count)
1036{
1037 struct snd_pcm_runtime *runtime = substream->runtime;
1038 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1039 unsigned int len;
1040
1041 len = frames_to_bytes(runtime, count);
1042
1043 if (copy_from_user(runtime->dma_area, src, len))
1044 return -EFAULT;
1045
1046 snd_printddd("playback copy%d %u bytes\n",
1047 substream->number, len);
1048
1049 hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream,
1050 runtime->dma_area, len, &dpcm->format));
1051
1052 dpcm->pcm_buf_host_rw_ofs += len;
1053
1054 return 0;
1055}
1056
1057static int snd_card_asihpi_playback_silence(struct snd_pcm_substream *
1058 substream, int channel,
1059 snd_pcm_uframes_t pos,
1060 snd_pcm_uframes_t count)
1061{
1062 /* Usually writes silence to DMA buffer, which should be overwritten
1063 by real audio later. Our fifos cannot be overwritten, and are not
1064 free-running DMAs. Silence is output on fifo underflow.
1065 This callback is still required to allow the copy callback to be used.
1066 */
1067 return 0;
1068}
1069
1070static struct snd_pcm_ops snd_card_asihpi_playback_ops = {
1071 .open = snd_card_asihpi_playback_open,
1072 .close = snd_card_asihpi_playback_close,
1073 .ioctl = snd_card_asihpi_playback_ioctl,
1074 .hw_params = snd_card_asihpi_pcm_hw_params,
1075 .hw_free = snd_card_asihpi_hw_free,
1076 .prepare = snd_card_asihpi_playback_prepare,
1077 .trigger = snd_card_asihpi_trigger,
1078 .pointer = snd_card_asihpi_playback_pointer,
1079 .copy = snd_card_asihpi_playback_copy,
1080 .silence = snd_card_asihpi_playback_silence,
1081};
1082
1083static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = { 1083static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
1084 .open = snd_card_asihpi_playback_open, 1084 .open = snd_card_asihpi_playback_open,
1085 .close = snd_card_asihpi_playback_close, 1085 .close = snd_card_asihpi_playback_close,
@@ -1211,18 +1211,16 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1211 snd_card_asihpi_capture_format(card, dpcm->h_stream, 1211 snd_card_asihpi_capture_format(card, dpcm->h_stream,
1212 &snd_card_asihpi_capture); 1212 &snd_card_asihpi_capture);
1213 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture); 1213 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
1214 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED; 1214 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED |
1215 1215 SNDRV_PCM_INFO_MMAP |
1216 if (card->support_mmap) 1216 SNDRV_PCM_INFO_MMAP_VALID;
1217 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP |
1218 SNDRV_PCM_INFO_MMAP_VALID;
1219 1217
1220 if (card->support_grouping) 1218 if (card->support_grouping)
1221 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START; 1219 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START;
1222 1220
1223 runtime->hw = snd_card_asihpi_capture; 1221 runtime->hw = snd_card_asihpi_capture;
1224 1222
1225 if (card->support_mmap) 1223 if (card->can_dma)
1226 err = snd_pcm_hw_constraint_pow2(runtime, 0, 1224 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1227 SNDRV_PCM_HW_PARAM_BUFFER_BYTES); 1225 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1228 if (err < 0) 1226 if (err < 0)
@@ -1246,28 +1244,6 @@ static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1246 return 0; 1244 return 0;
1247} 1245}
1248 1246
1249static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream,
1250 int channel, snd_pcm_uframes_t pos,
1251 void __user *dst, snd_pcm_uframes_t count)
1252{
1253 struct snd_pcm_runtime *runtime = substream->runtime;
1254 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1255 u32 len;
1256
1257 len = frames_to_bytes(runtime, count);
1258
1259 snd_printddd("capture copy%d %d bytes\n", substream->number, len);
1260 hpi_handle_error(hpi_instream_read_buf(dpcm->h_stream,
1261 runtime->dma_area, len));
1262
1263 dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len;
1264
1265 if (copy_to_user(dst, runtime->dma_area, len))
1266 return -EFAULT;
1267
1268 return 0;
1269}
1270
1271static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = { 1247static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1272 .open = snd_card_asihpi_capture_open, 1248 .open = snd_card_asihpi_capture_open,
1273 .close = snd_card_asihpi_capture_close, 1249 .close = snd_card_asihpi_capture_close,
@@ -1279,18 +1255,6 @@ static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1279 .pointer = snd_card_asihpi_capture_pointer, 1255 .pointer = snd_card_asihpi_capture_pointer,
1280}; 1256};
1281 1257
1282static struct snd_pcm_ops snd_card_asihpi_capture_ops = {
1283 .open = snd_card_asihpi_capture_open,
1284 .close = snd_card_asihpi_capture_close,
1285 .ioctl = snd_card_asihpi_capture_ioctl,
1286 .hw_params = snd_card_asihpi_pcm_hw_params,
1287 .hw_free = snd_card_asihpi_hw_free,
1288 .prepare = snd_card_asihpi_capture_prepare,
1289 .trigger = snd_card_asihpi_trigger,
1290 .pointer = snd_card_asihpi_capture_pointer,
1291 .copy = snd_card_asihpi_capture_copy
1292};
1293
1294static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, 1258static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1295 int device, int substreams) 1259 int device, int substreams)
1296{ 1260{
@@ -1303,17 +1267,10 @@ static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1303 if (err < 0) 1267 if (err < 0)
1304 return err; 1268 return err;
1305 /* pointer to ops struct is stored, dont change ops afterwards! */ 1269 /* pointer to ops struct is stored, dont change ops afterwards! */
1306 if (asihpi->support_mmap) {
1307 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, 1270 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1308 &snd_card_asihpi_playback_mmap_ops); 1271 &snd_card_asihpi_playback_mmap_ops);
1309 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 1272 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1310 &snd_card_asihpi_capture_mmap_ops); 1273 &snd_card_asihpi_capture_mmap_ops);
1311 } else {
1312 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1313 &snd_card_asihpi_playback_ops);
1314 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1315 &snd_card_asihpi_capture_ops);
1316 }
1317 1274
1318 pcm->private_data = asihpi; 1275 pcm->private_data = asihpi;
1319 pcm->info_flags = 0; 1276 pcm->info_flags = 0;
@@ -1413,14 +1370,16 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1413 struct hpi_control *hpi_ctl, 1370 struct hpi_control *hpi_ctl,
1414 char *name) 1371 char *name)
1415{ 1372{
1416 char *dir = ""; 1373 char *dir;
1417 memset(snd_control, 0, sizeof(*snd_control)); 1374 memset(snd_control, 0, sizeof(*snd_control));
1418 snd_control->name = hpi_ctl->name; 1375 snd_control->name = hpi_ctl->name;
1419 snd_control->private_value = hpi_ctl->h_control; 1376 snd_control->private_value = hpi_ctl->h_control;
1420 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 1377 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1421 snd_control->index = 0; 1378 snd_control->index = 0;
1422 1379
1423 if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM) 1380 if (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE == HPI_SOURCENODE_CLOCK_SOURCE)
1381 dir = ""; /* clock is neither capture nor playback */
1382 else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
1424 dir = "Capture "; /* On or towards a PCM capture destination*/ 1383 dir = "Capture "; /* On or towards a PCM capture destination*/
1425 else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) && 1384 else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1426 (!hpi_ctl->dst_node_type)) 1385 (!hpi_ctl->dst_node_type))
@@ -1433,7 +1392,7 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1433 dir = "Playback "; /* PCM Playback source, or output node */ 1392 dir = "Playback "; /* PCM Playback source, or output node */
1434 1393
1435 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type) 1394 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1436 sprintf(hpi_ctl->name, "%s%d %s%d %s%s", 1395 sprintf(hpi_ctl->name, "%s %d %s %d %s%s",
1437 asihpi_src_names[hpi_ctl->src_node_type], 1396 asihpi_src_names[hpi_ctl->src_node_type],
1438 hpi_ctl->src_node_index, 1397 hpi_ctl->src_node_index,
1439 asihpi_dst_names[hpi_ctl->dst_node_type], 1398 asihpi_dst_names[hpi_ctl->dst_node_type],
@@ -2875,14 +2834,14 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2875 if (err) 2834 if (err)
2876 asihpi->update_interval_frames = 512; 2835 asihpi->update_interval_frames = 512;
2877 2836
2878 if (!asihpi->support_mmap) 2837 if (!asihpi->can_dma)
2879 asihpi->update_interval_frames *= 2; 2838 asihpi->update_interval_frames *= 2;
2880 2839
2881 hpi_handle_error(hpi_instream_open(asihpi->adapter_index, 2840 hpi_handle_error(hpi_instream_open(asihpi->adapter_index,
2882 0, &h_stream)); 2841 0, &h_stream));
2883 2842
2884 err = hpi_instream_host_buffer_free(h_stream); 2843 err = hpi_instream_host_buffer_free(h_stream);
2885 asihpi->support_mmap = (!err); 2844 asihpi->can_dma = (!err);
2886 2845
2887 hpi_handle_error(hpi_instream_close(h_stream)); 2846 hpi_handle_error(hpi_instream_close(h_stream));
2888 2847
@@ -2894,8 +2853,8 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2894 asihpi->out_max_chans = 2; 2853 asihpi->out_max_chans = 2;
2895 } 2854 }
2896 2855
2897 snd_printk(KERN_INFO "supports mmap:%d grouping:%d mrx:%d\n", 2856 snd_printk(KERN_INFO "has dma:%d, grouping:%d, mrx:%d\n",
2898 asihpi->support_mmap, 2857 asihpi->can_dma,
2899 asihpi->support_grouping, 2858 asihpi->support_grouping,
2900 asihpi->support_mrx 2859 asihpi->support_mrx
2901 ); 2860 );
@@ -2925,10 +2884,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2925 by enable_hwdep module param*/ 2884 by enable_hwdep module param*/
2926 snd_asihpi_hpi_new(asihpi, 0, NULL); 2885 snd_asihpi_hpi_new(asihpi, 0, NULL);
2927 2886
2928 if (asihpi->support_mmap) 2887 strcpy(card->driver, "ASIHPI");
2929 strcpy(card->driver, "ASIHPI-MMAP");
2930 else
2931 strcpy(card->driver, "ASIHPI");
2932 2888
2933 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type); 2889 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type);
2934 sprintf(card->longname, "%s %i", 2890 sprintf(card->longname, "%s %i",
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
index 8c8aac4c567e..df4aed5295dd 100644
--- a/sound/pci/asihpi/hpi6000.c
+++ b/sound/pci/asihpi/hpi6000.c
@@ -200,8 +200,8 @@ static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
200static void subsys_create_adapter(struct hpi_message *phm, 200static void subsys_create_adapter(struct hpi_message *phm,
201 struct hpi_response *phr); 201 struct hpi_response *phr);
202 202
203static void subsys_delete_adapter(struct hpi_message *phm, 203static void adapter_delete(struct hpi_adapter_obj *pao,
204 struct hpi_response *phr); 204 struct hpi_message *phm, struct hpi_response *phr);
205 205
206static void adapter_get_asserts(struct hpi_adapter_obj *pao, 206static void adapter_get_asserts(struct hpi_adapter_obj *pao,
207 struct hpi_message *phm, struct hpi_response *phr); 207 struct hpi_message *phm, struct hpi_response *phr);
@@ -222,9 +222,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
222 case HPI_SUBSYS_CREATE_ADAPTER: 222 case HPI_SUBSYS_CREATE_ADAPTER:
223 subsys_create_adapter(phm, phr); 223 subsys_create_adapter(phm, phr);
224 break; 224 break;
225 case HPI_SUBSYS_DELETE_ADAPTER:
226 subsys_delete_adapter(phm, phr);
227 break;
228 default: 225 default:
229 phr->error = HPI_ERROR_INVALID_FUNC; 226 phr->error = HPI_ERROR_INVALID_FUNC;
230 break; 227 break;
@@ -279,6 +276,10 @@ static void adapter_message(struct hpi_adapter_obj *pao,
279 adapter_get_asserts(pao, phm, phr); 276 adapter_get_asserts(pao, phm, phr);
280 break; 277 break;
281 278
279 case HPI_ADAPTER_DELETE:
280 adapter_delete(pao, phm, phr);
281 break;
282
282 default: 283 default:
283 hw_message(pao, phm, phr); 284 hw_message(pao, phm, phr);
284 break; 285 break;
@@ -333,26 +334,22 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
333{ 334{
334 struct hpi_adapter_obj *pao = NULL; 335 struct hpi_adapter_obj *pao = NULL;
335 336
336 /* subsytem messages get executed by every HPI. */
337 /* All other messages are ignored unless the adapter index matches */
338 /* an adapter in the HPI */
339 /*HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->wObject, phm->wFunction); */
340
341 /* if Dsp has crashed then do not communicate with it any more */
342 if (phm->object != HPI_OBJ_SUBSYSTEM) { 337 if (phm->object != HPI_OBJ_SUBSYSTEM) {
343 pao = hpi_find_adapter(phm->adapter_index); 338 pao = hpi_find_adapter(phm->adapter_index);
344 if (!pao) { 339 if (!pao) {
345 HPI_DEBUG_LOG(DEBUG, 340 hpi_init_response(phr, phm->object, phm->function,
346 " %d,%d refused, for another HPI?\n", 341 HPI_ERROR_BAD_ADAPTER_NUMBER);
347 phm->object, phm->function); 342 HPI_DEBUG_LOG(DEBUG, "invalid adapter index: %d \n",
343 phm->adapter_index);
348 return; 344 return;
349 } 345 }
350 346
347 /* Don't even try to communicate with crashed DSP */
351 if (pao->dsp_crashed >= 10) { 348 if (pao->dsp_crashed >= 10) {
352 hpi_init_response(phr, phm->object, phm->function, 349 hpi_init_response(phr, phm->object, phm->function,
353 HPI_ERROR_DSP_HARDWARE); 350 HPI_ERROR_DSP_HARDWARE);
354 HPI_DEBUG_LOG(DEBUG, " %d,%d dsp crashed.\n", 351 HPI_DEBUG_LOG(DEBUG, "adapter %d dsp crashed\n",
355 phm->object, phm->function); 352 phm->adapter_index);
356 return; 353 return;
357 } 354 }
358 } 355 }
@@ -463,15 +460,9 @@ static void subsys_create_adapter(struct hpi_message *phm,
463 phr->error = 0; 460 phr->error = 0;
464} 461}
465 462
466static void subsys_delete_adapter(struct hpi_message *phm, 463static void adapter_delete(struct hpi_adapter_obj *pao,
467 struct hpi_response *phr) 464 struct hpi_message *phm, struct hpi_response *phr)
468{ 465{
469 struct hpi_adapter_obj *pao = NULL;
470
471 pao = hpi_find_adapter(phm->obj_index);
472 if (!pao)
473 return;
474
475 delete_adapter_obj(pao); 466 delete_adapter_obj(pao);
476 hpi_delete_adapter(pao); 467 hpi_delete_adapter(pao);
477 phr->error = 0; 468 phr->error = 0;
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c
index 22e9f08dea6d..9d5df54a6b46 100644
--- a/sound/pci/asihpi/hpi6205.c
+++ b/sound/pci/asihpi/hpi6205.c
@@ -152,8 +152,8 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
152 152
153static void subsys_create_adapter(struct hpi_message *phm, 153static void subsys_create_adapter(struct hpi_message *phm,
154 struct hpi_response *phr); 154 struct hpi_response *phr);
155static void subsys_delete_adapter(struct hpi_message *phm, 155static void adapter_delete(struct hpi_adapter_obj *pao,
156 struct hpi_response *phr); 156 struct hpi_message *phm, struct hpi_response *phr);
157 157
158static u16 create_adapter_obj(struct hpi_adapter_obj *pao, 158static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
159 u32 *pos_error_code); 159 u32 *pos_error_code);
@@ -223,15 +223,13 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
223 223
224/*****************************************************************************/ 224/*****************************************************************************/
225 225
226static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) 226static void subsys_message(struct hpi_adapter_obj *pao,
227 struct hpi_message *phm, struct hpi_response *phr)
227{ 228{
228 switch (phm->function) { 229 switch (phm->function) {
229 case HPI_SUBSYS_CREATE_ADAPTER: 230 case HPI_SUBSYS_CREATE_ADAPTER:
230 subsys_create_adapter(phm, phr); 231 subsys_create_adapter(phm, phr);
231 break; 232 break;
232 case HPI_SUBSYS_DELETE_ADAPTER:
233 subsys_delete_adapter(phm, phr);
234 break;
235 default: 233 default:
236 phr->error = HPI_ERROR_INVALID_FUNC; 234 phr->error = HPI_ERROR_INVALID_FUNC;
237 break; 235 break;
@@ -279,6 +277,10 @@ static void adapter_message(struct hpi_adapter_obj *pao,
279 struct hpi_message *phm, struct hpi_response *phr) 277 struct hpi_message *phm, struct hpi_response *phr)
280{ 278{
281 switch (phm->function) { 279 switch (phm->function) {
280 case HPI_ADAPTER_DELETE:
281 adapter_delete(pao, phm, phr);
282 break;
283
282 default: 284 default:
283 hw_message(pao, phm, phr); 285 hw_message(pao, phm, phr);
284 break; 286 break;
@@ -371,36 +373,17 @@ static void instream_message(struct hpi_adapter_obj *pao,
371/** Entry point to this HPI backend 373/** Entry point to this HPI backend
372 * All calls to the HPI start here 374 * All calls to the HPI start here
373 */ 375 */
374void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) 376void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
377 struct hpi_response *phr)
375{ 378{
376 struct hpi_adapter_obj *pao = NULL; 379 if (pao && (pao->dsp_crashed >= 10)
377 380 && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
378 /* subsytem messages are processed by every HPI. 381 /* allow last resort debug read even after crash */
379 * All other messages are ignored unless the adapter index matches 382 hpi_init_response(phr, phm->object, phm->function,
380 * an adapter in the HPI 383 HPI_ERROR_DSP_HARDWARE);
381 */ 384 HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", phm->object,
382 /* HPI_DEBUG_LOG(DEBUG, "HPI Obj=%d, Func=%d\n", phm->wObject, 385 phm->function);
383 phm->wFunction); */ 386 return;
384
385 /* if Dsp has crashed then do not communicate with it any more */
386 if (phm->object != HPI_OBJ_SUBSYSTEM) {
387 pao = hpi_find_adapter(phm->adapter_index);
388 if (!pao) {
389 HPI_DEBUG_LOG(DEBUG,
390 " %d,%d refused, for another HPI?\n",
391 phm->object, phm->function);
392 return;
393 }
394
395 if ((pao->dsp_crashed >= 10)
396 && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
397 /* allow last resort debug read even after crash */
398 hpi_init_response(phr, phm->object, phm->function,
399 HPI_ERROR_DSP_HARDWARE);
400 HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n",
401 phm->object, phm->function);
402 return;
403 }
404 } 387 }
405 388
406 /* Init default response */ 389 /* Init default response */
@@ -412,7 +395,7 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
412 case HPI_TYPE_MESSAGE: 395 case HPI_TYPE_MESSAGE:
413 switch (phm->object) { 396 switch (phm->object) {
414 case HPI_OBJ_SUBSYSTEM: 397 case HPI_OBJ_SUBSYSTEM:
415 subsys_message(phm, phr); 398 subsys_message(pao, phm, phr);
416 break; 399 break;
417 400
418 case HPI_OBJ_ADAPTER: 401 case HPI_OBJ_ADAPTER:
@@ -444,6 +427,26 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
444 } 427 }
445} 428}
446 429
430void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
431{
432 struct hpi_adapter_obj *pao = NULL;
433
434 if (phm->object != HPI_OBJ_SUBSYSTEM) {
435 /* normal messages must have valid adapter index */
436 pao = hpi_find_adapter(phm->adapter_index);
437 } else {
438 /* subsys messages don't address an adapter */
439 _HPI_6205(NULL, phm, phr);
440 return;
441 }
442
443 if (pao)
444 _HPI_6205(pao, phm, phr);
445 else
446 hpi_init_response(phr, phm->object, phm->function,
447 HPI_ERROR_BAD_ADAPTER_NUMBER);
448}
449
447/*****************************************************************************/ 450/*****************************************************************************/
448/* SUBSYSTEM */ 451/* SUBSYSTEM */
449 452
@@ -491,13 +494,11 @@ static void subsys_create_adapter(struct hpi_message *phm,
491} 494}
492 495
493/** delete an adapter - required by WDM driver */ 496/** delete an adapter - required by WDM driver */
494static void subsys_delete_adapter(struct hpi_message *phm, 497static void adapter_delete(struct hpi_adapter_obj *pao,
495 struct hpi_response *phr) 498 struct hpi_message *phm, struct hpi_response *phr)
496{ 499{
497 struct hpi_adapter_obj *pao;
498 struct hpi_hw_obj *phw; 500 struct hpi_hw_obj *phw;
499 501
500 pao = hpi_find_adapter(phm->obj_index);
501 if (!pao) { 502 if (!pao) {
502 phr->error = HPI_ERROR_INVALID_OBJ_INDEX; 503 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
503 return; 504 return;
@@ -563,11 +564,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
563 } 564 }
564 565
565 err = adapter_boot_load_dsp(pao, pos_error_code); 566 err = adapter_boot_load_dsp(pao, pos_error_code);
566 if (err) 567 if (err) {
568 HPI_DEBUG_LOG(ERROR, "DSP code load failed\n");
567 /* no need to clean up as SubSysCreateAdapter */ 569 /* no need to clean up as SubSysCreateAdapter */
568 /* calls DeleteAdapter on error. */ 570 /* calls DeleteAdapter on error. */
569 return err; 571 return err;
570 572 }
571 HPI_DEBUG_LOG(INFO, "load DSP code OK\n"); 573 HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
572 574
573 /* allow boot load even if mem alloc wont work */ 575 /* allow boot load even if mem alloc wont work */
@@ -604,6 +606,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
604 control_cache.number_of_controls, 606 control_cache.number_of_controls,
605 interface->control_cache.size_in_bytes, 607 interface->control_cache.size_in_bytes,
606 p_control_cache_virtual); 608 p_control_cache_virtual);
609
607 if (!phw->p_cache) 610 if (!phw->p_cache)
608 err = HPI_ERROR_MEMORY_ALLOC; 611 err = HPI_ERROR_MEMORY_ALLOC;
609 } 612 }
@@ -675,16 +678,14 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
675} 678}
676 679
677/** Free memory areas allocated by adapter 680/** Free memory areas allocated by adapter
678 * this routine is called from SubSysDeleteAdapter, 681 * this routine is called from AdapterDelete,
679 * and SubSysCreateAdapter if duplicate index 682 * and SubSysCreateAdapter if duplicate index
680*/ 683*/
681static void delete_adapter_obj(struct hpi_adapter_obj *pao) 684static void delete_adapter_obj(struct hpi_adapter_obj *pao)
682{ 685{
683 struct hpi_hw_obj *phw; 686 struct hpi_hw_obj *phw = pao->priv;
684 int i; 687 int i;
685 688
686 phw = pao->priv;
687
688 if (hpios_locked_mem_valid(&phw->h_control_cache)) { 689 if (hpios_locked_mem_valid(&phw->h_control_cache)) {
689 hpios_locked_mem_free(&phw->h_control_cache); 690 hpios_locked_mem_free(&phw->h_control_cache);
690 hpi_free_control_cache(phw->p_cache); 691 hpi_free_control_cache(phw->p_cache);
@@ -1275,6 +1276,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1275 case HPI_ADAPTER_FAMILY_ASI(0x6300): 1276 case HPI_ADAPTER_FAMILY_ASI(0x6300):
1276 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400); 1277 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400);
1277 break; 1278 break;
1279 case HPI_ADAPTER_FAMILY_ASI(0x5500):
1278 case HPI_ADAPTER_FAMILY_ASI(0x5600): 1280 case HPI_ADAPTER_FAMILY_ASI(0x5600):
1279 case HPI_ADAPTER_FAMILY_ASI(0x6500): 1281 case HPI_ADAPTER_FAMILY_ASI(0x6500):
1280 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600); 1282 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600);
@@ -2059,7 +2061,6 @@ static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us)
2059static void send_dsp_command(struct hpi_hw_obj *phw, int cmd) 2061static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
2060{ 2062{
2061 struct bus_master_interface *interface = phw->p_interface_buffer; 2063 struct bus_master_interface *interface = phw->p_interface_buffer;
2062
2063 u32 r; 2064 u32 r;
2064 2065
2065 interface->host_cmd = cmd; 2066 interface->host_cmd = cmd;
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h
index 3b9fd115da36..bf5eced76bac 100644
--- a/sound/pci/asihpi/hpi_internal.h
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -294,7 +294,7 @@ enum HPI_CONTROL_ATTRIBUTES {
294 294
295/* These defines are used to fill in protocol information for an Ethernet packet 295/* These defines are used to fill in protocol information for an Ethernet packet
296 sent using HMI on CS18102 */ 296 sent using HMI on CS18102 */
297/** ID supplied by Cirrius for ASI packets. */ 297/** ID supplied by Cirrus for ASI packets. */
298#define HPI_ETHERNET_PACKET_ID 0x85 298#define HPI_ETHERNET_PACKET_ID 0x85
299/** Simple packet - no special routing required */ 299/** Simple packet - no special routing required */
300#define HPI_ETHERNET_PACKET_V1 0x01 300#define HPI_ETHERNET_PACKET_V1 0x01
@@ -307,7 +307,7 @@ enum HPI_CONTROL_ATTRIBUTES {
307/** This packet must make its way to the host across the HPI interface */ 307/** This packet must make its way to the host across the HPI interface */
308#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41 308#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41
309 309
310#define HPI_ETHERNET_UDP_PORT (44600) /*!< UDP messaging port */ 310#define HPI_ETHERNET_UDP_PORT 44600 /**< HPI UDP service */
311 311
312/** Default network timeout in milli-seconds. */ 312/** Default network timeout in milli-seconds. */
313#define HPI_ETHERNET_TIMEOUT_MS 500 313#define HPI_ETHERNET_TIMEOUT_MS 500
@@ -397,14 +397,14 @@ enum HPI_FUNCTION_IDS {
397 HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1), 397 HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1),
398 HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2), 398 HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2),
399 HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3), 399 HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3),
400 HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), 400 /* HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), */
401 HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5), 401 HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5),
402 HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6), 402 HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6),
403 HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), 403 /* HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), */
404 HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8), 404 HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8),
405 HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9), 405 HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9),
406 HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), 406 /* HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), */
407 HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), 407 /* HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), */
408 HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12), 408 HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12),
409 HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13), 409 HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13),
410 HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14), 410 HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14),
@@ -433,7 +433,8 @@ enum HPI_FUNCTION_IDS {
433 HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18), 433 HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18),
434 HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19), 434 HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19),
435 HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20), 435 HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20),
436#define HPI_ADAPTER_FUNCTION_COUNT 20 436 HPI_ADAPTER_DELETE = HPI_FUNC_ID(ADAPTER, 21),
437#define HPI_ADAPTER_FUNCTION_COUNT 21
437 438
438 HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1), 439 HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1),
439 HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2), 440 HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2),
@@ -1561,8 +1562,6 @@ void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr);
1561u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource, 1562u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource,
1562 u16 *pw_adapter_index); 1563 u16 *pw_adapter_index);
1563 1564
1564u16 hpi_subsys_delete_adapter(u16 adapter_index);
1565
1566u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer, 1565u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer,
1567 struct hpi_hostbuffer_status **pp_status); 1566 struct hpi_hostbuffer_status **pp_status);
1568 1567
@@ -1584,9 +1583,7 @@ void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR);
1584 1583
1585/*////////////////////////////////////////////////////////////////////////// */ 1584/*////////////////////////////////////////////////////////////////////////// */
1586/* declarations for individual HPI entry points */ 1585/* declarations for individual HPI entry points */
1587hpi_handler_func HPI_1000;
1588hpi_handler_func HPI_6000; 1586hpi_handler_func HPI_6000;
1589hpi_handler_func HPI_6205; 1587hpi_handler_func HPI_6205;
1590hpi_handler_func HPI_COMMON;
1591 1588
1592#endif /* _HPI_INTERNAL_H_ */ 1589#endif /* _HPI_INTERNAL_H_ */
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
index 3e9c5c289764..b15a02e91f82 100644
--- a/sound/pci/asihpi/hpicmn.c
+++ b/sound/pci/asihpi/hpicmn.c
@@ -227,8 +227,9 @@ static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
227 if (info->control_type) { 227 if (info->control_type) {
228 pC->p_info[info->control_index] = info; 228 pC->p_info[info->control_index] = info;
229 cached++; 229 cached++;
230 } else /* dummy cache entry */ 230 } else { /* dummy cache entry */
231 pC->p_info[info->control_index] = NULL; 231 pC->p_info[info->control_index] = NULL;
232 }
232 233
233 byte_count += info->size_in32bit_words * 4; 234 byte_count += info->size_in32bit_words * 4;
234 235
@@ -298,7 +299,7 @@ struct pad_ofs_size {
298 unsigned int field_size; 299 unsigned int field_size;
299}; 300};
300 301
301static struct pad_ofs_size pad_desc[] = { 302static const struct pad_ofs_size pad_desc[] = {
302 HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */ 303 HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */
303 HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */ 304 HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */
304 HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */ 305 HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */
@@ -617,6 +618,10 @@ void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
617 } 618 }
618} 619}
619 620
621/** Allocate control cache.
622
623\return Cache pointer, or NULL if allocation fails.
624*/
620struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count, 625struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
621 const u32 size_in_bytes, u8 *p_dsp_control_buffer) 626 const u32 size_in_bytes, u8 *p_dsp_control_buffer)
622{ 627{
@@ -667,7 +672,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
667 phr->u.s.num_adapters = adapters.gw_num_adapters; 672 phr->u.s.num_adapters = adapters.gw_num_adapters;
668 break; 673 break;
669 case HPI_SUBSYS_CREATE_ADAPTER: 674 case HPI_SUBSYS_CREATE_ADAPTER:
670 case HPI_SUBSYS_DELETE_ADAPTER:
671 break; 675 break;
672 default: 676 default:
673 phr->error = HPI_ERROR_INVALID_FUNC; 677 phr->error = HPI_ERROR_INVALID_FUNC;
diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h
index 590f0b69e655..d53cdf6e535f 100644
--- a/sound/pci/asihpi/hpicmn.h
+++ b/sound/pci/asihpi/hpicmn.h
@@ -60,3 +60,5 @@ void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *pC,
60 struct hpi_message *phm, struct hpi_response *phr); 60 struct hpi_message *phm, struct hpi_response *phr);
61 61
62u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr); 62u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr);
63
64hpi_handler_func HPI_COMMON;
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
index c38fc9487560..7397b169b89f 100644
--- a/sound/pci/asihpi/hpifunc.c
+++ b/sound/pci/asihpi/hpifunc.c
@@ -105,33 +105,6 @@ u16 hpi_subsys_get_version_ex(u32 *pversion_ex)
105 return hr.error; 105 return hr.error;
106} 106}
107 107
108u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource,
109 u16 *pw_adapter_index)
110{
111 struct hpi_message hm;
112 struct hpi_response hr;
113
114 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
115 HPI_SUBSYS_CREATE_ADAPTER);
116 hm.u.s.resource = *p_resource;
117
118 hpi_send_recv(&hm, &hr);
119
120 *pw_adapter_index = hr.u.s.adapter_index;
121 return hr.error;
122}
123
124u16 hpi_subsys_delete_adapter(u16 adapter_index)
125{
126 struct hpi_message hm;
127 struct hpi_response hr;
128 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
129 HPI_SUBSYS_DELETE_ADAPTER);
130 hm.obj_index = adapter_index;
131 hpi_send_recv(&hm, &hr);
132 return hr.error;
133}
134
135u16 hpi_subsys_get_num_adapters(int *pn_num_adapters) 108u16 hpi_subsys_get_num_adapters(int *pn_num_adapters)
136{ 109{
137 struct hpi_message hm; 110 struct hpi_message hm;
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c
index 360028b9abf5..7352a5f7b4f7 100644
--- a/sound/pci/asihpi/hpimsgx.c
+++ b/sound/pci/asihpi/hpimsgx.c
@@ -211,24 +211,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
211 HPIMSGX__init(phm, phr); 211 HPIMSGX__init(phm, phr);
212 break; 212 break;
213 213
214 case HPI_SUBSYS_DELETE_ADAPTER:
215 HPIMSGX__cleanup(phm->obj_index, h_owner);
216 {
217 struct hpi_message hm;
218 struct hpi_response hr;
219 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
220 HPI_ADAPTER_CLOSE);
221 hm.adapter_index = phm->obj_index;
222 hw_entry_point(&hm, &hr);
223 }
224 if ((phm->obj_index < HPI_MAX_ADAPTERS)
225 && hpi_entry_points[phm->obj_index]) {
226 hpi_entry_points[phm->obj_index] (phm, phr);
227 hpi_entry_points[phm->obj_index] = NULL;
228 } else
229 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
230
231 break;
232 default: 214 default:
233 /* Must explicitly handle every subsys message in this switch */ 215 /* Must explicitly handle every subsys message in this switch */
234 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 216 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function,
@@ -247,6 +229,19 @@ static void adapter_message(struct hpi_message *phm, struct hpi_response *phr,
247 case HPI_ADAPTER_CLOSE: 229 case HPI_ADAPTER_CLOSE:
248 adapter_close(phm, phr); 230 adapter_close(phm, phr);
249 break; 231 break;
232 case HPI_ADAPTER_DELETE:
233 HPIMSGX__cleanup(phm->adapter_index, h_owner);
234 {
235 struct hpi_message hm;
236 struct hpi_response hr;
237 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
238 HPI_ADAPTER_CLOSE);
239 hm.adapter_index = phm->adapter_index;
240 hw_entry_point(&hm, &hr);
241 }
242 hw_entry_point(phm, phr);
243 break;
244
250 default: 245 default:
251 hw_entry_point(phm, phr); 246 hw_entry_point(phm, phr);
252 break; 247 break;
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index cd624f13ff8e..d8e7047512f8 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -25,6 +25,7 @@ Common Linux HPI ioctl and module probe/remove functions
25#include "hpidebug.h" 25#include "hpidebug.h"
26#include "hpimsgx.h" 26#include "hpimsgx.h"
27#include "hpioctl.h" 27#include "hpioctl.h"
28#include "hpicmn.h"
28 29
29#include <linux/fs.h> 30#include <linux/fs.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
@@ -161,26 +162,24 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
161 goto out; 162 goto out;
162 } 163 }
163 164
164 pa = &adapters[hm->h.adapter_index]; 165 switch (hm->h.function) {
166 case HPI_SUBSYS_CREATE_ADAPTER:
167 case HPI_ADAPTER_DELETE:
168 /* Application must not use these functions! */
169 hr->h.size = sizeof(hr->h);
170 hr->h.error = HPI_ERROR_INVALID_OPERATION;
171 hr->h.function = hm->h.function;
172 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
173 if (uncopied_bytes)
174 err = -EFAULT;
175 else
176 err = 0;
177 goto out;
178 }
179
165 hr->h.size = res_max_size; 180 hr->h.size = res_max_size;
166 if (hm->h.object == HPI_OBJ_SUBSYSTEM) { 181 if (hm->h.object == HPI_OBJ_SUBSYSTEM) {
167 switch (hm->h.function) { 182 hpi_send_recv_f(&hm->m0, &hr->r0, file);
168 case HPI_SUBSYS_CREATE_ADAPTER:
169 case HPI_SUBSYS_DELETE_ADAPTER:
170 /* Application must not use these functions! */
171 hr->h.size = sizeof(hr->h);
172 hr->h.error = HPI_ERROR_INVALID_OPERATION;
173 hr->h.function = hm->h.function;
174 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
175 if (uncopied_bytes)
176 err = -EFAULT;
177 else
178 err = 0;
179 goto out;
180
181 default:
182 hpi_send_recv_f(&hm->m0, &hr->r0, file);
183 }
184 } else { 183 } else {
185 u16 __user *ptr = NULL; 184 u16 __user *ptr = NULL;
186 u32 size = 0; 185 u32 size = 0;
@@ -188,8 +187,9 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
188 /* -1=no data 0=read from user mem, 1=write to user mem */ 187 /* -1=no data 0=read from user mem, 1=write to user mem */
189 int wrflag = -1; 188 int wrflag = -1;
190 u32 adapter = hm->h.adapter_index; 189 u32 adapter = hm->h.adapter_index;
190 pa = &adapters[adapter];
191 191
192 if ((hm->h.adapter_index > HPI_MAX_ADAPTERS) || (!pa->type)) { 192 if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) {
193 hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER, 193 hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER,
194 HPI_ADAPTER_OPEN, 194 HPI_ADAPTER_OPEN,
195 HPI_ERROR_BAD_ADAPTER_NUMBER); 195 HPI_ERROR_BAD_ADAPTER_NUMBER);
@@ -317,7 +317,7 @@ out:
317int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, 317int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
318 const struct pci_device_id *pci_id) 318 const struct pci_device_id *pci_id)
319{ 319{
320 int err, idx, nm; 320 int idx, nm;
321 unsigned int memlen; 321 unsigned int memlen;
322 struct hpi_message hm; 322 struct hpi_message hm;
323 struct hpi_response hr; 323 struct hpi_response hr;
@@ -351,11 +351,8 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
351 nm = HPI_MAX_ADAPTER_MEM_SPACES; 351 nm = HPI_MAX_ADAPTER_MEM_SPACES;
352 352
353 for (idx = 0; idx < nm; idx++) { 353 for (idx = 0; idx < nm; idx++) {
354 HPI_DEBUG_LOG(INFO, "resource %d %s %08llx-%08llx %04llx\n", 354 HPI_DEBUG_LOG(INFO, "resource %d %pR\n", idx,
355 idx, pci_dev->resource[idx].name, 355 &pci_dev->resource[idx]);
356 (unsigned long long)pci_resource_start(pci_dev, idx),
357 (unsigned long long)pci_resource_end(pci_dev, idx),
358 (unsigned long long)pci_resource_flags(pci_dev, idx));
359 356
360 if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) { 357 if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) {
361 memlen = pci_resource_len(pci_dev, idx); 358 memlen = pci_resource_len(pci_dev, idx);
@@ -395,17 +392,20 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
395 392
396 adapter.index = hr.u.s.adapter_index; 393 adapter.index = hr.u.s.adapter_index;
397 adapter.type = hr.u.s.adapter_type; 394 adapter.type = hr.u.s.adapter_type;
395
396 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
397 HPI_ADAPTER_OPEN);
398 hm.adapter_index = adapter.index; 398 hm.adapter_index = adapter.index;
399 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
399 400
400 err = hpi_adapter_open(adapter.index); 401 if (hr.error)
401 if (err)
402 goto err; 402 goto err;
403 403
404 adapter.snd_card_asihpi = NULL; 404 adapter.snd_card_asihpi = NULL;
405 /* WARNING can't init mutex in 'adapter' 405 /* WARNING can't init mutex in 'adapter'
406 * and then copy it to adapters[] ?!?! 406 * and then copy it to adapters[] ?!?!
407 */ 407 */
408 adapters[hr.u.s.adapter_index] = adapter; 408 adapters[adapter.index] = adapter;
409 mutex_init(&adapters[adapter.index].mutex); 409 mutex_init(&adapters[adapter.index].mutex);
410 pci_set_drvdata(pci_dev, &adapters[adapter.index]); 410 pci_set_drvdata(pci_dev, &adapters[adapter.index]);
411 411
@@ -440,10 +440,9 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
440 struct hpi_adapter *pa; 440 struct hpi_adapter *pa;
441 pa = pci_get_drvdata(pci_dev); 441 pa = pci_get_drvdata(pci_dev);
442 442
443 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, 443 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
444 HPI_SUBSYS_DELETE_ADAPTER); 444 HPI_ADAPTER_DELETE);
445 hm.obj_index = pa->index; 445 hm.adapter_index = pa->index;
446 hm.adapter_index = HPI_ADAPTER_INDEX_INVALID;
447 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); 446 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
448 447
449 /* unmap PCI memory space, mapped during device init. */ 448 /* unmap PCI memory space, mapped during device init. */
diff --git a/sound/pci/au88x0/au8810.h b/sound/pci/au88x0/au8810.h
index 5d69c31fe3f4..79fbee3845eb 100644
--- a/sound/pci/au88x0/au8810.h
+++ b/sound/pci/au88x0/au8810.h
@@ -4,7 +4,7 @@
4 4
5#define CHIP_AU8810 5#define CHIP_AU8810
6 6
7#define CARD_NAME "Aureal Advantage 3D Sound Processor" 7#define CARD_NAME "Aureal Advantage"
8#define CARD_NAME_SHORT "au8810" 8#define CARD_NAME_SHORT "au8810"
9 9
10#define NR_ADB 0x10 10#define NR_ADB 0x10
diff --git a/sound/pci/au88x0/au8820.h b/sound/pci/au88x0/au8820.h
index abbe85e4f7a9..cafdb9668a34 100644
--- a/sound/pci/au88x0/au8820.h
+++ b/sound/pci/au88x0/au8820.h
@@ -11,7 +11,7 @@
11 11
12#define CHIP_AU8820 12#define CHIP_AU8820
13 13
14#define CARD_NAME "Aureal Vortex 3D Sound Processor" 14#define CARD_NAME "Aureal Vortex"
15#define CARD_NAME_SHORT "au8820" 15#define CARD_NAME_SHORT "au8820"
16 16
17/* Number of ADB and WT channels */ 17/* Number of ADB and WT channels */
diff --git a/sound/pci/au88x0/au8830.h b/sound/pci/au88x0/au8830.h
index 04ece1b1c218..999b29ab34ad 100644
--- a/sound/pci/au88x0/au8830.h
+++ b/sound/pci/au88x0/au8830.h
@@ -11,7 +11,7 @@
11 11
12#define CHIP_AU8830 12#define CHIP_AU8830
13 13
14#define CARD_NAME "Aureal Vortex 2 3D Sound Processor" 14#define CARD_NAME "Aureal Vortex 2"
15#define CARD_NAME_SHORT "au8830" 15#define CARD_NAME_SHORT "au8830"
16 16
17#define NR_ADB 0x20 17#define NR_ADB 0x20
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index 62e959120c44..c5f7ae46afef 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -426,11 +426,11 @@ static struct snd_pcm_ops snd_vortex_playback_ops = {
426*/ 426*/
427 427
428static char *vortex_pcm_prettyname[VORTEX_PCM_LAST] = { 428static char *vortex_pcm_prettyname[VORTEX_PCM_LAST] = {
429 "AU88x0 ADB", 429 CARD_NAME " ADB",
430 "AU88x0 SPDIF", 430 CARD_NAME " SPDIF",
431 "AU88x0 A3D", 431 CARD_NAME " A3D",
432 "AU88x0 WT", 432 CARD_NAME " WT",
433 "AU88x0 I2S", 433 CARD_NAME " I2S",
434}; 434};
435static char *vortex_pcm_name[VORTEX_PCM_LAST] = { 435static char *vortex_pcm_name[VORTEX_PCM_LAST] = {
436 "adb", 436 "adb",
@@ -527,7 +527,8 @@ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
527 nr_capt, &pcm); 527 nr_capt, &pcm);
528 if (err < 0) 528 if (err < 0)
529 return err; 529 return err;
530 strcpy(pcm->name, vortex_pcm_name[idx]); 530 snprintf(pcm->name, sizeof(pcm->name),
531 "%s %s", CARD_NAME_SHORT, vortex_pcm_name[idx]);
531 chip->pcm[idx] = pcm; 532 chip->pcm[idx] = pcm;
532 // This is an evil hack, but it saves a lot of duplicated code. 533 // This is an evil hack, but it saves a lot of duplicated code.
533 VORTEX_PCM_TYPE(pcm) = idx; 534 VORTEX_PCM_TYPE(pcm) = idx;
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 7a9401462c1c..dae4050ede5c 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -303,6 +303,9 @@ static const u32 db_table[101] = {
303static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); 303static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1);
304static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0); 304static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0);
305 305
306/* EMU10K1 bass/treble db gain */
307static const DECLARE_TLV_DB_SCALE(snd_emu10k1_bass_treble_db_scale, -1200, 60, 0);
308
306static const u32 onoff_table[2] = { 309static const u32 onoff_table[2] = {
307 0x00000000, 0x00000001 310 0x00000000, 0x00000001
308}; 311};
@@ -2163,6 +2166,7 @@ static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2163 ctl->min = 0; 2166 ctl->min = 0;
2164 ctl->max = 40; 2167 ctl->max = 40;
2165 ctl->value[0] = ctl->value[1] = 20; 2168 ctl->value[0] = ctl->value[1] = 20;
2169 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
2166 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS; 2170 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
2167 ctl = &controls[i + 1]; 2171 ctl = &controls[i + 1];
2168 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2172 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
@@ -2172,6 +2176,7 @@ static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2172 ctl->min = 0; 2176 ctl->min = 0;
2173 ctl->max = 40; 2177 ctl->max = 40;
2174 ctl->value[0] = ctl->value[1] = 20; 2178 ctl->value[0] = ctl->value[1] = 20;
2179 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
2175 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE; 2180 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
2176 2181
2177#define BASS_GPR 0x8c 2182#define BASS_GPR 0x8c
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 05afe06e353a..9d890a5aec5a 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -1729,8 +1729,6 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
1729 "Master Mono Playback Volume", 1729 "Master Mono Playback Volume",
1730 "PCM Out Path & Mute", 1730 "PCM Out Path & Mute",
1731 "Mono Output Select", 1731 "Mono Output Select",
1732 "Front Playback Switch",
1733 "Front Playback Volume",
1734 "Surround Playback Switch", 1732 "Surround Playback Switch",
1735 "Surround Playback Volume", 1733 "Surround Playback Volume",
1736 "Center Playback Switch", 1734 "Center Playback Switch",
@@ -1879,6 +1877,8 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
1879 emu->rear_ac97 = 1; 1877 emu->rear_ac97 = 1;
1880 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT); 1878 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT);
1881 snd_ac97_write_cache(emu->ac97, AC97_HEADPHONE, 0x0202); 1879 snd_ac97_write_cache(emu->ac97, AC97_HEADPHONE, 0x0202);
1880 remove_ctl(card,"Front Playback Volume");
1881 remove_ctl(card,"Front Playback Switch");
1882 } 1882 }
1883 /* remove unused AC97 controls */ 1883 /* remove unused AC97 controls */
1884 snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202); 1884 snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
@@ -1913,6 +1913,12 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
1913 for (; *c; c += 2) 1913 for (; *c; c += 2)
1914 rename_ctl(card, c[0], c[1]); 1914 rename_ctl(card, c[0], c[1]);
1915 1915
1916 if (emu->card_capabilities->subsystem == 0x80401102) { /* SB Live! Platinum CT4760P */
1917 remove_ctl(card, "Center Playback Volume");
1918 remove_ctl(card, "LFE Playback Volume");
1919 remove_ctl(card, "Wave Center Playback Volume");
1920 remove_ctl(card, "Wave LFE Playback Volume");
1921 }
1916 if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */ 1922 if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */
1917 rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume"); 1923 rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume");
1918 rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume"); 1924 rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume");
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 7c17f45d876d..ab0a6156a704 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -112,6 +112,10 @@
112#include <sound/ac97_codec.h> 112#include <sound/ac97_codec.h>
113#include <sound/initval.h> 113#include <sound/initval.h>
114 114
115#ifdef CONFIG_SND_ES1968_RADIO
116#include <sound/tea575x-tuner.h>
117#endif
118
115#define CARD_NAME "ESS Maestro1/2" 119#define CARD_NAME "ESS Maestro1/2"
116#define DRIVER_NAME "ES1968" 120#define DRIVER_NAME "ES1968"
117 121
@@ -553,6 +557,10 @@ struct es1968 {
553 spinlock_t ac97_lock; 557 spinlock_t ac97_lock;
554 struct tasklet_struct hwvol_tq; 558 struct tasklet_struct hwvol_tq;
555#endif 559#endif
560
561#ifdef CONFIG_SND_ES1968_RADIO
562 struct snd_tea575x tea;
563#endif
556}; 564};
557 565
558static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); 566static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
@@ -2571,6 +2579,63 @@ static int __devinit snd_es1968_input_register(struct es1968 *chip)
2571} 2579}
2572#endif /* CONFIG_SND_ES1968_INPUT */ 2580#endif /* CONFIG_SND_ES1968_INPUT */
2573 2581
2582#ifdef CONFIG_SND_ES1968_RADIO
2583#define GPIO_DATA 0x60
2584#define IO_MASK 4 /* mask register offset from GPIO_DATA
2585 bits 1=unmask write to given bit */
2586#define IO_DIR 8 /* direction register offset from GPIO_DATA
2587 bits 0/1=read/write direction */
2588/* mask bits for GPIO lines */
2589#define STR_DATA 0x0040 /* GPIO6 */
2590#define STR_CLK 0x0080 /* GPIO7 */
2591#define STR_WREN 0x0100 /* GPIO8 */
2592#define STR_MOST 0x0200 /* GPIO9 */
2593
2594static void snd_es1968_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
2595{
2596 struct es1968 *chip = tea->private_data;
2597 unsigned long io = chip->io_port + GPIO_DATA;
2598 u16 val = 0;
2599
2600 val |= (pins & TEA575X_DATA) ? STR_DATA : 0;
2601 val |= (pins & TEA575X_CLK) ? STR_CLK : 0;
2602 val |= (pins & TEA575X_WREN) ? STR_WREN : 0;
2603
2604 outw(val, io);
2605}
2606
2607static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea)
2608{
2609 struct es1968 *chip = tea->private_data;
2610 unsigned long io = chip->io_port + GPIO_DATA;
2611 u16 val = inw(io);
2612
2613 return (val & STR_DATA) ? TEA575X_DATA : 0 |
2614 (val & STR_MOST) ? TEA575X_MOST : 0;
2615}
2616
2617static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output)
2618{
2619 struct es1968 *chip = tea->private_data;
2620 unsigned long io = chip->io_port + GPIO_DATA;
2621 u16 odir = inw(io + IO_DIR);
2622
2623 if (output) {
2624 outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
2625 outw(odir | STR_DATA | STR_CLK | STR_WREN, io + IO_DIR);
2626 } else {
2627 outw(~(STR_CLK | STR_WREN | STR_DATA | STR_MOST), io + IO_MASK);
2628 outw((odir & ~(STR_DATA | STR_MOST)) | STR_CLK | STR_WREN, io + IO_DIR);
2629 }
2630}
2631
2632static struct snd_tea575x_ops snd_es1968_tea_ops = {
2633 .set_pins = snd_es1968_tea575x_set_pins,
2634 .get_pins = snd_es1968_tea575x_get_pins,
2635 .set_direction = snd_es1968_tea575x_set_direction,
2636};
2637#endif
2638
2574static int snd_es1968_free(struct es1968 *chip) 2639static int snd_es1968_free(struct es1968 *chip)
2575{ 2640{
2576#ifdef CONFIG_SND_ES1968_INPUT 2641#ifdef CONFIG_SND_ES1968_INPUT
@@ -2585,6 +2650,10 @@ static int snd_es1968_free(struct es1968 *chip)
2585 outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */ 2650 outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */
2586 } 2651 }
2587 2652
2653#ifdef CONFIG_SND_ES1968_RADIO
2654 snd_tea575x_exit(&chip->tea);
2655#endif
2656
2588 if (chip->irq >= 0) 2657 if (chip->irq >= 0)
2589 free_irq(chip->irq, chip); 2658 free_irq(chip->irq, chip);
2590 snd_es1968_free_gameport(chip); 2659 snd_es1968_free_gameport(chip);
@@ -2723,6 +2792,15 @@ static int __devinit snd_es1968_create(struct snd_card *card,
2723 2792
2724 snd_card_set_dev(card, &pci->dev); 2793 snd_card_set_dev(card, &pci->dev);
2725 2794
2795#ifdef CONFIG_SND_ES1968_RADIO
2796 chip->tea.private_data = chip;
2797 chip->tea.ops = &snd_es1968_tea_ops;
2798 strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card));
2799 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
2800 if (!snd_tea575x_init(&chip->tea))
2801 printk(KERN_INFO "es1968: detected TEA575x radio\n");
2802#endif
2803
2726 *chip_ret = chip; 2804 *chip_ret = chip;
2727 2805
2728 return 0; 2806 return 0;
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index e1baad74ea4b..eacd4901a308 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -38,7 +38,6 @@
38 38
39#ifdef CONFIG_SND_FM801_TEA575X_BOOL 39#ifdef CONFIG_SND_FM801_TEA575X_BOOL
40#include <sound/tea575x-tuner.h> 40#include <sound/tea575x-tuner.h>
41#define TEA575X_RADIO 1
42#endif 41#endif
43 42
44MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 43MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
@@ -53,7 +52,7 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card *
53/* 52/*
54 * Enable TEA575x tuner 53 * Enable TEA575x tuner
55 * 1 = MediaForte 256-PCS 54 * 1 = MediaForte 256-PCS
56 * 2 = MediaForte 256-PCPR 55 * 2 = MediaForte 256-PCP
57 * 3 = MediaForte 64-PCR 56 * 3 = MediaForte 64-PCR
58 * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card 57 * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card
59 * High 16-bits are video (radio) device number + 1 58 * High 16-bits are video (radio) device number + 1
@@ -67,7 +66,7 @@ MODULE_PARM_DESC(id, "ID string for the FM801 soundcard.");
67module_param_array(enable, bool, NULL, 0444); 66module_param_array(enable, bool, NULL, 0444);
68MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); 67MODULE_PARM_DESC(enable, "Enable FM801 soundcard.");
69module_param_array(tea575x_tuner, int, NULL, 0444); 68module_param_array(tea575x_tuner, int, NULL, 0444);
70MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (1 = SF256-PCS, 2=SF256-PCPR, 3=SF64-PCR, +16=tuner-only)."); 69MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only).");
71 70
72#define TUNER_ONLY (1<<4) 71#define TUNER_ONLY (1<<4)
73#define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF) 72#define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF)
@@ -196,7 +195,7 @@ struct fm801 {
196 spinlock_t reg_lock; 195 spinlock_t reg_lock;
197 struct snd_info_entry *proc_entry; 196 struct snd_info_entry *proc_entry;
198 197
199#ifdef TEA575X_RADIO 198#ifdef CONFIG_SND_FM801_TEA575X_BOOL
200 struct snd_tea575x tea; 199 struct snd_tea575x tea;
201#endif 200#endif
202 201
@@ -715,310 +714,89 @@ static int __devinit snd_fm801_pcm(struct fm801 *chip, int device, struct snd_pc
715 * TEA5757 radio 714 * TEA5757 radio
716 */ 715 */
717 716
718#ifdef TEA575X_RADIO 717#ifdef CONFIG_SND_FM801_TEA575X_BOOL
719
720/* 256PCS GPIO numbers */
721#define TEA_256PCS_DATA 1
722#define TEA_256PCS_WRITE_ENABLE 2 /* inverted */
723#define TEA_256PCS_BUS_CLOCK 3
724
725static void snd_fm801_tea575x_256pcs_write(struct snd_tea575x *tea, unsigned int val)
726{
727 struct fm801 *chip = tea->private_data;
728 unsigned short reg;
729 int i = 25;
730 718
731 spin_lock_irq(&chip->reg_lock); 719/* GPIO to TEA575x maps */
732 reg = inw(FM801_REG(chip, GPIO_CTRL)); 720struct snd_fm801_tea575x_gpio {
733 /* use GPIO lines and set write enable bit */ 721 u8 data, clk, wren, most;
734 reg |= FM801_GPIO_GS(TEA_256PCS_DATA) | 722 char *name;
735 FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) | 723};
736 FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK);
737 /* all of lines are in the write direction */
738 /* clear data and clock lines */
739 reg &= ~(FM801_GPIO_GD(TEA_256PCS_DATA) |
740 FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) |
741 FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) |
742 FM801_GPIO_GP(TEA_256PCS_DATA) |
743 FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK) |
744 FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE));
745 outw(reg, FM801_REG(chip, GPIO_CTRL));
746 udelay(1);
747
748 while (i--) {
749 if (val & (1 << i))
750 reg |= FM801_GPIO_GP(TEA_256PCS_DATA);
751 else
752 reg &= ~FM801_GPIO_GP(TEA_256PCS_DATA);
753 outw(reg, FM801_REG(chip, GPIO_CTRL));
754 udelay(1);
755 reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
756 outw(reg, FM801_REG(chip, GPIO_CTRL));
757 reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
758 outw(reg, FM801_REG(chip, GPIO_CTRL));
759 udelay(1);
760 }
761 724
762 /* and reset the write enable bit */ 725static struct snd_fm801_tea575x_gpio snd_fm801_tea575x_gpios[] = {
763 reg |= FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE) | 726 { .data = 1, .clk = 3, .wren = 2, .most = 0, .name = "SF256-PCS" },
764 FM801_GPIO_GP(TEA_256PCS_DATA); 727 { .data = 1, .clk = 0, .wren = 2, .most = 3, .name = "SF256-PCP" },
765 outw(reg, FM801_REG(chip, GPIO_CTRL)); 728 { .data = 2, .clk = 0, .wren = 1, .most = 3, .name = "SF64-PCR" },
766 spin_unlock_irq(&chip->reg_lock); 729};
767}
768 730
769static unsigned int snd_fm801_tea575x_256pcs_read(struct snd_tea575x *tea) 731static void snd_fm801_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
770{ 732{
771 struct fm801 *chip = tea->private_data; 733 struct fm801 *chip = tea->private_data;
772 unsigned short reg; 734 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
773 unsigned int val = 0; 735 struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1];
774 int i;
775
776 spin_lock_irq(&chip->reg_lock);
777 reg = inw(FM801_REG(chip, GPIO_CTRL));
778 /* use GPIO lines, set data direction to input */
779 reg |= FM801_GPIO_GS(TEA_256PCS_DATA) |
780 FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) |
781 FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK) |
782 FM801_GPIO_GD(TEA_256PCS_DATA) |
783 FM801_GPIO_GP(TEA_256PCS_DATA) |
784 FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE);
785 /* all of lines are in the write direction, except data */
786 /* clear data, write enable and clock lines */
787 reg &= ~(FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) |
788 FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) |
789 FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK));
790
791 for (i = 0; i < 24; i++) {
792 reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
793 outw(reg, FM801_REG(chip, GPIO_CTRL));
794 udelay(1);
795 reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
796 outw(reg, FM801_REG(chip, GPIO_CTRL));
797 udelay(1);
798 val <<= 1;
799 if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCS_DATA))
800 val |= 1;
801 }
802 736
803 spin_unlock_irq(&chip->reg_lock); 737 reg &= ~(FM801_GPIO_GP(gpio.data) |
738 FM801_GPIO_GP(gpio.clk) |
739 FM801_GPIO_GP(gpio.wren));
804 740
805 return val; 741 reg |= (pins & TEA575X_DATA) ? FM801_GPIO_GP(gpio.data) : 0;
806} 742 reg |= (pins & TEA575X_CLK) ? FM801_GPIO_GP(gpio.clk) : 0;
743 /* WRITE_ENABLE is inverted */
744 reg |= (pins & TEA575X_WREN) ? 0 : FM801_GPIO_GP(gpio.wren);
807 745
808/* 256PCPR GPIO numbers */
809#define TEA_256PCPR_BUS_CLOCK 0
810#define TEA_256PCPR_DATA 1
811#define TEA_256PCPR_WRITE_ENABLE 2 /* inverted */
812
813static void snd_fm801_tea575x_256pcpr_write(struct snd_tea575x *tea, unsigned int val)
814{
815 struct fm801 *chip = tea->private_data;
816 unsigned short reg;
817 int i = 25;
818
819 spin_lock_irq(&chip->reg_lock);
820 reg = inw(FM801_REG(chip, GPIO_CTRL));
821 /* use GPIO lines and set write enable bit */
822 reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) |
823 FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) |
824 FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK);
825 /* all of lines are in the write direction */
826 /* clear data and clock lines */
827 reg &= ~(FM801_GPIO_GD(TEA_256PCPR_DATA) |
828 FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) |
829 FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) |
830 FM801_GPIO_GP(TEA_256PCPR_DATA) |
831 FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK) |
832 FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE));
833 outw(reg, FM801_REG(chip, GPIO_CTRL)); 746 outw(reg, FM801_REG(chip, GPIO_CTRL));
834 udelay(1);
835
836 while (i--) {
837 if (val & (1 << i))
838 reg |= FM801_GPIO_GP(TEA_256PCPR_DATA);
839 else
840 reg &= ~FM801_GPIO_GP(TEA_256PCPR_DATA);
841 outw(reg, FM801_REG(chip, GPIO_CTRL));
842 udelay(1);
843 reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
844 outw(reg, FM801_REG(chip, GPIO_CTRL));
845 reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
846 outw(reg, FM801_REG(chip, GPIO_CTRL));
847 udelay(1);
848 }
849
850 /* and reset the write enable bit */
851 reg |= FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE) |
852 FM801_GPIO_GP(TEA_256PCPR_DATA);
853 outw(reg, FM801_REG(chip, GPIO_CTRL));
854 spin_unlock_irq(&chip->reg_lock);
855} 747}
856 748
857static unsigned int snd_fm801_tea575x_256pcpr_read(struct snd_tea575x *tea) 749static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea)
858{ 750{
859 struct fm801 *chip = tea->private_data; 751 struct fm801 *chip = tea->private_data;
860 unsigned short reg; 752 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
861 unsigned int val = 0; 753 struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1];
862 int i;
863
864 spin_lock_irq(&chip->reg_lock);
865 reg = inw(FM801_REG(chip, GPIO_CTRL));
866 /* use GPIO lines, set data direction to input */
867 reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) |
868 FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) |
869 FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK) |
870 FM801_GPIO_GD(TEA_256PCPR_DATA) |
871 FM801_GPIO_GP(TEA_256PCPR_DATA) |
872 FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE);
873 /* all of lines are in the write direction, except data */
874 /* clear data, write enable and clock lines */
875 reg &= ~(FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) |
876 FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) |
877 FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK));
878
879 for (i = 0; i < 24; i++) {
880 reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
881 outw(reg, FM801_REG(chip, GPIO_CTRL));
882 udelay(1);
883 reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
884 outw(reg, FM801_REG(chip, GPIO_CTRL));
885 udelay(1);
886 val <<= 1;
887 if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCPR_DATA))
888 val |= 1;
889 }
890 754
891 spin_unlock_irq(&chip->reg_lock); 755 return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 |
892 756 (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0;
893 return val;
894} 757}
895 758
896/* 64PCR GPIO numbers */ 759static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output)
897#define TEA_64PCR_BUS_CLOCK 0
898#define TEA_64PCR_WRITE_ENABLE 1 /* inverted */
899#define TEA_64PCR_DATA 2
900
901static void snd_fm801_tea575x_64pcr_write(struct snd_tea575x *tea, unsigned int val)
902{ 760{
903 struct fm801 *chip = tea->private_data; 761 struct fm801 *chip = tea->private_data;
904 unsigned short reg; 762 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
905 int i = 25; 763 struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1];
906 764
907 spin_lock_irq(&chip->reg_lock);
908 reg = inw(FM801_REG(chip, GPIO_CTRL));
909 /* use GPIO lines and set write enable bit */ 765 /* use GPIO lines and set write enable bit */
910 reg |= FM801_GPIO_GS(TEA_64PCR_DATA) | 766 reg |= FM801_GPIO_GS(gpio.data) |
911 FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) | 767 FM801_GPIO_GS(gpio.wren) |
912 FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK); 768 FM801_GPIO_GS(gpio.clk) |
913 /* all of lines are in the write direction */ 769 FM801_GPIO_GS(gpio.most);
914 /* clear data and clock lines */ 770 if (output) {
915 reg &= ~(FM801_GPIO_GD(TEA_64PCR_DATA) | 771 /* all of lines are in the write direction */
916 FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) | 772 /* clear data and clock lines */
917 FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) | 773 reg &= ~(FM801_GPIO_GD(gpio.data) |
918 FM801_GPIO_GP(TEA_64PCR_DATA) | 774 FM801_GPIO_GD(gpio.wren) |
919 FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK) | 775 FM801_GPIO_GD(gpio.clk) |
920 FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE)); 776 FM801_GPIO_GP(gpio.data) |
921 outw(reg, FM801_REG(chip, GPIO_CTRL)); 777 FM801_GPIO_GP(gpio.clk) |
922 udelay(1); 778 FM801_GPIO_GP(gpio.wren));
923 779 } else {
924 while (i--) { 780 /* use GPIO lines, set data direction to input */
925 if (val & (1 << i)) 781 reg |= FM801_GPIO_GD(gpio.data) |
926 reg |= FM801_GPIO_GP(TEA_64PCR_DATA); 782 FM801_GPIO_GD(gpio.most) |
927 else 783 FM801_GPIO_GP(gpio.data) |
928 reg &= ~FM801_GPIO_GP(TEA_64PCR_DATA); 784 FM801_GPIO_GP(gpio.most) |
929 outw(reg, FM801_REG(chip, GPIO_CTRL)); 785 FM801_GPIO_GP(gpio.wren);
930 udelay(1); 786 /* all of lines are in the write direction, except data */
931 reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); 787 /* clear data, write enable and clock lines */
932 outw(reg, FM801_REG(chip, GPIO_CTRL)); 788 reg &= ~(FM801_GPIO_GD(gpio.wren) |
933 reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); 789 FM801_GPIO_GD(gpio.clk) |
934 outw(reg, FM801_REG(chip, GPIO_CTRL)); 790 FM801_GPIO_GP(gpio.clk));
935 udelay(1);
936 } 791 }
937 792
938 /* and reset the write enable bit */
939 reg |= FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE) |
940 FM801_GPIO_GP(TEA_64PCR_DATA);
941 outw(reg, FM801_REG(chip, GPIO_CTRL)); 793 outw(reg, FM801_REG(chip, GPIO_CTRL));
942 spin_unlock_irq(&chip->reg_lock);
943}
944
945static unsigned int snd_fm801_tea575x_64pcr_read(struct snd_tea575x *tea)
946{
947 struct fm801 *chip = tea->private_data;
948 unsigned short reg;
949 unsigned int val = 0;
950 int i;
951
952 spin_lock_irq(&chip->reg_lock);
953 reg = inw(FM801_REG(chip, GPIO_CTRL));
954 /* use GPIO lines, set data direction to input */
955 reg |= FM801_GPIO_GS(TEA_64PCR_DATA) |
956 FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) |
957 FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK) |
958 FM801_GPIO_GD(TEA_64PCR_DATA) |
959 FM801_GPIO_GP(TEA_64PCR_DATA) |
960 FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
961 /* all of lines are in the write direction, except data */
962 /* clear data, write enable and clock lines */
963 reg &= ~(FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) |
964 FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) |
965 FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK));
966
967 for (i = 0; i < 24; i++) {
968 reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
969 outw(reg, FM801_REG(chip, GPIO_CTRL));
970 udelay(1);
971 reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
972 outw(reg, FM801_REG(chip, GPIO_CTRL));
973 udelay(1);
974 val <<= 1;
975 if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_64PCR_DATA))
976 val |= 1;
977 }
978
979 spin_unlock_irq(&chip->reg_lock);
980
981 return val;
982} 794}
983 795
984static void snd_fm801_tea575x_64pcr_mute(struct snd_tea575x *tea, 796static struct snd_tea575x_ops snd_fm801_tea_ops = {
985 unsigned int mute) 797 .set_pins = snd_fm801_tea575x_set_pins,
986{ 798 .get_pins = snd_fm801_tea575x_get_pins,
987 struct fm801 *chip = tea->private_data; 799 .set_direction = snd_fm801_tea575x_set_direction,
988 unsigned short reg;
989
990 spin_lock_irq(&chip->reg_lock);
991
992 reg = inw(FM801_REG(chip, GPIO_CTRL));
993 if (mute)
994 /* 0xf800 (mute) */
995 reg &= ~FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
996 else
997 /* 0xf802 (unmute) */
998 reg |= FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
999 outw(reg, FM801_REG(chip, GPIO_CTRL));
1000 udelay(1);
1001
1002 spin_unlock_irq(&chip->reg_lock);
1003}
1004
1005static struct snd_tea575x_ops snd_fm801_tea_ops[3] = {
1006 {
1007 /* 1 = MediaForte 256-PCS */
1008 .write = snd_fm801_tea575x_256pcs_write,
1009 .read = snd_fm801_tea575x_256pcs_read,
1010 },
1011 {
1012 /* 2 = MediaForte 256-PCPR */
1013 .write = snd_fm801_tea575x_256pcpr_write,
1014 .read = snd_fm801_tea575x_256pcpr_read,
1015 },
1016 {
1017 /* 3 = MediaForte 64-PCR */
1018 .write = snd_fm801_tea575x_64pcr_write,
1019 .read = snd_fm801_tea575x_64pcr_read,
1020 .mute = snd_fm801_tea575x_64pcr_mute,
1021 }
1022}; 800};
1023#endif 801#endif
1024 802
@@ -1371,7 +1149,7 @@ static int snd_fm801_free(struct fm801 *chip)
1371 outw(cmdw, FM801_REG(chip, IRQ_MASK)); 1149 outw(cmdw, FM801_REG(chip, IRQ_MASK));
1372 1150
1373 __end_hw: 1151 __end_hw:
1374#ifdef TEA575X_RADIO 1152#ifdef CONFIG_SND_FM801_TEA575X_BOOL
1375 snd_tea575x_exit(&chip->tea); 1153 snd_tea575x_exit(&chip->tea);
1376#endif 1154#endif
1377 if (chip->irq >= 0) 1155 if (chip->irq >= 0)
@@ -1450,16 +1228,25 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1450 1228
1451 snd_card_set_dev(card, &pci->dev); 1229 snd_card_set_dev(card, &pci->dev);
1452 1230
1453#ifdef TEA575X_RADIO 1231#ifdef CONFIG_SND_FM801_TEA575X_BOOL
1232 chip->tea.private_data = chip;
1233 chip->tea.ops = &snd_fm801_tea_ops;
1234 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
1454 if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && 1235 if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 &&
1455 (tea575x_tuner & TUNER_TYPE_MASK) < 4) { 1236 (tea575x_tuner & TUNER_TYPE_MASK) < 4) {
1456 chip->tea.dev_nr = tea575x_tuner >> 16; 1237 if (snd_tea575x_init(&chip->tea))
1457 chip->tea.card = card; 1238 snd_printk(KERN_ERR "TEA575x radio not found\n");
1458 chip->tea.freq_fixup = 10700; 1239 } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0)
1459 chip->tea.private_data = chip; 1240 /* autodetect tuner connection */
1460 chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & TUNER_TYPE_MASK) - 1]; 1241 for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) {
1461 snd_tea575x_init(&chip->tea); 1242 chip->tea575x_tuner = tea575x_tuner;
1462 } 1243 if (!snd_tea575x_init(&chip->tea)) {
1244 snd_printk(KERN_INFO "detected TEA575x radio type %s\n",
1245 snd_fm801_tea575x_gpios[tea575x_tuner - 1].name);
1246 break;
1247 }
1248 }
1249 strlcpy(chip->tea.card, snd_fm801_tea575x_gpios[(tea575x_tuner & TUNER_TYPE_MASK) - 1].name, sizeof(chip->tea.card));
1463#endif 1250#endif
1464 1251
1465 *rchip = chip; 1252 *rchip = chip;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 759ade12e758..8edd998509f7 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -307,6 +307,12 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
307} 307}
308EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); 308EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes);
309 309
310static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
311 hda_nid_t *conn_list, int max_conns);
312static bool add_conn_list(struct snd_array *array, hda_nid_t nid);
313static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst,
314 hda_nid_t *src, int len);
315
310/** 316/**
311 * snd_hda_get_connections - get connection list 317 * snd_hda_get_connections - get connection list
312 * @codec: the HDA codec 318 * @codec: the HDA codec
@@ -320,7 +326,44 @@ EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes);
320 * Returns the number of connections, or a negative error code. 326 * Returns the number of connections, or a negative error code.
321 */ 327 */
322int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 328int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
323 hda_nid_t *conn_list, int max_conns) 329 hda_nid_t *conn_list, int max_conns)
330{
331 struct snd_array *array = &codec->conn_lists;
332 int i, len, old_used;
333 hda_nid_t list[HDA_MAX_CONNECTIONS];
334
335 /* look up the cached results */
336 for (i = 0; i < array->used; ) {
337 hda_nid_t *p = snd_array_elem(array, i);
338 len = p[1];
339 if (nid == *p)
340 return copy_conn_list(nid, conn_list, max_conns,
341 p + 2, len);
342 i += len + 2;
343 }
344
345 len = _hda_get_connections(codec, nid, list, HDA_MAX_CONNECTIONS);
346 if (len < 0)
347 return len;
348
349 /* add to the cache */
350 old_used = array->used;
351 if (!add_conn_list(array, nid) || !add_conn_list(array, len))
352 goto error_add;
353 for (i = 0; i < len; i++)
354 if (!add_conn_list(array, list[i]))
355 goto error_add;
356
357 return copy_conn_list(nid, conn_list, max_conns, list, len);
358
359 error_add:
360 array->used = old_used;
361 return -ENOMEM;
362}
363EXPORT_SYMBOL_HDA(snd_hda_get_connections);
364
365static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
366 hda_nid_t *conn_list, int max_conns)
324{ 367{
325 unsigned int parm; 368 unsigned int parm;
326 int i, conn_len, conns; 369 int i, conn_len, conns;
@@ -417,8 +460,28 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
417 } 460 }
418 return conns; 461 return conns;
419} 462}
420EXPORT_SYMBOL_HDA(snd_hda_get_connections);
421 463
464static bool add_conn_list(struct snd_array *array, hda_nid_t nid)
465{
466 hda_nid_t *p = snd_array_new(array);
467 if (!p)
468 return false;
469 *p = nid;
470 return true;
471}
472
473static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst,
474 hda_nid_t *src, int len)
475{
476 if (len > max_dst) {
477 snd_printk(KERN_ERR "hda_codec: "
478 "Too many connections %d for NID 0x%x\n",
479 len, nid);
480 return -EINVAL;
481 }
482 memcpy(dst, src, len * sizeof(hda_nid_t));
483 return len;
484}
422 485
423/** 486/**
424 * snd_hda_queue_unsol_event - add an unsolicited event to queue 487 * snd_hda_queue_unsol_event - add an unsolicited event to queue
@@ -1019,6 +1082,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
1019 list_del(&codec->list); 1082 list_del(&codec->list);
1020 snd_array_free(&codec->mixers); 1083 snd_array_free(&codec->mixers);
1021 snd_array_free(&codec->nids); 1084 snd_array_free(&codec->nids);
1085 snd_array_free(&codec->conn_lists);
1022 codec->bus->caddr_tbl[codec->addr] = NULL; 1086 codec->bus->caddr_tbl[codec->addr] = NULL;
1023 if (codec->patch_ops.free) 1087 if (codec->patch_ops.free)
1024 codec->patch_ops.free(codec); 1088 codec->patch_ops.free(codec);
@@ -1079,6 +1143,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
1079 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); 1143 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
1080 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); 1144 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
1081 snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); 1145 snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
1146 snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64);
1082 if (codec->bus->modelname) { 1147 if (codec->bus->modelname) {
1083 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); 1148 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
1084 if (!codec->modelname) { 1149 if (!codec->modelname) {
@@ -2556,7 +2621,7 @@ static unsigned int convert_to_spdif_status(unsigned short val)
2556static void set_dig_out(struct hda_codec *codec, hda_nid_t nid, 2621static void set_dig_out(struct hda_codec *codec, hda_nid_t nid,
2557 int verb, int val) 2622 int verb, int val)
2558{ 2623{
2559 hda_nid_t *d; 2624 const hda_nid_t *d;
2560 2625
2561 snd_hda_codec_write_cache(codec, nid, 0, verb, val); 2626 snd_hda_codec_write_cache(codec, nid, 0, verb, val);
2562 d = codec->slave_dig_outs; 2627 d = codec->slave_dig_outs;
@@ -3807,7 +3872,8 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config);
3807 * 3872 *
3808 * Returns 0 if successful, or a negative error code. 3873 * Returns 0 if successful, or a negative error code.
3809 */ 3874 */
3810int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) 3875int snd_hda_add_new_ctls(struct hda_codec *codec,
3876 const struct snd_kcontrol_new *knew)
3811{ 3877{
3812 int err; 3878 int err;
3813 3879
@@ -3950,7 +4016,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
3950 struct hda_loopback_check *check, 4016 struct hda_loopback_check *check,
3951 hda_nid_t nid) 4017 hda_nid_t nid)
3952{ 4018{
3953 struct hda_amp_list *p; 4019 const struct hda_amp_list *p;
3954 int ch, v; 4020 int ch, v;
3955 4021
3956 if (!check->amplist) 4022 if (!check->amplist)
@@ -4118,7 +4184,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
4118 -1); 4184 -1);
4119 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 4185 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
4120 if (codec->slave_dig_outs) { 4186 if (codec->slave_dig_outs) {
4121 hda_nid_t *d; 4187 const hda_nid_t *d;
4122 for (d = codec->slave_dig_outs; *d; d++) 4188 for (d = codec->slave_dig_outs; *d; d++)
4123 snd_hda_codec_setup_stream(codec, *d, stream_tag, 0, 4189 snd_hda_codec_setup_stream(codec, *d, stream_tag, 0,
4124 format); 4190 format);
@@ -4133,7 +4199,7 @@ static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
4133{ 4199{
4134 snd_hda_codec_cleanup_stream(codec, nid); 4200 snd_hda_codec_cleanup_stream(codec, nid);
4135 if (codec->slave_dig_outs) { 4201 if (codec->slave_dig_outs) {
4136 hda_nid_t *d; 4202 const hda_nid_t *d;
4137 for (d = codec->slave_dig_outs; *d; d++) 4203 for (d = codec->slave_dig_outs; *d; d++)
4138 snd_hda_codec_cleanup_stream(codec, *d); 4204 snd_hda_codec_cleanup_stream(codec, *d);
4139 } 4205 }
@@ -4280,7 +4346,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
4280 unsigned int format, 4346 unsigned int format,
4281 struct snd_pcm_substream *substream) 4347 struct snd_pcm_substream *substream)
4282{ 4348{
4283 hda_nid_t *nids = mout->dac_nids; 4349 const hda_nid_t *nids = mout->dac_nids;
4284 int chs = substream->runtime->channels; 4350 int chs = substream->runtime->channels;
4285 int i; 4351 int i;
4286 4352
@@ -4335,7 +4401,7 @@ EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_prepare);
4335int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, 4401int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
4336 struct hda_multi_out *mout) 4402 struct hda_multi_out *mout)
4337{ 4403{
4338 hda_nid_t *nids = mout->dac_nids; 4404 const hda_nid_t *nids = mout->dac_nids;
4339 int i; 4405 int i;
4340 4406
4341 for (i = 0; i < mout->num_dacs; i++) 4407 for (i = 0; i < mout->num_dacs; i++)
@@ -4360,7 +4426,7 @@ EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup);
4360 * Helper for automatic pin configuration 4426 * Helper for automatic pin configuration
4361 */ 4427 */
4362 4428
4363static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) 4429static int is_in_nid_list(hda_nid_t nid, const hda_nid_t *list)
4364{ 4430{
4365 for (; *list; list++) 4431 for (; *list; list++)
4366 if (*list == nid) 4432 if (*list == nid)
@@ -4441,7 +4507,7 @@ static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg)
4441 */ 4507 */
4442int snd_hda_parse_pin_def_config(struct hda_codec *codec, 4508int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4443 struct auto_pin_cfg *cfg, 4509 struct auto_pin_cfg *cfg,
4444 hda_nid_t *ignore_nids) 4510 const hda_nid_t *ignore_nids)
4445{ 4511{
4446 hda_nid_t nid, end_nid; 4512 hda_nid_t nid, end_nid;
4447 short seq, assoc_line_out, assoc_speaker; 4513 short seq, assoc_line_out, assoc_speaker;
@@ -4632,10 +4698,13 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4632 /* 4698 /*
4633 * debug prints of the parsed results 4699 * debug prints of the parsed results
4634 */ 4700 */
4635 snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", 4701 snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x) type:%s\n",
4636 cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1], 4702 cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1],
4637 cfg->line_out_pins[2], cfg->line_out_pins[3], 4703 cfg->line_out_pins[2], cfg->line_out_pins[3],
4638 cfg->line_out_pins[4]); 4704 cfg->line_out_pins[4],
4705 cfg->line_out_type == AUTO_PIN_HP_OUT ? "hp" :
4706 (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ?
4707 "speaker" : "line"));
4639 snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", 4708 snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
4640 cfg->speaker_outs, cfg->speaker_pins[0], 4709 cfg->speaker_outs, cfg->speaker_pins[0],
4641 cfg->speaker_pins[1], cfg->speaker_pins[2], 4710 cfg->speaker_pins[1], cfg->speaker_pins[2],
@@ -4986,6 +5055,8 @@ static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid,
4986 return "Line-out"; 5055 return "Line-out";
4987 case SND_JACK_HEADSET: 5056 case SND_JACK_HEADSET:
4988 return "Headset"; 5057 return "Headset";
5058 case SND_JACK_VIDEOOUT:
5059 return "HDMI/DP";
4989 default: 5060 default:
4990 return "Misc"; 5061 return "Misc";
4991 } 5062 }
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index e46d5420a9f2..59c97306c1de 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -825,12 +825,14 @@ struct hda_codec {
825 struct hda_cache_rec amp_cache; /* cache for amp access */ 825 struct hda_cache_rec amp_cache; /* cache for amp access */
826 struct hda_cache_rec cmd_cache; /* cache for other commands */ 826 struct hda_cache_rec cmd_cache; /* cache for other commands */
827 827
828 struct snd_array conn_lists; /* connection-list array */
829
828 struct mutex spdif_mutex; 830 struct mutex spdif_mutex;
829 struct mutex control_mutex; 831 struct mutex control_mutex;
830 unsigned int spdif_status; /* IEC958 status bits */ 832 unsigned int spdif_status; /* IEC958 status bits */
831 unsigned short spdif_ctls; /* SPDIF control bits */ 833 unsigned short spdif_ctls; /* SPDIF control bits */
832 unsigned int spdif_in_enable; /* SPDIF input enable? */ 834 unsigned int spdif_in_enable; /* SPDIF input enable? */
833 hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ 835 const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
834 struct snd_array init_pins; /* initial (BIOS) pin configurations */ 836 struct snd_array init_pins; /* initial (BIOS) pin configurations */
835 struct snd_array driver_pins; /* pin configs set by codec parser */ 837 struct snd_array driver_pins; /* pin configs set by codec parser */
836 struct snd_array cvt_setups; /* audio convert setups */ 838 struct snd_array cvt_setups; /* audio convert setups */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 70a9d32f0e96..43a036716d25 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -126,6 +126,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
126 "{Intel, ICH10}," 126 "{Intel, ICH10},"
127 "{Intel, PCH}," 127 "{Intel, PCH},"
128 "{Intel, CPT}," 128 "{Intel, CPT},"
129 "{Intel, PPT},"
129 "{Intel, PBG}," 130 "{Intel, PBG},"
130 "{Intel, SCH}," 131 "{Intel, SCH},"
131 "{ATI, SB450}," 132 "{ATI, SB450},"
@@ -1091,7 +1092,13 @@ static void azx_init_pci(struct azx *chip)
1091 ? "Failed" : "OK"); 1092 ? "Failed" : "OK");
1092 } 1093 }
1093 break; 1094 break;
1094 1095 default:
1096 /* AMD Hudson needs the similar snoop, as it seems... */
1097 if (chip->pci->vendor == PCI_VENDOR_ID_AMD)
1098 update_pci_byte(chip->pci,
1099 ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR,
1100 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP);
1101 break;
1095 } 1102 }
1096} 1103}
1097 1104
@@ -1446,6 +1453,17 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1446 } 1453 }
1447 } 1454 }
1448 1455
1456 /* AMD chipsets often cause the communication stalls upon certain
1457 * sequence like the pin-detection. It seems that forcing the synced
1458 * access works around the stall. Grrr...
1459 */
1460 if (chip->pci->vendor == PCI_VENDOR_ID_AMD ||
1461 chip->pci->vendor == PCI_VENDOR_ID_ATI) {
1462 snd_printk(KERN_INFO SFX "Enable sync_write for AMD chipset\n");
1463 chip->bus->sync_write = 1;
1464 chip->bus->allow_bus_reset = 1;
1465 }
1466
1449 /* Then create codec instances */ 1467 /* Then create codec instances */
1450 for (c = 0; c < max_slots; c++) { 1468 for (c = 0; c < max_slots; c++) {
1451 if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { 1469 if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
@@ -2349,9 +2367,16 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
2349 /* Check VIA/ATI HD Audio Controller exist */ 2367 /* Check VIA/ATI HD Audio Controller exist */
2350 switch (chip->driver_type) { 2368 switch (chip->driver_type) {
2351 case AZX_DRIVER_VIA: 2369 case AZX_DRIVER_VIA:
2352 case AZX_DRIVER_ATI:
2353 /* Use link position directly, avoid any transfer problem. */ 2370 /* Use link position directly, avoid any transfer problem. */
2354 return POS_FIX_VIACOMBO; 2371 return POS_FIX_VIACOMBO;
2372 case AZX_DRIVER_ATI:
2373 /* ATI chipsets don't work well with position-buffer */
2374 return POS_FIX_LPIB;
2375 case AZX_DRIVER_GENERIC:
2376 /* AMD chipsets also don't work with position-buffer */
2377 if (chip->pci->vendor == PCI_VENDOR_ID_AMD)
2378 return POS_FIX_LPIB;
2379 break;
2355 } 2380 }
2356 2381
2357 return POS_FIX_AUTO; 2382 return POS_FIX_AUTO;
@@ -2549,6 +2574,13 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2549 gcap &= ~ICH6_GCAP_64OK; 2574 gcap &= ~ICH6_GCAP_64OK;
2550 pci_dev_put(p_smbus); 2575 pci_dev_put(p_smbus);
2551 } 2576 }
2577 } else {
2578 /* FIXME: not sure whether this is really needed, but
2579 * Hudson isn't stable enough for allowing everything...
2580 * let's check later again.
2581 */
2582 if (chip->pci->vendor == PCI_VENDOR_ID_AMD)
2583 gcap &= ~ICH6_GCAP_64OK;
2552 } 2584 }
2553 2585
2554 /* disable 64bit DMA address for Teradici */ 2586 /* disable 64bit DMA address for Teradici */
@@ -2759,6 +2791,8 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2759 { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH }, 2791 { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH },
2760 /* PBG */ 2792 /* PBG */
2761 { PCI_DEVICE(0x8086, 0x1d20), .driver_data = AZX_DRIVER_PCH }, 2793 { PCI_DEVICE(0x8086, 0x1d20), .driver_data = AZX_DRIVER_PCH },
2794 /* Panther Point */
2795 { PCI_DEVICE(0x8086, 0x1e20), .driver_data = AZX_DRIVER_PCH },
2762 /* SCH */ 2796 /* SCH */
2763 { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, 2797 { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH },
2764 /* Generic Intel */ 2798 /* Generic Intel */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index ff5e2ac2239a..08ec073444e2 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -267,11 +267,11 @@ enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */
267 267
268struct hda_multi_out { 268struct hda_multi_out {
269 int num_dacs; /* # of DACs, must be more than 1 */ 269 int num_dacs; /* # of DACs, must be more than 1 */
270 hda_nid_t *dac_nids; /* DAC list */ 270 const hda_nid_t *dac_nids; /* DAC list */
271 hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */ 271 hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */
272 hda_nid_t extra_out_nid[3]; /* optional DACs, 0 when not exists */ 272 hda_nid_t extra_out_nid[3]; /* optional DACs, 0 when not exists */
273 hda_nid_t dig_out_nid; /* digital out audio widget */ 273 hda_nid_t dig_out_nid; /* digital out audio widget */
274 hda_nid_t *slave_dig_outs; 274 const hda_nid_t *slave_dig_outs;
275 int max_channels; /* currently supported analog channels */ 275 int max_channels; /* currently supported analog channels */
276 int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */ 276 int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */
277 int no_share_stream; /* don't share a stream with multiple pins */ 277 int no_share_stream; /* don't share a stream with multiple pins */
@@ -347,7 +347,7 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
347 int num_configs, const char * const *models, 347 int num_configs, const char * const *models,
348 const struct snd_pci_quirk *tbl); 348 const struct snd_pci_quirk *tbl);
349int snd_hda_add_new_ctls(struct hda_codec *codec, 349int snd_hda_add_new_ctls(struct hda_codec *codec,
350 struct snd_kcontrol_new *knew); 350 const struct snd_kcontrol_new *knew);
351 351
352/* 352/*
353 * unsolicited event handler 353 * unsolicited event handler
@@ -443,7 +443,7 @@ struct auto_pin_cfg {
443 443
444int snd_hda_parse_pin_def_config(struct hda_codec *codec, 444int snd_hda_parse_pin_def_config(struct hda_codec *codec,
445 struct auto_pin_cfg *cfg, 445 struct auto_pin_cfg *cfg,
446 hda_nid_t *ignore_nids); 446 const hda_nid_t *ignore_nids);
447 447
448/* amp values */ 448/* amp values */
449#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8)) 449#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8))
@@ -493,6 +493,12 @@ u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid);
493u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); 493u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
494int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); 494int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
495 495
496static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
497{
498 return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) &&
499 (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP);
500}
501
496/* flags for hda_nid_item */ 502/* flags for hda_nid_item */
497#define HDA_NID_ITEM_AMP (1<<0) 503#define HDA_NID_ITEM_AMP (1<<0)
498 504
@@ -567,7 +573,7 @@ struct hda_amp_list {
567}; 573};
568 574
569struct hda_loopback_check { 575struct hda_loopback_check {
570 struct hda_amp_list *amplist; 576 const struct hda_amp_list *amplist;
571 int power_on; 577 int power_on;
572}; 578};
573 579
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 2942d2a9ea10..f1b3875c57df 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -30,7 +30,7 @@
30#include "hda_beep.h" 30#include "hda_beep.h"
31 31
32struct ad198x_spec { 32struct ad198x_spec {
33 struct snd_kcontrol_new *mixers[6]; 33 const struct snd_kcontrol_new *mixers[6];
34 int num_mixers; 34 int num_mixers;
35 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 35 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
36 const struct hda_verb *init_verbs[6]; /* initialization verbs 36 const struct hda_verb *init_verbs[6]; /* initialization verbs
@@ -46,17 +46,17 @@ struct ad198x_spec {
46 unsigned int cur_eapd; 46 unsigned int cur_eapd;
47 unsigned int need_dac_fix; 47 unsigned int need_dac_fix;
48 48
49 hda_nid_t *alt_dac_nid; 49 const hda_nid_t *alt_dac_nid;
50 struct hda_pcm_stream *stream_analog_alt_playback; 50 const struct hda_pcm_stream *stream_analog_alt_playback;
51 51
52 /* capture */ 52 /* capture */
53 unsigned int num_adc_nids; 53 unsigned int num_adc_nids;
54 hda_nid_t *adc_nids; 54 const hda_nid_t *adc_nids;
55 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 55 hda_nid_t dig_in_nid; /* digital-in NID; optional */
56 56
57 /* capture source */ 57 /* capture source */
58 const struct hda_input_mux *input_mux; 58 const struct hda_input_mux *input_mux;
59 hda_nid_t *capsrc_nids; 59 const hda_nid_t *capsrc_nids;
60 unsigned int cur_mux[3]; 60 unsigned int cur_mux[3];
61 61
62 /* channel model */ 62 /* channel model */
@@ -182,13 +182,13 @@ static void ad198x_free_kctls(struct hda_codec *codec);
182 182
183#ifdef CONFIG_SND_HDA_INPUT_BEEP 183#ifdef CONFIG_SND_HDA_INPUT_BEEP
184/* additional beep mixers; the actual parameters are overwritten at build */ 184/* additional beep mixers; the actual parameters are overwritten at build */
185static struct snd_kcontrol_new ad_beep_mixer[] = { 185static const struct snd_kcontrol_new ad_beep_mixer[] = {
186 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT), 186 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT),
187 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT), 187 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT),
188 { } /* end */ 188 { } /* end */
189}; 189};
190 190
191static struct snd_kcontrol_new ad_beep2_mixer[] = { 191static const struct snd_kcontrol_new ad_beep2_mixer[] = {
192 HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT), 192 HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT),
193 HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT), 193 HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT),
194 { } /* end */ 194 { } /* end */
@@ -231,7 +231,7 @@ static int ad198x_build_controls(struct hda_codec *codec)
231 /* create beep controls if needed */ 231 /* create beep controls if needed */
232#ifdef CONFIG_SND_HDA_INPUT_BEEP 232#ifdef CONFIG_SND_HDA_INPUT_BEEP
233 if (spec->beep_amp) { 233 if (spec->beep_amp) {
234 struct snd_kcontrol_new *knew; 234 const struct snd_kcontrol_new *knew;
235 knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer; 235 knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer;
236 for ( ; knew->name; knew++) { 236 for ( ; knew->name; knew++) {
237 struct snd_kcontrol *kctl; 237 struct snd_kcontrol *kctl;
@@ -331,7 +331,7 @@ static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
331 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 331 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
332} 332}
333 333
334static struct hda_pcm_stream ad198x_pcm_analog_alt_playback = { 334static const struct hda_pcm_stream ad198x_pcm_analog_alt_playback = {
335 .substreams = 1, 335 .substreams = 1,
336 .channels_min = 2, 336 .channels_min = 2,
337 .channels_max = 2, 337 .channels_max = 2,
@@ -403,7 +403,7 @@ static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
403 403
404/* 404/*
405 */ 405 */
406static struct hda_pcm_stream ad198x_pcm_analog_playback = { 406static const struct hda_pcm_stream ad198x_pcm_analog_playback = {
407 .substreams = 1, 407 .substreams = 1,
408 .channels_min = 2, 408 .channels_min = 2,
409 .channels_max = 6, /* changed later */ 409 .channels_max = 6, /* changed later */
@@ -415,7 +415,7 @@ static struct hda_pcm_stream ad198x_pcm_analog_playback = {
415 }, 415 },
416}; 416};
417 417
418static struct hda_pcm_stream ad198x_pcm_analog_capture = { 418static const struct hda_pcm_stream ad198x_pcm_analog_capture = {
419 .substreams = 1, 419 .substreams = 1,
420 .channels_min = 2, 420 .channels_min = 2,
421 .channels_max = 2, 421 .channels_max = 2,
@@ -426,7 +426,7 @@ static struct hda_pcm_stream ad198x_pcm_analog_capture = {
426 }, 426 },
427}; 427};
428 428
429static struct hda_pcm_stream ad198x_pcm_digital_playback = { 429static const struct hda_pcm_stream ad198x_pcm_digital_playback = {
430 .substreams = 1, 430 .substreams = 1,
431 .channels_min = 2, 431 .channels_min = 2,
432 .channels_max = 2, 432 .channels_max = 2,
@@ -439,7 +439,7 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = {
439 }, 439 },
440}; 440};
441 441
442static struct hda_pcm_stream ad198x_pcm_digital_capture = { 442static const struct hda_pcm_stream ad198x_pcm_digital_capture = {
443 .substreams = 1, 443 .substreams = 1,
444 .channels_min = 2, 444 .channels_min = 2,
445 .channels_max = 2, 445 .channels_max = 2,
@@ -489,11 +489,6 @@ static int ad198x_build_pcms(struct hda_codec *codec)
489 return 0; 489 return 0;
490} 490}
491 491
492static inline void ad198x_shutup(struct hda_codec *codec)
493{
494 snd_hda_shutup_pins(codec);
495}
496
497static void ad198x_free_kctls(struct hda_codec *codec) 492static void ad198x_free_kctls(struct hda_codec *codec)
498{ 493{
499 struct ad198x_spec *spec = codec->spec; 494 struct ad198x_spec *spec = codec->spec;
@@ -547,6 +542,12 @@ static void ad198x_power_eapd(struct hda_codec *codec)
547 } 542 }
548} 543}
549 544
545static void ad198x_shutup(struct hda_codec *codec)
546{
547 snd_hda_shutup_pins(codec);
548 ad198x_power_eapd(codec);
549}
550
550static void ad198x_free(struct hda_codec *codec) 551static void ad198x_free(struct hda_codec *codec)
551{ 552{
552 struct ad198x_spec *spec = codec->spec; 553 struct ad198x_spec *spec = codec->spec;
@@ -564,12 +565,11 @@ static void ad198x_free(struct hda_codec *codec)
564static int ad198x_suspend(struct hda_codec *codec, pm_message_t state) 565static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
565{ 566{
566 ad198x_shutup(codec); 567 ad198x_shutup(codec);
567 ad198x_power_eapd(codec);
568 return 0; 568 return 0;
569} 569}
570#endif 570#endif
571 571
572static struct hda_codec_ops ad198x_patch_ops = { 572static const struct hda_codec_ops ad198x_patch_ops = {
573 .build_controls = ad198x_build_controls, 573 .build_controls = ad198x_build_controls,
574 .build_pcms = ad198x_build_pcms, 574 .build_pcms = ad198x_build_pcms,
575 .init = ad198x_init, 575 .init = ad198x_init,
@@ -639,13 +639,13 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
639#define AD1986A_CLFE_DAC 0x05 639#define AD1986A_CLFE_DAC 0x05
640#define AD1986A_ADC 0x06 640#define AD1986A_ADC 0x06
641 641
642static hda_nid_t ad1986a_dac_nids[3] = { 642static const hda_nid_t ad1986a_dac_nids[3] = {
643 AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC 643 AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
644}; 644};
645static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC }; 645static const hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
646static hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 }; 646static const hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 };
647 647
648static struct hda_input_mux ad1986a_capture_source = { 648static const struct hda_input_mux ad1986a_capture_source = {
649 .num_items = 7, 649 .num_items = 7,
650 .items = { 650 .items = {
651 { "Mic", 0x0 }, 651 { "Mic", 0x0 },
@@ -659,7 +659,7 @@ static struct hda_input_mux ad1986a_capture_source = {
659}; 659};
660 660
661 661
662static struct hda_bind_ctls ad1986a_bind_pcm_vol = { 662static const struct hda_bind_ctls ad1986a_bind_pcm_vol = {
663 .ops = &snd_hda_bind_vol, 663 .ops = &snd_hda_bind_vol,
664 .values = { 664 .values = {
665 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), 665 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
@@ -669,7 +669,7 @@ static struct hda_bind_ctls ad1986a_bind_pcm_vol = {
669 }, 669 },
670}; 670};
671 671
672static struct hda_bind_ctls ad1986a_bind_pcm_sw = { 672static const struct hda_bind_ctls ad1986a_bind_pcm_sw = {
673 .ops = &snd_hda_bind_sw, 673 .ops = &snd_hda_bind_sw,
674 .values = { 674 .values = {
675 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), 675 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
@@ -682,7 +682,7 @@ static struct hda_bind_ctls ad1986a_bind_pcm_sw = {
682/* 682/*
683 * mixers 683 * mixers
684 */ 684 */
685static struct snd_kcontrol_new ad1986a_mixers[] = { 685static const struct snd_kcontrol_new ad1986a_mixers[] = {
686 /* 686 /*
687 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity 687 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
688 */ 688 */
@@ -723,7 +723,7 @@ static struct snd_kcontrol_new ad1986a_mixers[] = {
723}; 723};
724 724
725/* additional mixers for 3stack mode */ 725/* additional mixers for 3stack mode */
726static struct snd_kcontrol_new ad1986a_3st_mixers[] = { 726static const struct snd_kcontrol_new ad1986a_3st_mixers[] = {
727 { 727 {
728 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 728 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
729 .name = "Channel Mode", 729 .name = "Channel Mode",
@@ -735,10 +735,10 @@ static struct snd_kcontrol_new ad1986a_3st_mixers[] = {
735}; 735};
736 736
737/* laptop model - 2ch only */ 737/* laptop model - 2ch only */
738static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC }; 738static const hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };
739 739
740/* master controls both pins 0x1a and 0x1b */ 740/* master controls both pins 0x1a and 0x1b */
741static struct hda_bind_ctls ad1986a_laptop_master_vol = { 741static const struct hda_bind_ctls ad1986a_laptop_master_vol = {
742 .ops = &snd_hda_bind_vol, 742 .ops = &snd_hda_bind_vol,
743 .values = { 743 .values = {
744 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), 744 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
@@ -747,7 +747,7 @@ static struct hda_bind_ctls ad1986a_laptop_master_vol = {
747 }, 747 },
748}; 748};
749 749
750static struct hda_bind_ctls ad1986a_laptop_master_sw = { 750static const struct hda_bind_ctls ad1986a_laptop_master_sw = {
751 .ops = &snd_hda_bind_sw, 751 .ops = &snd_hda_bind_sw,
752 .values = { 752 .values = {
753 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), 753 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
@@ -756,7 +756,7 @@ static struct hda_bind_ctls ad1986a_laptop_master_sw = {
756 }, 756 },
757}; 757};
758 758
759static struct snd_kcontrol_new ad1986a_laptop_mixers[] = { 759static const struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
760 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), 760 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
761 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), 761 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
762 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), 762 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
@@ -787,7 +787,7 @@ static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
787 787
788/* laptop-eapd model - 2ch only */ 788/* laptop-eapd model - 2ch only */
789 789
790static struct hda_input_mux ad1986a_laptop_eapd_capture_source = { 790static const struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
791 .num_items = 3, 791 .num_items = 3,
792 .items = { 792 .items = {
793 { "Mic", 0x0 }, 793 { "Mic", 0x0 },
@@ -796,7 +796,7 @@ static struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
796 }, 796 },
797}; 797};
798 798
799static struct hda_input_mux ad1986a_automic_capture_source = { 799static const struct hda_input_mux ad1986a_automic_capture_source = {
800 .num_items = 2, 800 .num_items = 2,
801 .items = { 801 .items = {
802 { "Mic", 0x0 }, 802 { "Mic", 0x0 },
@@ -804,13 +804,13 @@ static struct hda_input_mux ad1986a_automic_capture_source = {
804 }, 804 },
805}; 805};
806 806
807static struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = { 807static const struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = {
808 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), 808 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
809 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), 809 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
810 { } /* end */ 810 { } /* end */
811}; 811};
812 812
813static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { 813static const struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
814 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), 814 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
815 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), 815 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
816 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 816 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
@@ -837,7 +837,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
837 { } /* end */ 837 { } /* end */
838}; 838};
839 839
840static struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = { 840static const struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = {
841 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT), 841 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT),
842 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT), 842 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT),
843 { } /* end */ 843 { } /* end */
@@ -931,7 +931,7 @@ static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol,
931 return change; 931 return change;
932} 932}
933 933
934static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { 934static const struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
935 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), 935 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
936 { 936 {
937 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 937 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -949,7 +949,7 @@ static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
949/* 949/*
950 * initialization verbs 950 * initialization verbs
951 */ 951 */
952static struct hda_verb ad1986a_init_verbs[] = { 952static const struct hda_verb ad1986a_init_verbs[] = {
953 /* Front, Surround, CLFE DAC; mute as default */ 953 /* Front, Surround, CLFE DAC; mute as default */
954 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 954 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
955 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 955 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
@@ -1004,7 +1004,7 @@ static struct hda_verb ad1986a_init_verbs[] = {
1004 { } /* end */ 1004 { } /* end */
1005}; 1005};
1006 1006
1007static struct hda_verb ad1986a_ch2_init[] = { 1007static const struct hda_verb ad1986a_ch2_init[] = {
1008 /* Surround out -> Line In */ 1008 /* Surround out -> Line In */
1009 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1009 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1010 /* Line-in selectors */ 1010 /* Line-in selectors */
@@ -1016,7 +1016,7 @@ static struct hda_verb ad1986a_ch2_init[] = {
1016 { } /* end */ 1016 { } /* end */
1017}; 1017};
1018 1018
1019static struct hda_verb ad1986a_ch4_init[] = { 1019static const struct hda_verb ad1986a_ch4_init[] = {
1020 /* Surround out -> Surround */ 1020 /* Surround out -> Surround */
1021 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1021 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1022 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1022 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
@@ -1026,7 +1026,7 @@ static struct hda_verb ad1986a_ch4_init[] = {
1026 { } /* end */ 1026 { } /* end */
1027}; 1027};
1028 1028
1029static struct hda_verb ad1986a_ch6_init[] = { 1029static const struct hda_verb ad1986a_ch6_init[] = {
1030 /* Surround out -> Surround out */ 1030 /* Surround out -> Surround out */
1031 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1031 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1032 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1032 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
@@ -1036,19 +1036,19 @@ static struct hda_verb ad1986a_ch6_init[] = {
1036 { } /* end */ 1036 { } /* end */
1037}; 1037};
1038 1038
1039static struct hda_channel_mode ad1986a_modes[3] = { 1039static const struct hda_channel_mode ad1986a_modes[3] = {
1040 { 2, ad1986a_ch2_init }, 1040 { 2, ad1986a_ch2_init },
1041 { 4, ad1986a_ch4_init }, 1041 { 4, ad1986a_ch4_init },
1042 { 6, ad1986a_ch6_init }, 1042 { 6, ad1986a_ch6_init },
1043}; 1043};
1044 1044
1045/* eapd initialization */ 1045/* eapd initialization */
1046static struct hda_verb ad1986a_eapd_init_verbs[] = { 1046static const struct hda_verb ad1986a_eapd_init_verbs[] = {
1047 {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, 1047 {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
1048 {} 1048 {}
1049}; 1049};
1050 1050
1051static struct hda_verb ad1986a_automic_verbs[] = { 1051static const struct hda_verb ad1986a_automic_verbs[] = {
1052 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1052 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1053 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1053 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1054 /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/ 1054 /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/
@@ -1058,7 +1058,7 @@ static struct hda_verb ad1986a_automic_verbs[] = {
1058}; 1058};
1059 1059
1060/* Ultra initialization */ 1060/* Ultra initialization */
1061static struct hda_verb ad1986a_ultra_init[] = { 1061static const struct hda_verb ad1986a_ultra_init[] = {
1062 /* eapd initialization */ 1062 /* eapd initialization */
1063 { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, 1063 { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
1064 /* CLFE -> Mic in */ 1064 /* CLFE -> Mic in */
@@ -1069,7 +1069,7 @@ static struct hda_verb ad1986a_ultra_init[] = {
1069}; 1069};
1070 1070
1071/* pin sensing on HP jack */ 1071/* pin sensing on HP jack */
1072static struct hda_verb ad1986a_hp_init_verbs[] = { 1072static const struct hda_verb ad1986a_hp_init_verbs[] = {
1073 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT}, 1073 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT},
1074 {} 1074 {}
1075}; 1075};
@@ -1120,7 +1120,7 @@ static const char * const ad1986a_models[AD1986A_MODELS] = {
1120 [AD1986A_SAMSUNG_P50] = "samsung-p50", 1120 [AD1986A_SAMSUNG_P50] = "samsung-p50",
1121}; 1121};
1122 1122
1123static struct snd_pci_quirk ad1986a_cfg_tbl[] = { 1123static const struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1124 SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD), 1124 SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD),
1125 SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD), 1125 SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD),
1126 SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD), 1126 SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD),
@@ -1152,7 +1152,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1152}; 1152};
1153 1153
1154#ifdef CONFIG_SND_HDA_POWER_SAVE 1154#ifdef CONFIG_SND_HDA_POWER_SAVE
1155static struct hda_amp_list ad1986a_loopbacks[] = { 1155static const struct hda_amp_list ad1986a_loopbacks[] = {
1156 { 0x13, HDA_OUTPUT, 0 }, /* Mic */ 1156 { 0x13, HDA_OUTPUT, 0 }, /* Mic */
1157 { 0x14, HDA_OUTPUT, 0 }, /* Phone */ 1157 { 0x14, HDA_OUTPUT, 0 }, /* Phone */
1158 { 0x15, HDA_OUTPUT, 0 }, /* CD */ 1158 { 0x15, HDA_OUTPUT, 0 }, /* CD */
@@ -1329,11 +1329,11 @@ static int patch_ad1986a(struct hda_codec *codec)
1329#define AD1983_DAC 0x03 1329#define AD1983_DAC 0x03
1330#define AD1983_ADC 0x04 1330#define AD1983_ADC 0x04
1331 1331
1332static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; 1332static const hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
1333static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC }; 1333static const hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
1334static hda_nid_t ad1983_capsrc_nids[1] = { 0x15 }; 1334static const hda_nid_t ad1983_capsrc_nids[1] = { 0x15 };
1335 1335
1336static struct hda_input_mux ad1983_capture_source = { 1336static const struct hda_input_mux ad1983_capture_source = {
1337 .num_items = 4, 1337 .num_items = 4,
1338 .items = { 1338 .items = {
1339 { "Mic", 0x0 }, 1339 { "Mic", 0x0 },
@@ -1348,7 +1348,7 @@ static struct hda_input_mux ad1983_capture_source = {
1348 */ 1348 */
1349static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1349static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1350{ 1350{
1351 static char *texts[] = { "PCM", "ADC" }; 1351 static const char * const texts[] = { "PCM", "ADC" };
1352 1352
1353 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1353 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1354 uinfo->count = 1; 1354 uinfo->count = 1;
@@ -1385,7 +1385,7 @@ static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
1385 return 0; 1385 return 0;
1386} 1386}
1387 1387
1388static struct snd_kcontrol_new ad1983_mixers[] = { 1388static const struct snd_kcontrol_new ad1983_mixers[] = {
1389 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), 1389 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1390 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), 1390 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1391 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), 1391 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
@@ -1418,7 +1418,7 @@ static struct snd_kcontrol_new ad1983_mixers[] = {
1418 { } /* end */ 1418 { } /* end */
1419}; 1419};
1420 1420
1421static struct hda_verb ad1983_init_verbs[] = { 1421static const struct hda_verb ad1983_init_verbs[] = {
1422 /* Front, HP, Mono; mute as default */ 1422 /* Front, HP, Mono; mute as default */
1423 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1423 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1424 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1424 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
@@ -1458,7 +1458,7 @@ static struct hda_verb ad1983_init_verbs[] = {
1458}; 1458};
1459 1459
1460#ifdef CONFIG_SND_HDA_POWER_SAVE 1460#ifdef CONFIG_SND_HDA_POWER_SAVE
1461static struct hda_amp_list ad1983_loopbacks[] = { 1461static const struct hda_amp_list ad1983_loopbacks[] = {
1462 { 0x12, HDA_OUTPUT, 0 }, /* Mic */ 1462 { 0x12, HDA_OUTPUT, 0 }, /* Mic */
1463 { 0x13, HDA_OUTPUT, 0 }, /* Line */ 1463 { 0x13, HDA_OUTPUT, 0 }, /* Line */
1464 { } /* end */ 1464 { } /* end */
@@ -1518,12 +1518,12 @@ static int patch_ad1983(struct hda_codec *codec)
1518#define AD1981_DAC 0x03 1518#define AD1981_DAC 0x03
1519#define AD1981_ADC 0x04 1519#define AD1981_ADC 0x04
1520 1520
1521static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; 1521static const hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
1522static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC }; 1522static const hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
1523static hda_nid_t ad1981_capsrc_nids[1] = { 0x15 }; 1523static const hda_nid_t ad1981_capsrc_nids[1] = { 0x15 };
1524 1524
1525/* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ 1525/* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
1526static struct hda_input_mux ad1981_capture_source = { 1526static const struct hda_input_mux ad1981_capture_source = {
1527 .num_items = 7, 1527 .num_items = 7,
1528 .items = { 1528 .items = {
1529 { "Front Mic", 0x0 }, 1529 { "Front Mic", 0x0 },
@@ -1536,7 +1536,7 @@ static struct hda_input_mux ad1981_capture_source = {
1536 }, 1536 },
1537}; 1537};
1538 1538
1539static struct snd_kcontrol_new ad1981_mixers[] = { 1539static const struct snd_kcontrol_new ad1981_mixers[] = {
1540 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), 1540 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1541 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), 1541 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1542 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), 1542 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
@@ -1577,7 +1577,7 @@ static struct snd_kcontrol_new ad1981_mixers[] = {
1577 { } /* end */ 1577 { } /* end */
1578}; 1578};
1579 1579
1580static struct hda_verb ad1981_init_verbs[] = { 1580static const struct hda_verb ad1981_init_verbs[] = {
1581 /* Front, HP, Mono; mute as default */ 1581 /* Front, HP, Mono; mute as default */
1582 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1582 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1583 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1583 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
@@ -1625,7 +1625,7 @@ static struct hda_verb ad1981_init_verbs[] = {
1625}; 1625};
1626 1626
1627#ifdef CONFIG_SND_HDA_POWER_SAVE 1627#ifdef CONFIG_SND_HDA_POWER_SAVE
1628static struct hda_amp_list ad1981_loopbacks[] = { 1628static const struct hda_amp_list ad1981_loopbacks[] = {
1629 { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */ 1629 { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
1630 { 0x13, HDA_OUTPUT, 0 }, /* Line */ 1630 { 0x13, HDA_OUTPUT, 0 }, /* Line */
1631 { 0x1b, HDA_OUTPUT, 0 }, /* Aux */ 1631 { 0x1b, HDA_OUTPUT, 0 }, /* Aux */
@@ -1645,7 +1645,7 @@ static struct hda_amp_list ad1981_loopbacks[] = {
1645#define AD1981_HP_EVENT 0x37 1645#define AD1981_HP_EVENT 0x37
1646#define AD1981_MIC_EVENT 0x38 1646#define AD1981_MIC_EVENT 0x38
1647 1647
1648static struct hda_verb ad1981_hp_init_verbs[] = { 1648static const struct hda_verb ad1981_hp_init_verbs[] = {
1649 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */ 1649 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */
1650 /* pin sensing on HP and Mic jacks */ 1650 /* pin sensing on HP and Mic jacks */
1651 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, 1651 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
@@ -1674,7 +1674,7 @@ static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1674} 1674}
1675 1675
1676/* bind volumes of both NID 0x05 and 0x06 */ 1676/* bind volumes of both NID 0x05 and 0x06 */
1677static struct hda_bind_ctls ad1981_hp_bind_master_vol = { 1677static const struct hda_bind_ctls ad1981_hp_bind_master_vol = {
1678 .ops = &snd_hda_bind_vol, 1678 .ops = &snd_hda_bind_vol,
1679 .values = { 1679 .values = {
1680 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), 1680 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
@@ -1696,12 +1696,12 @@ static void ad1981_hp_automute(struct hda_codec *codec)
1696/* toggle input of built-in and mic jack appropriately */ 1696/* toggle input of built-in and mic jack appropriately */
1697static void ad1981_hp_automic(struct hda_codec *codec) 1697static void ad1981_hp_automic(struct hda_codec *codec)
1698{ 1698{
1699 static struct hda_verb mic_jack_on[] = { 1699 static const struct hda_verb mic_jack_on[] = {
1700 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1700 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1701 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 1701 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1702 {} 1702 {}
1703 }; 1703 };
1704 static struct hda_verb mic_jack_off[] = { 1704 static const struct hda_verb mic_jack_off[] = {
1705 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1705 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1706 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 1706 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1707 {} 1707 {}
@@ -1730,7 +1730,7 @@ static void ad1981_hp_unsol_event(struct hda_codec *codec,
1730 } 1730 }
1731} 1731}
1732 1732
1733static struct hda_input_mux ad1981_hp_capture_source = { 1733static const struct hda_input_mux ad1981_hp_capture_source = {
1734 .num_items = 3, 1734 .num_items = 3,
1735 .items = { 1735 .items = {
1736 { "Mic", 0x0 }, 1736 { "Mic", 0x0 },
@@ -1739,7 +1739,7 @@ static struct hda_input_mux ad1981_hp_capture_source = {
1739 }, 1739 },
1740}; 1740};
1741 1741
1742static struct snd_kcontrol_new ad1981_hp_mixers[] = { 1742static const struct snd_kcontrol_new ad1981_hp_mixers[] = {
1743 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), 1743 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1744 { 1744 {
1745 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1745 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1790,7 +1790,7 @@ static int ad1981_hp_init(struct hda_codec *codec)
1790} 1790}
1791 1791
1792/* configuration for Toshiba Laptops */ 1792/* configuration for Toshiba Laptops */
1793static struct hda_verb ad1981_toshiba_init_verbs[] = { 1793static const struct hda_verb ad1981_toshiba_init_verbs[] = {
1794 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */ 1794 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
1795 /* pin sensing on HP and Mic jacks */ 1795 /* pin sensing on HP and Mic jacks */
1796 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, 1796 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
@@ -1798,14 +1798,14 @@ static struct hda_verb ad1981_toshiba_init_verbs[] = {
1798 {} 1798 {}
1799}; 1799};
1800 1800
1801static struct snd_kcontrol_new ad1981_toshiba_mixers[] = { 1801static const struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
1802 HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT), 1802 HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
1803 HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT), 1803 HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
1804 { } 1804 { }
1805}; 1805};
1806 1806
1807/* configuration for Lenovo Thinkpad T60 */ 1807/* configuration for Lenovo Thinkpad T60 */
1808static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = { 1808static const struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1809 HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT), 1809 HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1810 HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT), 1810 HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1811 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), 1811 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
@@ -1835,7 +1835,7 @@ static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1835 { } /* end */ 1835 { } /* end */
1836}; 1836};
1837 1837
1838static struct hda_input_mux ad1981_thinkpad_capture_source = { 1838static const struct hda_input_mux ad1981_thinkpad_capture_source = {
1839 .num_items = 3, 1839 .num_items = 3,
1840 .items = { 1840 .items = {
1841 { "Mic", 0x0 }, 1841 { "Mic", 0x0 },
@@ -1860,7 +1860,7 @@ static const char * const ad1981_models[AD1981_MODELS] = {
1860 [AD1981_TOSHIBA] = "toshiba" 1860 [AD1981_TOSHIBA] = "toshiba"
1861}; 1861};
1862 1862
1863static struct snd_pci_quirk ad1981_cfg_tbl[] = { 1863static const struct snd_pci_quirk ad1981_cfg_tbl[] = {
1864 SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), 1864 SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
1865 SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD), 1865 SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
1866 /* All HP models */ 1866 /* All HP models */
@@ -2075,32 +2075,32 @@ enum {
2075 * mixers 2075 * mixers
2076 */ 2076 */
2077 2077
2078static hda_nid_t ad1988_6stack_dac_nids[4] = { 2078static const hda_nid_t ad1988_6stack_dac_nids[4] = {
2079 0x04, 0x06, 0x05, 0x0a 2079 0x04, 0x06, 0x05, 0x0a
2080}; 2080};
2081 2081
2082static hda_nid_t ad1988_3stack_dac_nids[3] = { 2082static const hda_nid_t ad1988_3stack_dac_nids[3] = {
2083 0x04, 0x05, 0x0a 2083 0x04, 0x05, 0x0a
2084}; 2084};
2085 2085
2086/* for AD1988A revision-2, DAC2-4 are swapped */ 2086/* for AD1988A revision-2, DAC2-4 are swapped */
2087static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = { 2087static const hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
2088 0x04, 0x05, 0x0a, 0x06 2088 0x04, 0x05, 0x0a, 0x06
2089}; 2089};
2090 2090
2091static hda_nid_t ad1988_alt_dac_nid[1] = { 2091static const hda_nid_t ad1988_alt_dac_nid[1] = {
2092 0x03 2092 0x03
2093}; 2093};
2094 2094
2095static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = { 2095static const hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
2096 0x04, 0x0a, 0x06 2096 0x04, 0x0a, 0x06
2097}; 2097};
2098 2098
2099static hda_nid_t ad1988_adc_nids[3] = { 2099static const hda_nid_t ad1988_adc_nids[3] = {
2100 0x08, 0x09, 0x0f 2100 0x08, 0x09, 0x0f
2101}; 2101};
2102 2102
2103static hda_nid_t ad1988_capsrc_nids[3] = { 2103static const hda_nid_t ad1988_capsrc_nids[3] = {
2104 0x0c, 0x0d, 0x0e 2104 0x0c, 0x0d, 0x0e
2105}; 2105};
2106 2106
@@ -2108,11 +2108,11 @@ static hda_nid_t ad1988_capsrc_nids[3] = {
2108#define AD1988_SPDIF_OUT_HDMI 0x0b 2108#define AD1988_SPDIF_OUT_HDMI 0x0b
2109#define AD1988_SPDIF_IN 0x07 2109#define AD1988_SPDIF_IN 0x07
2110 2110
2111static hda_nid_t ad1989b_slave_dig_outs[] = { 2111static const hda_nid_t ad1989b_slave_dig_outs[] = {
2112 AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0 2112 AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0
2113}; 2113};
2114 2114
2115static struct hda_input_mux ad1988_6stack_capture_source = { 2115static const struct hda_input_mux ad1988_6stack_capture_source = {
2116 .num_items = 5, 2116 .num_items = 5,
2117 .items = { 2117 .items = {
2118 { "Front Mic", 0x1 }, /* port-B */ 2118 { "Front Mic", 0x1 }, /* port-B */
@@ -2123,7 +2123,7 @@ static struct hda_input_mux ad1988_6stack_capture_source = {
2123 }, 2123 },
2124}; 2124};
2125 2125
2126static struct hda_input_mux ad1988_laptop_capture_source = { 2126static const struct hda_input_mux ad1988_laptop_capture_source = {
2127 .num_items = 3, 2127 .num_items = 3,
2128 .items = { 2128 .items = {
2129 { "Mic/Line", 0x1 }, /* port-B */ 2129 { "Mic/Line", 0x1 }, /* port-B */
@@ -2166,7 +2166,7 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
2166} 2166}
2167 2167
2168/* 6-stack mode */ 2168/* 6-stack mode */
2169static struct snd_kcontrol_new ad1988_6stack_mixers1[] = { 2169static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
2170 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2170 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2171 HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT), 2171 HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2172 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 2172 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
@@ -2175,7 +2175,7 @@ static struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
2175 { } /* end */ 2175 { } /* end */
2176}; 2176};
2177 2177
2178static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = { 2178static const struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
2179 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2179 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2180 HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT), 2180 HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
2181 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 2181 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
@@ -2184,7 +2184,7 @@ static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
2184 { } /* end */ 2184 { } /* end */
2185}; 2185};
2186 2186
2187static struct snd_kcontrol_new ad1988_6stack_mixers2[] = { 2187static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2188 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), 2188 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2189 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), 2189 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
2190 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), 2190 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
@@ -2211,14 +2211,14 @@ static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2211 { } /* end */ 2211 { } /* end */
2212}; 2212};
2213 2213
2214static struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = { 2214static const struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = {
2215 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 2215 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2216 2216
2217 { } /* end */ 2217 { } /* end */
2218}; 2218};
2219 2219
2220/* 3-stack mode */ 2220/* 3-stack mode */
2221static struct snd_kcontrol_new ad1988_3stack_mixers1[] = { 2221static const struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
2222 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2222 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2223 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), 2223 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2224 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 2224 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
@@ -2226,7 +2226,7 @@ static struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
2226 { } /* end */ 2226 { } /* end */
2227}; 2227};
2228 2228
2229static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = { 2229static const struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
2230 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2230 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2231 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), 2231 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2232 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT), 2232 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
@@ -2234,7 +2234,7 @@ static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
2234 { } /* end */ 2234 { } /* end */
2235}; 2235};
2236 2236
2237static struct snd_kcontrol_new ad1988_3stack_mixers2[] = { 2237static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2238 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), 2238 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2239 HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT), 2239 HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
2240 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT), 2240 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
@@ -2268,7 +2268,7 @@ static struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2268}; 2268};
2269 2269
2270/* laptop mode */ 2270/* laptop mode */
2271static struct snd_kcontrol_new ad1988_laptop_mixers[] = { 2271static const struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2272 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2272 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2273 HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT), 2273 HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
2274 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), 2274 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
@@ -2299,7 +2299,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2299}; 2299};
2300 2300
2301/* capture */ 2301/* capture */
2302static struct snd_kcontrol_new ad1988_capture_mixers[] = { 2302static const struct snd_kcontrol_new ad1988_capture_mixers[] = {
2303 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 2303 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2304 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 2304 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2305 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 2305 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -2324,7 +2324,7 @@ static struct snd_kcontrol_new ad1988_capture_mixers[] = {
2324static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol, 2324static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
2325 struct snd_ctl_elem_info *uinfo) 2325 struct snd_ctl_elem_info *uinfo)
2326{ 2326{
2327 static char *texts[] = { 2327 static const char * const texts[] = {
2328 "PCM", "ADC1", "ADC2", "ADC3" 2328 "PCM", "ADC1", "ADC2", "ADC3"
2329 }; 2329 };
2330 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2330 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -2405,7 +2405,7 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
2405 return change; 2405 return change;
2406} 2406}
2407 2407
2408static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = { 2408static const struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2409 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 2409 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2410 { 2410 {
2411 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2411 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -2418,12 +2418,12 @@ static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2418 { } /* end */ 2418 { } /* end */
2419}; 2419};
2420 2420
2421static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = { 2421static const struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
2422 HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT), 2422 HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
2423 { } /* end */ 2423 { } /* end */
2424}; 2424};
2425 2425
2426static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = { 2426static const struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
2427 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 2427 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2428 HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 2428 HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2429 { } /* end */ 2429 { } /* end */
@@ -2436,7 +2436,7 @@ static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
2436/* 2436/*
2437 * for 6-stack (+dig) 2437 * for 6-stack (+dig)
2438 */ 2438 */
2439static struct hda_verb ad1988_6stack_init_verbs[] = { 2439static const struct hda_verb ad1988_6stack_init_verbs[] = {
2440 /* Front, Surround, CLFE, side DAC; unmute as default */ 2440 /* Front, Surround, CLFE, side DAC; unmute as default */
2441 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2441 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2442 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2442 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -2496,7 +2496,7 @@ static struct hda_verb ad1988_6stack_init_verbs[] = {
2496 { } 2496 { }
2497}; 2497};
2498 2498
2499static struct hda_verb ad1988_6stack_fp_init_verbs[] = { 2499static const struct hda_verb ad1988_6stack_fp_init_verbs[] = {
2500 /* Headphone; unmute as default */ 2500 /* Headphone; unmute as default */
2501 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2501 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2502 /* Port-A front headphon path */ 2502 /* Port-A front headphon path */
@@ -2509,7 +2509,7 @@ static struct hda_verb ad1988_6stack_fp_init_verbs[] = {
2509 { } 2509 { }
2510}; 2510};
2511 2511
2512static struct hda_verb ad1988_capture_init_verbs[] = { 2512static const struct hda_verb ad1988_capture_init_verbs[] = {
2513 /* mute analog mix */ 2513 /* mute analog mix */
2514 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2514 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2515 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2515 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
@@ -2527,7 +2527,7 @@ static struct hda_verb ad1988_capture_init_verbs[] = {
2527 { } 2527 { }
2528}; 2528};
2529 2529
2530static struct hda_verb ad1988_spdif_init_verbs[] = { 2530static const struct hda_verb ad1988_spdif_init_verbs[] = {
2531 /* SPDIF out sel */ 2531 /* SPDIF out sel */
2532 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ 2532 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2533 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */ 2533 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
@@ -2539,14 +2539,14 @@ static struct hda_verb ad1988_spdif_init_verbs[] = {
2539 { } 2539 { }
2540}; 2540};
2541 2541
2542static struct hda_verb ad1988_spdif_in_init_verbs[] = { 2542static const struct hda_verb ad1988_spdif_in_init_verbs[] = {
2543 /* unmute SPDIF input pin */ 2543 /* unmute SPDIF input pin */
2544 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2544 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2545 { } 2545 { }
2546}; 2546};
2547 2547
2548/* AD1989 has no ADC -> SPDIF route */ 2548/* AD1989 has no ADC -> SPDIF route */
2549static struct hda_verb ad1989_spdif_init_verbs[] = { 2549static const struct hda_verb ad1989_spdif_init_verbs[] = {
2550 /* SPDIF-1 out pin */ 2550 /* SPDIF-1 out pin */
2551 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2551 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2552 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 2552 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
@@ -2559,7 +2559,7 @@ static struct hda_verb ad1989_spdif_init_verbs[] = {
2559/* 2559/*
2560 * verbs for 3stack (+dig) 2560 * verbs for 3stack (+dig)
2561 */ 2561 */
2562static struct hda_verb ad1988_3stack_ch2_init[] = { 2562static const struct hda_verb ad1988_3stack_ch2_init[] = {
2563 /* set port-C to line-in */ 2563 /* set port-C to line-in */
2564 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2564 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2565 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2565 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
@@ -2569,7 +2569,7 @@ static struct hda_verb ad1988_3stack_ch2_init[] = {
2569 { } /* end */ 2569 { } /* end */
2570}; 2570};
2571 2571
2572static struct hda_verb ad1988_3stack_ch6_init[] = { 2572static const struct hda_verb ad1988_3stack_ch6_init[] = {
2573 /* set port-C to surround out */ 2573 /* set port-C to surround out */
2574 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2574 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2575 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2575 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
@@ -2579,12 +2579,12 @@ static struct hda_verb ad1988_3stack_ch6_init[] = {
2579 { } /* end */ 2579 { } /* end */
2580}; 2580};
2581 2581
2582static struct hda_channel_mode ad1988_3stack_modes[2] = { 2582static const struct hda_channel_mode ad1988_3stack_modes[2] = {
2583 { 2, ad1988_3stack_ch2_init }, 2583 { 2, ad1988_3stack_ch2_init },
2584 { 6, ad1988_3stack_ch6_init }, 2584 { 6, ad1988_3stack_ch6_init },
2585}; 2585};
2586 2586
2587static struct hda_verb ad1988_3stack_init_verbs[] = { 2587static const struct hda_verb ad1988_3stack_init_verbs[] = {
2588 /* Front, Surround, CLFE, side DAC; unmute as default */ 2588 /* Front, Surround, CLFE, side DAC; unmute as default */
2589 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2589 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2590 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2590 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -2644,13 +2644,13 @@ static struct hda_verb ad1988_3stack_init_verbs[] = {
2644/* 2644/*
2645 * verbs for laptop mode (+dig) 2645 * verbs for laptop mode (+dig)
2646 */ 2646 */
2647static struct hda_verb ad1988_laptop_hp_on[] = { 2647static const struct hda_verb ad1988_laptop_hp_on[] = {
2648 /* unmute port-A and mute port-D */ 2648 /* unmute port-A and mute port-D */
2649 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2649 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2650 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2650 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2651 { } /* end */ 2651 { } /* end */
2652}; 2652};
2653static struct hda_verb ad1988_laptop_hp_off[] = { 2653static const struct hda_verb ad1988_laptop_hp_off[] = {
2654 /* mute port-A and unmute port-D */ 2654 /* mute port-A and unmute port-D */
2655 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2655 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2656 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2656 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
@@ -2659,7 +2659,7 @@ static struct hda_verb ad1988_laptop_hp_off[] = {
2659 2659
2660#define AD1988_HP_EVENT 0x01 2660#define AD1988_HP_EVENT 0x01
2661 2661
2662static struct hda_verb ad1988_laptop_init_verbs[] = { 2662static const struct hda_verb ad1988_laptop_init_verbs[] = {
2663 /* Front, Surround, CLFE, side DAC; unmute as default */ 2663 /* Front, Surround, CLFE, side DAC; unmute as default */
2664 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2664 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2665 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2665 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -2723,7 +2723,7 @@ static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
2723} 2723}
2724 2724
2725#ifdef CONFIG_SND_HDA_POWER_SAVE 2725#ifdef CONFIG_SND_HDA_POWER_SAVE
2726static struct hda_amp_list ad1988_loopbacks[] = { 2726static const struct hda_amp_list ad1988_loopbacks[] = {
2727 { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 2727 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
2728 { 0x20, HDA_INPUT, 1 }, /* Line */ 2728 { 0x20, HDA_INPUT, 1 }, /* Line */
2729 { 0x20, HDA_INPUT, 4 }, /* Mic */ 2729 { 0x20, HDA_INPUT, 4 }, /* Mic */
@@ -2741,7 +2741,7 @@ enum {
2741 AD_CTL_WIDGET_MUTE, 2741 AD_CTL_WIDGET_MUTE,
2742 AD_CTL_BIND_MUTE, 2742 AD_CTL_BIND_MUTE,
2743}; 2743};
2744static struct snd_kcontrol_new ad1988_control_templates[] = { 2744static const struct snd_kcontrol_new ad1988_control_templates[] = {
2745 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2745 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2746 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2746 HDA_CODEC_MUTE(NULL, 0, 0, 0),
2747 HDA_BIND_MUTE(NULL, 0, 0, 0), 2747 HDA_BIND_MUTE(NULL, 0, 0, 0),
@@ -2770,18 +2770,18 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name,
2770#define AD1988_PIN_CD_NID 0x18 2770#define AD1988_PIN_CD_NID 0x18
2771#define AD1988_PIN_BEEP_NID 0x10 2771#define AD1988_PIN_BEEP_NID 0x10
2772 2772
2773static hda_nid_t ad1988_mixer_nids[8] = { 2773static const hda_nid_t ad1988_mixer_nids[8] = {
2774 /* A B C D E F G H */ 2774 /* A B C D E F G H */
2775 0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28 2775 0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
2776}; 2776};
2777 2777
2778static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx) 2778static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
2779{ 2779{
2780 static hda_nid_t idx_to_dac[8] = { 2780 static const hda_nid_t idx_to_dac[8] = {
2781 /* A B C D E F G H */ 2781 /* A B C D E F G H */
2782 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a 2782 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
2783 }; 2783 };
2784 static hda_nid_t idx_to_dac_rev2[8] = { 2784 static const hda_nid_t idx_to_dac_rev2[8] = {
2785 /* A B C D E F G H */ 2785 /* A B C D E F G H */
2786 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06 2786 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
2787 }; 2787 };
@@ -2791,13 +2791,13 @@ static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
2791 return idx_to_dac[idx]; 2791 return idx_to_dac[idx];
2792} 2792}
2793 2793
2794static hda_nid_t ad1988_boost_nids[8] = { 2794static const hda_nid_t ad1988_boost_nids[8] = {
2795 0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0 2795 0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
2796}; 2796};
2797 2797
2798static int ad1988_pin_idx(hda_nid_t nid) 2798static int ad1988_pin_idx(hda_nid_t nid)
2799{ 2799{
2800 static hda_nid_t ad1988_io_pins[8] = { 2800 static const hda_nid_t ad1988_io_pins[8] = {
2801 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25 2801 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
2802 }; 2802 };
2803 int i; 2803 int i;
@@ -2809,7 +2809,7 @@ static int ad1988_pin_idx(hda_nid_t nid)
2809 2809
2810static int ad1988_pin_to_loopback_idx(hda_nid_t nid) 2810static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
2811{ 2811{
2812 static int loopback_idx[8] = { 2812 static const int loopback_idx[8] = {
2813 2, 0, 1, 3, 4, 5, 1, 4 2813 2, 0, 1, 3, 4, 5, 1, 4
2814 }; 2814 };
2815 switch (nid) { 2815 switch (nid) {
@@ -2822,7 +2822,7 @@ static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
2822 2822
2823static int ad1988_pin_to_adc_idx(hda_nid_t nid) 2823static int ad1988_pin_to_adc_idx(hda_nid_t nid)
2824{ 2824{
2825 static int adc_idx[8] = { 2825 static const int adc_idx[8] = {
2826 0, 1, 2, 8, 4, 3, 6, 7 2826 0, 1, 2, 8, 4, 3, 6, 7
2827 }; 2827 };
2828 switch (nid) { 2828 switch (nid) {
@@ -2845,7 +2845,7 @@ static int ad1988_auto_fill_dac_nids(struct hda_codec *codec,
2845 /* check the pins hardwired to audio widget */ 2845 /* check the pins hardwired to audio widget */
2846 for (i = 0; i < cfg->line_outs; i++) { 2846 for (i = 0; i < cfg->line_outs; i++) {
2847 idx = ad1988_pin_idx(cfg->line_out_pins[i]); 2847 idx = ad1988_pin_idx(cfg->line_out_pins[i]);
2848 spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx); 2848 spec->private_dac_nids[i] = ad1988_idx_to_dac(codec, idx);
2849 } 2849 }
2850 spec->multiout.num_dacs = cfg->line_outs; 2850 spec->multiout.num_dacs = cfg->line_outs;
2851 return 0; 2851 return 0;
@@ -3070,6 +3070,7 @@ static void ad1988_auto_init_analog_input(struct hda_codec *codec)
3070 3070
3071 for (i = 0; i < cfg->num_inputs; i++) { 3071 for (i = 0; i < cfg->num_inputs; i++) {
3072 hda_nid_t nid = cfg->inputs[i].pin; 3072 hda_nid_t nid = cfg->inputs[i].pin;
3073 int type = cfg->inputs[i].type;
3073 switch (nid) { 3074 switch (nid) {
3074 case 0x15: /* port-C */ 3075 case 0x15: /* port-C */
3075 snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0); 3076 snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
@@ -3079,7 +3080,7 @@ static void ad1988_auto_init_analog_input(struct hda_codec *codec)
3079 break; 3080 break;
3080 } 3081 }
3081 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 3082 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3082 i == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN); 3083 type == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN);
3083 if (nid != AD1988_PIN_CD_NID) 3084 if (nid != AD1988_PIN_CD_NID)
3084 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3085 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3085 AMP_OUT_MUTE); 3086 AMP_OUT_MUTE);
@@ -3154,7 +3155,7 @@ static const char * const ad1988_models[AD1988_MODEL_LAST] = {
3154 [AD1988_AUTO] = "auto", 3155 [AD1988_AUTO] = "auto",
3155}; 3156};
3156 3157
3157static struct snd_pci_quirk ad1988_cfg_tbl[] = { 3158static const struct snd_pci_quirk ad1988_cfg_tbl[] = {
3158 SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG), 3159 SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
3159 SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG), 3160 SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
3160 SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG), 3161 SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
@@ -3342,21 +3343,21 @@ static int patch_ad1988(struct hda_codec *codec)
3342 * but no build-up framework is given, so far. 3343 * but no build-up framework is given, so far.
3343 */ 3344 */
3344 3345
3345static hda_nid_t ad1884_dac_nids[1] = { 3346static const hda_nid_t ad1884_dac_nids[1] = {
3346 0x04, 3347 0x04,
3347}; 3348};
3348 3349
3349static hda_nid_t ad1884_adc_nids[2] = { 3350static const hda_nid_t ad1884_adc_nids[2] = {
3350 0x08, 0x09, 3351 0x08, 0x09,
3351}; 3352};
3352 3353
3353static hda_nid_t ad1884_capsrc_nids[2] = { 3354static const hda_nid_t ad1884_capsrc_nids[2] = {
3354 0x0c, 0x0d, 3355 0x0c, 0x0d,
3355}; 3356};
3356 3357
3357#define AD1884_SPDIF_OUT 0x02 3358#define AD1884_SPDIF_OUT 0x02
3358 3359
3359static struct hda_input_mux ad1884_capture_source = { 3360static const struct hda_input_mux ad1884_capture_source = {
3360 .num_items = 4, 3361 .num_items = 4,
3361 .items = { 3362 .items = {
3362 { "Front Mic", 0x0 }, 3363 { "Front Mic", 0x0 },
@@ -3366,7 +3367,7 @@ static struct hda_input_mux ad1884_capture_source = {
3366 }, 3367 },
3367}; 3368};
3368 3369
3369static struct snd_kcontrol_new ad1884_base_mixers[] = { 3370static const struct snd_kcontrol_new ad1884_base_mixers[] = {
3370 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 3371 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3371 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ 3372 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3372 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 3373 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
@@ -3410,7 +3411,7 @@ static struct snd_kcontrol_new ad1884_base_mixers[] = {
3410 { } /* end */ 3411 { } /* end */
3411}; 3412};
3412 3413
3413static struct snd_kcontrol_new ad1984_dmic_mixers[] = { 3414static const struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3414 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT), 3415 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
3415 HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT), 3416 HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
3416 HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0, 3417 HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
@@ -3423,7 +3424,7 @@ static struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3423/* 3424/*
3424 * initialization verbs 3425 * initialization verbs
3425 */ 3426 */
3426static struct hda_verb ad1884_init_verbs[] = { 3427static const struct hda_verb ad1884_init_verbs[] = {
3427 /* DACs; mute as default */ 3428 /* DACs; mute as default */
3428 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3429 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3429 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3430 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -3469,7 +3470,7 @@ static struct hda_verb ad1884_init_verbs[] = {
3469}; 3470};
3470 3471
3471#ifdef CONFIG_SND_HDA_POWER_SAVE 3472#ifdef CONFIG_SND_HDA_POWER_SAVE
3472static struct hda_amp_list ad1884_loopbacks[] = { 3473static const struct hda_amp_list ad1884_loopbacks[] = {
3473 { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 3474 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3474 { 0x20, HDA_INPUT, 1 }, /* Mic */ 3475 { 0x20, HDA_INPUT, 1 }, /* Mic */
3475 { 0x20, HDA_INPUT, 2 }, /* CD */ 3476 { 0x20, HDA_INPUT, 2 }, /* CD */
@@ -3541,7 +3542,7 @@ static int patch_ad1884(struct hda_codec *codec)
3541/* 3542/*
3542 * Lenovo Thinkpad T61/X61 3543 * Lenovo Thinkpad T61/X61
3543 */ 3544 */
3544static struct hda_input_mux ad1984_thinkpad_capture_source = { 3545static const struct hda_input_mux ad1984_thinkpad_capture_source = {
3545 .num_items = 4, 3546 .num_items = 4,
3546 .items = { 3547 .items = {
3547 { "Mic", 0x0 }, 3548 { "Mic", 0x0 },
@@ -3555,7 +3556,7 @@ static struct hda_input_mux ad1984_thinkpad_capture_source = {
3555/* 3556/*
3556 * Dell Precision T3400 3557 * Dell Precision T3400
3557 */ 3558 */
3558static struct hda_input_mux ad1984_dell_desktop_capture_source = { 3559static const struct hda_input_mux ad1984_dell_desktop_capture_source = {
3559 .num_items = 3, 3560 .num_items = 3,
3560 .items = { 3561 .items = {
3561 { "Front Mic", 0x0 }, 3562 { "Front Mic", 0x0 },
@@ -3565,7 +3566,7 @@ static struct hda_input_mux ad1984_dell_desktop_capture_source = {
3565}; 3566};
3566 3567
3567 3568
3568static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = { 3569static const struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3569 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 3570 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3570 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ 3571 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3571 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 3572 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
@@ -3611,7 +3612,7 @@ static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3611}; 3612};
3612 3613
3613/* additional verbs */ 3614/* additional verbs */
3614static struct hda_verb ad1984_thinkpad_init_verbs[] = { 3615static const struct hda_verb ad1984_thinkpad_init_verbs[] = {
3615 /* Port-E (docking station mic) pin */ 3616 /* Port-E (docking station mic) pin */
3616 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3617 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3617 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3618 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
@@ -3629,7 +3630,7 @@ static struct hda_verb ad1984_thinkpad_init_verbs[] = {
3629/* 3630/*
3630 * Dell Precision T3400 3631 * Dell Precision T3400
3631 */ 3632 */
3632static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = { 3633static const struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3633 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 3634 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 3635 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3635 HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT), 3636 HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
@@ -3680,7 +3681,7 @@ static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3680 return 0; 3681 return 0;
3681} 3682}
3682 3683
3683static struct hda_pcm_stream ad1984_pcm_dmic_capture = { 3684static const struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3684 .substreams = 2, 3685 .substreams = 2,
3685 .channels_min = 2, 3686 .channels_min = 2,
3686 .channels_max = 2, 3687 .channels_max = 2,
@@ -3722,7 +3723,7 @@ static const char * const ad1984_models[AD1984_MODELS] = {
3722 [AD1984_DELL_DESKTOP] = "dell_desktop", 3723 [AD1984_DELL_DESKTOP] = "dell_desktop",
3723}; 3724};
3724 3725
3725static struct snd_pci_quirk ad1984_cfg_tbl[] = { 3726static const struct snd_pci_quirk ad1984_cfg_tbl[] = {
3726 /* Lenovo Thinkpad T61/X61 */ 3727 /* Lenovo Thinkpad T61/X61 */
3727 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD), 3728 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD),
3728 SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP), 3729 SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
@@ -3787,7 +3788,7 @@ static int patch_ad1984(struct hda_codec *codec)
3787 * We share the single DAC for both HP and line-outs (see AD1884/1984). 3788 * We share the single DAC for both HP and line-outs (see AD1884/1984).
3788 */ 3789 */
3789 3790
3790static hda_nid_t ad1884a_dac_nids[1] = { 3791static const hda_nid_t ad1884a_dac_nids[1] = {
3791 0x03, 3792 0x03,
3792}; 3793};
3793 3794
@@ -3796,7 +3797,7 @@ static hda_nid_t ad1884a_dac_nids[1] = {
3796 3797
3797#define AD1884A_SPDIF_OUT 0x02 3798#define AD1884A_SPDIF_OUT 0x02
3798 3799
3799static struct hda_input_mux ad1884a_capture_source = { 3800static const struct hda_input_mux ad1884a_capture_source = {
3800 .num_items = 5, 3801 .num_items = 5,
3801 .items = { 3802 .items = {
3802 { "Front Mic", 0x0 }, 3803 { "Front Mic", 0x0 },
@@ -3807,7 +3808,7 @@ static struct hda_input_mux ad1884a_capture_source = {
3807 }, 3808 },
3808}; 3809};
3809 3810
3810static struct snd_kcontrol_new ad1884a_base_mixers[] = { 3811static const struct snd_kcontrol_new ad1884a_base_mixers[] = {
3811 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 3812 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3812 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), 3813 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3813 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 3814 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
@@ -3859,7 +3860,7 @@ static struct snd_kcontrol_new ad1884a_base_mixers[] = {
3859/* 3860/*
3860 * initialization verbs 3861 * initialization verbs
3861 */ 3862 */
3862static struct hda_verb ad1884a_init_verbs[] = { 3863static const struct hda_verb ad1884a_init_verbs[] = {
3863 /* DACs; unmute as default */ 3864 /* DACs; unmute as default */
3864 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 3865 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3865 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 3866 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
@@ -3914,7 +3915,7 @@ static struct hda_verb ad1884a_init_verbs[] = {
3914}; 3915};
3915 3916
3916#ifdef CONFIG_SND_HDA_POWER_SAVE 3917#ifdef CONFIG_SND_HDA_POWER_SAVE
3917static struct hda_amp_list ad1884a_loopbacks[] = { 3918static const struct hda_amp_list ad1884a_loopbacks[] = {
3918 { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 3919 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3919 { 0x20, HDA_INPUT, 1 }, /* Mic */ 3920 { 0x20, HDA_INPUT, 1 }, /* Mic */
3920 { 0x20, HDA_INPUT, 2 }, /* CD */ 3921 { 0x20, HDA_INPUT, 2 }, /* CD */
@@ -3947,7 +3948,7 @@ static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
3947 return ret; 3948 return ret;
3948} 3949}
3949 3950
3950static struct snd_kcontrol_new ad1884a_laptop_mixers[] = { 3951static const struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3951 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 3952 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3952 { 3953 {
3953 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3954 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -3975,7 +3976,7 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3975 { } /* end */ 3976 { } /* end */
3976}; 3977};
3977 3978
3978static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { 3979static const struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3979 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 3980 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3980 /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 3981 /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
3981 { 3982 {
@@ -4095,7 +4096,7 @@ static int ad1884a_laptop_init(struct hda_codec *codec)
4095} 4096}
4096 4097
4097/* additional verbs for laptop model */ 4098/* additional verbs for laptop model */
4098static struct hda_verb ad1884a_laptop_verbs[] = { 4099static const struct hda_verb ad1884a_laptop_verbs[] = {
4099 /* Port-A (HP) pin - always unmuted */ 4100 /* Port-A (HP) pin - always unmuted */
4100 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4101 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4101 /* Port-F (int speaker) mixer - route only from analog mixer */ 4102 /* Port-F (int speaker) mixer - route only from analog mixer */
@@ -4126,7 +4127,7 @@ static struct hda_verb ad1884a_laptop_verbs[] = {
4126 { } /* end */ 4127 { } /* end */
4127}; 4128};
4128 4129
4129static struct hda_verb ad1884a_mobile_verbs[] = { 4130static const struct hda_verb ad1884a_mobile_verbs[] = {
4130 /* DACs; unmute as default */ 4131 /* DACs; unmute as default */
4131 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 4132 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4132 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 4133 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
@@ -4181,7 +4182,7 @@ static struct hda_verb ad1884a_mobile_verbs[] = {
4181 * 0x17 - built-in mic 4182 * 0x17 - built-in mic
4182 */ 4183 */
4183 4184
4184static struct hda_verb ad1984a_thinkpad_verbs[] = { 4185static const struct hda_verb ad1984a_thinkpad_verbs[] = {
4185 /* HP unmute */ 4186 /* HP unmute */
4186 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4187 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4187 /* analog mix */ 4188 /* analog mix */
@@ -4198,7 +4199,7 @@ static struct hda_verb ad1984a_thinkpad_verbs[] = {
4198 { } /* end */ 4199 { } /* end */
4199}; 4200};
4200 4201
4201static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = { 4202static const struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4202 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 4203 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4203 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), 4204 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4204 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 4205 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
@@ -4219,7 +4220,7 @@ static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4219 { } /* end */ 4220 { } /* end */
4220}; 4221};
4221 4222
4222static struct hda_input_mux ad1984a_thinkpad_capture_source = { 4223static const struct hda_input_mux ad1984a_thinkpad_capture_source = {
4223 .num_items = 3, 4224 .num_items = 3,
4224 .items = { 4225 .items = {
4225 { "Mic", 0x0 }, 4226 { "Mic", 0x0 },
@@ -4262,7 +4263,7 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec)
4262 * 0x15 - mic-in 4263 * 0x15 - mic-in
4263 */ 4264 */
4264 4265
4265static struct hda_verb ad1984a_precision_verbs[] = { 4266static const struct hda_verb ad1984a_precision_verbs[] = {
4266 /* Unmute main output path */ 4267 /* Unmute main output path */
4267 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 4268 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4268 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */ 4269 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */
@@ -4288,7 +4289,7 @@ static struct hda_verb ad1984a_precision_verbs[] = {
4288 { } /* end */ 4289 { } /* end */
4289}; 4290};
4290 4291
4291static struct snd_kcontrol_new ad1984a_precision_mixers[] = { 4292static const struct snd_kcontrol_new ad1984a_precision_mixers[] = {
4292 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 4293 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4293 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), 4294 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4294 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 4295 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
@@ -4344,7 +4345,7 @@ static int ad1984a_precision_init(struct hda_codec *codec)
4344 * digital-mic (0x17) - Internal mic 4345 * digital-mic (0x17) - Internal mic
4345 */ 4346 */
4346 4347
4347static struct hda_verb ad1984a_touchsmart_verbs[] = { 4348static const struct hda_verb ad1984a_touchsmart_verbs[] = {
4348 /* DACs; unmute as default */ 4349 /* DACs; unmute as default */
4349 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 4350 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4350 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 4351 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
@@ -4396,7 +4397,7 @@ static struct hda_verb ad1984a_touchsmart_verbs[] = {
4396 { } /* end */ 4397 { } /* end */
4397}; 4398};
4398 4399
4399static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = { 4400static const struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4400 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 4401 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4401/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 4402/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4402 { 4403 {
@@ -4475,7 +4476,7 @@ static const char * const ad1884a_models[AD1884A_MODELS] = {
4475 [AD1984A_PRECISION] = "precision", 4476 [AD1984A_PRECISION] = "precision",
4476}; 4477};
4477 4478
4478static struct snd_pci_quirk ad1884a_cfg_tbl[] = { 4479static const struct snd_pci_quirk ad1884a_cfg_tbl[] = {
4479 SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION), 4480 SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION),
4480 SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), 4481 SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
4481 SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), 4482 SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
@@ -4614,22 +4615,22 @@ static int patch_ad1884a(struct hda_codec *codec)
4614 * port-G - rear clfe-out (6stack) 4615 * port-G - rear clfe-out (6stack)
4615 */ 4616 */
4616 4617
4617static hda_nid_t ad1882_dac_nids[3] = { 4618static const hda_nid_t ad1882_dac_nids[3] = {
4618 0x04, 0x03, 0x05 4619 0x04, 0x03, 0x05
4619}; 4620};
4620 4621
4621static hda_nid_t ad1882_adc_nids[2] = { 4622static const hda_nid_t ad1882_adc_nids[2] = {
4622 0x08, 0x09, 4623 0x08, 0x09,
4623}; 4624};
4624 4625
4625static hda_nid_t ad1882_capsrc_nids[2] = { 4626static const hda_nid_t ad1882_capsrc_nids[2] = {
4626 0x0c, 0x0d, 4627 0x0c, 0x0d,
4627}; 4628};
4628 4629
4629#define AD1882_SPDIF_OUT 0x02 4630#define AD1882_SPDIF_OUT 0x02
4630 4631
4631/* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */ 4632/* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
4632static struct hda_input_mux ad1882_capture_source = { 4633static const struct hda_input_mux ad1882_capture_source = {
4633 .num_items = 5, 4634 .num_items = 5,
4634 .items = { 4635 .items = {
4635 { "Front Mic", 0x1 }, 4636 { "Front Mic", 0x1 },
@@ -4641,7 +4642,7 @@ static struct hda_input_mux ad1882_capture_source = {
4641}; 4642};
4642 4643
4643/* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */ 4644/* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */
4644static struct hda_input_mux ad1882a_capture_source = { 4645static const struct hda_input_mux ad1882a_capture_source = {
4645 .num_items = 5, 4646 .num_items = 5,
4646 .items = { 4647 .items = {
4647 { "Front Mic", 0x1 }, 4648 { "Front Mic", 0x1 },
@@ -4652,7 +4653,7 @@ static struct hda_input_mux ad1882a_capture_source = {
4652 }, 4653 },
4653}; 4654};
4654 4655
4655static struct snd_kcontrol_new ad1882_base_mixers[] = { 4656static const struct snd_kcontrol_new ad1882_base_mixers[] = {
4656 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 4657 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
4657 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 4658 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
4658 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 4659 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
@@ -4694,7 +4695,7 @@ static struct snd_kcontrol_new ad1882_base_mixers[] = {
4694 { } /* end */ 4695 { } /* end */
4695}; 4696};
4696 4697
4697static struct snd_kcontrol_new ad1882_loopback_mixers[] = { 4698static const struct snd_kcontrol_new ad1882_loopback_mixers[] = {
4698 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 4699 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4699 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 4700 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4700 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), 4701 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
@@ -4706,7 +4707,7 @@ static struct snd_kcontrol_new ad1882_loopback_mixers[] = {
4706 { } /* end */ 4707 { } /* end */
4707}; 4708};
4708 4709
4709static struct snd_kcontrol_new ad1882a_loopback_mixers[] = { 4710static const struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4710 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 4711 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4711 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 4712 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4712 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 4713 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
@@ -4719,7 +4720,7 @@ static struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4719 { } /* end */ 4720 { } /* end */
4720}; 4721};
4721 4722
4722static struct snd_kcontrol_new ad1882_3stack_mixers[] = { 4723static const struct snd_kcontrol_new ad1882_3stack_mixers[] = {
4723 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), 4724 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4724 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT), 4725 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
4725 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT), 4726 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
@@ -4733,14 +4734,14 @@ static struct snd_kcontrol_new ad1882_3stack_mixers[] = {
4733 { } /* end */ 4734 { } /* end */
4734}; 4735};
4735 4736
4736static struct snd_kcontrol_new ad1882_6stack_mixers[] = { 4737static const struct snd_kcontrol_new ad1882_6stack_mixers[] = {
4737 HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT), 4738 HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4738 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT), 4739 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
4739 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT), 4740 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
4740 { } /* end */ 4741 { } /* end */
4741}; 4742};
4742 4743
4743static struct hda_verb ad1882_ch2_init[] = { 4744static const struct hda_verb ad1882_ch2_init[] = {
4744 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4745 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4745 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4746 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4746 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4747 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
@@ -4750,7 +4751,7 @@ static struct hda_verb ad1882_ch2_init[] = {
4750 { } /* end */ 4751 { } /* end */
4751}; 4752};
4752 4753
4753static struct hda_verb ad1882_ch4_init[] = { 4754static const struct hda_verb ad1882_ch4_init[] = {
4754 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4755 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4755 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4756 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4756 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4757 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -4760,7 +4761,7 @@ static struct hda_verb ad1882_ch4_init[] = {
4760 { } /* end */ 4761 { } /* end */
4761}; 4762};
4762 4763
4763static struct hda_verb ad1882_ch6_init[] = { 4764static const struct hda_verb ad1882_ch6_init[] = {
4764 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4765 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4765 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4766 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4766 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4767 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -4770,7 +4771,7 @@ static struct hda_verb ad1882_ch6_init[] = {
4770 { } /* end */ 4771 { } /* end */
4771}; 4772};
4772 4773
4773static struct hda_channel_mode ad1882_modes[3] = { 4774static const struct hda_channel_mode ad1882_modes[3] = {
4774 { 2, ad1882_ch2_init }, 4775 { 2, ad1882_ch2_init },
4775 { 4, ad1882_ch4_init }, 4776 { 4, ad1882_ch4_init },
4776 { 6, ad1882_ch6_init }, 4777 { 6, ad1882_ch6_init },
@@ -4779,7 +4780,7 @@ static struct hda_channel_mode ad1882_modes[3] = {
4779/* 4780/*
4780 * initialization verbs 4781 * initialization verbs
4781 */ 4782 */
4782static struct hda_verb ad1882_init_verbs[] = { 4783static const struct hda_verb ad1882_init_verbs[] = {
4783 /* DACs; mute as default */ 4784 /* DACs; mute as default */
4784 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4785 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4785 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4786 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -4848,7 +4849,7 @@ static struct hda_verb ad1882_init_verbs[] = {
4848}; 4849};
4849 4850
4850#ifdef CONFIG_SND_HDA_POWER_SAVE 4851#ifdef CONFIG_SND_HDA_POWER_SAVE
4851static struct hda_amp_list ad1882_loopbacks[] = { 4852static const struct hda_amp_list ad1882_loopbacks[] = {
4852 { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 4853 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
4853 { 0x20, HDA_INPUT, 1 }, /* Mic */ 4854 { 0x20, HDA_INPUT, 1 }, /* Mic */
4854 { 0x20, HDA_INPUT, 4 }, /* Line */ 4855 { 0x20, HDA_INPUT, 4 }, /* Line */
@@ -4945,7 +4946,7 @@ static int patch_ad1882(struct hda_codec *codec)
4945/* 4946/*
4946 * patch entries 4947 * patch entries
4947 */ 4948 */
4948static struct hda_codec_preset snd_hda_preset_analog[] = { 4949static const struct hda_codec_preset snd_hda_preset_analog[] = {
4949 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a }, 4950 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a },
4950 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, 4951 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
4951 { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a }, 4952 { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a },
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c
index 46c8bf48c31f..61b92634b161 100644
--- a/sound/pci/hda/patch_ca0110.c
+++ b/sound/pci/hda/patch_ca0110.c
@@ -134,7 +134,7 @@ static int ca0110_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
134/* 134/*
135 */ 135 */
136 136
137static char *dirstr[2] = { "Playback", "Capture" }; 137static const char * const dirstr[2] = { "Playback", "Capture" };
138 138
139static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, 139static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
140 int chan, int dir) 140 int chan, int dir)
@@ -171,7 +171,7 @@ static int ca0110_build_controls(struct hda_codec *codec)
171{ 171{
172 struct ca0110_spec *spec = codec->spec; 172 struct ca0110_spec *spec = codec->spec;
173 struct auto_pin_cfg *cfg = &spec->autocfg; 173 struct auto_pin_cfg *cfg = &spec->autocfg;
174 static char *prefix[AUTO_CFG_MAX_OUTS] = { 174 static const char * const prefix[AUTO_CFG_MAX_OUTS] = {
175 "Front", "Surround", NULL, "Side", "Multi" 175 "Front", "Surround", NULL, "Side", "Multi"
176 }; 176 };
177 hda_nid_t mutenid; 177 hda_nid_t mutenid;
@@ -259,7 +259,7 @@ static int ca0110_build_controls(struct hda_codec *codec)
259 259
260/* 260/*
261 */ 261 */
262static struct hda_pcm_stream ca0110_pcm_analog_playback = { 262static const struct hda_pcm_stream ca0110_pcm_analog_playback = {
263 .substreams = 1, 263 .substreams = 1,
264 .channels_min = 2, 264 .channels_min = 2,
265 .channels_max = 8, 265 .channels_max = 8,
@@ -270,7 +270,7 @@ static struct hda_pcm_stream ca0110_pcm_analog_playback = {
270 }, 270 },
271}; 271};
272 272
273static struct hda_pcm_stream ca0110_pcm_analog_capture = { 273static const struct hda_pcm_stream ca0110_pcm_analog_capture = {
274 .substreams = 1, 274 .substreams = 1,
275 .channels_min = 2, 275 .channels_min = 2,
276 .channels_max = 2, 276 .channels_max = 2,
@@ -280,7 +280,7 @@ static struct hda_pcm_stream ca0110_pcm_analog_capture = {
280 }, 280 },
281}; 281};
282 282
283static struct hda_pcm_stream ca0110_pcm_digital_playback = { 283static const struct hda_pcm_stream ca0110_pcm_digital_playback = {
284 .substreams = 1, 284 .substreams = 1,
285 .channels_min = 2, 285 .channels_min = 2,
286 .channels_max = 2, 286 .channels_max = 2,
@@ -291,7 +291,7 @@ static struct hda_pcm_stream ca0110_pcm_digital_playback = {
291 }, 291 },
292}; 292};
293 293
294static struct hda_pcm_stream ca0110_pcm_digital_capture = { 294static const struct hda_pcm_stream ca0110_pcm_digital_capture = {
295 .substreams = 1, 295 .substreams = 1,
296 .channels_min = 2, 296 .channels_min = 2,
297 .channels_max = 2, 297 .channels_max = 2,
@@ -389,7 +389,7 @@ static void ca0110_free(struct hda_codec *codec)
389 kfree(codec->spec); 389 kfree(codec->spec);
390} 390}
391 391
392static struct hda_codec_ops ca0110_patch_ops = { 392static const struct hda_codec_ops ca0110_patch_ops = {
393 .build_controls = ca0110_build_controls, 393 .build_controls = ca0110_build_controls,
394 .build_pcms = ca0110_build_pcms, 394 .build_pcms = ca0110_build_pcms,
395 .init = ca0110_init, 395 .init = ca0110_init,
@@ -539,7 +539,7 @@ static int patch_ca0110(struct hda_codec *codec)
539/* 539/*
540 * patch entries 540 * patch entries
541 */ 541 */
542static struct hda_codec_preset snd_hda_preset_ca0110[] = { 542static const struct hda_codec_preset snd_hda_preset_ca0110[] = {
543 { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 }, 543 { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 },
544 { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 }, 544 { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 },
545 { .id = 0x1102000d, .name = "SB0880 X-Fi", .patch = patch_ca0110 }, 545 { .id = 0x1102000d, .name = "SB0880 X-Fi", .patch = patch_ca0110 },
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 067982f4f182..26a1521045bb 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -51,7 +51,7 @@ struct cs_spec {
51 unsigned int cur_adc_format; 51 unsigned int cur_adc_format;
52 hda_nid_t dig_in; 52 hda_nid_t dig_in;
53 53
54 struct hda_bind_ctls *capture_bind[2]; 54 const struct hda_bind_ctls *capture_bind[2];
55 55
56 unsigned int gpio_mask; 56 unsigned int gpio_mask;
57 unsigned int gpio_dir; 57 unsigned int gpio_dir;
@@ -231,7 +231,7 @@ static int cs_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
231 231
232/* 232/*
233 */ 233 */
234static struct hda_pcm_stream cs_pcm_analog_playback = { 234static const struct hda_pcm_stream cs_pcm_analog_playback = {
235 .substreams = 1, 235 .substreams = 1,
236 .channels_min = 2, 236 .channels_min = 2,
237 .channels_max = 2, 237 .channels_max = 2,
@@ -242,7 +242,7 @@ static struct hda_pcm_stream cs_pcm_analog_playback = {
242 }, 242 },
243}; 243};
244 244
245static struct hda_pcm_stream cs_pcm_analog_capture = { 245static const struct hda_pcm_stream cs_pcm_analog_capture = {
246 .substreams = 1, 246 .substreams = 1,
247 .channels_min = 2, 247 .channels_min = 2,
248 .channels_max = 2, 248 .channels_max = 2,
@@ -252,7 +252,7 @@ static struct hda_pcm_stream cs_pcm_analog_capture = {
252 }, 252 },
253}; 253};
254 254
255static struct hda_pcm_stream cs_pcm_digital_playback = { 255static const struct hda_pcm_stream cs_pcm_digital_playback = {
256 .substreams = 1, 256 .substreams = 1,
257 .channels_min = 2, 257 .channels_min = 2,
258 .channels_max = 2, 258 .channels_max = 2,
@@ -264,7 +264,7 @@ static struct hda_pcm_stream cs_pcm_digital_playback = {
264 }, 264 },
265}; 265};
266 266
267static struct hda_pcm_stream cs_pcm_digital_capture = { 267static const struct hda_pcm_stream cs_pcm_digital_capture = {
268 .substreams = 1, 268 .substreams = 1,
269 .channels_min = 2, 269 .channels_min = 2,
270 .channels_max = 2, 270 .channels_max = 2,
@@ -331,8 +331,8 @@ static int is_ext_mic(struct hda_codec *codec, unsigned int idx)
331 struct cs_spec *spec = codec->spec; 331 struct cs_spec *spec = codec->spec;
332 struct auto_pin_cfg *cfg = &spec->autocfg; 332 struct auto_pin_cfg *cfg = &spec->autocfg;
333 hda_nid_t pin = cfg->inputs[idx].pin; 333 hda_nid_t pin = cfg->inputs[idx].pin;
334 unsigned int val = snd_hda_query_pin_caps(codec, pin); 334 unsigned int val;
335 if (!(val & AC_PINCAP_PRES_DETECT)) 335 if (!is_jack_detectable(codec, pin))
336 return 0; 336 return 0;
337 val = snd_hda_codec_get_pincfg(codec, pin); 337 val = snd_hda_codec_get_pincfg(codec, pin);
338 return (snd_hda_get_input_pin_attr(val) != INPUT_PIN_ATTR_INT); 338 return (snd_hda_get_input_pin_attr(val) != INPUT_PIN_ATTR_INT);
@@ -349,8 +349,7 @@ static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
349 hda_nid_t pins[2]; 349 hda_nid_t pins[2];
350 unsigned int type; 350 unsigned int type;
351 int j, nums; 351 int j, nums;
352 type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) 352 type = get_wcaps_type(get_wcaps(codec, nid));
353 >> AC_WCAP_TYPE_SHIFT;
354 if (type != AC_WID_AUD_IN) 353 if (type != AC_WID_AUD_IN)
355 continue; 354 continue;
356 nums = snd_hda_get_connections(codec, nid, pins, 355 nums = snd_hda_get_connections(codec, nid, pins,
@@ -559,10 +558,10 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx,
559 const char *name; 558 const char *name;
560 int err, index; 559 int err, index;
561 struct snd_kcontrol *kctl; 560 struct snd_kcontrol *kctl;
562 static char *speakers[] = { 561 static const char * const speakers[] = {
563 "Front Speaker", "Surround Speaker", "Bass Speaker" 562 "Front Speaker", "Surround Speaker", "Bass Speaker"
564 }; 563 };
565 static char *line_outs[] = { 564 static const char * const line_outs[] = {
566 "Front Line-Out", "Surround Line-Out", "Bass Line-Out" 565 "Front Line-Out", "Surround Line-Out", "Bass Line-Out"
567 }; 566 };
568 567
@@ -642,7 +641,7 @@ static int build_output(struct hda_codec *codec)
642/* 641/*
643 */ 642 */
644 643
645static struct snd_kcontrol_new cs_capture_ctls[] = { 644static const struct snd_kcontrol_new cs_capture_ctls[] = {
646 HDA_BIND_SW("Capture Switch", 0), 645 HDA_BIND_SW("Capture Switch", 0),
647 HDA_BIND_VOL("Capture Volume", 0), 646 HDA_BIND_VOL("Capture Volume", 0),
648}; 647};
@@ -710,7 +709,7 @@ static int cs_capture_source_put(struct snd_kcontrol *kcontrol,
710 return change_cur_input(codec, idx, 0); 709 return change_cur_input(codec, idx, 0);
711} 710}
712 711
713static struct snd_kcontrol_new cs_capture_source = { 712static const struct snd_kcontrol_new cs_capture_source = {
714 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 713 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
715 .name = "Capture Source", 714 .name = "Capture Source",
716 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 715 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -719,7 +718,7 @@ static struct snd_kcontrol_new cs_capture_source = {
719 .put = cs_capture_source_put, 718 .put = cs_capture_source_put,
720}; 719};
721 720
722static struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec, 721static const struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec,
723 struct hda_ctl_ops *ops) 722 struct hda_ctl_ops *ops)
724{ 723{
725 struct cs_spec *spec = codec->spec; 724 struct cs_spec *spec = codec->spec;
@@ -847,15 +846,14 @@ static void cs_automute(struct hda_codec *codec)
847{ 846{
848 struct cs_spec *spec = codec->spec; 847 struct cs_spec *spec = codec->spec;
849 struct auto_pin_cfg *cfg = &spec->autocfg; 848 struct auto_pin_cfg *cfg = &spec->autocfg;
850 unsigned int caps, hp_present; 849 unsigned int hp_present;
851 hda_nid_t nid; 850 hda_nid_t nid;
852 int i; 851 int i;
853 852
854 hp_present = 0; 853 hp_present = 0;
855 for (i = 0; i < cfg->hp_outs; i++) { 854 for (i = 0; i < cfg->hp_outs; i++) {
856 nid = cfg->hp_pins[i]; 855 nid = cfg->hp_pins[i];
857 caps = snd_hda_query_pin_caps(codec, nid); 856 if (!is_jack_detectable(codec, nid))
858 if (!(caps & AC_PINCAP_PRES_DETECT))
859 continue; 857 continue;
860 hp_present = snd_hda_jack_detect(codec, nid); 858 hp_present = snd_hda_jack_detect(codec, nid);
861 if (hp_present) 859 if (hp_present)
@@ -924,7 +922,7 @@ static void init_output(struct hda_codec *codec)
924 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); 922 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
925 if (!cfg->speaker_outs) 923 if (!cfg->speaker_outs)
926 continue; 924 continue;
927 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { 925 if (is_jack_detectable(codec, nid)) {
928 snd_hda_codec_write(codec, nid, 0, 926 snd_hda_codec_write(codec, nid, 0,
929 AC_VERB_SET_UNSOLICITED_ENABLE, 927 AC_VERB_SET_UNSOLICITED_ENABLE,
930 AC_USRSP_EN | HP_EVENT); 928 AC_USRSP_EN | HP_EVENT);
@@ -983,7 +981,7 @@ static void init_input(struct hda_codec *codec)
983 cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); 981 cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
984} 982}
985 983
986static struct hda_verb cs_coef_init_verbs[] = { 984static const struct hda_verb cs_coef_init_verbs[] = {
987 {0x11, AC_VERB_SET_PROC_STATE, 1}, 985 {0x11, AC_VERB_SET_PROC_STATE, 1},
988 {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, 986 {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG},
989 {0x11, AC_VERB_SET_PROC_COEF, 987 {0x11, AC_VERB_SET_PROC_COEF,
@@ -1017,7 +1015,7 @@ static struct hda_verb cs_coef_init_verbs[] = {
1017 * blocks, which will alleviate the issue. 1015 * blocks, which will alleviate the issue.
1018 */ 1016 */
1019 1017
1020static struct hda_verb cs_errata_init_verbs[] = { 1018static const struct hda_verb cs_errata_init_verbs[] = {
1021 {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */ 1019 {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */
1022 {0x11, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */ 1020 {0x11, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */
1023 1021
@@ -1126,7 +1124,7 @@ static void cs_unsol_event(struct hda_codec *codec, unsigned int res)
1126 } 1124 }
1127} 1125}
1128 1126
1129static struct hda_codec_ops cs_patch_ops = { 1127static const struct hda_codec_ops cs_patch_ops = {
1130 .build_controls = cs_build_controls, 1128 .build_controls = cs_build_controls,
1131 .build_pcms = cs_build_pcms, 1129 .build_pcms = cs_build_pcms,
1132 .init = cs_init, 1130 .init = cs_init,
@@ -1166,7 +1164,7 @@ static const char * const cs420x_models[CS420X_MODELS] = {
1166}; 1164};
1167 1165
1168 1166
1169static struct snd_pci_quirk cs420x_cfg_tbl[] = { 1167static const struct snd_pci_quirk cs420x_cfg_tbl[] = {
1170 SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53), 1168 SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53),
1171 SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55), 1169 SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55),
1172 SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), 1170 SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55),
@@ -1180,7 +1178,7 @@ struct cs_pincfg {
1180 u32 val; 1178 u32 val;
1181}; 1179};
1182 1180
1183static struct cs_pincfg mbp53_pincfgs[] = { 1181static const struct cs_pincfg mbp53_pincfgs[] = {
1184 { 0x09, 0x012b4050 }, 1182 { 0x09, 0x012b4050 },
1185 { 0x0a, 0x90100141 }, 1183 { 0x0a, 0x90100141 },
1186 { 0x0b, 0x90100140 }, 1184 { 0x0b, 0x90100140 },
@@ -1194,7 +1192,7 @@ static struct cs_pincfg mbp53_pincfgs[] = {
1194 {} /* terminator */ 1192 {} /* terminator */
1195}; 1193};
1196 1194
1197static struct cs_pincfg mbp55_pincfgs[] = { 1195static const struct cs_pincfg mbp55_pincfgs[] = {
1198 { 0x09, 0x012b4030 }, 1196 { 0x09, 0x012b4030 },
1199 { 0x0a, 0x90100121 }, 1197 { 0x0a, 0x90100121 },
1200 { 0x0b, 0x90100120 }, 1198 { 0x0b, 0x90100120 },
@@ -1208,7 +1206,7 @@ static struct cs_pincfg mbp55_pincfgs[] = {
1208 {} /* terminator */ 1206 {} /* terminator */
1209}; 1207};
1210 1208
1211static struct cs_pincfg imac27_pincfgs[] = { 1209static const struct cs_pincfg imac27_pincfgs[] = {
1212 { 0x09, 0x012b4050 }, 1210 { 0x09, 0x012b4050 },
1213 { 0x0a, 0x90100140 }, 1211 { 0x0a, 0x90100140 },
1214 { 0x0b, 0x90100142 }, 1212 { 0x0b, 0x90100142 },
@@ -1222,7 +1220,7 @@ static struct cs_pincfg imac27_pincfgs[] = {
1222 {} /* terminator */ 1220 {} /* terminator */
1223}; 1221};
1224 1222
1225static struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = { 1223static const struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = {
1226 [CS420X_MBP53] = mbp53_pincfgs, 1224 [CS420X_MBP53] = mbp53_pincfgs,
1227 [CS420X_MBP55] = mbp55_pincfgs, 1225 [CS420X_MBP55] = mbp55_pincfgs,
1228 [CS420X_IMAC27] = imac27_pincfgs, 1226 [CS420X_IMAC27] = imac27_pincfgs,
@@ -1283,7 +1281,7 @@ static int patch_cs420x(struct hda_codec *codec)
1283/* 1281/*
1284 * patch entries 1282 * patch entries
1285 */ 1283 */
1286static struct hda_codec_preset snd_hda_preset_cirrus[] = { 1284static const struct hda_codec_preset snd_hda_preset_cirrus[] = {
1287 { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x }, 1285 { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x },
1288 { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x }, 1286 { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x },
1289 {} /* terminator */ 1287 {} /* terminator */
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 1f8bbcd0f802..ab3308daa960 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -53,7 +53,7 @@ struct cmi_spec {
53 int num_dacs; 53 int num_dacs;
54 54
55 /* capture */ 55 /* capture */
56 hda_nid_t *adc_nids; 56 const hda_nid_t *adc_nids;
57 hda_nid_t dig_in_nid; 57 hda_nid_t dig_in_nid;
58 58
59 /* capture source */ 59 /* capture source */
@@ -110,7 +110,7 @@ static int cmi_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
110 */ 110 */
111 111
112/* 3-stack / 2 channel */ 112/* 3-stack / 2 channel */
113static struct hda_verb cmi9880_ch2_init[] = { 113static const struct hda_verb cmi9880_ch2_init[] = {
114 /* set line-in PIN for input */ 114 /* set line-in PIN for input */
115 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 115 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
116 /* set mic PIN for input, also enable vref */ 116 /* set mic PIN for input, also enable vref */
@@ -121,7 +121,7 @@ static struct hda_verb cmi9880_ch2_init[] = {
121}; 121};
122 122
123/* 3-stack / 6 channel */ 123/* 3-stack / 6 channel */
124static struct hda_verb cmi9880_ch6_init[] = { 124static const struct hda_verb cmi9880_ch6_init[] = {
125 /* set line-in PIN for output */ 125 /* set line-in PIN for output */
126 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 126 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
127 /* set mic PIN for output */ 127 /* set mic PIN for output */
@@ -132,7 +132,7 @@ static struct hda_verb cmi9880_ch6_init[] = {
132}; 132};
133 133
134/* 3-stack+front / 8 channel */ 134/* 3-stack+front / 8 channel */
135static struct hda_verb cmi9880_ch8_init[] = { 135static const struct hda_verb cmi9880_ch8_init[] = {
136 /* set line-in PIN for output */ 136 /* set line-in PIN for output */
137 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 137 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
138 /* set mic PIN for output */ 138 /* set mic PIN for output */
@@ -142,7 +142,7 @@ static struct hda_verb cmi9880_ch8_init[] = {
142 {} 142 {}
143}; 143};
144 144
145static struct hda_channel_mode cmi9880_channel_modes[3] = { 145static const struct hda_channel_mode cmi9880_channel_modes[3] = {
146 { 2, cmi9880_ch2_init }, 146 { 2, cmi9880_ch2_init },
147 { 6, cmi9880_ch6_init }, 147 { 6, cmi9880_ch6_init },
148 { 8, cmi9880_ch8_init }, 148 { 8, cmi9880_ch8_init },
@@ -174,7 +174,7 @@ static int cmi_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
174 174
175/* 175/*
176 */ 176 */
177static struct snd_kcontrol_new cmi9880_basic_mixer[] = { 177static const struct snd_kcontrol_new cmi9880_basic_mixer[] = {
178 /* CMI9880 has no playback volumes! */ 178 /* CMI9880 has no playback volumes! */
179 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), /* front */ 179 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), /* front */
180 HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0x0, HDA_OUTPUT), 180 HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0x0, HDA_OUTPUT),
@@ -205,7 +205,7 @@ static struct snd_kcontrol_new cmi9880_basic_mixer[] = {
205/* 205/*
206 * shared I/O pins 206 * shared I/O pins
207 */ 207 */
208static struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = { 208static const struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = {
209 { 209 {
210 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 210 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
211 .name = "Channel Mode", 211 .name = "Channel Mode",
@@ -219,7 +219,7 @@ static struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = {
219/* AUD-in selections: 219/* AUD-in selections:
220 * 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x1f 0x20 220 * 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x1f 0x20
221 */ 221 */
222static struct hda_input_mux cmi9880_basic_mux = { 222static const struct hda_input_mux cmi9880_basic_mux = {
223 .num_items = 4, 223 .num_items = 4,
224 .items = { 224 .items = {
225 { "Front Mic", 0x5 }, 225 { "Front Mic", 0x5 },
@@ -229,7 +229,7 @@ static struct hda_input_mux cmi9880_basic_mux = {
229 } 229 }
230}; 230};
231 231
232static struct hda_input_mux cmi9880_no_line_mux = { 232static const struct hda_input_mux cmi9880_no_line_mux = {
233 .num_items = 3, 233 .num_items = 3,
234 .items = { 234 .items = {
235 { "Front Mic", 0x5 }, 235 { "Front Mic", 0x5 },
@@ -239,11 +239,11 @@ static struct hda_input_mux cmi9880_no_line_mux = {
239}; 239};
240 240
241/* front, rear, clfe, rear_surr */ 241/* front, rear, clfe, rear_surr */
242static hda_nid_t cmi9880_dac_nids[4] = { 242static const hda_nid_t cmi9880_dac_nids[4] = {
243 0x03, 0x04, 0x05, 0x06 243 0x03, 0x04, 0x05, 0x06
244}; 244};
245/* ADC0, ADC1 */ 245/* ADC0, ADC1 */
246static hda_nid_t cmi9880_adc_nids[2] = { 246static const hda_nid_t cmi9880_adc_nids[2] = {
247 0x08, 0x09 247 0x08, 0x09
248}; 248};
249 249
@@ -252,7 +252,7 @@ static hda_nid_t cmi9880_adc_nids[2] = {
252 252
253/* 253/*
254 */ 254 */
255static struct hda_verb cmi9880_basic_init[] = { 255static const struct hda_verb cmi9880_basic_init[] = {
256 /* port-D for line out (rear panel) */ 256 /* port-D for line out (rear panel) */
257 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 257 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
258 /* port-E for HP out (front panel) */ 258 /* port-E for HP out (front panel) */
@@ -281,7 +281,7 @@ static struct hda_verb cmi9880_basic_init[] = {
281 {} /* terminator */ 281 {} /* terminator */
282}; 282};
283 283
284static struct hda_verb cmi9880_allout_init[] = { 284static const struct hda_verb cmi9880_allout_init[] = {
285 /* port-D for line out (rear panel) */ 285 /* port-D for line out (rear panel) */
286 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 286 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
287 /* port-E for HP out (front panel) */ 287 /* port-E for HP out (front panel) */
@@ -528,7 +528,7 @@ static int cmi9880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
528 528
529/* 529/*
530 */ 530 */
531static struct hda_pcm_stream cmi9880_pcm_analog_playback = { 531static const struct hda_pcm_stream cmi9880_pcm_analog_playback = {
532 .substreams = 1, 532 .substreams = 1,
533 .channels_min = 2, 533 .channels_min = 2,
534 .channels_max = 8, 534 .channels_max = 8,
@@ -540,7 +540,7 @@ static struct hda_pcm_stream cmi9880_pcm_analog_playback = {
540 }, 540 },
541}; 541};
542 542
543static struct hda_pcm_stream cmi9880_pcm_analog_capture = { 543static const struct hda_pcm_stream cmi9880_pcm_analog_capture = {
544 .substreams = 2, 544 .substreams = 2,
545 .channels_min = 2, 545 .channels_min = 2,
546 .channels_max = 2, 546 .channels_max = 2,
@@ -551,7 +551,7 @@ static struct hda_pcm_stream cmi9880_pcm_analog_capture = {
551 }, 551 },
552}; 552};
553 553
554static struct hda_pcm_stream cmi9880_pcm_digital_playback = { 554static const struct hda_pcm_stream cmi9880_pcm_digital_playback = {
555 .substreams = 1, 555 .substreams = 1,
556 .channels_min = 2, 556 .channels_min = 2,
557 .channels_max = 2, 557 .channels_max = 2,
@@ -563,7 +563,7 @@ static struct hda_pcm_stream cmi9880_pcm_digital_playback = {
563 }, 563 },
564}; 564};
565 565
566static struct hda_pcm_stream cmi9880_pcm_digital_capture = { 566static const struct hda_pcm_stream cmi9880_pcm_digital_capture = {
567 .substreams = 1, 567 .substreams = 1,
568 .channels_min = 2, 568 .channels_min = 2,
569 .channels_max = 2, 569 .channels_max = 2,
@@ -617,14 +617,14 @@ static const char * const cmi9880_models[CMI_MODELS] = {
617 [CMI_AUTO] = "auto", 617 [CMI_AUTO] = "auto",
618}; 618};
619 619
620static struct snd_pci_quirk cmi9880_cfg_tbl[] = { 620static const struct snd_pci_quirk cmi9880_cfg_tbl[] = {
621 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", CMI_FULL_DIG), 621 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", CMI_FULL_DIG),
622 SND_PCI_QUIRK(0x1854, 0x002b, "LG LS75", CMI_MINIMAL), 622 SND_PCI_QUIRK(0x1854, 0x002b, "LG LS75", CMI_MINIMAL),
623 SND_PCI_QUIRK(0x1854, 0x0032, "LG", CMI_FULL_DIG), 623 SND_PCI_QUIRK(0x1854, 0x0032, "LG", CMI_FULL_DIG),
624 {} /* terminator */ 624 {} /* terminator */
625}; 625};
626 626
627static struct hda_codec_ops cmi9880_patch_ops = { 627static const struct hda_codec_ops cmi9880_patch_ops = {
628 .build_controls = cmi9880_build_controls, 628 .build_controls = cmi9880_build_controls,
629 .build_pcms = cmi9880_build_pcms, 629 .build_pcms = cmi9880_build_pcms,
630 .init = cmi9880_init, 630 .init = cmi9880_init,
@@ -745,7 +745,7 @@ static int patch_cmi9880(struct hda_codec *codec)
745/* 745/*
746 * patch entries 746 * patch entries
747 */ 747 */
748static struct hda_codec_preset snd_hda_preset_cmedia[] = { 748static const struct hda_codec_preset snd_hda_preset_cmedia[] = {
749 { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 }, 749 { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 },
750 { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 }, 750 { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 },
751 {} /* terminator */ 751 {} /* terminator */
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index ad97d937d3a8..4f37477d3c71 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -39,6 +39,7 @@
39 39
40#define CONEXANT_HP_EVENT 0x37 40#define CONEXANT_HP_EVENT 0x37
41#define CONEXANT_MIC_EVENT 0x38 41#define CONEXANT_MIC_EVENT 0x38
42#define CONEXANT_LINE_EVENT 0x39
42 43
43/* Conexant 5051 specific */ 44/* Conexant 5051 specific */
44 45
@@ -55,9 +56,16 @@ struct pin_dac_pair {
55 int type; 56 int type;
56}; 57};
57 58
59struct imux_info {
60 hda_nid_t pin; /* input pin NID */
61 hda_nid_t adc; /* connected ADC NID */
62 hda_nid_t boost; /* optional boost volume NID */
63 int index; /* corresponding to autocfg.input */
64};
65
58struct conexant_spec { 66struct conexant_spec {
59 67
60 struct snd_kcontrol_new *mixers[5]; 68 const struct snd_kcontrol_new *mixers[5];
61 int num_mixers; 69 int num_mixers;
62 hda_nid_t vmaster_nid; 70 hda_nid_t vmaster_nid;
63 71
@@ -74,14 +82,17 @@ struct conexant_spec {
74 */ 82 */
75 unsigned int cur_eapd; 83 unsigned int cur_eapd;
76 unsigned int hp_present; 84 unsigned int hp_present;
85 unsigned int line_present;
77 unsigned int auto_mic; 86 unsigned int auto_mic;
78 int auto_mic_ext; /* autocfg.inputs[] index for ext mic */ 87 int auto_mic_ext; /* imux_pins[] index for ext mic */
88 int auto_mic_dock; /* imux_pins[] index for dock mic */
89 int auto_mic_int; /* imux_pins[] index for int mic */
79 unsigned int need_dac_fix; 90 unsigned int need_dac_fix;
80 hda_nid_t slave_dig_outs[2]; 91 hda_nid_t slave_dig_outs[2];
81 92
82 /* capture */ 93 /* capture */
83 unsigned int num_adc_nids; 94 unsigned int num_adc_nids;
84 hda_nid_t *adc_nids; 95 const hda_nid_t *adc_nids;
85 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 96 hda_nid_t dig_in_nid; /* digital-in NID; optional */
86 97
87 unsigned int cur_adc_idx; 98 unsigned int cur_adc_idx;
@@ -89,9 +100,11 @@ struct conexant_spec {
89 unsigned int cur_adc_stream_tag; 100 unsigned int cur_adc_stream_tag;
90 unsigned int cur_adc_format; 101 unsigned int cur_adc_format;
91 102
103 const struct hda_pcm_stream *capture_stream;
104
92 /* capture source */ 105 /* capture source */
93 const struct hda_input_mux *input_mux; 106 const struct hda_input_mux *input_mux;
94 hda_nid_t *capsrc_nids; 107 const hda_nid_t *capsrc_nids;
95 unsigned int cur_mux[3]; 108 unsigned int cur_mux[3];
96 109
97 /* channel model */ 110 /* channel model */
@@ -106,12 +119,17 @@ struct conexant_spec {
106 /* dynamic controls, init_verbs and input_mux */ 119 /* dynamic controls, init_verbs and input_mux */
107 struct auto_pin_cfg autocfg; 120 struct auto_pin_cfg autocfg;
108 struct hda_input_mux private_imux; 121 struct hda_input_mux private_imux;
122 struct imux_info imux_info[HDA_MAX_NUM_INPUTS];
123 hda_nid_t private_adc_nids[HDA_MAX_NUM_INPUTS];
109 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 124 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
110 struct pin_dac_pair dac_info[8]; 125 struct pin_dac_pair dac_info[8];
111 int dac_info_filled; 126 int dac_info_filled;
112 127
113 unsigned int port_d_mode; 128 unsigned int port_d_mode;
114 unsigned int auto_mute:1; /* used in auto-parser */ 129 unsigned int auto_mute:1; /* used in auto-parser */
130 unsigned int detect_line:1; /* Line-out detection enabled */
131 unsigned int automute_lines:1; /* automute line-out as well */
132 unsigned int automute_hp_lo:1; /* both HP and LO available */
115 unsigned int dell_automute:1; 133 unsigned int dell_automute:1;
116 unsigned int dell_vostro:1; 134 unsigned int dell_vostro:1;
117 unsigned int ideapad:1; 135 unsigned int ideapad:1;
@@ -119,6 +137,8 @@ struct conexant_spec {
119 unsigned int hp_laptop:1; 137 unsigned int hp_laptop:1;
120 unsigned int asus:1; 138 unsigned int asus:1;
121 139
140 unsigned int adc_switching:1;
141
122 unsigned int ext_mic_present; 142 unsigned int ext_mic_present;
123 unsigned int recording; 143 unsigned int recording;
124 void (*capture_prepare)(struct hda_codec *codec); 144 void (*capture_prepare)(struct hda_codec *codec);
@@ -227,7 +247,7 @@ static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
227 247
228 248
229 249
230static struct hda_pcm_stream conexant_pcm_analog_playback = { 250static const struct hda_pcm_stream conexant_pcm_analog_playback = {
231 .substreams = 1, 251 .substreams = 1,
232 .channels_min = 2, 252 .channels_min = 2,
233 .channels_max = 2, 253 .channels_max = 2,
@@ -239,7 +259,7 @@ static struct hda_pcm_stream conexant_pcm_analog_playback = {
239 }, 259 },
240}; 260};
241 261
242static struct hda_pcm_stream conexant_pcm_analog_capture = { 262static const struct hda_pcm_stream conexant_pcm_analog_capture = {
243 .substreams = 1, 263 .substreams = 1,
244 .channels_min = 2, 264 .channels_min = 2,
245 .channels_max = 2, 265 .channels_max = 2,
@@ -251,7 +271,7 @@ static struct hda_pcm_stream conexant_pcm_analog_capture = {
251}; 271};
252 272
253 273
254static struct hda_pcm_stream conexant_pcm_digital_playback = { 274static const struct hda_pcm_stream conexant_pcm_digital_playback = {
255 .substreams = 1, 275 .substreams = 1,
256 .channels_min = 2, 276 .channels_min = 2,
257 .channels_max = 2, 277 .channels_max = 2,
@@ -263,7 +283,7 @@ static struct hda_pcm_stream conexant_pcm_digital_playback = {
263 }, 283 },
264}; 284};
265 285
266static struct hda_pcm_stream conexant_pcm_digital_capture = { 286static const struct hda_pcm_stream conexant_pcm_digital_capture = {
267 .substreams = 1, 287 .substreams = 1,
268 .channels_min = 2, 288 .channels_min = 2,
269 .channels_max = 2, 289 .channels_max = 2,
@@ -294,7 +314,7 @@ static int cx5051_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
294 return 0; 314 return 0;
295} 315}
296 316
297static struct hda_pcm_stream cx5051_pcm_analog_capture = { 317static const struct hda_pcm_stream cx5051_pcm_analog_capture = {
298 .substreams = 1, 318 .substreams = 1,
299 .channels_min = 2, 319 .channels_min = 2,
300 .channels_max = 2, 320 .channels_max = 2,
@@ -319,13 +339,19 @@ static int conexant_build_pcms(struct hda_codec *codec)
319 spec->multiout.max_channels; 339 spec->multiout.max_channels;
320 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 340 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
321 spec->multiout.dac_nids[0]; 341 spec->multiout.dac_nids[0];
322 if (codec->vendor_id == 0x14f15051) 342 if (spec->capture_stream)
323 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 343 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream;
324 cx5051_pcm_analog_capture; 344 else {
325 else 345 if (codec->vendor_id == 0x14f15051)
326 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 346 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
327 conexant_pcm_analog_capture; 347 cx5051_pcm_analog_capture;
328 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids; 348 else {
349 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
350 conexant_pcm_analog_capture;
351 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
352 spec->num_adc_nids;
353 }
354 }
329 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 355 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
330 356
331 if (spec->multiout.dig_out_nid) { 357 if (spec->multiout.dig_out_nid) {
@@ -433,7 +459,7 @@ static void conexant_free(struct hda_codec *codec)
433 kfree(codec->spec); 459 kfree(codec->spec);
434} 460}
435 461
436static struct snd_kcontrol_new cxt_capture_mixers[] = { 462static const struct snd_kcontrol_new cxt_capture_mixers[] = {
437 { 463 {
438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 464 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
439 .name = "Capture Source", 465 .name = "Capture Source",
@@ -446,7 +472,7 @@ static struct snd_kcontrol_new cxt_capture_mixers[] = {
446 472
447#ifdef CONFIG_SND_HDA_INPUT_BEEP 473#ifdef CONFIG_SND_HDA_INPUT_BEEP
448/* additional beep mixers; the actual parameters are overwritten at build */ 474/* additional beep mixers; the actual parameters are overwritten at build */
449static struct snd_kcontrol_new cxt_beep_mixer[] = { 475static const struct snd_kcontrol_new cxt_beep_mixer[] = {
450 HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), 476 HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT),
451 HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), 477 HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT),
452 { } /* end */ 478 { } /* end */
@@ -456,12 +482,18 @@ static struct snd_kcontrol_new cxt_beep_mixer[] = {
456static const char * const slave_vols[] = { 482static const char * const slave_vols[] = {
457 "Headphone Playback Volume", 483 "Headphone Playback Volume",
458 "Speaker Playback Volume", 484 "Speaker Playback Volume",
485 "Front Playback Volume",
486 "Surround Playback Volume",
487 "CLFE Playback Volume",
459 NULL 488 NULL
460}; 489};
461 490
462static const char * const slave_sws[] = { 491static const char * const slave_sws[] = {
463 "Headphone Playback Switch", 492 "Headphone Playback Switch",
464 "Speaker Playback Switch", 493 "Speaker Playback Switch",
494 "Front Playback Switch",
495 "Surround Playback Switch",
496 "CLFE Playback Switch",
465 NULL 497 NULL
466}; 498};
467 499
@@ -521,7 +553,7 @@ static int conexant_build_controls(struct hda_codec *codec)
521#ifdef CONFIG_SND_HDA_INPUT_BEEP 553#ifdef CONFIG_SND_HDA_INPUT_BEEP
522 /* create beep controls if needed */ 554 /* create beep controls if needed */
523 if (spec->beep_amp) { 555 if (spec->beep_amp) {
524 struct snd_kcontrol_new *knew; 556 const struct snd_kcontrol_new *knew;
525 for (knew = cxt_beep_mixer; knew->name; knew++) { 557 for (knew = cxt_beep_mixer; knew->name; knew++) {
526 struct snd_kcontrol *kctl; 558 struct snd_kcontrol *kctl;
527 kctl = snd_ctl_new1(knew, codec); 559 kctl = snd_ctl_new1(knew, codec);
@@ -546,7 +578,7 @@ static int conexant_suspend(struct hda_codec *codec, pm_message_t state)
546} 578}
547#endif 579#endif
548 580
549static struct hda_codec_ops conexant_patch_ops = { 581static const struct hda_codec_ops conexant_patch_ops = {
550 .build_controls = conexant_build_controls, 582 .build_controls = conexant_build_controls,
551 .build_pcms = conexant_build_pcms, 583 .build_pcms = conexant_build_pcms,
552 .init = conexant_init, 584 .init = conexant_init,
@@ -564,6 +596,7 @@ static struct hda_codec_ops conexant_patch_ops = {
564#define set_beep_amp(spec, nid, idx, dir) /* NOP */ 596#define set_beep_amp(spec, nid, idx, dir) /* NOP */
565#endif 597#endif
566 598
599static int patch_conexant_auto(struct hda_codec *codec);
567/* 600/*
568 * EAPD control 601 * EAPD control
569 * the private value = nid | (invert << 8) 602 * the private value = nid | (invert << 8)
@@ -662,16 +695,16 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
662 695
663/* Conexant 5045 specific */ 696/* Conexant 5045 specific */
664 697
665static hda_nid_t cxt5045_dac_nids[1] = { 0x19 }; 698static const hda_nid_t cxt5045_dac_nids[1] = { 0x19 };
666static hda_nid_t cxt5045_adc_nids[1] = { 0x1a }; 699static const hda_nid_t cxt5045_adc_nids[1] = { 0x1a };
667static hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a }; 700static const hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a };
668#define CXT5045_SPDIF_OUT 0x18 701#define CXT5045_SPDIF_OUT 0x18
669 702
670static struct hda_channel_mode cxt5045_modes[1] = { 703static const struct hda_channel_mode cxt5045_modes[1] = {
671 { 2, NULL }, 704 { 2, NULL },
672}; 705};
673 706
674static struct hda_input_mux cxt5045_capture_source = { 707static const struct hda_input_mux cxt5045_capture_source = {
675 .num_items = 2, 708 .num_items = 2,
676 .items = { 709 .items = {
677 { "IntMic", 0x1 }, 710 { "IntMic", 0x1 },
@@ -679,7 +712,7 @@ static struct hda_input_mux cxt5045_capture_source = {
679 } 712 }
680}; 713};
681 714
682static struct hda_input_mux cxt5045_capture_source_benq = { 715static const struct hda_input_mux cxt5045_capture_source_benq = {
683 .num_items = 5, 716 .num_items = 5,
684 .items = { 717 .items = {
685 { "IntMic", 0x1 }, 718 { "IntMic", 0x1 },
@@ -690,7 +723,7 @@ static struct hda_input_mux cxt5045_capture_source_benq = {
690 } 723 }
691}; 724};
692 725
693static struct hda_input_mux cxt5045_capture_source_hp530 = { 726static const struct hda_input_mux cxt5045_capture_source_hp530 = {
694 .num_items = 2, 727 .num_items = 2,
695 .items = { 728 .items = {
696 { "ExtMic", 0x1 }, 729 { "ExtMic", 0x1 },
@@ -723,7 +756,7 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
723} 756}
724 757
725/* bind volumes of both NID 0x10 and 0x11 */ 758/* bind volumes of both NID 0x10 and 0x11 */
726static struct hda_bind_ctls cxt5045_hp_bind_master_vol = { 759static const struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
727 .ops = &snd_hda_bind_vol, 760 .ops = &snd_hda_bind_vol,
728 .values = { 761 .values = {
729 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT), 762 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT),
@@ -735,12 +768,12 @@ static struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
735/* toggle input of built-in and mic jack appropriately */ 768/* toggle input of built-in and mic jack appropriately */
736static void cxt5045_hp_automic(struct hda_codec *codec) 769static void cxt5045_hp_automic(struct hda_codec *codec)
737{ 770{
738 static struct hda_verb mic_jack_on[] = { 771 static const struct hda_verb mic_jack_on[] = {
739 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 772 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
740 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 773 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
741 {} 774 {}
742 }; 775 };
743 static struct hda_verb mic_jack_off[] = { 776 static const struct hda_verb mic_jack_off[] = {
744 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 777 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
745 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 778 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
746 {} 779 {}
@@ -784,7 +817,7 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec,
784 } 817 }
785} 818}
786 819
787static struct snd_kcontrol_new cxt5045_mixers[] = { 820static const struct snd_kcontrol_new cxt5045_mixers[] = {
788 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), 821 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
789 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), 822 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
790 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), 823 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
@@ -808,7 +841,7 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
808 {} 841 {}
809}; 842};
810 843
811static struct snd_kcontrol_new cxt5045_benq_mixers[] = { 844static const struct snd_kcontrol_new cxt5045_benq_mixers[] = {
812 HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT), 845 HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
813 HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT), 846 HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
814 HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT), 847 HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
@@ -825,7 +858,7 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
825 {} 858 {}
826}; 859};
827 860
828static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { 861static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
829 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), 862 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
830 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), 863 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
831 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), 864 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
@@ -849,7 +882,7 @@ static struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
849 {} 882 {}
850}; 883};
851 884
852static struct hda_verb cxt5045_init_verbs[] = { 885static const struct hda_verb cxt5045_init_verbs[] = {
853 /* Line in, Mic */ 886 /* Line in, Mic */
854 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 887 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 888 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
@@ -875,7 +908,7 @@ static struct hda_verb cxt5045_init_verbs[] = {
875 { } /* end */ 908 { } /* end */
876}; 909};
877 910
878static struct hda_verb cxt5045_benq_init_verbs[] = { 911static const struct hda_verb cxt5045_benq_init_verbs[] = {
879 /* Internal Mic, Mic */ 912 /* Internal Mic, Mic */
880 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 913 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
881 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 914 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
@@ -901,13 +934,13 @@ static struct hda_verb cxt5045_benq_init_verbs[] = {
901 { } /* end */ 934 { } /* end */
902}; 935};
903 936
904static struct hda_verb cxt5045_hp_sense_init_verbs[] = { 937static const struct hda_verb cxt5045_hp_sense_init_verbs[] = {
905 /* pin sensing on HP jack */ 938 /* pin sensing on HP jack */
906 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, 939 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
907 { } /* end */ 940 { } /* end */
908}; 941};
909 942
910static struct hda_verb cxt5045_mic_sense_init_verbs[] = { 943static const struct hda_verb cxt5045_mic_sense_init_verbs[] = {
911 /* pin sensing on HP jack */ 944 /* pin sensing on HP jack */
912 {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, 945 {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
913 { } /* end */ 946 { } /* end */
@@ -917,7 +950,7 @@ static struct hda_verb cxt5045_mic_sense_init_verbs[] = {
917/* Test configuration for debugging, modelled after the ALC260 test 950/* Test configuration for debugging, modelled after the ALC260 test
918 * configuration. 951 * configuration.
919 */ 952 */
920static struct hda_input_mux cxt5045_test_capture_source = { 953static const struct hda_input_mux cxt5045_test_capture_source = {
921 .num_items = 5, 954 .num_items = 5,
922 .items = { 955 .items = {
923 { "MIXER", 0x0 }, 956 { "MIXER", 0x0 },
@@ -928,7 +961,7 @@ static struct hda_input_mux cxt5045_test_capture_source = {
928 }, 961 },
929}; 962};
930 963
931static struct snd_kcontrol_new cxt5045_test_mixer[] = { 964static const struct snd_kcontrol_new cxt5045_test_mixer[] = {
932 965
933 /* Output controls */ 966 /* Output controls */
934 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), 967 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
@@ -978,7 +1011,7 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
978 { } /* end */ 1011 { } /* end */
979}; 1012};
980 1013
981static struct hda_verb cxt5045_test_init_verbs[] = { 1014static const struct hda_verb cxt5045_test_init_verbs[] = {
982 /* Set connections */ 1015 /* Set connections */
983 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1016 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
984 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1017 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
@@ -1047,6 +1080,7 @@ enum {
1047#ifdef CONFIG_SND_DEBUG 1080#ifdef CONFIG_SND_DEBUG
1048 CXT5045_TEST, 1081 CXT5045_TEST,
1049#endif 1082#endif
1083 CXT5045_AUTO,
1050 CXT5045_MODELS 1084 CXT5045_MODELS
1051}; 1085};
1052 1086
@@ -1059,9 +1093,10 @@ static const char * const cxt5045_models[CXT5045_MODELS] = {
1059#ifdef CONFIG_SND_DEBUG 1093#ifdef CONFIG_SND_DEBUG
1060 [CXT5045_TEST] = "test", 1094 [CXT5045_TEST] = "test",
1061#endif 1095#endif
1096 [CXT5045_AUTO] = "auto",
1062}; 1097};
1063 1098
1064static struct snd_pci_quirk cxt5045_cfg_tbl[] = { 1099static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
1065 SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530), 1100 SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
1066 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series", 1101 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1067 CXT5045_LAPTOP_HPSENSE), 1102 CXT5045_LAPTOP_HPSENSE),
@@ -1085,6 +1120,16 @@ static int patch_cxt5045(struct hda_codec *codec)
1085 struct conexant_spec *spec; 1120 struct conexant_spec *spec;
1086 int board_config; 1121 int board_config;
1087 1122
1123 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1124 cxt5045_models,
1125 cxt5045_cfg_tbl);
1126#if 0 /* use the old method just for safety */
1127 if (board_config < 0)
1128 board_config = CXT5045_AUTO;
1129#endif
1130 if (board_config == CXT5045_AUTO)
1131 return patch_conexant_auto(codec);
1132
1088 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1133 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1089 if (!spec) 1134 if (!spec)
1090 return -ENOMEM; 1135 return -ENOMEM;
@@ -1111,9 +1156,6 @@ static int patch_cxt5045(struct hda_codec *codec)
1111 1156
1112 codec->patch_ops = conexant_patch_ops; 1157 codec->patch_ops = conexant_patch_ops;
1113 1158
1114 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1115 cxt5045_models,
1116 cxt5045_cfg_tbl);
1117 switch (board_config) { 1159 switch (board_config) {
1118 case CXT5045_LAPTOP_HPSENSE: 1160 case CXT5045_LAPTOP_HPSENSE:
1119 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; 1161 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
@@ -1196,15 +1238,15 @@ static int patch_cxt5045(struct hda_codec *codec)
1196/* Conexant 5047 specific */ 1238/* Conexant 5047 specific */
1197#define CXT5047_SPDIF_OUT 0x11 1239#define CXT5047_SPDIF_OUT 0x11
1198 1240
1199static hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */ 1241static const hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */
1200static hda_nid_t cxt5047_adc_nids[1] = { 0x12 }; 1242static const hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
1201static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a }; 1243static const hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a };
1202 1244
1203static struct hda_channel_mode cxt5047_modes[1] = { 1245static const struct hda_channel_mode cxt5047_modes[1] = {
1204 { 2, NULL }, 1246 { 2, NULL },
1205}; 1247};
1206 1248
1207static struct hda_input_mux cxt5047_toshiba_capture_source = { 1249static const struct hda_input_mux cxt5047_toshiba_capture_source = {
1208 .num_items = 2, 1250 .num_items = 2,
1209 .items = { 1251 .items = {
1210 { "ExtMic", 0x2 }, 1252 { "ExtMic", 0x2 },
@@ -1256,12 +1298,12 @@ static void cxt5047_hp_automute(struct hda_codec *codec)
1256/* toggle input of built-in and mic jack appropriately */ 1298/* toggle input of built-in and mic jack appropriately */
1257static void cxt5047_hp_automic(struct hda_codec *codec) 1299static void cxt5047_hp_automic(struct hda_codec *codec)
1258{ 1300{
1259 static struct hda_verb mic_jack_on[] = { 1301 static const struct hda_verb mic_jack_on[] = {
1260 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1302 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1261 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1303 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1262 {} 1304 {}
1263 }; 1305 };
1264 static struct hda_verb mic_jack_off[] = { 1306 static const struct hda_verb mic_jack_off[] = {
1265 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1307 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1266 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1308 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1267 {} 1309 {}
@@ -1289,7 +1331,7 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec,
1289 } 1331 }
1290} 1332}
1291 1333
1292static struct snd_kcontrol_new cxt5047_base_mixers[] = { 1334static const struct snd_kcontrol_new cxt5047_base_mixers[] = {
1293 HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT), 1335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT),
1294 HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT), 1336 HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT),
1295 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT), 1337 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
@@ -1309,19 +1351,19 @@ static struct snd_kcontrol_new cxt5047_base_mixers[] = {
1309 {} 1351 {}
1310}; 1352};
1311 1353
1312static struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = { 1354static const struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = {
1313 /* See the note in cxt5047_hp_master_sw_put */ 1355 /* See the note in cxt5047_hp_master_sw_put */
1314 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT), 1356 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT),
1315 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT), 1357 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1316 {} 1358 {}
1317}; 1359};
1318 1360
1319static struct snd_kcontrol_new cxt5047_hp_only_mixers[] = { 1361static const struct snd_kcontrol_new cxt5047_hp_only_mixers[] = {
1320 HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT), 1362 HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1321 { } /* end */ 1363 { } /* end */
1322}; 1364};
1323 1365
1324static struct hda_verb cxt5047_init_verbs[] = { 1366static const struct hda_verb cxt5047_init_verbs[] = {
1325 /* Line in, Mic, Built-in Mic */ 1367 /* Line in, Mic, Built-in Mic */
1326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1368 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, 1369 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
@@ -1348,7 +1390,7 @@ static struct hda_verb cxt5047_init_verbs[] = {
1348}; 1390};
1349 1391
1350/* configuration for Toshiba Laptops */ 1392/* configuration for Toshiba Laptops */
1351static struct hda_verb cxt5047_toshiba_init_verbs[] = { 1393static const struct hda_verb cxt5047_toshiba_init_verbs[] = {
1352 {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */ 1394 {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */
1353 {} 1395 {}
1354}; 1396};
@@ -1357,7 +1399,7 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = {
1357 * configuration. 1399 * configuration.
1358 */ 1400 */
1359#ifdef CONFIG_SND_DEBUG 1401#ifdef CONFIG_SND_DEBUG
1360static struct hda_input_mux cxt5047_test_capture_source = { 1402static const struct hda_input_mux cxt5047_test_capture_source = {
1361 .num_items = 4, 1403 .num_items = 4,
1362 .items = { 1404 .items = {
1363 { "LINE1 pin", 0x0 }, 1405 { "LINE1 pin", 0x0 },
@@ -1367,7 +1409,7 @@ static struct hda_input_mux cxt5047_test_capture_source = {
1367 }, 1409 },
1368}; 1410};
1369 1411
1370static struct snd_kcontrol_new cxt5047_test_mixer[] = { 1412static const struct snd_kcontrol_new cxt5047_test_mixer[] = {
1371 1413
1372 /* Output only controls */ 1414 /* Output only controls */
1373 HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT), 1415 HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT),
@@ -1420,7 +1462,7 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = {
1420 { } /* end */ 1462 { } /* end */
1421}; 1463};
1422 1464
1423static struct hda_verb cxt5047_test_init_verbs[] = { 1465static const struct hda_verb cxt5047_test_init_verbs[] = {
1424 /* Enable retasking pins as output, initially without power amp */ 1466 /* Enable retasking pins as output, initially without power amp */
1425 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1467 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1426 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1468 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -1492,6 +1534,7 @@ enum {
1492#ifdef CONFIG_SND_DEBUG 1534#ifdef CONFIG_SND_DEBUG
1493 CXT5047_TEST, 1535 CXT5047_TEST,
1494#endif 1536#endif
1537 CXT5047_AUTO,
1495 CXT5047_MODELS 1538 CXT5047_MODELS
1496}; 1539};
1497 1540
@@ -1502,9 +1545,10 @@ static const char * const cxt5047_models[CXT5047_MODELS] = {
1502#ifdef CONFIG_SND_DEBUG 1545#ifdef CONFIG_SND_DEBUG
1503 [CXT5047_TEST] = "test", 1546 [CXT5047_TEST] = "test",
1504#endif 1547#endif
1548 [CXT5047_AUTO] = "auto",
1505}; 1549};
1506 1550
1507static struct snd_pci_quirk cxt5047_cfg_tbl[] = { 1551static const struct snd_pci_quirk cxt5047_cfg_tbl[] = {
1508 SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP), 1552 SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP),
1509 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series", 1553 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1510 CXT5047_LAPTOP), 1554 CXT5047_LAPTOP),
@@ -1517,6 +1561,16 @@ static int patch_cxt5047(struct hda_codec *codec)
1517 struct conexant_spec *spec; 1561 struct conexant_spec *spec;
1518 int board_config; 1562 int board_config;
1519 1563
1564 board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1565 cxt5047_models,
1566 cxt5047_cfg_tbl);
1567#if 0 /* not enabled as default, as BIOS often broken for this codec */
1568 if (board_config < 0)
1569 board_config = CXT5047_AUTO;
1570#endif
1571 if (board_config == CXT5047_AUTO)
1572 return patch_conexant_auto(codec);
1573
1520 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1574 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1521 if (!spec) 1575 if (!spec)
1522 return -ENOMEM; 1576 return -ENOMEM;
@@ -1540,9 +1594,6 @@ static int patch_cxt5047(struct hda_codec *codec)
1540 1594
1541 codec->patch_ops = conexant_patch_ops; 1595 codec->patch_ops = conexant_patch_ops;
1542 1596
1543 board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1544 cxt5047_models,
1545 cxt5047_cfg_tbl);
1546 switch (board_config) { 1597 switch (board_config) {
1547 case CXT5047_LAPTOP: 1598 case CXT5047_LAPTOP:
1548 spec->num_mixers = 2; 1599 spec->num_mixers = 2;
@@ -1591,10 +1642,10 @@ static int patch_cxt5047(struct hda_codec *codec)
1591} 1642}
1592 1643
1593/* Conexant 5051 specific */ 1644/* Conexant 5051 specific */
1594static hda_nid_t cxt5051_dac_nids[1] = { 0x10 }; 1645static const hda_nid_t cxt5051_dac_nids[1] = { 0x10 };
1595static hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 }; 1646static const hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 };
1596 1647
1597static struct hda_channel_mode cxt5051_modes[1] = { 1648static const struct hda_channel_mode cxt5051_modes[1] = {
1598 { 2, NULL }, 1649 { 2, NULL },
1599}; 1650};
1600 1651
@@ -1696,7 +1747,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1696 snd_hda_input_jack_report(codec, nid); 1747 snd_hda_input_jack_report(codec, nid);
1697} 1748}
1698 1749
1699static struct snd_kcontrol_new cxt5051_playback_mixers[] = { 1750static const struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1700 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 1751 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1701 { 1752 {
1702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1753 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1709,7 +1760,7 @@ static struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1709 {} 1760 {}
1710}; 1761};
1711 1762
1712static struct snd_kcontrol_new cxt5051_capture_mixers[] = { 1763static const struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1713 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1764 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1714 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1765 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1715 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), 1766 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
@@ -1719,7 +1770,7 @@ static struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1719 {} 1770 {}
1720}; 1771};
1721 1772
1722static struct snd_kcontrol_new cxt5051_hp_mixers[] = { 1773static const struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1723 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1774 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1724 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1775 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1725 HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT), 1776 HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT),
@@ -1727,19 +1778,19 @@ static struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1727 {} 1778 {}
1728}; 1779};
1729 1780
1730static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = { 1781static const struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1731 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT), 1782 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT),
1732 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT), 1783 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT),
1733 {} 1784 {}
1734}; 1785};
1735 1786
1736static struct snd_kcontrol_new cxt5051_f700_mixers[] = { 1787static const struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1737 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT), 1788 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT),
1738 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT), 1789 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT),
1739 {} 1790 {}
1740}; 1791};
1741 1792
1742static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = { 1793static const struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1743 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1794 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1744 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1795 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1745 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), 1796 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
@@ -1747,7 +1798,7 @@ static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1747 {} 1798 {}
1748}; 1799};
1749 1800
1750static struct hda_verb cxt5051_init_verbs[] = { 1801static const struct hda_verb cxt5051_init_verbs[] = {
1751 /* Line in, Mic */ 1802 /* Line in, Mic */
1752 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1803 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1753 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1804 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -1776,7 +1827,7 @@ static struct hda_verb cxt5051_init_verbs[] = {
1776 { } /* end */ 1827 { } /* end */
1777}; 1828};
1778 1829
1779static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = { 1830static const struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1780 /* Line in, Mic */ 1831 /* Line in, Mic */
1781 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1832 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1782 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1833 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -1801,7 +1852,7 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1801 { } /* end */ 1852 { } /* end */
1802}; 1853};
1803 1854
1804static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { 1855static const struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1805 /* Line in, Mic */ 1856 /* Line in, Mic */
1806 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1857 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1807 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1858 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -1834,7 +1885,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1834 { } /* end */ 1885 { } /* end */
1835}; 1886};
1836 1887
1837static struct hda_verb cxt5051_f700_init_verbs[] = { 1888static const struct hda_verb cxt5051_f700_init_verbs[] = {
1838 /* Line in, Mic */ 1889 /* Line in, Mic */
1839 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1890 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1840 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1891 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -1869,7 +1920,7 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1869 snd_hda_input_jack_report(codec, nid); 1920 snd_hda_input_jack_report(codec, nid);
1870} 1921}
1871 1922
1872static struct hda_verb cxt5051_ideapad_init_verbs[] = { 1923static const struct hda_verb cxt5051_ideapad_init_verbs[] = {
1873 /* Subwoofer */ 1924 /* Subwoofer */
1874 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1925 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1875 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 1926 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -1906,6 +1957,7 @@ enum {
1906 CXT5051_F700, /* HP Compaq Presario F700 */ 1957 CXT5051_F700, /* HP Compaq Presario F700 */
1907 CXT5051_TOSHIBA, /* Toshiba M300 & co */ 1958 CXT5051_TOSHIBA, /* Toshiba M300 & co */
1908 CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */ 1959 CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */
1960 CXT5051_AUTO, /* auto-parser */
1909 CXT5051_MODELS 1961 CXT5051_MODELS
1910}; 1962};
1911 1963
@@ -1917,9 +1969,10 @@ static const char *const cxt5051_models[CXT5051_MODELS] = {
1917 [CXT5051_F700] = "hp-700", 1969 [CXT5051_F700] = "hp-700",
1918 [CXT5051_TOSHIBA] = "toshiba", 1970 [CXT5051_TOSHIBA] = "toshiba",
1919 [CXT5051_IDEAPAD] = "ideapad", 1971 [CXT5051_IDEAPAD] = "ideapad",
1972 [CXT5051_AUTO] = "auto",
1920}; 1973};
1921 1974
1922static struct snd_pci_quirk cxt5051_cfg_tbl[] = { 1975static const struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1923 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), 1976 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1924 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP), 1977 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1925 SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700), 1978 SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
@@ -1937,6 +1990,16 @@ static int patch_cxt5051(struct hda_codec *codec)
1937 struct conexant_spec *spec; 1990 struct conexant_spec *spec;
1938 int board_config; 1991 int board_config;
1939 1992
1993 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1994 cxt5051_models,
1995 cxt5051_cfg_tbl);
1996#if 0 /* use the old method just for safety */
1997 if (board_config < 0)
1998 board_config = CXT5051_AUTO;
1999#endif
2000 if (board_config == CXT5051_AUTO)
2001 return patch_conexant_auto(codec);
2002
1940 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 2003 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1941 if (!spec) 2004 if (!spec)
1942 return -ENOMEM; 2005 return -ENOMEM;
@@ -1967,9 +2030,6 @@ static int patch_cxt5051(struct hda_codec *codec)
1967 2030
1968 codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; 2031 codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
1969 2032
1970 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1971 cxt5051_models,
1972 cxt5051_cfg_tbl);
1973 spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC; 2033 spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC;
1974 switch (board_config) { 2034 switch (board_config) {
1975 case CXT5051_HP: 2035 case CXT5051_HP:
@@ -2011,17 +2071,17 @@ static int patch_cxt5051(struct hda_codec *codec)
2011 2071
2012/* Conexant 5066 specific */ 2072/* Conexant 5066 specific */
2013 2073
2014static hda_nid_t cxt5066_dac_nids[1] = { 0x10 }; 2074static const hda_nid_t cxt5066_dac_nids[1] = { 0x10 };
2015static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 }; 2075static const hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
2016static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 }; 2076static const hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
2017static hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 }; 2077static const hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 };
2018 2078
2019/* OLPC's microphone port is DC coupled for use with external sensors, 2079/* OLPC's microphone port is DC coupled for use with external sensors,
2020 * therefore we use a 50% mic bias in order to center the input signal with 2080 * therefore we use a 50% mic bias in order to center the input signal with
2021 * the DC input range of the codec. */ 2081 * the DC input range of the codec. */
2022#define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50 2082#define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50
2023 2083
2024static struct hda_channel_mode cxt5066_modes[1] = { 2084static const struct hda_channel_mode cxt5066_modes[1] = {
2025 { 2, NULL }, 2085 { 2, NULL },
2026}; 2086};
2027 2087
@@ -2176,7 +2236,7 @@ static void cxt5066_vostro_automic(struct hda_codec *codec)
2176 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2236 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2177 {} 2237 {}
2178 }; 2238 };
2179 static struct hda_verb ext_mic_absent[] = { 2239 static const struct hda_verb ext_mic_absent[] = {
2180 /* enable internal mic, port C */ 2240 /* enable internal mic, port C */
2181 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2241 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2182 2242
@@ -2209,7 +2269,7 @@ static void cxt5066_ideapad_automic(struct hda_codec *codec)
2209 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2269 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2210 {} 2270 {}
2211 }; 2271 };
2212 static struct hda_verb ext_mic_absent[] = { 2272 static const struct hda_verb ext_mic_absent[] = {
2213 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, 2273 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2214 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2274 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2215 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2275 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
@@ -2257,7 +2317,7 @@ static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2257{ 2317{
2258 unsigned int ext_present, dock_present; 2318 unsigned int ext_present, dock_present;
2259 2319
2260 static struct hda_verb ext_mic_present[] = { 2320 static const struct hda_verb ext_mic_present[] = {
2261 {0x14, AC_VERB_SET_CONNECT_SEL, 0}, 2321 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2262 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, 2322 {0x17, AC_VERB_SET_CONNECT_SEL, 1},
2263 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2323 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -2265,7 +2325,7 @@ static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2265 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2325 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2266 {} 2326 {}
2267 }; 2327 };
2268 static struct hda_verb dock_mic_present[] = { 2328 static const struct hda_verb dock_mic_present[] = {
2269 {0x14, AC_VERB_SET_CONNECT_SEL, 0}, 2329 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2270 {0x17, AC_VERB_SET_CONNECT_SEL, 0}, 2330 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2271 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2331 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -2273,7 +2333,7 @@ static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2273 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2333 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2274 {} 2334 {}
2275 }; 2335 };
2276 static struct hda_verb ext_mic_absent[] = { 2336 static const struct hda_verb ext_mic_absent[] = {
2277 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, 2337 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2278 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2338 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2279 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2339 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
@@ -2537,7 +2597,7 @@ static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec)
2537} 2597}
2538 2598
2539static void conexant_check_dig_outs(struct hda_codec *codec, 2599static void conexant_check_dig_outs(struct hda_codec *codec,
2540 hda_nid_t *dig_pins, 2600 const hda_nid_t *dig_pins,
2541 int num_pins) 2601 int num_pins)
2542{ 2602{
2543 struct conexant_spec *spec = codec->spec; 2603 struct conexant_spec *spec = codec->spec;
@@ -2557,7 +2617,7 @@ static void conexant_check_dig_outs(struct hda_codec *codec,
2557 } 2617 }
2558} 2618}
2559 2619
2560static struct hda_input_mux cxt5066_capture_source = { 2620static const struct hda_input_mux cxt5066_capture_source = {
2561 .num_items = 4, 2621 .num_items = 4,
2562 .items = { 2622 .items = {
2563 { "Mic B", 0 }, 2623 { "Mic B", 0 },
@@ -2567,7 +2627,7 @@ static struct hda_input_mux cxt5066_capture_source = {
2567 }, 2627 },
2568}; 2628};
2569 2629
2570static struct hda_bind_ctls cxt5066_bind_capture_vol_others = { 2630static const struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2571 .ops = &snd_hda_bind_vol, 2631 .ops = &snd_hda_bind_vol,
2572 .values = { 2632 .values = {
2573 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), 2633 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
@@ -2576,7 +2636,7 @@ static struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2576 }, 2636 },
2577}; 2637};
2578 2638
2579static struct hda_bind_ctls cxt5066_bind_capture_sw_others = { 2639static const struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2580 .ops = &snd_hda_bind_sw, 2640 .ops = &snd_hda_bind_sw,
2581 .values = { 2641 .values = {
2582 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), 2642 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
@@ -2585,12 +2645,12 @@ static struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2585 }, 2645 },
2586}; 2646};
2587 2647
2588static struct snd_kcontrol_new cxt5066_mixer_master[] = { 2648static const struct snd_kcontrol_new cxt5066_mixer_master[] = {
2589 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 2649 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
2590 {} 2650 {}
2591}; 2651};
2592 2652
2593static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = { 2653static const struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2594 { 2654 {
2595 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2655 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2596 .name = "Master Playback Volume", 2656 .name = "Master Playback Volume",
@@ -2609,7 +2669,7 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2609 {} 2669 {}
2610}; 2670};
2611 2671
2612static struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = { 2672static const struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
2613 { 2673 {
2614 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2674 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2615 .name = "DC Mode Enable Switch", 2675 .name = "DC Mode Enable Switch",
@@ -2627,7 +2687,7 @@ static struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
2627 {} 2687 {}
2628}; 2688};
2629 2689
2630static struct snd_kcontrol_new cxt5066_mixers[] = { 2690static const struct snd_kcontrol_new cxt5066_mixers[] = {
2631 { 2691 {
2632 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2692 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2633 .name = "Master Playback Switch", 2693 .name = "Master Playback Switch",
@@ -2650,7 +2710,7 @@ static struct snd_kcontrol_new cxt5066_mixers[] = {
2650 {} 2710 {}
2651}; 2711};
2652 2712
2653static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { 2713static const struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2654 { 2714 {
2655 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2715 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2656 .name = "Internal Mic Boost Capture Enum", 2716 .name = "Internal Mic Boost Capture Enum",
@@ -2662,7 +2722,7 @@ static struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2662 {} 2722 {}
2663}; 2723};
2664 2724
2665static struct hda_verb cxt5066_init_verbs[] = { 2725static const struct hda_verb cxt5066_init_verbs[] = {
2666 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ 2726 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2667 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ 2727 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2668 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ 2728 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
@@ -2717,7 +2777,7 @@ static struct hda_verb cxt5066_init_verbs[] = {
2717 { } /* end */ 2777 { } /* end */
2718}; 2778};
2719 2779
2720static struct hda_verb cxt5066_init_verbs_olpc[] = { 2780static const struct hda_verb cxt5066_init_verbs_olpc[] = {
2721 /* Port A: headphones */ 2781 /* Port A: headphones */
2722 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2782 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2723 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2783 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
@@ -2778,7 +2838,7 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = {
2778 { } /* end */ 2838 { } /* end */
2779}; 2839};
2780 2840
2781static struct hda_verb cxt5066_init_verbs_vostro[] = { 2841static const struct hda_verb cxt5066_init_verbs_vostro[] = {
2782 /* Port A: headphones */ 2842 /* Port A: headphones */
2783 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2843 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2784 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2844 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
@@ -2839,7 +2899,7 @@ static struct hda_verb cxt5066_init_verbs_vostro[] = {
2839 { } /* end */ 2899 { } /* end */
2840}; 2900};
2841 2901
2842static struct hda_verb cxt5066_init_verbs_ideapad[] = { 2902static const struct hda_verb cxt5066_init_verbs_ideapad[] = {
2843 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ 2903 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2844 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ 2904 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2845 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ 2905 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
@@ -2889,7 +2949,7 @@ static struct hda_verb cxt5066_init_verbs_ideapad[] = {
2889 { } /* end */ 2949 { } /* end */
2890}; 2950};
2891 2951
2892static struct hda_verb cxt5066_init_verbs_thinkpad[] = { 2952static const struct hda_verb cxt5066_init_verbs_thinkpad[] = {
2893 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ 2953 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2894 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */ 2954 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2895 2955
@@ -2947,13 +3007,13 @@ static struct hda_verb cxt5066_init_verbs_thinkpad[] = {
2947 { } /* end */ 3007 { } /* end */
2948}; 3008};
2949 3009
2950static struct hda_verb cxt5066_init_verbs_portd_lo[] = { 3010static const struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2951 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3011 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2952 { } /* end */ 3012 { } /* end */
2953}; 3013};
2954 3014
2955 3015
2956static struct hda_verb cxt5066_init_verbs_hp_laptop[] = { 3016static const struct hda_verb cxt5066_init_verbs_hp_laptop[] = {
2957 {0x14, AC_VERB_SET_CONNECT_SEL, 0x0}, 3017 {0x14, AC_VERB_SET_CONNECT_SEL, 0x0},
2958 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, 3018 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2959 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, 3019 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
@@ -2997,6 +3057,7 @@ enum {
2997 CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */ 3057 CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */
2998 CXT5066_ASUS, /* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */ 3058 CXT5066_ASUS, /* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */
2999 CXT5066_HP_LAPTOP, /* HP Laptop */ 3059 CXT5066_HP_LAPTOP, /* HP Laptop */
3060 CXT5066_AUTO, /* BIOS auto-parser */
3000 CXT5066_MODELS 3061 CXT5066_MODELS
3001}; 3062};
3002 3063
@@ -3009,9 +3070,10 @@ static const char * const cxt5066_models[CXT5066_MODELS] = {
3009 [CXT5066_THINKPAD] = "thinkpad", 3070 [CXT5066_THINKPAD] = "thinkpad",
3010 [CXT5066_ASUS] = "asus", 3071 [CXT5066_ASUS] = "asus",
3011 [CXT5066_HP_LAPTOP] = "hp-laptop", 3072 [CXT5066_HP_LAPTOP] = "hp-laptop",
3073 [CXT5066_AUTO] = "auto",
3012}; 3074};
3013 3075
3014static struct snd_pci_quirk cxt5066_cfg_tbl[] = { 3076static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3015 SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), 3077 SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
3016 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), 3078 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
3017 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), 3079 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
@@ -3046,6 +3108,15 @@ static int patch_cxt5066(struct hda_codec *codec)
3046 struct conexant_spec *spec; 3108 struct conexant_spec *spec;
3047 int board_config; 3109 int board_config;
3048 3110
3111 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
3112 cxt5066_models, cxt5066_cfg_tbl);
3113#if 0 /* use the old method just for safety */
3114 if (board_config < 0)
3115 board_config = CXT5066_AUTO;
3116#endif
3117 if (board_config == CXT5066_AUTO)
3118 return patch_conexant_auto(codec);
3119
3049 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3120 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3050 if (!spec) 3121 if (!spec)
3051 return -ENOMEM; 3122 return -ENOMEM;
@@ -3076,8 +3147,6 @@ static int patch_cxt5066(struct hda_codec *codec)
3076 3147
3077 set_beep_amp(spec, 0x13, 0, HDA_OUTPUT); 3148 set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
3078 3149
3079 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
3080 cxt5066_models, cxt5066_cfg_tbl);
3081 switch (board_config) { 3150 switch (board_config) {
3082 default: 3151 default:
3083 case CXT5066_LAPTOP: 3152 case CXT5066_LAPTOP:
@@ -3195,7 +3264,45 @@ static int patch_cxt5066(struct hda_codec *codec)
3195 * Automatic parser for CX20641 & co 3264 * Automatic parser for CX20641 & co
3196 */ 3265 */
3197 3266
3198static hda_nid_t cx_auto_adc_nids[] = { 0x14 }; 3267static int cx_auto_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3268 struct hda_codec *codec,
3269 unsigned int stream_tag,
3270 unsigned int format,
3271 struct snd_pcm_substream *substream)
3272{
3273 struct conexant_spec *spec = codec->spec;
3274 hda_nid_t adc = spec->imux_info[spec->cur_mux[0]].adc;
3275 if (spec->adc_switching) {
3276 spec->cur_adc = adc;
3277 spec->cur_adc_stream_tag = stream_tag;
3278 spec->cur_adc_format = format;
3279 }
3280 snd_hda_codec_setup_stream(codec, adc, stream_tag, 0, format);
3281 return 0;
3282}
3283
3284static int cx_auto_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3285 struct hda_codec *codec,
3286 struct snd_pcm_substream *substream)
3287{
3288 struct conexant_spec *spec = codec->spec;
3289 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3290 spec->cur_adc = 0;
3291 return 0;
3292}
3293
3294static const struct hda_pcm_stream cx_auto_pcm_analog_capture = {
3295 .substreams = 1,
3296 .channels_min = 2,
3297 .channels_max = 2,
3298 .nid = 0, /* fill later */
3299 .ops = {
3300 .prepare = cx_auto_capture_pcm_prepare,
3301 .cleanup = cx_auto_capture_pcm_cleanup
3302 },
3303};
3304
3305static const hda_nid_t cx_auto_adc_nids[] = { 0x14 };
3199 3306
3200/* get the connection index of @nid in the widget @mux */ 3307/* get the connection index of @nid in the widget @mux */
3201static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 3308static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
@@ -3320,61 +3427,339 @@ static void cx_auto_parse_output(struct hda_codec *codec)
3320 spec->multiout.dac_nids = spec->private_dac_nids; 3427 spec->multiout.dac_nids = spec->private_dac_nids;
3321 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3428 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3322 3429
3323 if (cfg->hp_outs > 0) 3430 for (i = 0; i < cfg->hp_outs; i++) {
3324 spec->auto_mute = 1; 3431 if (is_jack_detectable(codec, cfg->hp_pins[i])) {
3432 spec->auto_mute = 1;
3433 break;
3434 }
3435 }
3436 if (spec->auto_mute && cfg->line_out_pins[0] &&
3437 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
3438 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
3439 for (i = 0; i < cfg->line_outs; i++) {
3440 if (is_jack_detectable(codec, cfg->line_out_pins[i])) {
3441 spec->detect_line = 1;
3442 break;
3443 }
3444 }
3445 spec->automute_lines = spec->detect_line;
3446 }
3447
3325 spec->vmaster_nid = spec->private_dac_nids[0]; 3448 spec->vmaster_nid = spec->private_dac_nids[0];
3326} 3449}
3327 3450
3451static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3452 hda_nid_t *pins, bool on);
3453
3454static void do_automute(struct hda_codec *codec, int num_pins,
3455 hda_nid_t *pins, bool on)
3456{
3457 int i;
3458 for (i = 0; i < num_pins; i++)
3459 snd_hda_codec_write(codec, pins[i], 0,
3460 AC_VERB_SET_PIN_WIDGET_CONTROL,
3461 on ? PIN_OUT : 0);
3462 cx_auto_turn_eapd(codec, num_pins, pins, on);
3463}
3464
3465static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
3466{
3467 int i, present = 0;
3468
3469 for (i = 0; i < num_pins; i++) {
3470 hda_nid_t nid = pins[i];
3471 if (!nid || !is_jack_detectable(codec, nid))
3472 break;
3473 snd_hda_input_jack_report(codec, nid);
3474 present |= snd_hda_jack_detect(codec, nid);
3475 }
3476 return present;
3477}
3478
3328/* auto-mute/unmute speaker and line outs according to headphone jack */ 3479/* auto-mute/unmute speaker and line outs according to headphone jack */
3480static void cx_auto_update_speakers(struct hda_codec *codec)
3481{
3482 struct conexant_spec *spec = codec->spec;
3483 struct auto_pin_cfg *cfg = &spec->autocfg;
3484 int on;
3485
3486 if (!spec->auto_mute)
3487 on = 0;
3488 else
3489 on = spec->hp_present | spec->line_present;
3490 cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on);
3491 do_automute(codec, cfg->speaker_outs, cfg->speaker_pins, !on);
3492
3493 /* toggle line-out mutes if needed, too */
3494 /* if LO is a copy of either HP or Speaker, don't need to handle it */
3495 if (cfg->line_out_pins[0] == cfg->hp_pins[0] ||
3496 cfg->line_out_pins[0] == cfg->speaker_pins[0])
3497 return;
3498 if (!spec->automute_lines || !spec->auto_mute)
3499 on = 0;
3500 else
3501 on = spec->hp_present;
3502 do_automute(codec, cfg->line_outs, cfg->line_out_pins, !on);
3503}
3504
3329static void cx_auto_hp_automute(struct hda_codec *codec) 3505static void cx_auto_hp_automute(struct hda_codec *codec)
3330{ 3506{
3331 struct conexant_spec *spec = codec->spec; 3507 struct conexant_spec *spec = codec->spec;
3332 struct auto_pin_cfg *cfg = &spec->autocfg; 3508 struct auto_pin_cfg *cfg = &spec->autocfg;
3333 int i, present;
3334 3509
3335 if (!spec->auto_mute) 3510 if (!spec->auto_mute)
3336 return; 3511 return;
3337 present = 0; 3512 spec->hp_present = detect_jacks(codec, cfg->hp_outs, cfg->hp_pins);
3338 for (i = 0; i < cfg->hp_outs; i++) { 3513 cx_auto_update_speakers(codec);
3339 if (snd_hda_jack_detect(codec, cfg->hp_pins[i])) { 3514}
3340 present = 1; 3515
3341 break; 3516static void cx_auto_line_automute(struct hda_codec *codec)
3342 } 3517{
3518 struct conexant_spec *spec = codec->spec;
3519 struct auto_pin_cfg *cfg = &spec->autocfg;
3520
3521 if (!spec->auto_mute || !spec->detect_line)
3522 return;
3523 spec->line_present = detect_jacks(codec, cfg->line_outs,
3524 cfg->line_out_pins);
3525 cx_auto_update_speakers(codec);
3526}
3527
3528static int cx_automute_mode_info(struct snd_kcontrol *kcontrol,
3529 struct snd_ctl_elem_info *uinfo)
3530{
3531 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3532 struct conexant_spec *spec = codec->spec;
3533 static const char * const texts2[] = {
3534 "Disabled", "Enabled"
3535 };
3536 static const char * const texts3[] = {
3537 "Disabled", "Speaker Only", "Line-Out+Speaker"
3538 };
3539 const char * const *texts;
3540
3541 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3542 uinfo->count = 1;
3543 if (spec->automute_hp_lo) {
3544 uinfo->value.enumerated.items = 3;
3545 texts = texts3;
3546 } else {
3547 uinfo->value.enumerated.items = 2;
3548 texts = texts2;
3343 } 3549 }
3344 for (i = 0; i < cfg->line_outs; i++) { 3550 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3345 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0, 3551 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
3346 AC_VERB_SET_PIN_WIDGET_CONTROL, 3552 strcpy(uinfo->value.enumerated.name,
3347 present ? 0 : PIN_OUT); 3553 texts[uinfo->value.enumerated.item]);
3554 return 0;
3555}
3556
3557static int cx_automute_mode_get(struct snd_kcontrol *kcontrol,
3558 struct snd_ctl_elem_value *ucontrol)
3559{
3560 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3561 struct conexant_spec *spec = codec->spec;
3562 unsigned int val;
3563 if (!spec->auto_mute)
3564 val = 0;
3565 else if (!spec->automute_lines)
3566 val = 1;
3567 else
3568 val = 2;
3569 ucontrol->value.enumerated.item[0] = val;
3570 return 0;
3571}
3572
3573static int cx_automute_mode_put(struct snd_kcontrol *kcontrol,
3574 struct snd_ctl_elem_value *ucontrol)
3575{
3576 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3577 struct conexant_spec *spec = codec->spec;
3578
3579 switch (ucontrol->value.enumerated.item[0]) {
3580 case 0:
3581 if (!spec->auto_mute)
3582 return 0;
3583 spec->auto_mute = 0;
3584 break;
3585 case 1:
3586 if (spec->auto_mute && !spec->automute_lines)
3587 return 0;
3588 spec->auto_mute = 1;
3589 spec->automute_lines = 0;
3590 break;
3591 case 2:
3592 if (!spec->automute_hp_lo)
3593 return -EINVAL;
3594 if (spec->auto_mute && spec->automute_lines)
3595 return 0;
3596 spec->auto_mute = 1;
3597 spec->automute_lines = 1;
3598 break;
3599 default:
3600 return -EINVAL;
3348 } 3601 }
3349 for (i = 0; !present && i < cfg->line_outs; i++) 3602 cx_auto_update_speakers(codec);
3350 if (snd_hda_jack_detect(codec, cfg->line_out_pins[i])) 3603 return 1;
3351 present = 1; 3604}
3352 for (i = 0; i < cfg->speaker_outs; i++) { 3605
3353 snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, 3606static const struct snd_kcontrol_new cx_automute_mode_enum[] = {
3354 AC_VERB_SET_PIN_WIDGET_CONTROL, 3607 {
3355 present ? 0 : PIN_OUT); 3608 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3609 .name = "Auto-Mute Mode",
3610 .info = cx_automute_mode_info,
3611 .get = cx_automute_mode_get,
3612 .put = cx_automute_mode_put,
3613 },
3614 { }
3615};
3616
3617static int cx_auto_mux_enum_info(struct snd_kcontrol *kcontrol,
3618 struct snd_ctl_elem_info *uinfo)
3619{
3620 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3621 struct conexant_spec *spec = codec->spec;
3622
3623 return snd_hda_input_mux_info(&spec->private_imux, uinfo);
3624}
3625
3626static int cx_auto_mux_enum_get(struct snd_kcontrol *kcontrol,
3627 struct snd_ctl_elem_value *ucontrol)
3628{
3629 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3630 struct conexant_spec *spec = codec->spec;
3631
3632 ucontrol->value.enumerated.item[0] = spec->cur_mux[0];
3633 return 0;
3634}
3635
3636/* look for the route the given pin from mux and return the index;
3637 * if do_select is set, actually select the route.
3638 */
3639static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
3640 hda_nid_t pin, hda_nid_t *srcp,
3641 bool do_select, int depth)
3642{
3643 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3644 int i, nums;
3645
3646 switch (get_wcaps_type(get_wcaps(codec, mux))) {
3647 case AC_WID_AUD_IN:
3648 case AC_WID_AUD_SEL:
3649 case AC_WID_AUD_MIX:
3650 break;
3651 default:
3652 return -1;
3356 } 3653 }
3654
3655 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3656 for (i = 0; i < nums; i++)
3657 if (conn[i] == pin) {
3658 if (do_select)
3659 snd_hda_codec_write(codec, mux, 0,
3660 AC_VERB_SET_CONNECT_SEL, i);
3661 if (srcp)
3662 *srcp = mux;
3663 return i;
3664 }
3665 depth++;
3666 if (depth == 2)
3667 return -1;
3668 for (i = 0; i < nums; i++) {
3669 int ret = __select_input_connection(codec, conn[i], pin, srcp,
3670 do_select, depth);
3671 if (ret >= 0) {
3672 if (do_select)
3673 snd_hda_codec_write(codec, mux, 0,
3674 AC_VERB_SET_CONNECT_SEL, i);
3675 return i;
3676 }
3677 }
3678 return -1;
3679}
3680
3681static void select_input_connection(struct hda_codec *codec, hda_nid_t mux,
3682 hda_nid_t pin)
3683{
3684 __select_input_connection(codec, mux, pin, NULL, true, 0);
3685}
3686
3687static int get_input_connection(struct hda_codec *codec, hda_nid_t mux,
3688 hda_nid_t pin)
3689{
3690 return __select_input_connection(codec, mux, pin, NULL, false, 0);
3691}
3692
3693static int cx_auto_mux_enum_update(struct hda_codec *codec,
3694 const struct hda_input_mux *imux,
3695 unsigned int idx)
3696{
3697 struct conexant_spec *spec = codec->spec;
3698 hda_nid_t adc;
3699
3700 if (!imux->num_items)
3701 return 0;
3702 if (idx >= imux->num_items)
3703 idx = imux->num_items - 1;
3704 if (spec->cur_mux[0] == idx)
3705 return 0;
3706 adc = spec->imux_info[idx].adc;
3707 select_input_connection(codec, spec->imux_info[idx].adc,
3708 spec->imux_info[idx].pin);
3709 if (spec->cur_adc && spec->cur_adc != adc) {
3710 /* stream is running, let's swap the current ADC */
3711 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
3712 spec->cur_adc = adc;
3713 snd_hda_codec_setup_stream(codec, adc,
3714 spec->cur_adc_stream_tag, 0,
3715 spec->cur_adc_format);
3716 }
3717 spec->cur_mux[0] = idx;
3718 return 1;
3719}
3720
3721static int cx_auto_mux_enum_put(struct snd_kcontrol *kcontrol,
3722 struct snd_ctl_elem_value *ucontrol)
3723{
3724 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3725 struct conexant_spec *spec = codec->spec;
3726
3727 return cx_auto_mux_enum_update(codec, &spec->private_imux,
3728 ucontrol->value.enumerated.item[0]);
3729}
3730
3731static const struct snd_kcontrol_new cx_auto_capture_mixers[] = {
3732 {
3733 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3734 .name = "Capture Source",
3735 .info = cx_auto_mux_enum_info,
3736 .get = cx_auto_mux_enum_get,
3737 .put = cx_auto_mux_enum_put
3738 },
3739 {}
3740};
3741
3742static bool select_automic(struct hda_codec *codec, int idx, bool detect)
3743{
3744 struct conexant_spec *spec = codec->spec;
3745 if (idx < 0)
3746 return false;
3747 if (detect && !snd_hda_jack_detect(codec, spec->imux_info[idx].pin))
3748 return false;
3749 cx_auto_mux_enum_update(codec, &spec->private_imux, idx);
3750 return true;
3357} 3751}
3358 3752
3359/* automatic switch internal and external mic */ 3753/* automatic switch internal and external mic */
3360static void cx_auto_automic(struct hda_codec *codec) 3754static void cx_auto_automic(struct hda_codec *codec)
3361{ 3755{
3362 struct conexant_spec *spec = codec->spec; 3756 struct conexant_spec *spec = codec->spec;
3363 struct auto_pin_cfg *cfg = &spec->autocfg;
3364 struct hda_input_mux *imux = &spec->private_imux;
3365 int ext_idx = spec->auto_mic_ext;
3366 3757
3367 if (!spec->auto_mic) 3758 if (!spec->auto_mic)
3368 return; 3759 return;
3369 if (snd_hda_jack_detect(codec, cfg->inputs[ext_idx].pin)) { 3760 if (!select_automic(codec, spec->auto_mic_ext, true))
3370 snd_hda_codec_write(codec, spec->adc_nids[0], 0, 3761 if (!select_automic(codec, spec->auto_mic_dock, true))
3371 AC_VERB_SET_CONNECT_SEL, 3762 select_automic(codec, spec->auto_mic_int, false);
3372 imux->items[ext_idx].index);
3373 } else {
3374 snd_hda_codec_write(codec, spec->adc_nids[0], 0,
3375 AC_VERB_SET_CONNECT_SEL,
3376 imux->items[!ext_idx].index);
3377 }
3378} 3763}
3379 3764
3380static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) 3765static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -3383,7 +3768,9 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
3383 switch (res >> 26) { 3768 switch (res >> 26) {
3384 case CONEXANT_HP_EVENT: 3769 case CONEXANT_HP_EVENT:
3385 cx_auto_hp_automute(codec); 3770 cx_auto_hp_automute(codec);
3386 snd_hda_input_jack_report(codec, nid); 3771 break;
3772 case CONEXANT_LINE_EVENT:
3773 cx_auto_line_automute(codec);
3387 break; 3774 break;
3388 case CONEXANT_MIC_EVENT: 3775 case CONEXANT_MIC_EVENT:
3389 cx_auto_automic(codec); 3776 cx_auto_automic(codec);
@@ -3392,43 +3779,45 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
3392 } 3779 }
3393} 3780}
3394 3781
3395/* return true if it's an internal-mic pin */
3396static int is_int_mic(struct hda_codec *codec, hda_nid_t pin)
3397{
3398 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin);
3399 return get_defcfg_device(def_conf) == AC_JACK_MIC_IN &&
3400 snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT;
3401}
3402
3403/* return true if it's an external-mic pin */
3404static int is_ext_mic(struct hda_codec *codec, hda_nid_t pin)
3405{
3406 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin);
3407 return get_defcfg_device(def_conf) == AC_JACK_MIC_IN &&
3408 snd_hda_get_input_pin_attr(def_conf) >= INPUT_PIN_ATTR_NORMAL &&
3409 (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_PRES_DETECT);
3410}
3411
3412/* check whether the pin config is suitable for auto-mic switching; 3782/* check whether the pin config is suitable for auto-mic switching;
3413 * auto-mic is enabled only when one int-mic and one-ext mic exist 3783 * auto-mic is enabled only when one int-mic and one ext- and/or
3784 * one dock-mic exist
3414 */ 3785 */
3415static void cx_auto_check_auto_mic(struct hda_codec *codec) 3786static void cx_auto_check_auto_mic(struct hda_codec *codec)
3416{ 3787{
3417 struct conexant_spec *spec = codec->spec; 3788 struct conexant_spec *spec = codec->spec;
3418 struct auto_pin_cfg *cfg = &spec->autocfg; 3789 int pset[INPUT_PIN_ATTR_NORMAL + 1];
3790 int i;
3419 3791
3420 if (is_ext_mic(codec, cfg->inputs[0].pin) && 3792 for (i = 0; i < INPUT_PIN_ATTR_NORMAL; i++)
3421 is_int_mic(codec, cfg->inputs[1].pin)) { 3793 pset[i] = -1;
3422 spec->auto_mic = 1; 3794 for (i = 0; i < spec->private_imux.num_items; i++) {
3423 spec->auto_mic_ext = 1; 3795 hda_nid_t pin = spec->imux_info[i].pin;
3424 return; 3796 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin);
3425 } 3797 int type, attr;
3426 if (is_int_mic(codec, cfg->inputs[1].pin) && 3798 attr = snd_hda_get_input_pin_attr(def_conf);
3427 is_ext_mic(codec, cfg->inputs[0].pin)) { 3799 if (attr == INPUT_PIN_ATTR_UNUSED)
3428 spec->auto_mic = 1; 3800 return; /* invalid entry */
3429 spec->auto_mic_ext = 0; 3801 if (attr > INPUT_PIN_ATTR_NORMAL)
3430 return; 3802 attr = INPUT_PIN_ATTR_NORMAL;
3803 if (attr != INPUT_PIN_ATTR_INT &&
3804 !is_jack_detectable(codec, pin))
3805 return; /* non-detectable pin */
3806 type = get_defcfg_device(def_conf);
3807 if (type != AC_JACK_MIC_IN &&
3808 (attr != INPUT_PIN_ATTR_DOCK || type != AC_JACK_LINE_IN))
3809 return; /* no valid input type */
3810 if (pset[attr] >= 0)
3811 return; /* already occupied */
3812 pset[attr] = i;
3431 } 3813 }
3814 if (pset[INPUT_PIN_ATTR_INT] < 0 ||
3815 (pset[INPUT_PIN_ATTR_NORMAL] < 0 && pset[INPUT_PIN_ATTR_DOCK]))
3816 return; /* no input to switch*/
3817 spec->auto_mic = 1;
3818 spec->auto_mic_ext = pset[INPUT_PIN_ATTR_NORMAL];
3819 spec->auto_mic_dock = pset[INPUT_PIN_ATTR_DOCK];
3820 spec->auto_mic_int = pset[INPUT_PIN_ATTR_INT];
3432} 3821}
3433 3822
3434static void cx_auto_parse_input(struct hda_codec *codec) 3823static void cx_auto_parse_input(struct hda_codec *codec)
@@ -3436,22 +3825,37 @@ static void cx_auto_parse_input(struct hda_codec *codec)
3436 struct conexant_spec *spec = codec->spec; 3825 struct conexant_spec *spec = codec->spec;
3437 struct auto_pin_cfg *cfg = &spec->autocfg; 3826 struct auto_pin_cfg *cfg = &spec->autocfg;
3438 struct hda_input_mux *imux; 3827 struct hda_input_mux *imux;
3439 int i; 3828 int i, j;
3440 3829
3441 imux = &spec->private_imux; 3830 imux = &spec->private_imux;
3442 for (i = 0; i < cfg->num_inputs; i++) { 3831 for (i = 0; i < cfg->num_inputs; i++) {
3443 int idx = get_connection_index(codec, spec->adc_nids[0], 3832 for (j = 0; j < spec->num_adc_nids; j++) {
3444 cfg->inputs[i].pin); 3833 hda_nid_t adc = spec->adc_nids[j];
3445 if (idx >= 0) { 3834 int idx = get_input_connection(codec, adc,
3446 const char *label; 3835 cfg->inputs[i].pin);
3447 label = hda_get_autocfg_input_label(codec, cfg, i); 3836 if (idx >= 0) {
3448 snd_hda_add_imux_item(imux, label, idx, NULL); 3837 const char *label;
3838 label = hda_get_autocfg_input_label(codec, cfg, i);
3839 spec->imux_info[imux->num_items].index = i;
3840 spec->imux_info[imux->num_items].boost = 0;
3841 spec->imux_info[imux->num_items].adc = adc;
3842 spec->imux_info[imux->num_items].pin =
3843 cfg->inputs[i].pin;
3844 snd_hda_add_imux_item(imux, label, idx, NULL);
3845 break;
3846 }
3449 } 3847 }
3450 } 3848 }
3451 if (imux->num_items == 2 && cfg->num_inputs == 2) 3849 if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items)
3452 cx_auto_check_auto_mic(codec); 3850 cx_auto_check_auto_mic(codec);
3453 if (imux->num_items > 1 && !spec->auto_mic) 3851 if (imux->num_items > 1 && !spec->auto_mic) {
3454 spec->input_mux = imux; 3852 for (i = 1; i < imux->num_items; i++) {
3853 if (spec->imux_info[i].adc != spec->imux_info[0].adc) {
3854 spec->adc_switching = 1;
3855 break;
3856 }
3857 }
3858 }
3455} 3859}
3456 3860
3457/* get digital-input audio widget corresponding to the given pin */ 3861/* get digital-input audio widget corresponding to the given pin */
@@ -3517,14 +3921,15 @@ static int cx_auto_parse_auto_config(struct hda_codec *codec)
3517 return 0; 3921 return 0;
3518} 3922}
3519 3923
3520static void cx_auto_turn_on_eapd(struct hda_codec *codec, int num_pins, 3924static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3521 hda_nid_t *pins) 3925 hda_nid_t *pins, bool on)
3522{ 3926{
3523 int i; 3927 int i;
3524 for (i = 0; i < num_pins; i++) { 3928 for (i = 0; i < num_pins; i++) {
3525 if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD) 3929 if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD)
3526 snd_hda_codec_write(codec, pins[i], 0, 3930 snd_hda_codec_write(codec, pins[i], 0,
3527 AC_VERB_SET_EAPD_BTLENABLE, 0x02); 3931 AC_VERB_SET_EAPD_BTLENABLE,
3932 on ? 0x02 : 0);
3528 } 3933 }
3529} 3934}
3530 3935
@@ -3537,6 +3942,34 @@ static void select_connection(struct hda_codec *codec, hda_nid_t pin,
3537 AC_VERB_SET_CONNECT_SEL, idx); 3942 AC_VERB_SET_CONNECT_SEL, idx);
3538} 3943}
3539 3944
3945static void mute_outputs(struct hda_codec *codec, int num_nids,
3946 const hda_nid_t *nids)
3947{
3948 int i, val;
3949
3950 for (i = 0; i < num_nids; i++) {
3951 hda_nid_t nid = nids[i];
3952 if (!(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
3953 continue;
3954 if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE)
3955 val = AMP_OUT_MUTE;
3956 else
3957 val = AMP_OUT_ZERO;
3958 snd_hda_codec_write(codec, nid, 0,
3959 AC_VERB_SET_AMP_GAIN_MUTE, val);
3960 }
3961}
3962
3963static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
3964 hda_nid_t *pins, unsigned int tag)
3965{
3966 int i;
3967 for (i = 0; i < num_pins; i++)
3968 snd_hda_codec_write(codec, pins[i], 0,
3969 AC_VERB_SET_UNSOLICITED_ENABLE,
3970 AC_USRSP_EN | tag);
3971}
3972
3540static void cx_auto_init_output(struct hda_codec *codec) 3973static void cx_auto_init_output(struct hda_codec *codec)
3541{ 3974{
3542 struct conexant_spec *spec = codec->spec; 3975 struct conexant_spec *spec = codec->spec;
@@ -3544,51 +3977,53 @@ static void cx_auto_init_output(struct hda_codec *codec)
3544 hda_nid_t nid; 3977 hda_nid_t nid;
3545 int i; 3978 int i;
3546 3979
3547 for (i = 0; i < spec->multiout.num_dacs; i++) 3980 mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids);
3548 snd_hda_codec_write(codec, spec->multiout.dac_nids[i], 0,
3549 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3550
3551 for (i = 0; i < cfg->hp_outs; i++) 3981 for (i = 0; i < cfg->hp_outs; i++)
3552 snd_hda_codec_write(codec, cfg->hp_pins[i], 0, 3982 snd_hda_codec_write(codec, cfg->hp_pins[i], 0,
3553 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); 3983 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
3554 if (spec->auto_mute) { 3984 mute_outputs(codec, cfg->hp_outs, cfg->hp_pins);
3555 for (i = 0; i < cfg->hp_outs; i++) { 3985 mute_outputs(codec, cfg->line_outs, cfg->line_out_pins);
3556 snd_hda_codec_write(codec, cfg->hp_pins[i], 0, 3986 mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins);
3557 AC_VERB_SET_UNSOLICITED_ENABLE,
3558 AC_USRSP_EN | CONEXANT_HP_EVENT);
3559 }
3560 cx_auto_hp_automute(codec);
3561 } else {
3562 for (i = 0; i < cfg->line_outs; i++)
3563 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
3564 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3565 for (i = 0; i < cfg->speaker_outs; i++)
3566 snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
3567 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3568 }
3569
3570 for (i = 0; i < spec->dac_info_filled; i++) { 3987 for (i = 0; i < spec->dac_info_filled; i++) {
3571 nid = spec->dac_info[i].dac; 3988 nid = spec->dac_info[i].dac;
3572 if (!nid) 3989 if (!nid)
3573 nid = spec->multiout.dac_nids[0]; 3990 nid = spec->multiout.dac_nids[0];
3574 select_connection(codec, spec->dac_info[i].pin, nid); 3991 select_connection(codec, spec->dac_info[i].pin, nid);
3575 } 3992 }
3576 3993 if (spec->auto_mute) {
3577 /* turn on EAPD */ 3994 enable_unsol_pins(codec, cfg->hp_outs, cfg->hp_pins,
3578 cx_auto_turn_on_eapd(codec, cfg->line_outs, cfg->line_out_pins); 3995 CONEXANT_HP_EVENT);
3579 cx_auto_turn_on_eapd(codec, cfg->hp_outs, cfg->hp_pins); 3996 spec->hp_present = detect_jacks(codec, cfg->hp_outs,
3580 cx_auto_turn_on_eapd(codec, cfg->speaker_outs, cfg->speaker_pins); 3997 cfg->hp_pins);
3998 if (spec->detect_line) {
3999 enable_unsol_pins(codec, cfg->line_outs,
4000 cfg->line_out_pins,
4001 CONEXANT_LINE_EVENT);
4002 spec->line_present =
4003 detect_jacks(codec, cfg->line_outs,
4004 cfg->line_out_pins);
4005 }
4006 }
4007 cx_auto_update_speakers(codec);
3581} 4008}
3582 4009
3583static void cx_auto_init_input(struct hda_codec *codec) 4010static void cx_auto_init_input(struct hda_codec *codec)
3584{ 4011{
3585 struct conexant_spec *spec = codec->spec; 4012 struct conexant_spec *spec = codec->spec;
3586 struct auto_pin_cfg *cfg = &spec->autocfg; 4013 struct auto_pin_cfg *cfg = &spec->autocfg;
3587 int i; 4014 int i, val;
3588 4015
3589 for (i = 0; i < spec->num_adc_nids; i++) 4016 for (i = 0; i < spec->num_adc_nids; i++) {
3590 snd_hda_codec_write(codec, spec->adc_nids[i], 0, 4017 hda_nid_t nid = spec->adc_nids[i];
3591 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)); 4018 if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP))
4019 continue;
4020 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE)
4021 val = AMP_IN_MUTE(0);
4022 else
4023 val = AMP_IN_UNMUTE(0);
4024 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4025 val);
4026 }
3592 4027
3593 for (i = 0; i < cfg->num_inputs; i++) { 4028 for (i = 0; i < cfg->num_inputs; i++) {
3594 unsigned int type; 4029 unsigned int type;
@@ -3601,17 +4036,22 @@ static void cx_auto_init_input(struct hda_codec *codec)
3601 } 4036 }
3602 4037
3603 if (spec->auto_mic) { 4038 if (spec->auto_mic) {
3604 int ext_idx = spec->auto_mic_ext; 4039 if (spec->auto_mic_ext >= 0) {
3605 snd_hda_codec_write(codec, cfg->inputs[ext_idx].pin, 0, 4040 snd_hda_codec_write(codec,
3606 AC_VERB_SET_UNSOLICITED_ENABLE, 4041 cfg->inputs[spec->auto_mic_ext].pin, 0,
3607 AC_USRSP_EN | CONEXANT_MIC_EVENT); 4042 AC_VERB_SET_UNSOLICITED_ENABLE,
4043 AC_USRSP_EN | CONEXANT_MIC_EVENT);
4044 }
4045 if (spec->auto_mic_dock >= 0) {
4046 snd_hda_codec_write(codec,
4047 cfg->inputs[spec->auto_mic_dock].pin, 0,
4048 AC_VERB_SET_UNSOLICITED_ENABLE,
4049 AC_USRSP_EN | CONEXANT_MIC_EVENT);
4050 }
3608 cx_auto_automic(codec); 4051 cx_auto_automic(codec);
3609 } else { 4052 } else {
3610 for (i = 0; i < spec->num_adc_nids; i++) { 4053 select_input_connection(codec, spec->imux_info[0].adc,
3611 snd_hda_codec_write(codec, spec->adc_nids[i], 0, 4054 spec->imux_info[0].pin);
3612 AC_VERB_SET_CONNECT_SEL,
3613 spec->private_imux.items[0].index);
3614 }
3615 } 4055 }
3616} 4056}
3617 4057
@@ -3646,7 +4086,7 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
3646 HDA_CODEC_VOLUME(name, 0, 0, 0), 4086 HDA_CODEC_VOLUME(name, 0, 0, 0),
3647 HDA_CODEC_MUTE(name, 0, 0, 0), 4087 HDA_CODEC_MUTE(name, 0, 0, 0),
3648 }; 4088 };
3649 static char *sfx[2] = { "Volume", "Switch" }; 4089 static const char * const sfx[2] = { "Volume", "Switch" };
3650 int i, err; 4090 int i, err;
3651 4091
3652 for (i = 0; i < 2; i++) { 4092 for (i = 0; i < 2; i++) {
@@ -3674,6 +4114,19 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
3674#define cx_auto_add_pb_volume(codec, nid, str, idx) \ 4114#define cx_auto_add_pb_volume(codec, nid, str, idx) \
3675 cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT) 4115 cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT)
3676 4116
4117static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac,
4118 hda_nid_t pin, const char *name, int idx)
4119{
4120 unsigned int caps;
4121 caps = query_amp_caps(codec, dac, HDA_OUTPUT);
4122 if (caps & AC_AMPCAP_NUM_STEPS)
4123 return cx_auto_add_pb_volume(codec, dac, name, idx);
4124 caps = query_amp_caps(codec, pin, HDA_OUTPUT);
4125 if (caps & AC_AMPCAP_NUM_STEPS)
4126 return cx_auto_add_pb_volume(codec, pin, name, idx);
4127 return 0;
4128}
4129
3677static int cx_auto_build_output_controls(struct hda_codec *codec) 4130static int cx_auto_build_output_controls(struct hda_codec *codec)
3678{ 4131{
3679 struct conexant_spec *spec = codec->spec; 4132 struct conexant_spec *spec = codec->spec;
@@ -3682,8 +4135,10 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
3682 static const char * const texts[3] = { "Front", "Surround", "CLFE" }; 4135 static const char * const texts[3] = { "Front", "Surround", "CLFE" };
3683 4136
3684 if (spec->dac_info_filled == 1) 4137 if (spec->dac_info_filled == 1)
3685 return cx_auto_add_pb_volume(codec, spec->dac_info[0].dac, 4138 return try_add_pb_volume(codec, spec->dac_info[0].dac,
3686 "Master", 0); 4139 spec->dac_info[0].pin,
4140 "Master", 0);
4141
3687 for (i = 0; i < spec->dac_info_filled; i++) { 4142 for (i = 0; i < spec->dac_info_filled; i++) {
3688 const char *label; 4143 const char *label;
3689 int idx, type; 4144 int idx, type;
@@ -3707,74 +4162,123 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
3707 idx = num_spk++; 4162 idx = num_spk++;
3708 break; 4163 break;
3709 } 4164 }
3710 err = cx_auto_add_pb_volume(codec, spec->dac_info[i].dac, 4165 err = try_add_pb_volume(codec, spec->dac_info[i].dac,
3711 label, idx); 4166 spec->dac_info[i].pin,
4167 label, idx);
4168 if (err < 0)
4169 return err;
4170 }
4171
4172 if (spec->auto_mute) {
4173 err = snd_hda_add_new_ctls(codec, cx_automute_mode_enum);
3712 if (err < 0) 4174 if (err < 0)
3713 return err; 4175 return err;
3714 } 4176 }
4177
4178 return 0;
4179}
4180
4181static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
4182 const char *label, const char *pfx,
4183 int cidx)
4184{
4185 struct conexant_spec *spec = codec->spec;
4186 int i;
4187
4188 for (i = 0; i < spec->num_adc_nids; i++) {
4189 hda_nid_t adc_nid = spec->adc_nids[i];
4190 int idx = get_input_connection(codec, adc_nid, nid);
4191 if (idx < 0)
4192 continue;
4193 return cx_auto_add_volume_idx(codec, label, pfx,
4194 cidx, adc_nid, HDA_INPUT, idx);
4195 }
4196 return 0;
4197}
4198
4199static int cx_auto_add_boost_volume(struct hda_codec *codec, int idx,
4200 const char *label, int cidx)
4201{
4202 struct conexant_spec *spec = codec->spec;
4203 hda_nid_t mux, nid;
4204 int i, con;
4205
4206 nid = spec->imux_info[idx].pin;
4207 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
4208 return cx_auto_add_volume(codec, label, " Boost", cidx,
4209 nid, HDA_INPUT);
4210 con = __select_input_connection(codec, spec->imux_info[idx].adc, nid,
4211 &mux, false, 0);
4212 if (con < 0)
4213 return 0;
4214 for (i = 0; i < idx; i++) {
4215 if (spec->imux_info[i].boost == mux)
4216 return 0; /* already present */
4217 }
4218
4219 if (get_wcaps(codec, mux) & AC_WCAP_OUT_AMP) {
4220 spec->imux_info[idx].boost = mux;
4221 return cx_auto_add_volume(codec, label, " Boost", 0,
4222 mux, HDA_OUTPUT);
4223 }
3715 return 0; 4224 return 0;
3716} 4225}
3717 4226
3718static int cx_auto_build_input_controls(struct hda_codec *codec) 4227static int cx_auto_build_input_controls(struct hda_codec *codec)
3719{ 4228{
3720 struct conexant_spec *spec = codec->spec; 4229 struct conexant_spec *spec = codec->spec;
3721 struct auto_pin_cfg *cfg = &spec->autocfg; 4230 struct hda_input_mux *imux = &spec->private_imux;
3722 static const char *prev_label; 4231 const char *prev_label;
3723 int i, err, cidx, conn_len; 4232 int input_conn[HDA_MAX_NUM_INPUTS];
3724 hda_nid_t conn[HDA_MAX_CONNECTIONS]; 4233 int i, err, cidx;
3725 4234 int multi_connection;
3726 int multi_adc_volume = 0; /* If the ADC nid has several input volumes */ 4235
3727 int adc_nid = spec->adc_nids[0]; 4236 multi_connection = 0;
3728 4237 for (i = 0; i < imux->num_items; i++) {
3729 conn_len = snd_hda_get_connections(codec, adc_nid, conn, 4238 cidx = get_input_connection(codec, spec->imux_info[i].adc,
3730 HDA_MAX_CONNECTIONS); 4239 spec->imux_info[i].pin);
3731 if (conn_len < 0) 4240 input_conn[i] = (spec->imux_info[i].adc << 8) | cidx;
3732 return conn_len; 4241 if (i > 0 && input_conn[i] != input_conn[0])
3733 4242 multi_connection = 1;
3734 multi_adc_volume = cfg->num_inputs > 1 && conn_len > 1;
3735 if (!multi_adc_volume) {
3736 err = cx_auto_add_volume(codec, "Capture", "", 0, adc_nid,
3737 HDA_INPUT);
3738 if (err < 0)
3739 return err;
3740 } 4243 }
3741 4244
3742 prev_label = NULL; 4245 prev_label = NULL;
3743 cidx = 0; 4246 cidx = 0;
3744 for (i = 0; i < cfg->num_inputs; i++) { 4247 for (i = 0; i < imux->num_items; i++) {
3745 hda_nid_t nid = cfg->inputs[i].pin; 4248 hda_nid_t nid = spec->imux_info[i].pin;
3746 const char *label; 4249 const char *label;
3747 int j;
3748 int pin_amp = get_wcaps(codec, nid) & AC_WCAP_IN_AMP;
3749 if (!pin_amp && !multi_adc_volume)
3750 continue;
3751 4250
3752 label = hda_get_autocfg_input_label(codec, cfg, i); 4251 label = hda_get_autocfg_input_label(codec, &spec->autocfg,
4252 spec->imux_info[i].index);
3753 if (label == prev_label) 4253 if (label == prev_label)
3754 cidx++; 4254 cidx++;
3755 else 4255 else
3756 cidx = 0; 4256 cidx = 0;
3757 prev_label = label; 4257 prev_label = label;
3758 4258
3759 if (pin_amp) { 4259 err = cx_auto_add_boost_volume(codec, i, label, cidx);
3760 err = cx_auto_add_volume(codec, label, " Boost", cidx, 4260 if (err < 0)
3761 nid, HDA_INPUT); 4261 return err;
3762 if (err < 0)
3763 return err;
3764 }
3765 4262
3766 if (!multi_adc_volume) 4263 if (!multi_connection) {
3767 continue; 4264 if (i > 0)
3768 for (j = 0; j < conn_len; j++) { 4265 continue;
3769 if (conn[j] == nid) { 4266 err = cx_auto_add_capture_volume(codec, nid,
3770 err = cx_auto_add_volume_idx(codec, label, 4267 "Capture", "", cidx);
3771 " Capture", cidx, adc_nid, HDA_INPUT, j); 4268 } else {
3772 if (err < 0) 4269 err = cx_auto_add_capture_volume(codec, nid,
3773 return err; 4270 label, " Capture", cidx);
3774 break;
3775 }
3776 } 4271 }
4272 if (err < 0)
4273 return err;
3777 } 4274 }
4275
4276 if (spec->private_imux.num_items > 1 && !spec->auto_mic) {
4277 err = snd_hda_add_new_ctls(codec, cx_auto_capture_mixers);
4278 if (err < 0)
4279 return err;
4280 }
4281
3778 return 0; 4282 return 0;
3779} 4283}
3780 4284
@@ -3791,7 +4295,29 @@ static int cx_auto_build_controls(struct hda_codec *codec)
3791 return conexant_build_controls(codec); 4295 return conexant_build_controls(codec);
3792} 4296}
3793 4297
3794static struct hda_codec_ops cx_auto_patch_ops = { 4298static int cx_auto_search_adcs(struct hda_codec *codec)
4299{
4300 struct conexant_spec *spec = codec->spec;
4301 hda_nid_t nid, end_nid;
4302
4303 end_nid = codec->start_nid + codec->num_nodes;
4304 for (nid = codec->start_nid; nid < end_nid; nid++) {
4305 unsigned int caps = get_wcaps(codec, nid);
4306 if (get_wcaps_type(caps) != AC_WID_AUD_IN)
4307 continue;
4308 if (caps & AC_WCAP_DIGITAL)
4309 continue;
4310 if (snd_BUG_ON(spec->num_adc_nids >=
4311 ARRAY_SIZE(spec->private_adc_nids)))
4312 break;
4313 spec->private_adc_nids[spec->num_adc_nids++] = nid;
4314 }
4315 spec->adc_nids = spec->private_adc_nids;
4316 return 0;
4317}
4318
4319
4320static const struct hda_codec_ops cx_auto_patch_ops = {
3795 .build_controls = cx_auto_build_controls, 4321 .build_controls = cx_auto_build_controls,
3796 .build_pcms = conexant_build_pcms, 4322 .build_pcms = conexant_build_pcms,
3797 .init = cx_auto_init, 4323 .init = cx_auto_init,
@@ -3808,19 +4334,24 @@ static int patch_conexant_auto(struct hda_codec *codec)
3808 struct conexant_spec *spec; 4334 struct conexant_spec *spec;
3809 int err; 4335 int err;
3810 4336
4337 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4338 codec->chip_name);
4339
3811 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4340 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3812 if (!spec) 4341 if (!spec)
3813 return -ENOMEM; 4342 return -ENOMEM;
3814 codec->spec = spec; 4343 codec->spec = spec;
3815 spec->adc_nids = cx_auto_adc_nids; 4344 codec->pin_amp_workaround = 1;
3816 spec->num_adc_nids = ARRAY_SIZE(cx_auto_adc_nids); 4345 err = cx_auto_search_adcs(codec);
3817 spec->capsrc_nids = spec->adc_nids; 4346 if (err < 0)
4347 return err;
3818 err = cx_auto_parse_auto_config(codec); 4348 err = cx_auto_parse_auto_config(codec);
3819 if (err < 0) { 4349 if (err < 0) {
3820 kfree(codec->spec); 4350 kfree(codec->spec);
3821 codec->spec = NULL; 4351 codec->spec = NULL;
3822 return err; 4352 return err;
3823 } 4353 }
4354 spec->capture_stream = &cx_auto_pcm_analog_capture;
3824 codec->patch_ops = cx_auto_patch_ops; 4355 codec->patch_ops = cx_auto_patch_ops;
3825 if (spec->beep_amp) 4356 if (spec->beep_amp)
3826 snd_hda_attach_beep_device(codec, spec->beep_amp); 4357 snd_hda_attach_beep_device(codec, spec->beep_amp);
@@ -3830,7 +4361,7 @@ static int patch_conexant_auto(struct hda_codec *codec)
3830/* 4361/*
3831 */ 4362 */
3832 4363
3833static struct hda_codec_preset snd_hda_preset_conexant[] = { 4364static const struct hda_codec_preset snd_hda_preset_conexant[] = {
3834 { .id = 0x14f15045, .name = "CX20549 (Venice)", 4365 { .id = 0x14f15045, .name = "CX20549 (Venice)",
3835 .patch = patch_cxt5045 }, 4366 .patch = patch_cxt5045 },
3836 { .id = 0x14f15047, .name = "CX20551 (Waikiki)", 4367 { .id = 0x14f15047, .name = "CX20551 (Waikiki)",
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 715615a88a8d..322901873222 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -33,6 +33,7 @@
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/moduleparam.h> 34#include <linux/moduleparam.h>
35#include <sound/core.h> 35#include <sound/core.h>
36#include <sound/jack.h>
36#include "hda_codec.h" 37#include "hda_codec.h"
37#include "hda_local.h" 38#include "hda_local.h"
38 39
@@ -76,7 +77,7 @@ struct hdmi_spec {
76 * ati/nvhdmi specific 77 * ati/nvhdmi specific
77 */ 78 */
78 struct hda_multi_out multiout; 79 struct hda_multi_out multiout;
79 struct hda_pcm_stream *pcm_playback; 80 const struct hda_pcm_stream *pcm_playback;
80 81
81 /* misc flags */ 82 /* misc flags */
82 /* PD bit indicates only the update, not the current state */ 83 /* PD bit indicates only the update, not the current state */
@@ -720,6 +721,8 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
720 &spec->sink_eld[index]); 721 &spec->sink_eld[index]);
721 /* TODO: do real things about ELD */ 722 /* TODO: do real things about ELD */
722 } 723 }
724
725 snd_hda_input_jack_report(codec, tag);
723} 726}
724 727
725static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) 728static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
@@ -912,6 +915,7 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
912static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) 915static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
913{ 916{
914 struct hdmi_spec *spec = codec->spec; 917 struct hdmi_spec *spec = codec->spec;
918 int err;
915 919
916 if (spec->num_pins >= MAX_HDMI_PINS) { 920 if (spec->num_pins >= MAX_HDMI_PINS) {
917 snd_printk(KERN_WARNING 921 snd_printk(KERN_WARNING
@@ -919,6 +923,12 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
919 return -E2BIG; 923 return -E2BIG;
920 } 924 }
921 925
926 err = snd_hda_input_jack_add(codec, pin_nid,
927 SND_JACK_VIDEOOUT, NULL);
928 if (err < 0)
929 return err;
930 snd_hda_input_jack_report(codec, pin_nid);
931
922 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]); 932 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
923 933
924 spec->pin[spec->num_pins] = pin_nid; 934 spec->pin[spec->num_pins] = pin_nid;
@@ -1044,7 +1054,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1044 return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); 1054 return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
1045} 1055}
1046 1056
1047static struct hda_pcm_stream generic_hdmi_pcm_playback = { 1057static const struct hda_pcm_stream generic_hdmi_pcm_playback = {
1048 .substreams = 1, 1058 .substreams = 1,
1049 .channels_min = 2, 1059 .channels_min = 2,
1050 .ops = { 1060 .ops = {
@@ -1120,11 +1130,12 @@ static void generic_hdmi_free(struct hda_codec *codec)
1120 1130
1121 for (i = 0; i < spec->num_pins; i++) 1131 for (i = 0; i < spec->num_pins; i++)
1122 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]); 1132 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
1133 snd_hda_input_jack_free(codec);
1123 1134
1124 kfree(spec); 1135 kfree(spec);
1125} 1136}
1126 1137
1127static struct hda_codec_ops generic_hdmi_patch_ops = { 1138static const struct hda_codec_ops generic_hdmi_patch_ops = {
1128 .init = generic_hdmi_init, 1139 .init = generic_hdmi_init,
1129 .free = generic_hdmi_free, 1140 .free = generic_hdmi_free,
1130 .build_pcms = generic_hdmi_build_pcms, 1141 .build_pcms = generic_hdmi_build_pcms,
@@ -1169,12 +1180,12 @@ static int patch_generic_hdmi(struct hda_codec *codec)
1169#define nvhdmi_master_con_nid_7x 0x04 1180#define nvhdmi_master_con_nid_7x 0x04
1170#define nvhdmi_master_pin_nid_7x 0x05 1181#define nvhdmi_master_pin_nid_7x 0x05
1171 1182
1172static hda_nid_t nvhdmi_con_nids_7x[4] = { 1183static const hda_nid_t nvhdmi_con_nids_7x[4] = {
1173 /*front, rear, clfe, rear_surr */ 1184 /*front, rear, clfe, rear_surr */
1174 0x6, 0x8, 0xa, 0xc, 1185 0x6, 0x8, 0xa, 0xc,
1175}; 1186};
1176 1187
1177static struct hda_verb nvhdmi_basic_init_7x[] = { 1188static const struct hda_verb nvhdmi_basic_init_7x[] = {
1178 /* set audio protect on */ 1189 /* set audio protect on */
1179 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, 1190 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
1180 /* enable digital output on pin widget */ 1191 /* enable digital output on pin widget */
@@ -1435,7 +1446,7 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1435 return 0; 1446 return 0;
1436} 1447}
1437 1448
1438static struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = { 1449static const struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = {
1439 .substreams = 1, 1450 .substreams = 1,
1440 .channels_min = 2, 1451 .channels_min = 2,
1441 .channels_max = 8, 1452 .channels_max = 8,
@@ -1450,7 +1461,7 @@ static struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = {
1450 }, 1461 },
1451}; 1462};
1452 1463
1453static struct hda_pcm_stream nvhdmi_pcm_playback_2ch = { 1464static const struct hda_pcm_stream nvhdmi_pcm_playback_2ch = {
1454 .substreams = 1, 1465 .substreams = 1,
1455 .channels_min = 2, 1466 .channels_min = 2,
1456 .channels_max = 2, 1467 .channels_max = 2,
@@ -1465,14 +1476,14 @@ static struct hda_pcm_stream nvhdmi_pcm_playback_2ch = {
1465 }, 1476 },
1466}; 1477};
1467 1478
1468static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = { 1479static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
1469 .build_controls = generic_hdmi_build_controls, 1480 .build_controls = generic_hdmi_build_controls,
1470 .build_pcms = generic_hdmi_build_pcms, 1481 .build_pcms = generic_hdmi_build_pcms,
1471 .init = nvhdmi_7x_init, 1482 .init = nvhdmi_7x_init,
1472 .free = generic_hdmi_free, 1483 .free = generic_hdmi_free,
1473}; 1484};
1474 1485
1475static struct hda_codec_ops nvhdmi_patch_ops_2ch = { 1486static const struct hda_codec_ops nvhdmi_patch_ops_2ch = {
1476 .build_controls = generic_hdmi_build_controls, 1487 .build_controls = generic_hdmi_build_controls,
1477 .build_pcms = generic_hdmi_build_pcms, 1488 .build_pcms = generic_hdmi_build_pcms,
1478 .init = nvhdmi_7x_init, 1489 .init = nvhdmi_7x_init,
@@ -1568,7 +1579,7 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1568 return 0; 1579 return 0;
1569} 1580}
1570 1581
1571static struct hda_pcm_stream atihdmi_pcm_digital_playback = { 1582static const struct hda_pcm_stream atihdmi_pcm_digital_playback = {
1572 .substreams = 1, 1583 .substreams = 1,
1573 .channels_min = 2, 1584 .channels_min = 2,
1574 .channels_max = 2, 1585 .channels_max = 2,
@@ -1580,7 +1591,7 @@ static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
1580 }, 1591 },
1581}; 1592};
1582 1593
1583static struct hda_verb atihdmi_basic_init[] = { 1594static const struct hda_verb atihdmi_basic_init[] = {
1584 /* enable digital output on pin widget */ 1595 /* enable digital output on pin widget */
1585 { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1596 { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1586 {} /* terminator */ 1597 {} /* terminator */
@@ -1599,7 +1610,7 @@ static int atihdmi_init(struct hda_codec *codec)
1599 return 0; 1610 return 0;
1600} 1611}
1601 1612
1602static struct hda_codec_ops atihdmi_patch_ops = { 1613static const struct hda_codec_ops atihdmi_patch_ops = {
1603 .build_controls = generic_hdmi_build_controls, 1614 .build_controls = generic_hdmi_build_controls,
1604 .build_pcms = generic_hdmi_build_pcms, 1615 .build_pcms = generic_hdmi_build_pcms,
1605 .init = atihdmi_init, 1616 .init = atihdmi_init,
@@ -1634,7 +1645,7 @@ static int patch_atihdmi(struct hda_codec *codec)
1634/* 1645/*
1635 * patch entries 1646 * patch entries
1636 */ 1647 */
1637static struct hda_codec_preset snd_hda_preset_hdmi[] = { 1648static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
1638{ .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi }, 1649{ .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
1639{ .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi }, 1650{ .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
1640{ .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi }, 1651{ .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
@@ -1677,6 +1688,7 @@ static struct hda_codec_preset snd_hda_preset_hdmi[] = {
1677{ .id = 0x80862803, .name = "Eaglelake HDMI", .patch = patch_generic_hdmi }, 1688{ .id = 0x80862803, .name = "Eaglelake HDMI", .patch = patch_generic_hdmi },
1678{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, 1689{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
1679{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, 1690{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi },
1691{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi },
1680{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, 1692{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi },
1681{} /* terminator */ 1693{} /* terminator */
1682}; 1694};
@@ -1722,6 +1734,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862802");
1722MODULE_ALIAS("snd-hda-codec-id:80862803"); 1734MODULE_ALIAS("snd-hda-codec-id:80862803");
1723MODULE_ALIAS("snd-hda-codec-id:80862804"); 1735MODULE_ALIAS("snd-hda-codec-id:80862804");
1724MODULE_ALIAS("snd-hda-codec-id:80862805"); 1736MODULE_ALIAS("snd-hda-codec-id:80862805");
1737MODULE_ALIAS("snd-hda-codec-id:80862806");
1725MODULE_ALIAS("snd-hda-codec-id:808629fb"); 1738MODULE_ALIAS("snd-hda-codec-id:808629fb");
1726 1739
1727MODULE_LICENSE("GPL"); 1740MODULE_LICENSE("GPL");
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index c82979a8cd09..7a4e10002f56 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -299,11 +299,23 @@ struct alc_customize_define {
299 299
300struct alc_fixup; 300struct alc_fixup;
301 301
302struct alc_multi_io {
303 hda_nid_t pin; /* multi-io widget pin NID */
304 hda_nid_t dac; /* DAC to be connected */
305 unsigned int ctl_in; /* cached input-pin control value */
306};
307
308enum {
309 ALC_AUTOMUTE_PIN, /* change the pin control */
310 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
311 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
312};
313
302struct alc_spec { 314struct alc_spec {
303 /* codec parameterization */ 315 /* codec parameterization */
304 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 316 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
305 unsigned int num_mixers; 317 unsigned int num_mixers;
306 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 318 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
307 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 319 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
308 320
309 const struct hda_verb *init_verbs[10]; /* initialization verbs 321 const struct hda_verb *init_verbs[10]; /* initialization verbs
@@ -313,14 +325,14 @@ struct alc_spec {
313 unsigned int num_init_verbs; 325 unsigned int num_init_verbs;
314 326
315 char stream_name_analog[32]; /* analog PCM stream */ 327 char stream_name_analog[32]; /* analog PCM stream */
316 struct hda_pcm_stream *stream_analog_playback; 328 const struct hda_pcm_stream *stream_analog_playback;
317 struct hda_pcm_stream *stream_analog_capture; 329 const struct hda_pcm_stream *stream_analog_capture;
318 struct hda_pcm_stream *stream_analog_alt_playback; 330 const struct hda_pcm_stream *stream_analog_alt_playback;
319 struct hda_pcm_stream *stream_analog_alt_capture; 331 const struct hda_pcm_stream *stream_analog_alt_capture;
320 332
321 char stream_name_digital[32]; /* digital PCM stream */ 333 char stream_name_digital[32]; /* digital PCM stream */
322 struct hda_pcm_stream *stream_digital_playback; 334 const struct hda_pcm_stream *stream_digital_playback;
323 struct hda_pcm_stream *stream_digital_capture; 335 const struct hda_pcm_stream *stream_digital_capture;
324 336
325 /* playback */ 337 /* playback */
326 struct hda_multi_out multiout; /* playback set-up 338 struct hda_multi_out multiout; /* playback set-up
@@ -333,8 +345,8 @@ struct alc_spec {
333 345
334 /* capture */ 346 /* capture */
335 unsigned int num_adc_nids; 347 unsigned int num_adc_nids;
336 hda_nid_t *adc_nids; 348 const hda_nid_t *adc_nids;
337 hda_nid_t *capsrc_nids; 349 const hda_nid_t *capsrc_nids;
338 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 350 hda_nid_t dig_in_nid; /* digital-in NID; optional */
339 351
340 /* capture setup for dynamic dual-adc switch */ 352 /* capture setup for dynamic dual-adc switch */
@@ -348,6 +360,7 @@ struct alc_spec {
348 const struct hda_input_mux *input_mux; 360 const struct hda_input_mux *input_mux;
349 unsigned int cur_mux[3]; 361 unsigned int cur_mux[3];
350 struct alc_mic_route ext_mic; 362 struct alc_mic_route ext_mic;
363 struct alc_mic_route dock_mic;
351 struct alc_mic_route int_mic; 364 struct alc_mic_route int_mic;
352 365
353 /* channel model */ 366 /* channel model */
@@ -375,17 +388,27 @@ struct alc_spec {
375#ifdef CONFIG_SND_HDA_POWER_SAVE 388#ifdef CONFIG_SND_HDA_POWER_SAVE
376 void (*power_hook)(struct hda_codec *codec); 389 void (*power_hook)(struct hda_codec *codec);
377#endif 390#endif
391 void (*shutup)(struct hda_codec *codec);
378 392
379 /* for pin sensing */ 393 /* for pin sensing */
380 unsigned int sense_updated: 1;
381 unsigned int jack_present: 1; 394 unsigned int jack_present: 1;
382 unsigned int master_sw: 1; 395 unsigned int line_jack_present:1;
396 unsigned int master_mute:1;
383 unsigned int auto_mic:1; 397 unsigned int auto_mic:1;
398 unsigned int automute:1; /* HP automute enabled */
399 unsigned int detect_line:1; /* Line-out detection enabled */
400 unsigned int automute_lines:1; /* automute line-out as well */
401 unsigned int automute_hp_lo:1; /* both HP and LO available */
384 402
385 /* other flags */ 403 /* other flags */
386 unsigned int no_analog :1; /* digital I/O only */ 404 unsigned int no_analog :1; /* digital I/O only */
387 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ 405 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
388 unsigned int single_input_src:1; 406 unsigned int single_input_src:1;
407
408 /* auto-mute control */
409 int automute_mode;
410 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
411
389 int init_amp; 412 int init_amp;
390 int codec_variant; /* flag for other variants */ 413 int codec_variant; /* flag for other variants */
391 414
@@ -403,25 +426,29 @@ struct alc_spec {
403 int fixup_id; 426 int fixup_id;
404 const struct alc_fixup *fixup_list; 427 const struct alc_fixup *fixup_list;
405 const char *fixup_name; 428 const char *fixup_name;
429
430 /* multi-io */
431 int multi_ios;
432 struct alc_multi_io multi_io[4];
406}; 433};
407 434
408/* 435/*
409 * configuration template - to be copied to the spec instance 436 * configuration template - to be copied to the spec instance
410 */ 437 */
411struct alc_config_preset { 438struct alc_config_preset {
412 struct snd_kcontrol_new *mixers[5]; /* should be identical size 439 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
413 * with spec 440 * with spec
414 */ 441 */
415 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 442 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
416 const struct hda_verb *init_verbs[5]; 443 const struct hda_verb *init_verbs[5];
417 unsigned int num_dacs; 444 unsigned int num_dacs;
418 hda_nid_t *dac_nids; 445 const hda_nid_t *dac_nids;
419 hda_nid_t dig_out_nid; /* optional */ 446 hda_nid_t dig_out_nid; /* optional */
420 hda_nid_t hp_nid; /* optional */ 447 hda_nid_t hp_nid; /* optional */
421 hda_nid_t *slave_dig_outs; 448 const hda_nid_t *slave_dig_outs;
422 unsigned int num_adc_nids; 449 unsigned int num_adc_nids;
423 hda_nid_t *adc_nids; 450 const hda_nid_t *adc_nids;
424 hda_nid_t *capsrc_nids; 451 const hda_nid_t *capsrc_nids;
425 hda_nid_t dig_in_nid; 452 hda_nid_t dig_in_nid;
426 unsigned int num_channel_mode; 453 unsigned int num_channel_mode;
427 const struct hda_channel_mode *channel_mode; 454 const struct hda_channel_mode *channel_mode;
@@ -433,7 +460,7 @@ struct alc_config_preset {
433 void (*setup)(struct hda_codec *); 460 void (*setup)(struct hda_codec *);
434 void (*init_hook)(struct hda_codec *); 461 void (*init_hook)(struct hda_codec *);
435#ifdef CONFIG_SND_HDA_POWER_SAVE 462#ifdef CONFIG_SND_HDA_POWER_SAVE
436 struct hda_amp_list *loopbacks; 463 const struct hda_amp_list *loopbacks;
437 void (*power_hook)(struct hda_codec *codec); 464 void (*power_hook)(struct hda_codec *codec);
438#endif 465#endif
439}; 466};
@@ -560,11 +587,11 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
560 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of 587 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
561 * March 2006. 588 * March 2006.
562 */ 589 */
563static char *alc_pin_mode_names[] = { 590static const char * const alc_pin_mode_names[] = {
564 "Mic 50pc bias", "Mic 80pc bias", 591 "Mic 50pc bias", "Mic 80pc bias",
565 "Line in", "Line out", "Headphone out", 592 "Line in", "Line out", "Headphone out",
566}; 593};
567static unsigned char alc_pin_mode_values[] = { 594static const unsigned char alc_pin_mode_values[] = {
568 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 595 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
569}; 596};
570/* The control can present all 5 options, or it can limit the options based 597/* The control can present all 5 options, or it can limit the options based
@@ -583,7 +610,7 @@ static unsigned char alc_pin_mode_values[] = {
583/* Info about the pin modes supported by the different pin direction modes. 610/* Info about the pin modes supported by the different pin direction modes.
584 * For each direction the minimum and maximum values are given. 611 * For each direction the minimum and maximum values are given.
585 */ 612 */
586static signed char alc_pin_mode_dir_info[5][2] = { 613static const signed char alc_pin_mode_dir_info[5][2] = {
587 { 0, 2 }, /* ALC_PIN_DIR_IN */ 614 { 0, 2 }, /* ALC_PIN_DIR_IN */
588 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 615 { 3, 4 }, /* ALC_PIN_DIR_OUT */
589 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 616 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
@@ -900,7 +927,7 @@ static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
900 927
901/* 928/*
902 */ 929 */
903static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) 930static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
904{ 931{
905 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) 932 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
906 return; 933 return;
@@ -971,21 +998,21 @@ static void setup_preset(struct hda_codec *codec,
971} 998}
972 999
973/* Enable GPIO mask and set output */ 1000/* Enable GPIO mask and set output */
974static struct hda_verb alc_gpio1_init_verbs[] = { 1001static const struct hda_verb alc_gpio1_init_verbs[] = {
975 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 1002 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
976 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 1003 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
977 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 1004 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
978 { } 1005 { }
979}; 1006};
980 1007
981static struct hda_verb alc_gpio2_init_verbs[] = { 1008static const struct hda_verb alc_gpio2_init_verbs[] = {
982 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 1009 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
983 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 1010 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
984 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 1011 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
985 { } 1012 { }
986}; 1013};
987 1014
988static struct hda_verb alc_gpio3_init_verbs[] = { 1015static const struct hda_verb alc_gpio3_init_verbs[] = {
989 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 1016 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
990 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 1017 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
991 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 1018 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
@@ -1031,6 +1058,7 @@ static int alc_init_jacks(struct hda_codec *codec)
1031 int err; 1058 int err;
1032 unsigned int hp_nid = spec->autocfg.hp_pins[0]; 1059 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1033 unsigned int mic_nid = spec->ext_mic.pin; 1060 unsigned int mic_nid = spec->ext_mic.pin;
1061 unsigned int dock_nid = spec->dock_mic.pin;
1034 1062
1035 if (hp_nid) { 1063 if (hp_nid) {
1036 err = snd_hda_input_jack_add(codec, hp_nid, 1064 err = snd_hda_input_jack_add(codec, hp_nid,
@@ -1047,46 +1075,116 @@ static int alc_init_jacks(struct hda_codec *codec)
1047 return err; 1075 return err;
1048 snd_hda_input_jack_report(codec, mic_nid); 1076 snd_hda_input_jack_report(codec, mic_nid);
1049 } 1077 }
1078 if (dock_nid) {
1079 err = snd_hda_input_jack_add(codec, dock_nid,
1080 SND_JACK_MICROPHONE, NULL);
1081 if (err < 0)
1082 return err;
1083 snd_hda_input_jack_report(codec, dock_nid);
1084 }
1050#endif /* CONFIG_SND_HDA_INPUT_JACK */ 1085#endif /* CONFIG_SND_HDA_INPUT_JACK */
1051 return 0; 1086 return 0;
1052} 1087}
1053 1088
1054static void alc_automute_speaker(struct hda_codec *codec, int pinctl) 1089static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1055{ 1090{
1056 struct alc_spec *spec = codec->spec; 1091 int i, present = 0;
1057 unsigned int mute;
1058 hda_nid_t nid;
1059 int i;
1060 1092
1061 spec->jack_present = 0; 1093 for (i = 0; i < num_pins; i++) {
1062 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { 1094 hda_nid_t nid = pins[i];
1063 nid = spec->autocfg.hp_pins[i];
1064 if (!nid) 1095 if (!nid)
1065 break; 1096 break;
1066 snd_hda_input_jack_report(codec, nid); 1097 snd_hda_input_jack_report(codec, nid);
1067 spec->jack_present |= snd_hda_jack_detect(codec, nid); 1098 present |= snd_hda_jack_detect(codec, nid);
1068 } 1099 }
1100 return present;
1101}
1102
1103static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
1104 bool mute, bool hp_out)
1105{
1106 struct alc_spec *spec = codec->spec;
1107 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
1108 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
1109 int i;
1069 1110
1070 mute = spec->jack_present ? HDA_AMP_MUTE : 0; 1111 for (i = 0; i < num_pins; i++) {
1071 /* Toggle internal speakers muting */ 1112 hda_nid_t nid = pins[i];
1072 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1073 nid = spec->autocfg.speaker_pins[i];
1074 if (!nid) 1113 if (!nid)
1075 break; 1114 break;
1076 if (pinctl) { 1115 switch (spec->automute_mode) {
1116 case ALC_AUTOMUTE_PIN:
1077 snd_hda_codec_write(codec, nid, 0, 1117 snd_hda_codec_write(codec, nid, 0,
1078 AC_VERB_SET_PIN_WIDGET_CONTROL, 1118 AC_VERB_SET_PIN_WIDGET_CONTROL,
1079 spec->jack_present ? 0 : PIN_OUT); 1119 pin_bits);
1080 } else { 1120 break;
1121 case ALC_AUTOMUTE_AMP:
1081 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 1122 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1082 HDA_AMP_MUTE, mute); 1123 HDA_AMP_MUTE, mute_bits);
1124 break;
1125 case ALC_AUTOMUTE_MIXER:
1126 nid = spec->automute_mixer_nid[i];
1127 if (!nid)
1128 break;
1129 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
1130 HDA_AMP_MUTE, mute_bits);
1131 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
1132 HDA_AMP_MUTE, mute_bits);
1133 break;
1083 } 1134 }
1084 } 1135 }
1085} 1136}
1086 1137
1087static void alc_automute_pin(struct hda_codec *codec) 1138/* Toggle internal speakers muting */
1139static void update_speakers(struct hda_codec *codec)
1140{
1141 struct alc_spec *spec = codec->spec;
1142 int on;
1143
1144 if (!spec->automute)
1145 on = 0;
1146 else
1147 on = spec->jack_present | spec->line_jack_present;
1148 on |= spec->master_mute;
1149 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1150 spec->autocfg.speaker_pins, on, false);
1151
1152 /* toggle line-out mutes if needed, too */
1153 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1154 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1155 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
1156 return;
1157 if (!spec->automute_lines || !spec->automute)
1158 on = 0;
1159 else
1160 on = spec->jack_present;
1161 on |= spec->master_mute;
1162 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1163 spec->autocfg.line_out_pins, on, false);
1164}
1165
1166static void alc_hp_automute(struct hda_codec *codec)
1088{ 1167{
1089 alc_automute_speaker(codec, 1); 1168 struct alc_spec *spec = codec->spec;
1169
1170 if (!spec->automute)
1171 return;
1172 spec->jack_present =
1173 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1174 spec->autocfg.hp_pins);
1175 update_speakers(codec);
1176}
1177
1178static void alc_line_automute(struct hda_codec *codec)
1179{
1180 struct alc_spec *spec = codec->spec;
1181
1182 if (!spec->automute || !spec->detect_line)
1183 return;
1184 spec->line_jack_present =
1185 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1186 spec->autocfg.line_out_pins);
1187 update_speakers(codec);
1090} 1188}
1091 1189
1092static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 1190static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
@@ -1128,7 +1226,7 @@ static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1128static void alc_mic_automute(struct hda_codec *codec) 1226static void alc_mic_automute(struct hda_codec *codec)
1129{ 1227{
1130 struct alc_spec *spec = codec->spec; 1228 struct alc_spec *spec = codec->spec;
1131 struct alc_mic_route *dead, *alive; 1229 struct alc_mic_route *dead1, *dead2, *alive;
1132 unsigned int present, type; 1230 unsigned int present, type;
1133 hda_nid_t cap_nid; 1231 hda_nid_t cap_nid;
1134 1232
@@ -1146,13 +1244,24 @@ static void alc_mic_automute(struct hda_codec *codec)
1146 1244
1147 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; 1245 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1148 1246
1247 alive = &spec->int_mic;
1248 dead1 = &spec->ext_mic;
1249 dead2 = &spec->dock_mic;
1250
1149 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1251 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1150 if (present) { 1252 if (present) {
1151 alive = &spec->ext_mic; 1253 alive = &spec->ext_mic;
1152 dead = &spec->int_mic; 1254 dead1 = &spec->int_mic;
1153 } else { 1255 dead2 = &spec->dock_mic;
1154 alive = &spec->int_mic; 1256 }
1155 dead = &spec->ext_mic; 1257 if (!present && spec->dock_mic.pin > 0) {
1258 present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1259 if (present) {
1260 alive = &spec->dock_mic;
1261 dead1 = &spec->int_mic;
1262 dead2 = &spec->ext_mic;
1263 }
1264 snd_hda_input_jack_report(codec, spec->dock_mic.pin);
1156 } 1265 }
1157 1266
1158 type = get_wcaps_type(get_wcaps(codec, cap_nid)); 1267 type = get_wcaps_type(get_wcaps(codec, cap_nid));
@@ -1161,9 +1270,14 @@ static void alc_mic_automute(struct hda_codec *codec)
1161 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1270 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1162 alive->mux_idx, 1271 alive->mux_idx,
1163 HDA_AMP_MUTE, 0); 1272 HDA_AMP_MUTE, 0);
1164 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1273 if (dead1->pin > 0)
1165 dead->mux_idx, 1274 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1166 HDA_AMP_MUTE, HDA_AMP_MUTE); 1275 dead1->mux_idx,
1276 HDA_AMP_MUTE, HDA_AMP_MUTE);
1277 if (dead2->pin > 0)
1278 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1279 dead2->mux_idx,
1280 HDA_AMP_MUTE, HDA_AMP_MUTE);
1167 } else { 1281 } else {
1168 /* MUX style (e.g. ALC880) */ 1282 /* MUX style (e.g. ALC880) */
1169 snd_hda_codec_write_cache(codec, cap_nid, 0, 1283 snd_hda_codec_write_cache(codec, cap_nid, 0,
@@ -1184,7 +1298,10 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1184 res >>= 26; 1298 res >>= 26;
1185 switch (res) { 1299 switch (res) {
1186 case ALC880_HP_EVENT: 1300 case ALC880_HP_EVENT:
1187 alc_automute_pin(codec); 1301 alc_hp_automute(codec);
1302 break;
1303 case ALC880_FRONT_EVENT:
1304 alc_line_automute(codec);
1188 break; 1305 break;
1189 case ALC880_MIC_EVENT: 1306 case ALC880_MIC_EVENT:
1190 alc_mic_automute(codec); 1307 alc_mic_automute(codec);
@@ -1194,7 +1311,8 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1194 1311
1195static void alc_inithook(struct hda_codec *codec) 1312static void alc_inithook(struct hda_codec *codec)
1196{ 1313{
1197 alc_automute_pin(codec); 1314 alc_hp_automute(codec);
1315 alc_line_automute(codec);
1198 alc_mic_automute(codec); 1316 alc_mic_automute(codec);
1199} 1317}
1200 1318
@@ -1236,6 +1354,43 @@ static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1236 on ? 2 : 0); 1354 on ? 2 : 0);
1237} 1355}
1238 1356
1357/* turn on/off EAPD controls of the codec */
1358static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1359{
1360 /* We currently only handle front, HP */
1361 switch (codec->vendor_id) {
1362 case 0x10ec0260:
1363 set_eapd(codec, 0x0f, on);
1364 set_eapd(codec, 0x10, on);
1365 break;
1366 case 0x10ec0262:
1367 case 0x10ec0267:
1368 case 0x10ec0268:
1369 case 0x10ec0269:
1370 case 0x10ec0270:
1371 case 0x10ec0272:
1372 case 0x10ec0660:
1373 case 0x10ec0662:
1374 case 0x10ec0663:
1375 case 0x10ec0665:
1376 case 0x10ec0862:
1377 case 0x10ec0889:
1378 case 0x10ec0892:
1379 set_eapd(codec, 0x14, on);
1380 set_eapd(codec, 0x15, on);
1381 break;
1382 }
1383}
1384
1385/* generic shutup callback;
1386 * just turning off EPAD and a little pause for avoiding pop-noise
1387 */
1388static void alc_eapd_shutup(struct hda_codec *codec)
1389{
1390 alc_auto_setup_eapd(codec, false);
1391 msleep(200);
1392}
1393
1239static void alc_auto_init_amp(struct hda_codec *codec, int type) 1394static void alc_auto_init_amp(struct hda_codec *codec, int type)
1240{ 1395{
1241 unsigned int tmp; 1396 unsigned int tmp;
@@ -1251,27 +1406,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1251 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 1406 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1252 break; 1407 break;
1253 case ALC_INIT_DEFAULT: 1408 case ALC_INIT_DEFAULT:
1254 switch (codec->vendor_id) { 1409 alc_auto_setup_eapd(codec, true);
1255 case 0x10ec0260:
1256 set_eapd(codec, 0x0f, 1);
1257 set_eapd(codec, 0x10, 1);
1258 break;
1259 case 0x10ec0262:
1260 case 0x10ec0267:
1261 case 0x10ec0268:
1262 case 0x10ec0269:
1263 case 0x10ec0270:
1264 case 0x10ec0272:
1265 case 0x10ec0660:
1266 case 0x10ec0662:
1267 case 0x10ec0663:
1268 case 0x10ec0665:
1269 case 0x10ec0862:
1270 case 0x10ec0889:
1271 set_eapd(codec, 0x14, 1);
1272 set_eapd(codec, 0x15, 1);
1273 break;
1274 }
1275 switch (codec->vendor_id) { 1410 switch (codec->vendor_id) {
1276 case 0x10ec0260: 1411 case 0x10ec0260:
1277 snd_hda_codec_write(codec, 0x1a, 0, 1412 snd_hda_codec_write(codec, 0x1a, 0,
@@ -1315,20 +1450,128 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1315 } 1450 }
1316} 1451}
1317 1452
1453static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1454 struct snd_ctl_elem_info *uinfo)
1455{
1456 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1457 struct alc_spec *spec = codec->spec;
1458 static const char * const texts2[] = {
1459 "Disabled", "Enabled"
1460 };
1461 static const char * const texts3[] = {
1462 "Disabled", "Speaker Only", "Line-Out+Speaker"
1463 };
1464 const char * const *texts;
1465
1466 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1467 uinfo->count = 1;
1468 if (spec->automute_hp_lo) {
1469 uinfo->value.enumerated.items = 3;
1470 texts = texts3;
1471 } else {
1472 uinfo->value.enumerated.items = 2;
1473 texts = texts2;
1474 }
1475 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1476 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1477 strcpy(uinfo->value.enumerated.name,
1478 texts[uinfo->value.enumerated.item]);
1479 return 0;
1480}
1481
1482static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1483 struct snd_ctl_elem_value *ucontrol)
1484{
1485 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1486 struct alc_spec *spec = codec->spec;
1487 unsigned int val;
1488 if (!spec->automute)
1489 val = 0;
1490 else if (!spec->automute_lines)
1491 val = 1;
1492 else
1493 val = 2;
1494 ucontrol->value.enumerated.item[0] = val;
1495 return 0;
1496}
1497
1498static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1499 struct snd_ctl_elem_value *ucontrol)
1500{
1501 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1502 struct alc_spec *spec = codec->spec;
1503
1504 switch (ucontrol->value.enumerated.item[0]) {
1505 case 0:
1506 if (!spec->automute)
1507 return 0;
1508 spec->automute = 0;
1509 break;
1510 case 1:
1511 if (spec->automute && !spec->automute_lines)
1512 return 0;
1513 spec->automute = 1;
1514 spec->automute_lines = 0;
1515 break;
1516 case 2:
1517 if (!spec->automute_hp_lo)
1518 return -EINVAL;
1519 if (spec->automute && spec->automute_lines)
1520 return 0;
1521 spec->automute = 1;
1522 spec->automute_lines = 1;
1523 break;
1524 default:
1525 return -EINVAL;
1526 }
1527 update_speakers(codec);
1528 return 1;
1529}
1530
1531static const struct snd_kcontrol_new alc_automute_mode_enum = {
1532 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1533 .name = "Auto-Mute Mode",
1534 .info = alc_automute_mode_info,
1535 .get = alc_automute_mode_get,
1536 .put = alc_automute_mode_put,
1537};
1538
1539static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1540
1541static int alc_add_automute_mode_enum(struct hda_codec *codec)
1542{
1543 struct alc_spec *spec = codec->spec;
1544 struct snd_kcontrol_new *knew;
1545
1546 knew = alc_kcontrol_new(spec);
1547 if (!knew)
1548 return -ENOMEM;
1549 *knew = alc_automute_mode_enum;
1550 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1551 if (!knew->name)
1552 return -ENOMEM;
1553 return 0;
1554}
1555
1318static void alc_init_auto_hp(struct hda_codec *codec) 1556static void alc_init_auto_hp(struct hda_codec *codec)
1319{ 1557{
1320 struct alc_spec *spec = codec->spec; 1558 struct alc_spec *spec = codec->spec;
1321 struct auto_pin_cfg *cfg = &spec->autocfg; 1559 struct auto_pin_cfg *cfg = &spec->autocfg;
1560 int present = 0;
1322 int i; 1561 int i;
1323 1562
1324 if (!cfg->hp_pins[0]) { 1563 if (cfg->hp_pins[0])
1325 if (cfg->line_out_type != AUTO_PIN_HP_OUT) 1564 present++;
1326 return; 1565 if (cfg->line_out_pins[0])
1327 } 1566 present++;
1567 if (cfg->speaker_pins[0])
1568 present++;
1569 if (present < 2) /* need two different output types */
1570 return;
1571 if (present == 3)
1572 spec->automute_hp_lo = 1; /* both HP and LO automute */
1328 1573
1329 if (!cfg->speaker_pins[0]) { 1574 if (!cfg->speaker_pins[0]) {
1330 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
1331 return;
1332 memcpy(cfg->speaker_pins, cfg->line_out_pins, 1575 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1333 sizeof(cfg->speaker_pins)); 1576 sizeof(cfg->speaker_pins));
1334 cfg->speaker_outs = cfg->line_outs; 1577 cfg->speaker_outs = cfg->line_outs;
@@ -1341,28 +1584,49 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1341 } 1584 }
1342 1585
1343 for (i = 0; i < cfg->hp_outs; i++) { 1586 for (i = 0; i < cfg->hp_outs; i++) {
1587 hda_nid_t nid = cfg->hp_pins[i];
1588 if (!is_jack_detectable(codec, nid))
1589 continue;
1344 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", 1590 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1345 cfg->hp_pins[i]); 1591 nid);
1346 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0, 1592 snd_hda_codec_write_cache(codec, nid, 0,
1347 AC_VERB_SET_UNSOLICITED_ENABLE, 1593 AC_VERB_SET_UNSOLICITED_ENABLE,
1348 AC_USRSP_EN | ALC880_HP_EVENT); 1594 AC_USRSP_EN | ALC880_HP_EVENT);
1595 spec->automute = 1;
1596 spec->automute_mode = ALC_AUTOMUTE_PIN;
1597 }
1598 if (spec->automute && cfg->line_out_pins[0] &&
1599 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1600 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1601 for (i = 0; i < cfg->line_outs; i++) {
1602 hda_nid_t nid = cfg->line_out_pins[i];
1603 if (!is_jack_detectable(codec, nid))
1604 continue;
1605 snd_printdd("realtek: Enable Line-Out auto-muting "
1606 "on NID 0x%x\n", nid);
1607 snd_hda_codec_write_cache(codec, nid, 0,
1608 AC_VERB_SET_UNSOLICITED_ENABLE,
1609 AC_USRSP_EN | ALC880_FRONT_EVENT);
1610 spec->detect_line = 1;
1611 }
1612 spec->automute_lines = spec->detect_line;
1613 }
1614
1615 if (spec->automute) {
1616 /* create a control for automute mode */
1617 alc_add_automute_mode_enum(codec);
1618 spec->unsol_event = alc_sku_unsol_event;
1349 } 1619 }
1350 spec->unsol_event = alc_sku_unsol_event;
1351} 1620}
1352 1621
1353static void alc_init_auto_mic(struct hda_codec *codec) 1622static void alc_init_auto_mic(struct hda_codec *codec)
1354{ 1623{
1355 struct alc_spec *spec = codec->spec; 1624 struct alc_spec *spec = codec->spec;
1356 struct auto_pin_cfg *cfg = &spec->autocfg; 1625 struct auto_pin_cfg *cfg = &spec->autocfg;
1357 hda_nid_t fixed, ext; 1626 hda_nid_t fixed, ext, dock;
1358 int i; 1627 int i;
1359 1628
1360 /* there must be only two mic inputs exclusively */ 1629 fixed = ext = dock = 0;
1361 for (i = 0; i < cfg->num_inputs; i++)
1362 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
1363 return;
1364
1365 fixed = ext = 0;
1366 for (i = 0; i < cfg->num_inputs; i++) { 1630 for (i = 0; i < cfg->num_inputs; i++) {
1367 hda_nid_t nid = cfg->inputs[i].pin; 1631 hda_nid_t nid = cfg->inputs[i].pin;
1368 unsigned int defcfg; 1632 unsigned int defcfg;
@@ -1371,26 +1635,45 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1371 case INPUT_PIN_ATTR_INT: 1635 case INPUT_PIN_ATTR_INT:
1372 if (fixed) 1636 if (fixed)
1373 return; /* already occupied */ 1637 return; /* already occupied */
1638 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1639 return; /* invalid type */
1374 fixed = nid; 1640 fixed = nid;
1375 break; 1641 break;
1376 case INPUT_PIN_ATTR_UNUSED: 1642 case INPUT_PIN_ATTR_UNUSED:
1377 return; /* invalid entry */ 1643 return; /* invalid entry */
1644 case INPUT_PIN_ATTR_DOCK:
1645 if (dock)
1646 return; /* already occupied */
1647 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1648 return; /* invalid type */
1649 dock = nid;
1650 break;
1378 default: 1651 default:
1379 if (ext) 1652 if (ext)
1380 return; /* already occupied */ 1653 return; /* already occupied */
1654 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1655 return; /* invalid type */
1381 ext = nid; 1656 ext = nid;
1382 break; 1657 break;
1383 } 1658 }
1384 } 1659 }
1660 if (!ext && dock) {
1661 ext = dock;
1662 dock = 0;
1663 }
1385 if (!ext || !fixed) 1664 if (!ext || !fixed)
1386 return; 1665 return;
1387 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) 1666 if (!is_jack_detectable(codec, ext))
1667 return; /* no unsol support */
1668 if (dock && !is_jack_detectable(codec, dock))
1388 return; /* no unsol support */ 1669 return; /* no unsol support */
1389 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", 1670 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1390 ext, fixed); 1671 ext, fixed, dock);
1391 spec->ext_mic.pin = ext; 1672 spec->ext_mic.pin = ext;
1673 spec->dock_mic.pin = dock;
1392 spec->int_mic.pin = fixed; 1674 spec->int_mic.pin = fixed;
1393 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1675 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1676 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1394 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1677 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1395 spec->auto_mic = 1; 1678 spec->auto_mic = 1;
1396 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0, 1679 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
@@ -1583,9 +1866,6 @@ do_sku:
1583 return 1; 1866 return 1;
1584 spec->autocfg.hp_pins[0] = nid; 1867 spec->autocfg.hp_pins[0] = nid;
1585 } 1868 }
1586
1587 alc_init_auto_hp(codec);
1588 alc_init_auto_mic(codec);
1589 return 1; 1869 return 1;
1590} 1870}
1591 1871
@@ -1598,9 +1878,10 @@ static void alc_ssid_check(struct hda_codec *codec,
1598 snd_printd("realtek: " 1878 snd_printd("realtek: "
1599 "Enable default setup for auto mode as fallback\n"); 1879 "Enable default setup for auto mode as fallback\n");
1600 spec->init_amp = ALC_INIT_DEFAULT; 1880 spec->init_amp = ALC_INIT_DEFAULT;
1601 alc_init_auto_hp(codec);
1602 alc_init_auto_mic(codec);
1603 } 1881 }
1882
1883 alc_init_auto_hp(codec);
1884 alc_init_auto_mic(codec);
1604} 1885}
1605 1886
1606/* 1887/*
@@ -1842,7 +2123,7 @@ static void alc_auto_parse_digital(struct hda_codec *codec)
1842/* 2123/*
1843 * 2ch mode 2124 * 2ch mode
1844 */ 2125 */
1845static struct hda_verb alc888_4ST_ch2_intel_init[] = { 2126static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
1846/* Mic-in jack as mic in */ 2127/* Mic-in jack as mic in */
1847 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2128 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1848 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2129 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
@@ -1857,7 +2138,7 @@ static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1857/* 2138/*
1858 * 4ch mode 2139 * 4ch mode
1859 */ 2140 */
1860static struct hda_verb alc888_4ST_ch4_intel_init[] = { 2141static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
1861/* Mic-in jack as mic in */ 2142/* Mic-in jack as mic in */
1862 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2143 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1863 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2144 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
@@ -1872,7 +2153,7 @@ static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1872/* 2153/*
1873 * 6ch mode 2154 * 6ch mode
1874 */ 2155 */
1875static struct hda_verb alc888_4ST_ch6_intel_init[] = { 2156static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
1876/* Mic-in jack as CLFE */ 2157/* Mic-in jack as CLFE */
1877 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2158 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1878 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2159 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
@@ -1887,7 +2168,7 @@ static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1887/* 2168/*
1888 * 8ch mode 2169 * 8ch mode
1889 */ 2170 */
1890static struct hda_verb alc888_4ST_ch8_intel_init[] = { 2171static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
1891/* Mic-in jack as CLFE */ 2172/* Mic-in jack as CLFE */
1892 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2173 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1893 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2174 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
@@ -1899,7 +2180,7 @@ static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1899 { } /* end */ 2180 { } /* end */
1900}; 2181};
1901 2182
1902static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { 2183static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1903 { 2, alc888_4ST_ch2_intel_init }, 2184 { 2, alc888_4ST_ch2_intel_init },
1904 { 4, alc888_4ST_ch4_intel_init }, 2185 { 4, alc888_4ST_ch4_intel_init },
1905 { 6, alc888_4ST_ch6_intel_init }, 2186 { 6, alc888_4ST_ch6_intel_init },
@@ -1910,7 +2191,7 @@ static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1910 * ALC888 Fujitsu Siemens Amillo xa3530 2191 * ALC888 Fujitsu Siemens Amillo xa3530
1911 */ 2192 */
1912 2193
1913static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { 2194static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1914/* Front Mic: set to PIN_IN (empty by default) */ 2195/* Front Mic: set to PIN_IN (empty by default) */
1915 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2196 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1916/* Connect Internal HP to Front */ 2197/* Connect Internal HP to Front */
@@ -1943,22 +2224,6 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1943 {} 2224 {}
1944}; 2225};
1945 2226
1946static void alc_automute_amp(struct hda_codec *codec)
1947{
1948 alc_automute_speaker(codec, 0);
1949}
1950
1951static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1952 unsigned int res)
1953{
1954 if (codec->vendor_id == 0x10ec0880)
1955 res >>= 28;
1956 else
1957 res >>= 26;
1958 if (res == ALC880_HP_EVENT)
1959 alc_automute_amp(codec);
1960}
1961
1962static void alc889_automute_setup(struct hda_codec *codec) 2227static void alc889_automute_setup(struct hda_codec *codec)
1963{ 2228{
1964 struct alc_spec *spec = codec->spec; 2229 struct alc_spec *spec = codec->spec;
@@ -1969,12 +2234,14 @@ static void alc889_automute_setup(struct hda_codec *codec)
1969 spec->autocfg.speaker_pins[2] = 0x17; 2234 spec->autocfg.speaker_pins[2] = 0x17;
1970 spec->autocfg.speaker_pins[3] = 0x19; 2235 spec->autocfg.speaker_pins[3] = 0x19;
1971 spec->autocfg.speaker_pins[4] = 0x1a; 2236 spec->autocfg.speaker_pins[4] = 0x1a;
2237 spec->automute = 1;
2238 spec->automute_mode = ALC_AUTOMUTE_AMP;
1972} 2239}
1973 2240
1974static void alc889_intel_init_hook(struct hda_codec *codec) 2241static void alc889_intel_init_hook(struct hda_codec *codec)
1975{ 2242{
1976 alc889_coef_init(codec); 2243 alc889_coef_init(codec);
1977 alc_automute_amp(codec); 2244 alc_hp_automute(codec);
1978} 2245}
1979 2246
1980static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) 2247static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
@@ -1985,13 +2252,15 @@ static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
1985 spec->autocfg.hp_pins[1] = 0x1b; /* hp */ 2252 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1986 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ 2253 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1987 spec->autocfg.speaker_pins[1] = 0x15; /* bass */ 2254 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2255 spec->automute = 1;
2256 spec->automute_mode = ALC_AUTOMUTE_AMP;
1988} 2257}
1989 2258
1990/* 2259/*
1991 * ALC888 Acer Aspire 4930G model 2260 * ALC888 Acer Aspire 4930G model
1992 */ 2261 */
1993 2262
1994static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { 2263static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1995/* Front Mic: set to PIN_IN (empty by default) */ 2264/* Front Mic: set to PIN_IN (empty by default) */
1996 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2265 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1997/* Unselect Front Mic by default in input mixer 3 */ 2266/* Unselect Front Mic by default in input mixer 3 */
@@ -2014,7 +2283,7 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2014 * ALC888 Acer Aspire 6530G model 2283 * ALC888 Acer Aspire 6530G model
2015 */ 2284 */
2016 2285
2017static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { 2286static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2018/* Route to built-in subwoofer as well as speakers */ 2287/* Route to built-in subwoofer as well as speakers */
2019 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2288 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2020 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2289 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -2044,7 +2313,7 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2044 *ALC888 Acer Aspire 7730G model 2313 *ALC888 Acer Aspire 7730G model
2045 */ 2314 */
2046 2315
2047static struct hda_verb alc888_acer_aspire_7730G_verbs[] = { 2316static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2048/* Bias voltage on for external mic port */ 2317/* Bias voltage on for external mic port */
2049 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, 2318 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2050/* Front Mic: set to PIN_IN (empty by default) */ 2319/* Front Mic: set to PIN_IN (empty by default) */
@@ -2074,7 +2343,7 @@ static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2074 * ALC889 Acer Aspire 8930G model 2343 * ALC889 Acer Aspire 8930G model
2075 */ 2344 */
2076 2345
2077static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { 2346static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2078/* Front Mic: set to PIN_IN (empty by default) */ 2347/* Front Mic: set to PIN_IN (empty by default) */
2079 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2348 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2080/* Unselect Front Mic by default in input mixer 3 */ 2349/* Unselect Front Mic by default in input mixer 3 */
@@ -2120,7 +2389,7 @@ static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2120 { } 2389 { }
2121}; 2390};
2122 2391
2123static struct hda_input_mux alc888_2_capture_sources[2] = { 2392static const struct hda_input_mux alc888_2_capture_sources[2] = {
2124 /* Front mic only available on one ADC */ 2393 /* Front mic only available on one ADC */
2125 { 2394 {
2126 .num_items = 4, 2395 .num_items = 4,
@@ -2141,7 +2410,7 @@ static struct hda_input_mux alc888_2_capture_sources[2] = {
2141 } 2410 }
2142}; 2411};
2143 2412
2144static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { 2413static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2145 /* Interal mic only available on one ADC */ 2414 /* Interal mic only available on one ADC */
2146 { 2415 {
2147 .num_items = 5, 2416 .num_items = 5,
@@ -2164,7 +2433,7 @@ static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2164 } 2433 }
2165}; 2434};
2166 2435
2167static struct hda_input_mux alc889_capture_sources[3] = { 2436static const struct hda_input_mux alc889_capture_sources[3] = {
2168 /* Digital mic only available on first "ADC" */ 2437 /* Digital mic only available on first "ADC" */
2169 { 2438 {
2170 .num_items = 5, 2439 .num_items = 5,
@@ -2196,7 +2465,7 @@ static struct hda_input_mux alc889_capture_sources[3] = {
2196 } 2465 }
2197}; 2466};
2198 2467
2199static struct snd_kcontrol_new alc888_base_mixer[] = { 2468static const struct snd_kcontrol_new alc888_base_mixer[] = {
2200 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2469 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2201 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2470 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2202 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2471 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2218,7 +2487,7 @@ static struct snd_kcontrol_new alc888_base_mixer[] = {
2218 { } /* end */ 2487 { } /* end */
2219}; 2488};
2220 2489
2221static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = { 2490static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2222 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2491 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2223 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2492 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2224 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2493 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2240,7 +2509,7 @@ static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2240 { } /* end */ 2509 { } /* end */
2241}; 2510};
2242 2511
2243static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { 2512static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2244 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2513 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2245 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2514 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2246 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2515 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2267,6 +2536,8 @@ static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2267 spec->autocfg.speaker_pins[0] = 0x14; 2536 spec->autocfg.speaker_pins[0] = 0x14;
2268 spec->autocfg.speaker_pins[1] = 0x16; 2537 spec->autocfg.speaker_pins[1] = 0x16;
2269 spec->autocfg.speaker_pins[2] = 0x17; 2538 spec->autocfg.speaker_pins[2] = 0x17;
2539 spec->automute = 1;
2540 spec->automute_mode = ALC_AUTOMUTE_AMP;
2270} 2541}
2271 2542
2272static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) 2543static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
@@ -2277,6 +2548,8 @@ static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2277 spec->autocfg.speaker_pins[0] = 0x14; 2548 spec->autocfg.speaker_pins[0] = 0x14;
2278 spec->autocfg.speaker_pins[1] = 0x16; 2549 spec->autocfg.speaker_pins[1] = 0x16;
2279 spec->autocfg.speaker_pins[2] = 0x17; 2550 spec->autocfg.speaker_pins[2] = 0x17;
2551 spec->automute = 1;
2552 spec->automute_mode = ALC_AUTOMUTE_AMP;
2280} 2553}
2281 2554
2282static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec) 2555static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
@@ -2287,6 +2560,8 @@ static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2287 spec->autocfg.speaker_pins[0] = 0x14; 2560 spec->autocfg.speaker_pins[0] = 0x14;
2288 spec->autocfg.speaker_pins[1] = 0x16; 2561 spec->autocfg.speaker_pins[1] = 0x16;
2289 spec->autocfg.speaker_pins[2] = 0x17; 2562 spec->autocfg.speaker_pins[2] = 0x17;
2563 spec->automute = 1;
2564 spec->automute_mode = ALC_AUTOMUTE_AMP;
2290} 2565}
2291 2566
2292static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) 2567static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
@@ -2297,6 +2572,8 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2297 spec->autocfg.speaker_pins[0] = 0x14; 2572 spec->autocfg.speaker_pins[0] = 0x14;
2298 spec->autocfg.speaker_pins[1] = 0x16; 2573 spec->autocfg.speaker_pins[1] = 0x16;
2299 spec->autocfg.speaker_pins[2] = 0x1b; 2574 spec->autocfg.speaker_pins[2] = 0x1b;
2575 spec->automute = 1;
2576 spec->automute_mode = ALC_AUTOMUTE_AMP;
2300} 2577}
2301 2578
2302/* 2579/*
@@ -2307,12 +2584,12 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2307 * F-Mic = 0x1b, HP = 0x19 2584 * F-Mic = 0x1b, HP = 0x19
2308 */ 2585 */
2309 2586
2310static hda_nid_t alc880_dac_nids[4] = { 2587static const hda_nid_t alc880_dac_nids[4] = {
2311 /* front, rear, clfe, rear_surr */ 2588 /* front, rear, clfe, rear_surr */
2312 0x02, 0x05, 0x04, 0x03 2589 0x02, 0x05, 0x04, 0x03
2313}; 2590};
2314 2591
2315static hda_nid_t alc880_adc_nids[3] = { 2592static const hda_nid_t alc880_adc_nids[3] = {
2316 /* ADC0-2 */ 2593 /* ADC0-2 */
2317 0x07, 0x08, 0x09, 2594 0x07, 0x08, 0x09,
2318}; 2595};
@@ -2321,7 +2598,7 @@ static hda_nid_t alc880_adc_nids[3] = {
2321 * but it shows zero connection in the real implementation on some devices. 2598 * but it shows zero connection in the real implementation on some devices.
2322 * Note: this is a 915GAV bug, fixed on 915GLV 2599 * Note: this is a 915GAV bug, fixed on 915GLV
2323 */ 2600 */
2324static hda_nid_t alc880_adc_nids_alt[2] = { 2601static const hda_nid_t alc880_adc_nids_alt[2] = {
2325 /* ADC1-2 */ 2602 /* ADC1-2 */
2326 0x08, 0x09, 2603 0x08, 0x09,
2327}; 2604};
@@ -2329,7 +2606,7 @@ static hda_nid_t alc880_adc_nids_alt[2] = {
2329#define ALC880_DIGOUT_NID 0x06 2606#define ALC880_DIGOUT_NID 0x06
2330#define ALC880_DIGIN_NID 0x0a 2607#define ALC880_DIGIN_NID 0x0a
2331 2608
2332static struct hda_input_mux alc880_capture_source = { 2609static const struct hda_input_mux alc880_capture_source = {
2333 .num_items = 4, 2610 .num_items = 4,
2334 .items = { 2611 .items = {
2335 { "Mic", 0x0 }, 2612 { "Mic", 0x0 },
@@ -2341,7 +2618,7 @@ static struct hda_input_mux alc880_capture_source = {
2341 2618
2342/* channel source setting (2/6 channel selection for 3-stack) */ 2619/* channel source setting (2/6 channel selection for 3-stack) */
2343/* 2ch mode */ 2620/* 2ch mode */
2344static struct hda_verb alc880_threestack_ch2_init[] = { 2621static const struct hda_verb alc880_threestack_ch2_init[] = {
2345 /* set line-in to input, mute it */ 2622 /* set line-in to input, mute it */
2346 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2623 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2347 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2624 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
@@ -2352,7 +2629,7 @@ static struct hda_verb alc880_threestack_ch2_init[] = {
2352}; 2629};
2353 2630
2354/* 6ch mode */ 2631/* 6ch mode */
2355static struct hda_verb alc880_threestack_ch6_init[] = { 2632static const struct hda_verb alc880_threestack_ch6_init[] = {
2356 /* set line-in to output, unmute it */ 2633 /* set line-in to output, unmute it */
2357 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2634 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2358 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2635 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
@@ -2362,12 +2639,12 @@ static struct hda_verb alc880_threestack_ch6_init[] = {
2362 { } /* end */ 2639 { } /* end */
2363}; 2640};
2364 2641
2365static struct hda_channel_mode alc880_threestack_modes[2] = { 2642static const struct hda_channel_mode alc880_threestack_modes[2] = {
2366 { 2, alc880_threestack_ch2_init }, 2643 { 2, alc880_threestack_ch2_init },
2367 { 6, alc880_threestack_ch6_init }, 2644 { 6, alc880_threestack_ch6_init },
2368}; 2645};
2369 2646
2370static struct snd_kcontrol_new alc880_three_stack_mixer[] = { 2647static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2371 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2648 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2372 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2649 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2373 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2650 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
@@ -2512,14 +2789,14 @@ static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2512 } 2789 }
2513 2790
2514#define DEFINE_CAPMIX(num) \ 2791#define DEFINE_CAPMIX(num) \
2515static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ 2792static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2516 _DEFINE_CAPMIX(num), \ 2793 _DEFINE_CAPMIX(num), \
2517 _DEFINE_CAPSRC(num), \ 2794 _DEFINE_CAPSRC(num), \
2518 { } /* end */ \ 2795 { } /* end */ \
2519} 2796}
2520 2797
2521#define DEFINE_CAPMIX_NOSRC(num) \ 2798#define DEFINE_CAPMIX_NOSRC(num) \
2522static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ 2799static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2523 _DEFINE_CAPMIX(num), \ 2800 _DEFINE_CAPMIX(num), \
2524 { } /* end */ \ 2801 { } /* end */ \
2525} 2802}
@@ -2542,7 +2819,7 @@ DEFINE_CAPMIX_NOSRC(3);
2542 */ 2819 */
2543 2820
2544/* additional mixers to alc880_three_stack_mixer */ 2821/* additional mixers to alc880_three_stack_mixer */
2545static struct snd_kcontrol_new alc880_five_stack_mixer[] = { 2822static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2546 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2823 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2547 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 2824 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2548 { } /* end */ 2825 { } /* end */
@@ -2550,7 +2827,7 @@ static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2550 2827
2551/* channel source setting (6/8 channel selection for 5-stack) */ 2828/* channel source setting (6/8 channel selection for 5-stack) */
2552/* 6ch mode */ 2829/* 6ch mode */
2553static struct hda_verb alc880_fivestack_ch6_init[] = { 2830static const struct hda_verb alc880_fivestack_ch6_init[] = {
2554 /* set line-in to input, mute it */ 2831 /* set line-in to input, mute it */
2555 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2832 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2556 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2833 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
@@ -2558,14 +2835,14 @@ static struct hda_verb alc880_fivestack_ch6_init[] = {
2558}; 2835};
2559 2836
2560/* 8ch mode */ 2837/* 8ch mode */
2561static struct hda_verb alc880_fivestack_ch8_init[] = { 2838static const struct hda_verb alc880_fivestack_ch8_init[] = {
2562 /* set line-in to output, unmute it */ 2839 /* set line-in to output, unmute it */
2563 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2840 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2564 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2841 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2565 { } /* end */ 2842 { } /* end */
2566}; 2843};
2567 2844
2568static struct hda_channel_mode alc880_fivestack_modes[2] = { 2845static const struct hda_channel_mode alc880_fivestack_modes[2] = {
2569 { 6, alc880_fivestack_ch6_init }, 2846 { 6, alc880_fivestack_ch6_init },
2570 { 8, alc880_fivestack_ch8_init }, 2847 { 8, alc880_fivestack_ch8_init },
2571}; 2848};
@@ -2580,12 +2857,12 @@ static struct hda_channel_mode alc880_fivestack_modes[2] = {
2580 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b 2857 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2581 */ 2858 */
2582 2859
2583static hda_nid_t alc880_6st_dac_nids[4] = { 2860static const hda_nid_t alc880_6st_dac_nids[4] = {
2584 /* front, rear, clfe, rear_surr */ 2861 /* front, rear, clfe, rear_surr */
2585 0x02, 0x03, 0x04, 0x05 2862 0x02, 0x03, 0x04, 0x05
2586}; 2863};
2587 2864
2588static struct hda_input_mux alc880_6stack_capture_source = { 2865static const struct hda_input_mux alc880_6stack_capture_source = {
2589 .num_items = 4, 2866 .num_items = 4,
2590 .items = { 2867 .items = {
2591 { "Mic", 0x0 }, 2868 { "Mic", 0x0 },
@@ -2596,11 +2873,11 @@ static struct hda_input_mux alc880_6stack_capture_source = {
2596}; 2873};
2597 2874
2598/* fixed 8-channels */ 2875/* fixed 8-channels */
2599static struct hda_channel_mode alc880_sixstack_modes[1] = { 2876static const struct hda_channel_mode alc880_sixstack_modes[1] = {
2600 { 8, NULL }, 2877 { 8, NULL },
2601}; 2878};
2602 2879
2603static struct snd_kcontrol_new alc880_six_stack_mixer[] = { 2880static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2604 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2881 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2605 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2882 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2606 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2883 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2655,18 +2932,18 @@ static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2655 * haven't setup any initialization verbs for these yet... 2932 * haven't setup any initialization verbs for these yet...
2656 */ 2933 */
2657 2934
2658static hda_nid_t alc880_w810_dac_nids[3] = { 2935static const hda_nid_t alc880_w810_dac_nids[3] = {
2659 /* front, rear/surround, clfe */ 2936 /* front, rear/surround, clfe */
2660 0x02, 0x03, 0x04 2937 0x02, 0x03, 0x04
2661}; 2938};
2662 2939
2663/* fixed 6 channels */ 2940/* fixed 6 channels */
2664static struct hda_channel_mode alc880_w810_modes[1] = { 2941static const struct hda_channel_mode alc880_w810_modes[1] = {
2665 { 6, NULL } 2942 { 6, NULL }
2666}; 2943};
2667 2944
2668/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 2945/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2669static struct snd_kcontrol_new alc880_w810_base_mixer[] = { 2946static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2670 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2947 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2671 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2948 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2672 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2949 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2688,17 +2965,17 @@ static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2688 * Line = 0x1a 2965 * Line = 0x1a
2689 */ 2966 */
2690 2967
2691static hda_nid_t alc880_z71v_dac_nids[1] = { 2968static const hda_nid_t alc880_z71v_dac_nids[1] = {
2692 0x02 2969 0x02
2693}; 2970};
2694#define ALC880_Z71V_HP_DAC 0x03 2971#define ALC880_Z71V_HP_DAC 0x03
2695 2972
2696/* fixed 2 channels */ 2973/* fixed 2 channels */
2697static struct hda_channel_mode alc880_2_jack_modes[1] = { 2974static const struct hda_channel_mode alc880_2_jack_modes[1] = {
2698 { 2, NULL } 2975 { 2, NULL }
2699}; 2976};
2700 2977
2701static struct snd_kcontrol_new alc880_z71v_mixer[] = { 2978static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
2702 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2979 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2703 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2980 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2704 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2981 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2718,12 +2995,12 @@ static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2718 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 2995 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2719 */ 2996 */
2720 2997
2721static hda_nid_t alc880_f1734_dac_nids[1] = { 2998static const hda_nid_t alc880_f1734_dac_nids[1] = {
2722 0x03 2999 0x03
2723}; 3000};
2724#define ALC880_F1734_HP_DAC 0x02 3001#define ALC880_F1734_HP_DAC 0x02
2725 3002
2726static struct snd_kcontrol_new alc880_f1734_mixer[] = { 3003static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
2727 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3004 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2728 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 3005 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2729 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3006 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2735,7 +3012,7 @@ static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2735 { } /* end */ 3012 { } /* end */
2736}; 3013};
2737 3014
2738static struct hda_input_mux alc880_f1734_capture_source = { 3015static const struct hda_input_mux alc880_f1734_capture_source = {
2739 .num_items = 2, 3016 .num_items = 2,
2740 .items = { 3017 .items = {
2741 { "Mic", 0x1 }, 3018 { "Mic", 0x1 },
@@ -2755,7 +3032,7 @@ static struct hda_input_mux alc880_f1734_capture_source = {
2755#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ 3032#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2756#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ 3033#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2757 3034
2758static struct snd_kcontrol_new alc880_asus_mixer[] = { 3035static const struct snd_kcontrol_new alc880_asus_mixer[] = {
2759 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3036 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2760 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 3037 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2761 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3038 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2789,14 +3066,14 @@ static struct snd_kcontrol_new alc880_asus_mixer[] = {
2789 */ 3066 */
2790 3067
2791/* additional mixers to alc880_asus_mixer */ 3068/* additional mixers to alc880_asus_mixer */
2792static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 3069static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2793 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 3070 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2794 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 3071 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2795 { } /* end */ 3072 { } /* end */
2796}; 3073};
2797 3074
2798/* TCL S700 */ 3075/* TCL S700 */
2799static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 3076static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2800 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3077 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2801 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 3078 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2802 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 3079 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -2810,7 +3087,7 @@ static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2810}; 3087};
2811 3088
2812/* Uniwill */ 3089/* Uniwill */
2813static struct snd_kcontrol_new alc880_uniwill_mixer[] = { 3090static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2814 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3091 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2815 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 3092 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2816 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3093 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2837,7 +3114,7 @@ static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2837 { } /* end */ 3114 { } /* end */
2838}; 3115};
2839 3116
2840static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { 3117static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2841 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3118 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2842 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 3119 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2843 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3120 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2851,7 +3128,7 @@ static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2851 { } /* end */ 3128 { } /* end */
2852}; 3129};
2853 3130
2854static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 3131static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2855 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3132 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2856 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 3133 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2857 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3134 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2878,7 +3155,6 @@ static const char * const alc_slave_vols[] = {
2878 "Speaker Playback Volume", 3155 "Speaker Playback Volume",
2879 "Mono Playback Volume", 3156 "Mono Playback Volume",
2880 "Line-Out Playback Volume", 3157 "Line-Out Playback Volume",
2881 "PCM Playback Volume",
2882 NULL, 3158 NULL,
2883}; 3159};
2884 3160
@@ -2893,7 +3169,6 @@ static const char * const alc_slave_sws[] = {
2893 "Mono Playback Switch", 3169 "Mono Playback Switch",
2894 "IEC958 Playback Switch", 3170 "IEC958 Playback Switch",
2895 "Line-Out Playback Switch", 3171 "Line-Out Playback Switch",
2896 "PCM Playback Switch",
2897 NULL, 3172 NULL,
2898}; 3173};
2899 3174
@@ -2914,7 +3189,7 @@ static void alc_free_kctls(struct hda_codec *codec);
2914 3189
2915#ifdef CONFIG_SND_HDA_INPUT_BEEP 3190#ifdef CONFIG_SND_HDA_INPUT_BEEP
2916/* additional beep mixers; the actual parameters are overwritten at build */ 3191/* additional beep mixers; the actual parameters are overwritten at build */
2917static struct snd_kcontrol_new alc_beep_mixer[] = { 3192static const struct snd_kcontrol_new alc_beep_mixer[] = {
2918 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), 3193 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2919 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), 3194 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
2920 { } /* end */ 3195 { } /* end */
@@ -2925,7 +3200,7 @@ static int alc_build_controls(struct hda_codec *codec)
2925{ 3200{
2926 struct alc_spec *spec = codec->spec; 3201 struct alc_spec *spec = codec->spec;
2927 struct snd_kcontrol *kctl = NULL; 3202 struct snd_kcontrol *kctl = NULL;
2928 struct snd_kcontrol_new *knew; 3203 const struct snd_kcontrol_new *knew;
2929 int i, j, err; 3204 int i, j, err;
2930 unsigned int u; 3205 unsigned int u;
2931 hda_nid_t nid; 3206 hda_nid_t nid;
@@ -2962,7 +3237,7 @@ static int alc_build_controls(struct hda_codec *codec)
2962#ifdef CONFIG_SND_HDA_INPUT_BEEP 3237#ifdef CONFIG_SND_HDA_INPUT_BEEP
2963 /* create beep controls if needed */ 3238 /* create beep controls if needed */
2964 if (spec->beep_amp) { 3239 if (spec->beep_amp) {
2965 struct snd_kcontrol_new *knew; 3240 const struct snd_kcontrol_new *knew;
2966 for (knew = alc_beep_mixer; knew->name; knew++) { 3241 for (knew = alc_beep_mixer; knew->name; knew++) {
2967 struct snd_kcontrol *kctl; 3242 struct snd_kcontrol *kctl;
2968 kctl = snd_ctl_new1(knew, codec); 3243 kctl = snd_ctl_new1(knew, codec);
@@ -3001,7 +3276,7 @@ static int alc_build_controls(struct hda_codec *codec)
3001 if (!kctl) 3276 if (!kctl)
3002 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 3277 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3003 for (i = 0; kctl && i < kctl->count; i++) { 3278 for (i = 0; kctl && i < kctl->count; i++) {
3004 hda_nid_t *nids = spec->capsrc_nids; 3279 const hda_nid_t *nids = spec->capsrc_nids;
3005 if (!nids) 3280 if (!nids)
3006 nids = spec->adc_nids; 3281 nids = spec->adc_nids;
3007 err = snd_hda_add_nid(codec, kctl, i, nids[i]); 3282 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
@@ -3079,7 +3354,7 @@ static int alc_build_controls(struct hda_codec *codec)
3079/* 3354/*
3080 * generic initialization of ADC, input mixers and output mixers 3355 * generic initialization of ADC, input mixers and output mixers
3081 */ 3356 */
3082static struct hda_verb alc880_volume_init_verbs[] = { 3357static const struct hda_verb alc880_volume_init_verbs[] = {
3083 /* 3358 /*
3084 * Unmute ADC0-2 and set the default input to mic-in 3359 * Unmute ADC0-2 and set the default input to mic-in
3085 */ 3360 */
@@ -3130,7 +3405,7 @@ static struct hda_verb alc880_volume_init_verbs[] = {
3130 * 3-stack pin configuration: 3405 * 3-stack pin configuration:
3131 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 3406 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3132 */ 3407 */
3133static struct hda_verb alc880_pin_3stack_init_verbs[] = { 3408static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
3134 /* 3409 /*
3135 * preset connection lists of input pins 3410 * preset connection lists of input pins
3136 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 3411 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
@@ -3168,7 +3443,7 @@ static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3168 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, 3443 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3169 * line-in/side = 0x1a, f-mic = 0x1b 3444 * line-in/side = 0x1a, f-mic = 0x1b
3170 */ 3445 */
3171static struct hda_verb alc880_pin_5stack_init_verbs[] = { 3446static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
3172 /* 3447 /*
3173 * preset connection lists of input pins 3448 * preset connection lists of input pins
3174 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 3449 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
@@ -3212,7 +3487,7 @@ static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3212 * W810 pin configuration: 3487 * W810 pin configuration:
3213 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b 3488 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3214 */ 3489 */
3215static struct hda_verb alc880_pin_w810_init_verbs[] = { 3490static const struct hda_verb alc880_pin_w810_init_verbs[] = {
3216 /* hphone/speaker input selector: front DAC */ 3491 /* hphone/speaker input selector: front DAC */
3217 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 3492 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3218 3493
@@ -3233,7 +3508,7 @@ static struct hda_verb alc880_pin_w810_init_verbs[] = {
3233 * Z71V pin configuration: 3508 * Z71V pin configuration:
3234 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) 3509 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3235 */ 3510 */
3236static struct hda_verb alc880_pin_z71v_init_verbs[] = { 3511static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
3237 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3512 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3238 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3513 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3239 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3514 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -3252,7 +3527,7 @@ static struct hda_verb alc880_pin_z71v_init_verbs[] = {
3252 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, 3527 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3253 * f-mic = 0x19, line = 0x1a, HP = 0x1b 3528 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3254 */ 3529 */
3255static struct hda_verb alc880_pin_6stack_init_verbs[] = { 3530static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
3256 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3531 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3257 3532
3258 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3533 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -3282,7 +3557,7 @@ static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3282 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, 3557 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3283 * line = 0x1a 3558 * line = 0x1a
3284 */ 3559 */
3285static struct hda_verb alc880_uniwill_init_verbs[] = { 3560static const struct hda_verb alc880_uniwill_init_verbs[] = {
3286 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3561 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3287 3562
3288 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3563 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -3320,7 +3595,7 @@ static struct hda_verb alc880_uniwill_init_verbs[] = {
3320* Uniwill P53 3595* Uniwill P53
3321* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 3596* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3322 */ 3597 */
3323static struct hda_verb alc880_uniwill_p53_init_verbs[] = { 3598static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3324 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3599 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3325 3600
3326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -3349,7 +3624,7 @@ static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3349 { } 3624 { }
3350}; 3625};
3351 3626
3352static struct hda_verb alc880_beep_init_verbs[] = { 3627static const struct hda_verb alc880_beep_init_verbs[] = {
3353 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, 3628 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3354 { } 3629 { }
3355}; 3630};
@@ -3372,11 +3647,13 @@ static void alc880_uniwill_setup(struct hda_codec *codec)
3372 spec->autocfg.hp_pins[0] = 0x14; 3647 spec->autocfg.hp_pins[0] = 0x14;
3373 spec->autocfg.speaker_pins[0] = 0x15; 3648 spec->autocfg.speaker_pins[0] = 0x15;
3374 spec->autocfg.speaker_pins[0] = 0x16; 3649 spec->autocfg.speaker_pins[0] = 0x16;
3650 spec->automute = 1;
3651 spec->automute_mode = ALC_AUTOMUTE_AMP;
3375} 3652}
3376 3653
3377static void alc880_uniwill_init_hook(struct hda_codec *codec) 3654static void alc880_uniwill_init_hook(struct hda_codec *codec)
3378{ 3655{
3379 alc_automute_amp(codec); 3656 alc_hp_automute(codec);
3380 alc88x_simple_mic_automute(codec); 3657 alc88x_simple_mic_automute(codec);
3381} 3658}
3382 3659
@@ -3391,7 +3668,7 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3391 alc88x_simple_mic_automute(codec); 3668 alc88x_simple_mic_automute(codec);
3392 break; 3669 break;
3393 default: 3670 default:
3394 alc_automute_amp_unsol_event(codec, res); 3671 alc_sku_unsol_event(codec, res);
3395 break; 3672 break;
3396 } 3673 }
3397} 3674}
@@ -3402,6 +3679,8 @@ static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3402 3679
3403 spec->autocfg.hp_pins[0] = 0x14; 3680 spec->autocfg.hp_pins[0] = 0x14;
3404 spec->autocfg.speaker_pins[0] = 0x15; 3681 spec->autocfg.speaker_pins[0] = 0x15;
3682 spec->automute = 1;
3683 spec->automute_mode = ALC_AUTOMUTE_AMP;
3405} 3684}
3406 3685
3407static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 3686static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
@@ -3426,14 +3705,14 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3426 if ((res >> 28) == ALC880_DCVOL_EVENT) 3705 if ((res >> 28) == ALC880_DCVOL_EVENT)
3427 alc880_uniwill_p53_dcvol_automute(codec); 3706 alc880_uniwill_p53_dcvol_automute(codec);
3428 else 3707 else
3429 alc_automute_amp_unsol_event(codec, res); 3708 alc_sku_unsol_event(codec, res);
3430} 3709}
3431 3710
3432/* 3711/*
3433 * F1734 pin configuration: 3712 * F1734 pin configuration:
3434 * HP = 0x14, speaker-out = 0x15, mic = 0x18 3713 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3435 */ 3714 */
3436static struct hda_verb alc880_pin_f1734_init_verbs[] = { 3715static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
3437 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01}, 3716 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3438 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3717 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3439 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3718 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -3465,7 +3744,7 @@ static struct hda_verb alc880_pin_f1734_init_verbs[] = {
3465 * ASUS pin configuration: 3744 * ASUS pin configuration:
3466 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a 3745 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3467 */ 3746 */
3468static struct hda_verb alc880_pin_asus_init_verbs[] = { 3747static const struct hda_verb alc880_pin_asus_init_verbs[] = {
3469 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3748 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3470 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3749 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3471 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3750 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
@@ -3499,7 +3778,7 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = {
3499#define alc880_gpio3_init_verbs alc_gpio3_init_verbs 3778#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3500 3779
3501/* Clevo m520g init */ 3780/* Clevo m520g init */
3502static struct hda_verb alc880_pin_clevo_init_verbs[] = { 3781static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
3503 /* headphone output */ 3782 /* headphone output */
3504 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3783 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3505 /* line-out */ 3784 /* line-out */
@@ -3527,7 +3806,7 @@ static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3527 { } 3806 { }
3528}; 3807};
3529 3808
3530static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 3809static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3531 /* change to EAPD mode */ 3810 /* change to EAPD mode */
3532 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3811 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3533 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3812 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
@@ -3565,12 +3844,12 @@ static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3565 */ 3844 */
3566 3845
3567/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ 3846/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3568static hda_nid_t alc880_lg_dac_nids[3] = { 3847static const hda_nid_t alc880_lg_dac_nids[3] = {
3569 0x05, 0x02, 0x03 3848 0x05, 0x02, 0x03
3570}; 3849};
3571 3850
3572/* seems analog CD is not working */ 3851/* seems analog CD is not working */
3573static struct hda_input_mux alc880_lg_capture_source = { 3852static const struct hda_input_mux alc880_lg_capture_source = {
3574 .num_items = 3, 3853 .num_items = 3,
3575 .items = { 3854 .items = {
3576 { "Mic", 0x1 }, 3855 { "Mic", 0x1 },
@@ -3580,34 +3859,34 @@ static struct hda_input_mux alc880_lg_capture_source = {
3580}; 3859};
3581 3860
3582/* 2,4,6 channel modes */ 3861/* 2,4,6 channel modes */
3583static struct hda_verb alc880_lg_ch2_init[] = { 3862static const struct hda_verb alc880_lg_ch2_init[] = {
3584 /* set line-in and mic-in to input */ 3863 /* set line-in and mic-in to input */
3585 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 3864 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3586 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3865 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3587 { } 3866 { }
3588}; 3867};
3589 3868
3590static struct hda_verb alc880_lg_ch4_init[] = { 3869static const struct hda_verb alc880_lg_ch4_init[] = {
3591 /* set line-in to out and mic-in to input */ 3870 /* set line-in to out and mic-in to input */
3592 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3871 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3593 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3872 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3594 { } 3873 { }
3595}; 3874};
3596 3875
3597static struct hda_verb alc880_lg_ch6_init[] = { 3876static const struct hda_verb alc880_lg_ch6_init[] = {
3598 /* set line-in and mic-in to output */ 3877 /* set line-in and mic-in to output */
3599 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3878 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3600 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3879 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3601 { } 3880 { }
3602}; 3881};
3603 3882
3604static struct hda_channel_mode alc880_lg_ch_modes[3] = { 3883static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
3605 { 2, alc880_lg_ch2_init }, 3884 { 2, alc880_lg_ch2_init },
3606 { 4, alc880_lg_ch4_init }, 3885 { 4, alc880_lg_ch4_init },
3607 { 6, alc880_lg_ch6_init }, 3886 { 6, alc880_lg_ch6_init },
3608}; 3887};
3609 3888
3610static struct snd_kcontrol_new alc880_lg_mixer[] = { 3889static const struct snd_kcontrol_new alc880_lg_mixer[] = {
3611 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3890 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3612 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT), 3891 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3613 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3892 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -3632,7 +3911,7 @@ static struct snd_kcontrol_new alc880_lg_mixer[] = {
3632 { } /* end */ 3911 { } /* end */
3633}; 3912};
3634 3913
3635static struct hda_verb alc880_lg_init_verbs[] = { 3914static const struct hda_verb alc880_lg_init_verbs[] = {
3636 /* set capture source to mic-in */ 3915 /* set capture source to mic-in */
3637 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3916 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3638 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3917 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -3670,6 +3949,8 @@ static void alc880_lg_setup(struct hda_codec *codec)
3670 3949
3671 spec->autocfg.hp_pins[0] = 0x1b; 3950 spec->autocfg.hp_pins[0] = 0x1b;
3672 spec->autocfg.speaker_pins[0] = 0x17; 3951 spec->autocfg.speaker_pins[0] = 0x17;
3952 spec->automute = 1;
3953 spec->automute_mode = ALC_AUTOMUTE_AMP;
3673} 3954}
3674 3955
3675/* 3956/*
@@ -3684,7 +3965,7 @@ static void alc880_lg_setup(struct hda_codec *codec)
3684 * SPDIF-Out: 0x1e 3965 * SPDIF-Out: 0x1e
3685 */ 3966 */
3686 3967
3687static struct hda_input_mux alc880_lg_lw_capture_source = { 3968static const struct hda_input_mux alc880_lg_lw_capture_source = {
3688 .num_items = 3, 3969 .num_items = 3,
3689 .items = { 3970 .items = {
3690 { "Mic", 0x0 }, 3971 { "Mic", 0x0 },
@@ -3695,7 +3976,7 @@ static struct hda_input_mux alc880_lg_lw_capture_source = {
3695 3976
3696#define alc880_lg_lw_modes alc880_threestack_modes 3977#define alc880_lg_lw_modes alc880_threestack_modes
3697 3978
3698static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 3979static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3699 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3980 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3700 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 3981 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3701 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3982 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
@@ -3720,7 +4001,7 @@ static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3720 { } /* end */ 4001 { } /* end */
3721}; 4002};
3722 4003
3723static struct hda_verb alc880_lg_lw_init_verbs[] = { 4004static const struct hda_verb alc880_lg_lw_init_verbs[] = {
3724 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 4005 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3725 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 4006 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3726 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 4007 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
@@ -3754,9 +4035,11 @@ static void alc880_lg_lw_setup(struct hda_codec *codec)
3754 4035
3755 spec->autocfg.hp_pins[0] = 0x1b; 4036 spec->autocfg.hp_pins[0] = 0x1b;
3756 spec->autocfg.speaker_pins[0] = 0x14; 4037 spec->autocfg.speaker_pins[0] = 0x14;
4038 spec->automute = 1;
4039 spec->automute_mode = ALC_AUTOMUTE_AMP;
3757} 4040}
3758 4041
3759static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { 4042static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3760 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4043 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3761 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 4044 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3762 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 4045 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -3766,7 +4049,7 @@ static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3766 { } /* end */ 4049 { } /* end */
3767}; 4050};
3768 4051
3769static struct hda_input_mux alc880_medion_rim_capture_source = { 4052static const struct hda_input_mux alc880_medion_rim_capture_source = {
3770 .num_items = 2, 4053 .num_items = 2,
3771 .items = { 4054 .items = {
3772 { "Mic", 0x0 }, 4055 { "Mic", 0x0 },
@@ -3774,7 +4057,7 @@ static struct hda_input_mux alc880_medion_rim_capture_source = {
3774 }, 4057 },
3775}; 4058};
3776 4059
3777static struct hda_verb alc880_medion_rim_init_verbs[] = { 4060static const struct hda_verb alc880_medion_rim_init_verbs[] = {
3778 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 4061 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3779 4062
3780 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4063 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -3801,7 +4084,7 @@ static struct hda_verb alc880_medion_rim_init_verbs[] = {
3801static void alc880_medion_rim_automute(struct hda_codec *codec) 4084static void alc880_medion_rim_automute(struct hda_codec *codec)
3802{ 4085{
3803 struct alc_spec *spec = codec->spec; 4086 struct alc_spec *spec = codec->spec;
3804 alc_automute_amp(codec); 4087 alc_hp_automute(codec);
3805 /* toggle EAPD */ 4088 /* toggle EAPD */
3806 if (spec->jack_present) 4089 if (spec->jack_present)
3807 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); 4090 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
@@ -3825,10 +4108,12 @@ static void alc880_medion_rim_setup(struct hda_codec *codec)
3825 4108
3826 spec->autocfg.hp_pins[0] = 0x14; 4109 spec->autocfg.hp_pins[0] = 0x14;
3827 spec->autocfg.speaker_pins[0] = 0x1b; 4110 spec->autocfg.speaker_pins[0] = 0x1b;
4111 spec->automute = 1;
4112 spec->automute_mode = ALC_AUTOMUTE_AMP;
3828} 4113}
3829 4114
3830#ifdef CONFIG_SND_HDA_POWER_SAVE 4115#ifdef CONFIG_SND_HDA_POWER_SAVE
3831static struct hda_amp_list alc880_loopbacks[] = { 4116static const struct hda_amp_list alc880_loopbacks[] = {
3832 { 0x0b, HDA_INPUT, 0 }, 4117 { 0x0b, HDA_INPUT, 0 },
3833 { 0x0b, HDA_INPUT, 1 }, 4118 { 0x0b, HDA_INPUT, 1 },
3834 { 0x0b, HDA_INPUT, 2 }, 4119 { 0x0b, HDA_INPUT, 2 },
@@ -3837,7 +4122,7 @@ static struct hda_amp_list alc880_loopbacks[] = {
3837 { } /* end */ 4122 { } /* end */
3838}; 4123};
3839 4124
3840static struct hda_amp_list alc880_lg_loopbacks[] = { 4125static const struct hda_amp_list alc880_lg_loopbacks[] = {
3841 { 0x0b, HDA_INPUT, 1 }, 4126 { 0x0b, HDA_INPUT, 1 },
3842 { 0x0b, HDA_INPUT, 6 }, 4127 { 0x0b, HDA_INPUT, 6 },
3843 { 0x0b, HDA_INPUT, 7 }, 4128 { 0x0b, HDA_INPUT, 7 },
@@ -4009,7 +4294,7 @@ static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4009 return 0; 4294 return 0;
4010} 4295}
4011 4296
4012static struct hda_pcm_stream dualmic_pcm_analog_capture = { 4297static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
4013 .substreams = 1, 4298 .substreams = 1,
4014 .channels_min = 2, 4299 .channels_min = 2,
4015 .channels_max = 2, 4300 .channels_max = 2,
@@ -4022,7 +4307,7 @@ static struct hda_pcm_stream dualmic_pcm_analog_capture = {
4022 4307
4023/* 4308/*
4024 */ 4309 */
4025static struct hda_pcm_stream alc880_pcm_analog_playback = { 4310static const struct hda_pcm_stream alc880_pcm_analog_playback = {
4026 .substreams = 1, 4311 .substreams = 1,
4027 .channels_min = 2, 4312 .channels_min = 2,
4028 .channels_max = 8, 4313 .channels_max = 8,
@@ -4034,21 +4319,21 @@ static struct hda_pcm_stream alc880_pcm_analog_playback = {
4034 }, 4319 },
4035}; 4320};
4036 4321
4037static struct hda_pcm_stream alc880_pcm_analog_capture = { 4322static const struct hda_pcm_stream alc880_pcm_analog_capture = {
4038 .substreams = 1, 4323 .substreams = 1,
4039 .channels_min = 2, 4324 .channels_min = 2,
4040 .channels_max = 2, 4325 .channels_max = 2,
4041 /* NID is set in alc_build_pcms */ 4326 /* NID is set in alc_build_pcms */
4042}; 4327};
4043 4328
4044static struct hda_pcm_stream alc880_pcm_analog_alt_playback = { 4329static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4045 .substreams = 1, 4330 .substreams = 1,
4046 .channels_min = 2, 4331 .channels_min = 2,
4047 .channels_max = 2, 4332 .channels_max = 2,
4048 /* NID is set in alc_build_pcms */ 4333 /* NID is set in alc_build_pcms */
4049}; 4334};
4050 4335
4051static struct hda_pcm_stream alc880_pcm_analog_alt_capture = { 4336static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4052 .substreams = 2, /* can be overridden */ 4337 .substreams = 2, /* can be overridden */
4053 .channels_min = 2, 4338 .channels_min = 2,
4054 .channels_max = 2, 4339 .channels_max = 2,
@@ -4059,7 +4344,7 @@ static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4059 }, 4344 },
4060}; 4345};
4061 4346
4062static struct hda_pcm_stream alc880_pcm_digital_playback = { 4347static const struct hda_pcm_stream alc880_pcm_digital_playback = {
4063 .substreams = 1, 4348 .substreams = 1,
4064 .channels_min = 2, 4349 .channels_min = 2,
4065 .channels_max = 2, 4350 .channels_max = 2,
@@ -4072,7 +4357,7 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = {
4072 }, 4357 },
4073}; 4358};
4074 4359
4075static struct hda_pcm_stream alc880_pcm_digital_capture = { 4360static const struct hda_pcm_stream alc880_pcm_digital_capture = {
4076 .substreams = 1, 4361 .substreams = 1,
4077 .channels_min = 2, 4362 .channels_min = 2,
4078 .channels_max = 2, 4363 .channels_max = 2,
@@ -4080,7 +4365,7 @@ static struct hda_pcm_stream alc880_pcm_digital_capture = {
4080}; 4365};
4081 4366
4082/* Used by alc_build_pcms to flag that a PCM has no playback stream */ 4367/* Used by alc_build_pcms to flag that a PCM has no playback stream */
4083static struct hda_pcm_stream alc_pcm_null_stream = { 4368static const struct hda_pcm_stream alc_pcm_null_stream = {
4084 .substreams = 0, 4369 .substreams = 0,
4085 .channels_min = 0, 4370 .channels_min = 0,
4086 .channels_max = 0, 4371 .channels_max = 0,
@@ -4174,7 +4459,7 @@ static int alc_build_pcms(struct hda_codec *codec)
4174 alc_pcm_null_stream; 4459 alc_pcm_null_stream;
4175 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 4460 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4176 } 4461 }
4177 if (spec->num_adc_nids > 1) { 4462 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
4178 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 4463 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4179 *spec->stream_analog_alt_capture; 4464 *spec->stream_analog_alt_capture;
4180 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 4465 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
@@ -4193,6 +4478,10 @@ static int alc_build_pcms(struct hda_codec *codec)
4193 4478
4194static inline void alc_shutup(struct hda_codec *codec) 4479static inline void alc_shutup(struct hda_codec *codec)
4195{ 4480{
4481 struct alc_spec *spec = codec->spec;
4482
4483 if (spec && spec->shutup)
4484 spec->shutup(codec);
4196 snd_hda_shutup_pins(codec); 4485 snd_hda_shutup_pins(codec);
4197} 4486}
4198 4487
@@ -4226,28 +4515,7 @@ static void alc_free(struct hda_codec *codec)
4226#ifdef CONFIG_SND_HDA_POWER_SAVE 4515#ifdef CONFIG_SND_HDA_POWER_SAVE
4227static void alc_power_eapd(struct hda_codec *codec) 4516static void alc_power_eapd(struct hda_codec *codec)
4228{ 4517{
4229 /* We currently only handle front, HP */ 4518 alc_auto_setup_eapd(codec, false);
4230 switch (codec->vendor_id) {
4231 case 0x10ec0260:
4232 set_eapd(codec, 0x0f, 0);
4233 set_eapd(codec, 0x10, 0);
4234 break;
4235 case 0x10ec0262:
4236 case 0x10ec0267:
4237 case 0x10ec0268:
4238 case 0x10ec0269:
4239 case 0x10ec0270:
4240 case 0x10ec0272:
4241 case 0x10ec0660:
4242 case 0x10ec0662:
4243 case 0x10ec0663:
4244 case 0x10ec0665:
4245 case 0x10ec0862:
4246 case 0x10ec0889:
4247 set_eapd(codec, 0x14, 0);
4248 set_eapd(codec, 0x15, 0);
4249 break;
4250 }
4251} 4519}
4252 4520
4253static int alc_suspend(struct hda_codec *codec, pm_message_t state) 4521static int alc_suspend(struct hda_codec *codec, pm_message_t state)
@@ -4263,6 +4531,7 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4263#ifdef SND_HDA_NEEDS_RESUME 4531#ifdef SND_HDA_NEEDS_RESUME
4264static int alc_resume(struct hda_codec *codec) 4532static int alc_resume(struct hda_codec *codec)
4265{ 4533{
4534 msleep(150); /* to avoid pop noise */
4266 codec->patch_ops.init(codec); 4535 codec->patch_ops.init(codec);
4267 snd_hda_codec_resume_amp(codec); 4536 snd_hda_codec_resume_amp(codec);
4268 snd_hda_codec_resume_cache(codec); 4537 snd_hda_codec_resume_cache(codec);
@@ -4273,7 +4542,7 @@ static int alc_resume(struct hda_codec *codec)
4273 4542
4274/* 4543/*
4275 */ 4544 */
4276static struct hda_codec_ops alc_patch_ops = { 4545static const struct hda_codec_ops alc_patch_ops = {
4277 .build_controls = alc_build_controls, 4546 .build_controls = alc_build_controls,
4278 .build_pcms = alc_build_pcms, 4547 .build_pcms = alc_build_pcms,
4279 .init = alc_init, 4548 .init = alc_init,
@@ -4308,11 +4577,11 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name)
4308 * enum controls. 4577 * enum controls.
4309 */ 4578 */
4310#ifdef CONFIG_SND_DEBUG 4579#ifdef CONFIG_SND_DEBUG
4311static hda_nid_t alc880_test_dac_nids[4] = { 4580static const hda_nid_t alc880_test_dac_nids[4] = {
4312 0x02, 0x03, 0x04, 0x05 4581 0x02, 0x03, 0x04, 0x05
4313}; 4582};
4314 4583
4315static struct hda_input_mux alc880_test_capture_source = { 4584static const struct hda_input_mux alc880_test_capture_source = {
4316 .num_items = 7, 4585 .num_items = 7,
4317 .items = { 4586 .items = {
4318 { "In-1", 0x0 }, 4587 { "In-1", 0x0 },
@@ -4325,7 +4594,7 @@ static struct hda_input_mux alc880_test_capture_source = {
4325 }, 4594 },
4326}; 4595};
4327 4596
4328static struct hda_channel_mode alc880_test_modes[4] = { 4597static const struct hda_channel_mode alc880_test_modes[4] = {
4329 { 2, NULL }, 4598 { 2, NULL },
4330 { 4, NULL }, 4599 { 4, NULL },
4331 { 6, NULL }, 4600 { 6, NULL },
@@ -4335,7 +4604,7 @@ static struct hda_channel_mode alc880_test_modes[4] = {
4335static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, 4604static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4336 struct snd_ctl_elem_info *uinfo) 4605 struct snd_ctl_elem_info *uinfo)
4337{ 4606{
4338 static char *texts[] = { 4607 static const char * const texts[] = {
4339 "N/A", "Line Out", "HP Out", 4608 "N/A", "Line Out", "HP Out",
4340 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 4609 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4341 }; 4610 };
@@ -4380,7 +4649,7 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4380{ 4649{
4381 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4650 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4382 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4651 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4383 static unsigned int ctls[] = { 4652 static const unsigned int ctls[] = {
4384 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 4653 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4385 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 4654 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4386 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 4655 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
@@ -4410,7 +4679,7 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4410static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, 4679static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4411 struct snd_ctl_elem_info *uinfo) 4680 struct snd_ctl_elem_info *uinfo)
4412{ 4681{
4413 static char *texts[] = { 4682 static const char * const texts[] = {
4414 "Front", "Surround", "CLFE", "Side" 4683 "Front", "Surround", "CLFE", "Side"
4415 }; 4684 };
4416 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4685 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -4471,7 +4740,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4471 .private_value = nid \ 4740 .private_value = nid \
4472 } 4741 }
4473 4742
4474static struct snd_kcontrol_new alc880_test_mixer[] = { 4743static const struct snd_kcontrol_new alc880_test_mixer[] = {
4475 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4744 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4476 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 4745 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4477 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 4746 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
@@ -4512,7 +4781,7 @@ static struct snd_kcontrol_new alc880_test_mixer[] = {
4512 { } /* end */ 4781 { } /* end */
4513}; 4782};
4514 4783
4515static struct hda_verb alc880_test_init_verbs[] = { 4784static const struct hda_verb alc880_test_init_verbs[] = {
4516 /* Unmute inputs of 0x0c - 0x0f */ 4785 /* Unmute inputs of 0x0c - 0x0f */
4517 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4786 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4518 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4787 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -4596,7 +4865,7 @@ static const char * const alc880_models[ALC880_MODEL_LAST] = {
4596 [ALC880_AUTO] = "auto", 4865 [ALC880_AUTO] = "auto",
4597}; 4866};
4598 4867
4599static struct snd_pci_quirk alc880_cfg_tbl[] = { 4868static const struct snd_pci_quirk alc880_cfg_tbl[] = {
4600 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), 4869 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4601 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), 4870 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4602 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), 4871 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
@@ -4676,7 +4945,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
4676/* 4945/*
4677 * ALC880 codec presets 4946 * ALC880 codec presets
4678 */ 4947 */
4679static struct alc_config_preset alc880_presets[] = { 4948static const struct alc_config_preset alc880_presets[] = {
4680 [ALC880_3ST] = { 4949 [ALC880_3ST] = {
4681 .mixers = { alc880_three_stack_mixer }, 4950 .mixers = { alc880_three_stack_mixer },
4682 .init_verbs = { alc880_volume_init_verbs, 4951 .init_verbs = { alc880_volume_init_verbs,
@@ -4794,7 +5063,7 @@ static struct alc_config_preset alc880_presets[] = {
4794 .input_mux = &alc880_f1734_capture_source, 5063 .input_mux = &alc880_f1734_capture_source,
4795 .unsol_event = alc880_uniwill_p53_unsol_event, 5064 .unsol_event = alc880_uniwill_p53_unsol_event,
4796 .setup = alc880_uniwill_p53_setup, 5065 .setup = alc880_uniwill_p53_setup,
4797 .init_hook = alc_automute_amp, 5066 .init_hook = alc_hp_automute,
4798 }, 5067 },
4799 [ALC880_ASUS] = { 5068 [ALC880_ASUS] = {
4800 .mixers = { alc880_asus_mixer }, 5069 .mixers = { alc880_asus_mixer },
@@ -4885,7 +5154,7 @@ static struct alc_config_preset alc880_presets[] = {
4885 .input_mux = &alc880_capture_source, 5154 .input_mux = &alc880_capture_source,
4886 .unsol_event = alc880_uniwill_p53_unsol_event, 5155 .unsol_event = alc880_uniwill_p53_unsol_event,
4887 .setup = alc880_uniwill_p53_setup, 5156 .setup = alc880_uniwill_p53_setup,
4888 .init_hook = alc_automute_amp, 5157 .init_hook = alc_hp_automute,
4889 }, 5158 },
4890 [ALC880_FUJITSU] = { 5159 [ALC880_FUJITSU] = {
4891 .mixers = { alc880_fujitsu_mixer }, 5160 .mixers = { alc880_fujitsu_mixer },
@@ -4900,7 +5169,7 @@ static struct alc_config_preset alc880_presets[] = {
4900 .input_mux = &alc880_capture_source, 5169 .input_mux = &alc880_capture_source,
4901 .unsol_event = alc880_uniwill_p53_unsol_event, 5170 .unsol_event = alc880_uniwill_p53_unsol_event,
4902 .setup = alc880_uniwill_p53_setup, 5171 .setup = alc880_uniwill_p53_setup,
4903 .init_hook = alc_automute_amp, 5172 .init_hook = alc_hp_automute,
4904 }, 5173 },
4905 [ALC880_CLEVO] = { 5174 [ALC880_CLEVO] = {
4906 .mixers = { alc880_three_stack_mixer }, 5175 .mixers = { alc880_three_stack_mixer },
@@ -4925,9 +5194,9 @@ static struct alc_config_preset alc880_presets[] = {
4925 .channel_mode = alc880_lg_ch_modes, 5194 .channel_mode = alc880_lg_ch_modes,
4926 .need_dac_fix = 1, 5195 .need_dac_fix = 1,
4927 .input_mux = &alc880_lg_capture_source, 5196 .input_mux = &alc880_lg_capture_source,
4928 .unsol_event = alc_automute_amp_unsol_event, 5197 .unsol_event = alc_sku_unsol_event,
4929 .setup = alc880_lg_setup, 5198 .setup = alc880_lg_setup,
4930 .init_hook = alc_automute_amp, 5199 .init_hook = alc_hp_automute,
4931#ifdef CONFIG_SND_HDA_POWER_SAVE 5200#ifdef CONFIG_SND_HDA_POWER_SAVE
4932 .loopbacks = alc880_lg_loopbacks, 5201 .loopbacks = alc880_lg_loopbacks,
4933#endif 5202#endif
@@ -4942,9 +5211,9 @@ static struct alc_config_preset alc880_presets[] = {
4942 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 5211 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4943 .channel_mode = alc880_lg_lw_modes, 5212 .channel_mode = alc880_lg_lw_modes,
4944 .input_mux = &alc880_lg_lw_capture_source, 5213 .input_mux = &alc880_lg_lw_capture_source,
4945 .unsol_event = alc_automute_amp_unsol_event, 5214 .unsol_event = alc_sku_unsol_event,
4946 .setup = alc880_lg_lw_setup, 5215 .setup = alc880_lg_lw_setup,
4947 .init_hook = alc_automute_amp, 5216 .init_hook = alc_hp_automute,
4948 }, 5217 },
4949 [ALC880_MEDION_RIM] = { 5218 [ALC880_MEDION_RIM] = {
4950 .mixers = { alc880_medion_rim_mixer }, 5219 .mixers = { alc880_medion_rim_mixer },
@@ -4984,20 +5253,25 @@ enum {
4984 ALC_CTL_WIDGET_MUTE, 5253 ALC_CTL_WIDGET_MUTE,
4985 ALC_CTL_BIND_MUTE, 5254 ALC_CTL_BIND_MUTE,
4986}; 5255};
4987static struct snd_kcontrol_new alc880_control_templates[] = { 5256static const struct snd_kcontrol_new alc880_control_templates[] = {
4988 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 5257 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4989 HDA_CODEC_MUTE(NULL, 0, 0, 0), 5258 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4990 HDA_BIND_MUTE(NULL, 0, 0, 0), 5259 HDA_BIND_MUTE(NULL, 0, 0, 0),
4991}; 5260};
4992 5261
5262static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5263{
5264 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5265 return snd_array_new(&spec->kctls);
5266}
5267
4993/* add dynamic controls */ 5268/* add dynamic controls */
4994static int add_control(struct alc_spec *spec, int type, const char *name, 5269static int add_control(struct alc_spec *spec, int type, const char *name,
4995 int cidx, unsigned long val) 5270 int cidx, unsigned long val)
4996{ 5271{
4997 struct snd_kcontrol_new *knew; 5272 struct snd_kcontrol_new *knew;
4998 5273
4999 snd_array_init(&spec->kctls, sizeof(*knew), 32); 5274 knew = alc_kcontrol_new(spec);
5000 knew = snd_array_new(&spec->kctls);
5001 if (!knew) 5275 if (!knew)
5002 return -ENOMEM; 5276 return -ENOMEM;
5003 *knew = alc880_control_templates[type]; 5277 *knew = alc880_control_templates[type];
@@ -5055,7 +5329,7 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5055 nid = cfg->line_out_pins[i]; 5329 nid = cfg->line_out_pins[i];
5056 if (alc880_is_fixed_pin(nid)) { 5330 if (alc880_is_fixed_pin(nid)) {
5057 int idx = alc880_fixed_pin_idx(nid); 5331 int idx = alc880_fixed_pin_idx(nid);
5058 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); 5332 spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
5059 assigned[idx] = 1; 5333 assigned[idx] = 1;
5060 } 5334 }
5061 } 5335 }
@@ -5067,7 +5341,7 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5067 /* search for an empty channel */ 5341 /* search for an empty channel */
5068 for (j = 0; j < cfg->line_outs; j++) { 5342 for (j = 0; j < cfg->line_outs; j++) {
5069 if (!assigned[j]) { 5343 if (!assigned[j]) {
5070 spec->multiout.dac_nids[i] = 5344 spec->private_dac_nids[i] =
5071 alc880_idx_to_dac(j); 5345 alc880_idx_to_dac(j);
5072 assigned[j] = 1; 5346 assigned[j] = 1;
5073 break; 5347 break;
@@ -5078,10 +5352,13 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5078 return 0; 5352 return 0;
5079} 5353}
5080 5354
5081static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg, 5355static const char *alc_get_line_out_pfx(struct alc_spec *spec,
5082 bool can_be_master) 5356 bool can_be_master)
5083{ 5357{
5084 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master) 5358 struct auto_pin_cfg *cfg = &spec->autocfg;
5359
5360 if (cfg->line_outs == 1 && !spec->multi_ios &&
5361 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5085 return "Master"; 5362 return "Master";
5086 5363
5087 switch (cfg->line_out_type) { 5364 switch (cfg->line_out_type) {
@@ -5092,7 +5369,7 @@ static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5092 case AUTO_PIN_HP_OUT: 5369 case AUTO_PIN_HP_OUT:
5093 return "Headphone"; 5370 return "Headphone";
5094 default: 5371 default:
5095 if (cfg->line_outs == 1) 5372 if (cfg->line_outs == 1 && !spec->multi_ios)
5096 return "PCM"; 5373 return "PCM";
5097 break; 5374 break;
5098 } 5375 }
@@ -5106,11 +5383,15 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5106 static const char * const chname[4] = { 5383 static const char * const chname[4] = {
5107 "Front", "Surround", NULL /*CLFE*/, "Side" 5384 "Front", "Surround", NULL /*CLFE*/, "Side"
5108 }; 5385 };
5109 const char *pfx = alc_get_line_out_pfx(cfg, false); 5386 const char *pfx = alc_get_line_out_pfx(spec, false);
5110 hda_nid_t nid; 5387 hda_nid_t nid;
5111 int i, err; 5388 int i, err, noutputs;
5112 5389
5113 for (i = 0; i < cfg->line_outs; i++) { 5390 noutputs = cfg->line_outs;
5391 if (spec->multi_ios > 0)
5392 noutputs += spec->multi_ios;
5393
5394 for (i = 0; i < noutputs; i++) {
5114 if (!spec->multiout.dac_nids[i]) 5395 if (!spec->multiout.dac_nids[i])
5115 continue; 5396 continue;
5116 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 5397 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
@@ -5376,6 +5657,8 @@ static void alc880_auto_init_input_src(struct hda_codec *codec)
5376 } 5657 }
5377} 5658}
5378 5659
5660static int alc_auto_add_multi_channel_mode(struct hda_codec *codec);
5661
5379/* parse the BIOS configuration and set up the alc_spec */ 5662/* parse the BIOS configuration and set up the alc_spec */
5380/* return 1 if successful, 0 if the proper config is not found, 5663/* return 1 if successful, 0 if the proper config is not found,
5381 * or a negative error code 5664 * or a negative error code
@@ -5384,7 +5667,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
5384{ 5667{
5385 struct alc_spec *spec = codec->spec; 5668 struct alc_spec *spec = codec->spec;
5386 int err; 5669 int err;
5387 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 5670 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5388 5671
5389 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5672 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5390 alc880_ignore); 5673 alc880_ignore);
@@ -5396,6 +5679,9 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
5396 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 5679 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5397 if (err < 0) 5680 if (err < 0)
5398 return err; 5681 return err;
5682 err = alc_auto_add_multi_channel_mode(codec);
5683 if (err < 0)
5684 return err;
5399 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 5685 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5400 if (err < 0) 5686 if (err < 0)
5401 return err; 5687 return err;
@@ -5467,6 +5753,12 @@ static void fixup_automic_adc(struct hda_codec *codec)
5467 spec->capsrc_nids += i; 5753 spec->capsrc_nids += i;
5468 spec->adc_nids += i; 5754 spec->adc_nids += i;
5469 spec->num_adc_nids = 1; 5755 spec->num_adc_nids = 1;
5756 /* optional dock-mic */
5757 eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5758 if (eidx < 0)
5759 spec->dock_mic.pin = 0;
5760 else
5761 spec->dock_mic.mux_idx = eidx;
5470 return; 5762 return;
5471 } 5763 }
5472 snd_printd(KERN_INFO "hda_codec: %s: " 5764 snd_printd(KERN_INFO "hda_codec: %s: "
@@ -5494,6 +5786,8 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5494 struct alc_spec *spec = codec->spec; 5786 struct alc_spec *spec = codec->spec;
5495 int i; 5787 int i;
5496 5788
5789 if (!pin)
5790 return 0;
5497 for (i = 0; i < spec->num_adc_nids; i++) { 5791 for (i = 0; i < spec->num_adc_nids; i++) {
5498 hda_nid_t cap = spec->capsrc_nids ? 5792 hda_nid_t cap = spec->capsrc_nids ?
5499 spec->capsrc_nids[i] : spec->adc_nids[i]; 5793 spec->capsrc_nids[i] : spec->adc_nids[i];
@@ -5534,6 +5828,7 @@ static void fixup_dual_adc_switch(struct hda_codec *codec)
5534{ 5828{
5535 struct alc_spec *spec = codec->spec; 5829 struct alc_spec *spec = codec->spec;
5536 init_capsrc_for_pin(codec, spec->ext_mic.pin); 5830 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5831 init_capsrc_for_pin(codec, spec->dock_mic.pin);
5537 init_capsrc_for_pin(codec, spec->int_mic.pin); 5832 init_capsrc_for_pin(codec, spec->int_mic.pin);
5538} 5833}
5539 5834
@@ -5550,7 +5845,7 @@ static void alc_init_special_input_src(struct hda_codec *codec)
5550static void set_capture_mixer(struct hda_codec *codec) 5845static void set_capture_mixer(struct hda_codec *codec)
5551{ 5846{
5552 struct alc_spec *spec = codec->spec; 5847 struct alc_spec *spec = codec->spec;
5553 static struct snd_kcontrol_new *caps[2][3] = { 5848 static const struct snd_kcontrol_new *caps[2][3] = {
5554 { alc_capture_mixer_nosrc1, 5849 { alc_capture_mixer_nosrc1,
5555 alc_capture_mixer_nosrc2, 5850 alc_capture_mixer_nosrc2,
5556 alc_capture_mixer_nosrc3 }, 5851 alc_capture_mixer_nosrc3 },
@@ -5576,7 +5871,7 @@ static void set_capture_mixer(struct hda_codec *codec)
5576} 5871}
5577 5872
5578/* fill adc_nids (and capsrc_nids) containing all active input pins */ 5873/* fill adc_nids (and capsrc_nids) containing all active input pins */
5579static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, 5874static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,
5580 int num_nids) 5875 int num_nids)
5581{ 5876{
5582 struct alc_spec *spec = codec->spec; 5877 struct alc_spec *spec = codec->spec;
@@ -5642,10 +5937,11 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5642#define set_beep_amp(spec, nid, idx, dir) \ 5937#define set_beep_amp(spec, nid, idx, dir) \
5643 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 5938 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5644 5939
5645static struct snd_pci_quirk beep_white_list[] = { 5940static const struct snd_pci_quirk beep_white_list[] = {
5646 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), 5941 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5647 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), 5942 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5648 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), 5943 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
5944 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
5649 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), 5945 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5650 {} 5946 {}
5651}; 5947};
@@ -5753,17 +6049,17 @@ static int patch_alc880(struct hda_codec *codec)
5753 * ALC260 support 6049 * ALC260 support
5754 */ 6050 */
5755 6051
5756static hda_nid_t alc260_dac_nids[1] = { 6052static const hda_nid_t alc260_dac_nids[1] = {
5757 /* front */ 6053 /* front */
5758 0x02, 6054 0x02,
5759}; 6055};
5760 6056
5761static hda_nid_t alc260_adc_nids[1] = { 6057static const hda_nid_t alc260_adc_nids[1] = {
5762 /* ADC0 */ 6058 /* ADC0 */
5763 0x04, 6059 0x04,
5764}; 6060};
5765 6061
5766static hda_nid_t alc260_adc_nids_alt[1] = { 6062static const hda_nid_t alc260_adc_nids_alt[1] = {
5767 /* ADC1 */ 6063 /* ADC1 */
5768 0x05, 6064 0x05,
5769}; 6065};
@@ -5771,7 +6067,7 @@ static hda_nid_t alc260_adc_nids_alt[1] = {
5771/* NIDs used when simultaneous access to both ADCs makes sense. Note that 6067/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5772 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 6068 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5773 */ 6069 */
5774static hda_nid_t alc260_dual_adc_nids[2] = { 6070static const hda_nid_t alc260_dual_adc_nids[2] = {
5775 /* ADC0, ADC1 */ 6071 /* ADC0, ADC1 */
5776 0x04, 0x05 6072 0x04, 0x05
5777}; 6073};
@@ -5779,7 +6075,7 @@ static hda_nid_t alc260_dual_adc_nids[2] = {
5779#define ALC260_DIGOUT_NID 0x03 6075#define ALC260_DIGOUT_NID 0x03
5780#define ALC260_DIGIN_NID 0x06 6076#define ALC260_DIGIN_NID 0x06
5781 6077
5782static struct hda_input_mux alc260_capture_source = { 6078static const struct hda_input_mux alc260_capture_source = {
5783 .num_items = 4, 6079 .num_items = 4,
5784 .items = { 6080 .items = {
5785 { "Mic", 0x0 }, 6081 { "Mic", 0x0 },
@@ -5795,7 +6091,7 @@ static struct hda_input_mux alc260_capture_source = {
5795 * recording the mixer output on the second ADC (ADC0 doesn't have a 6091 * recording the mixer output on the second ADC (ADC0 doesn't have a
5796 * connection to the mixer output). 6092 * connection to the mixer output).
5797 */ 6093 */
5798static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { 6094static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5799 { 6095 {
5800 .num_items = 3, 6096 .num_items = 3,
5801 .items = { 6097 .items = {
@@ -5819,7 +6115,7 @@ static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5819/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to 6115/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5820 * the Fujitsu S702x, but jacks are marked differently. 6116 * the Fujitsu S702x, but jacks are marked differently.
5821 */ 6117 */
5822static struct hda_input_mux alc260_acer_capture_sources[2] = { 6118static const struct hda_input_mux alc260_acer_capture_sources[2] = {
5823 { 6119 {
5824 .num_items = 4, 6120 .num_items = 4,
5825 .items = { 6121 .items = {
@@ -5842,7 +6138,7 @@ static struct hda_input_mux alc260_acer_capture_sources[2] = {
5842}; 6138};
5843 6139
5844/* Maxdata Favorit 100XS */ 6140/* Maxdata Favorit 100XS */
5845static struct hda_input_mux alc260_favorit100_capture_sources[2] = { 6141static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5846 { 6142 {
5847 .num_items = 2, 6143 .num_items = 2,
5848 .items = { 6144 .items = {
@@ -5866,7 +6162,7 @@ static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5866 * element which allows changing the channel mode, so the verb list is 6162 * element which allows changing the channel mode, so the verb list is
5867 * never used. 6163 * never used.
5868 */ 6164 */
5869static struct hda_channel_mode alc260_modes[1] = { 6165static const struct hda_channel_mode alc260_modes[1] = {
5870 { 2, NULL }, 6166 { 2, NULL },
5871}; 6167};
5872 6168
@@ -5880,7 +6176,7 @@ static struct hda_channel_mode alc260_modes[1] = {
5880 * acer: acer + capture 6176 * acer: acer + capture
5881 */ 6177 */
5882 6178
5883static struct snd_kcontrol_new alc260_base_output_mixer[] = { 6179static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
5884 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6180 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5885 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 6181 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5886 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6182 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
@@ -5890,7 +6186,7 @@ static struct snd_kcontrol_new alc260_base_output_mixer[] = {
5890 { } /* end */ 6186 { } /* end */
5891}; 6187};
5892 6188
5893static struct snd_kcontrol_new alc260_input_mixer[] = { 6189static const struct snd_kcontrol_new alc260_input_mixer[] = {
5894 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6190 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5895 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6191 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5896 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 6192 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
@@ -5903,21 +6199,14 @@ static struct snd_kcontrol_new alc260_input_mixer[] = {
5903}; 6199};
5904 6200
5905/* update HP, line and mono out pins according to the master switch */ 6201/* update HP, line and mono out pins according to the master switch */
5906static void alc260_hp_master_update(struct hda_codec *codec, 6202static void alc260_hp_master_update(struct hda_codec *codec)
5907 hda_nid_t hp, hda_nid_t line,
5908 hda_nid_t mono)
5909{ 6203{
5910 struct alc_spec *spec = codec->spec; 6204 struct alc_spec *spec = codec->spec;
5911 unsigned int val = spec->master_sw ? PIN_HP : 0; 6205
5912 /* change HP and line-out pins */ 6206 /* change HP pins */
5913 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 6207 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
5914 val); 6208 spec->autocfg.hp_pins, spec->master_mute, true);
5915 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 6209 update_speakers(codec);
5916 val);
5917 /* mono (speaker) depending on the HP jack sense */
5918 val = (val && !spec->jack_present) ? PIN_OUT : 0;
5919 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5920 val);
5921} 6210}
5922 6211
5923static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, 6212static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
@@ -5925,7 +6214,7 @@ static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5925{ 6214{
5926 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 6215 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5927 struct alc_spec *spec = codec->spec; 6216 struct alc_spec *spec = codec->spec;
5928 *ucontrol->value.integer.value = spec->master_sw; 6217 *ucontrol->value.integer.value = !spec->master_mute;
5929 return 0; 6218 return 0;
5930} 6219}
5931 6220
@@ -5934,20 +6223,16 @@ static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5934{ 6223{
5935 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 6224 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5936 struct alc_spec *spec = codec->spec; 6225 struct alc_spec *spec = codec->spec;
5937 int val = !!*ucontrol->value.integer.value; 6226 int val = !*ucontrol->value.integer.value;
5938 hda_nid_t hp, line, mono;
5939 6227
5940 if (val == spec->master_sw) 6228 if (val == spec->master_mute)
5941 return 0; 6229 return 0;
5942 spec->master_sw = val; 6230 spec->master_mute = val;
5943 hp = (kcontrol->private_value >> 16) & 0xff; 6231 alc260_hp_master_update(codec);
5944 line = (kcontrol->private_value >> 8) & 0xff;
5945 mono = kcontrol->private_value & 0xff;
5946 alc260_hp_master_update(codec, hp, line, mono);
5947 return 1; 6232 return 1;
5948} 6233}
5949 6234
5950static struct snd_kcontrol_new alc260_hp_output_mixer[] = { 6235static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5951 { 6236 {
5952 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6237 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5953 .name = "Master Playback Switch", 6238 .name = "Master Playback Switch",
@@ -5955,7 +6240,6 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5955 .info = snd_ctl_boolean_mono_info, 6240 .info = snd_ctl_boolean_mono_info,
5956 .get = alc260_hp_master_sw_get, 6241 .get = alc260_hp_master_sw_get,
5957 .put = alc260_hp_master_sw_put, 6242 .put = alc260_hp_master_sw_put,
5958 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5959 }, 6243 },
5960 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6244 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5961 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 6245 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
@@ -5967,26 +6251,23 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5967 { } /* end */ 6251 { } /* end */
5968}; 6252};
5969 6253
5970static struct hda_verb alc260_hp_unsol_verbs[] = { 6254static const struct hda_verb alc260_hp_unsol_verbs[] = {
5971 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6255 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5972 {}, 6256 {},
5973}; 6257};
5974 6258
5975static void alc260_hp_automute(struct hda_codec *codec) 6259static void alc260_hp_setup(struct hda_codec *codec)
5976{ 6260{
5977 struct alc_spec *spec = codec->spec; 6261 struct alc_spec *spec = codec->spec;
5978 6262
5979 spec->jack_present = snd_hda_jack_detect(codec, 0x10); 6263 spec->autocfg.hp_pins[0] = 0x0f;
5980 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); 6264 spec->autocfg.speaker_pins[0] = 0x10;
5981} 6265 spec->autocfg.speaker_pins[1] = 0x11;
5982 6266 spec->automute = 1;
5983static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res) 6267 spec->automute_mode = ALC_AUTOMUTE_PIN;
5984{
5985 if ((res >> 26) == ALC880_HP_EVENT)
5986 alc260_hp_automute(codec);
5987} 6268}
5988 6269
5989static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 6270static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5990 { 6271 {
5991 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6272 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5992 .name = "Master Playback Switch", 6273 .name = "Master Playback Switch",
@@ -5994,7 +6275,6 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5994 .info = snd_ctl_boolean_mono_info, 6275 .info = snd_ctl_boolean_mono_info,
5995 .get = alc260_hp_master_sw_get, 6276 .get = alc260_hp_master_sw_get,
5996 .put = alc260_hp_master_sw_put, 6277 .put = alc260_hp_master_sw_put,
5997 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
5998 }, 6278 },
5999 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6279 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6000 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 6280 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
@@ -6007,7 +6287,18 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6007 { } /* end */ 6287 { } /* end */
6008}; 6288};
6009 6289
6010static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { 6290static void alc260_hp_3013_setup(struct hda_codec *codec)
6291{
6292 struct alc_spec *spec = codec->spec;
6293
6294 spec->autocfg.hp_pins[0] = 0x15;
6295 spec->autocfg.speaker_pins[0] = 0x10;
6296 spec->autocfg.speaker_pins[1] = 0x11;
6297 spec->automute = 1;
6298 spec->automute_mode = ALC_AUTOMUTE_PIN;
6299}
6300
6301static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6011 .ops = &snd_hda_bind_vol, 6302 .ops = &snd_hda_bind_vol,
6012 .values = { 6303 .values = {
6013 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), 6304 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
@@ -6017,7 +6308,7 @@ static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6017 }, 6308 },
6018}; 6309};
6019 6310
6020static struct hda_bind_ctls alc260_dc7600_bind_switch = { 6311static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
6021 .ops = &snd_hda_bind_sw, 6312 .ops = &snd_hda_bind_sw,
6022 .values = { 6313 .values = {
6023 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), 6314 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
@@ -6026,7 +6317,7 @@ static struct hda_bind_ctls alc260_dc7600_bind_switch = {
6026 }, 6317 },
6027}; 6318};
6028 6319
6029static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { 6320static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6030 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), 6321 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6031 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), 6322 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6032 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), 6323 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
@@ -6034,49 +6325,27 @@ static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6034 { } /* end */ 6325 { } /* end */
6035}; 6326};
6036 6327
6037static struct hda_verb alc260_hp_3013_unsol_verbs[] = { 6328static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6038 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6329 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6039 {}, 6330 {},
6040}; 6331};
6041 6332
6042static void alc260_hp_3013_automute(struct hda_codec *codec) 6333static void alc260_hp_3012_setup(struct hda_codec *codec)
6043{ 6334{
6044 struct alc_spec *spec = codec->spec; 6335 struct alc_spec *spec = codec->spec;
6045 6336
6046 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 6337 spec->autocfg.hp_pins[0] = 0x10;
6047 alc260_hp_master_update(codec, 0x15, 0x10, 0x11); 6338 spec->autocfg.speaker_pins[0] = 0x0f;
6048} 6339 spec->autocfg.speaker_pins[1] = 0x11;
6049 6340 spec->autocfg.speaker_pins[2] = 0x15;
6050static void alc260_hp_3013_unsol_event(struct hda_codec *codec, 6341 spec->automute = 1;
6051 unsigned int res) 6342 spec->automute_mode = ALC_AUTOMUTE_PIN;
6052{
6053 if ((res >> 26) == ALC880_HP_EVENT)
6054 alc260_hp_3013_automute(codec);
6055}
6056
6057static void alc260_hp_3012_automute(struct hda_codec *codec)
6058{
6059 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
6060
6061 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6062 bits);
6063 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6064 bits);
6065 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6066 bits);
6067}
6068
6069static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
6070 unsigned int res)
6071{
6072 if ((res >> 26) == ALC880_HP_EVENT)
6073 alc260_hp_3012_automute(codec);
6074} 6343}
6075 6344
6076/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 6345/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
6077 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 6346 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6078 */ 6347 */
6079static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 6348static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6080 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6349 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6081 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 6350 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
6082 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 6351 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
@@ -6113,7 +6382,7 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6113 * controls for such models. On models without a "mono speaker" the control 6382 * controls for such models. On models without a "mono speaker" the control
6114 * won't do anything. 6383 * won't do anything.
6115 */ 6384 */
6116static struct snd_kcontrol_new alc260_acer_mixer[] = { 6385static const struct snd_kcontrol_new alc260_acer_mixer[] = {
6117 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6386 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6118 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 6387 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6119 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 6388 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
@@ -6134,7 +6403,7 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = {
6134 6403
6135/* Maxdata Favorit 100XS: one output and one input (0x12) jack 6404/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6136 */ 6405 */
6137static struct snd_kcontrol_new alc260_favorit100_mixer[] = { 6406static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6138 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6407 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6139 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 6408 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6140 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 6409 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
@@ -6147,7 +6416,7 @@ static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6147/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, 6416/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6148 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. 6417 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6149 */ 6418 */
6150static struct snd_kcontrol_new alc260_will_mixer[] = { 6419static const struct snd_kcontrol_new alc260_will_mixer[] = {
6151 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6420 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6152 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 6421 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6153 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6422 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
@@ -6164,7 +6433,7 @@ static struct snd_kcontrol_new alc260_will_mixer[] = {
6164/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, 6433/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6165 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. 6434 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6166 */ 6435 */
6167static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { 6436static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6168 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6437 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6169 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 6438 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6170 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
@@ -6181,7 +6450,7 @@ static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6181/* 6450/*
6182 * initialization verbs 6451 * initialization verbs
6183 */ 6452 */
6184static struct hda_verb alc260_init_verbs[] = { 6453static const struct hda_verb alc260_init_verbs[] = {
6185 /* Line In pin widget for input */ 6454 /* Line In pin widget for input */
6186 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6455 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6187 /* CD pin widget for input */ 6456 /* CD pin widget for input */
@@ -6245,7 +6514,7 @@ static struct hda_verb alc260_init_verbs[] = {
6245}; 6514};
6246 6515
6247#if 0 /* should be identical with alc260_init_verbs? */ 6516#if 0 /* should be identical with alc260_init_verbs? */
6248static struct hda_verb alc260_hp_init_verbs[] = { 6517static const struct hda_verb alc260_hp_init_verbs[] = {
6249 /* Headphone and output */ 6518 /* Headphone and output */
6250 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 6519 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6251 /* mono output */ 6520 /* mono output */
@@ -6295,7 +6564,7 @@ static struct hda_verb alc260_hp_init_verbs[] = {
6295}; 6564};
6296#endif 6565#endif
6297 6566
6298static struct hda_verb alc260_hp_3013_init_verbs[] = { 6567static const struct hda_verb alc260_hp_3013_init_verbs[] = {
6299 /* Line out and output */ 6568 /* Line out and output */
6300 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6569 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6301 /* mono output */ 6570 /* mono output */
@@ -6348,7 +6617,7 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = {
6348 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 6617 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6349 * audio = 0x16, internal speaker = 0x10. 6618 * audio = 0x16, internal speaker = 0x10.
6350 */ 6619 */
6351static struct hda_verb alc260_fujitsu_init_verbs[] = { 6620static const struct hda_verb alc260_fujitsu_init_verbs[] = {
6352 /* Disable all GPIOs */ 6621 /* Disable all GPIOs */
6353 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 6622 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6354 /* Internal speaker is connected to headphone pin */ 6623 /* Internal speaker is connected to headphone pin */
@@ -6430,7 +6699,7 @@ static struct hda_verb alc260_fujitsu_init_verbs[] = {
6430/* Initialisation sequence for ALC260 as configured in Acer TravelMate and 6699/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6431 * similar laptops (adapted from Fujitsu init verbs). 6700 * similar laptops (adapted from Fujitsu init verbs).
6432 */ 6701 */
6433static struct hda_verb alc260_acer_init_verbs[] = { 6702static const struct hda_verb alc260_acer_init_verbs[] = {
6434 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 6703 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6435 * the headphone jack. Turn this on and rely on the standard mute 6704 * the headphone jack. Turn this on and rely on the standard mute
6436 * methods whenever the user wants to turn these outputs off. 6705 * methods whenever the user wants to turn these outputs off.
@@ -6518,7 +6787,7 @@ static struct hda_verb alc260_acer_init_verbs[] = {
6518/* Initialisation sequence for Maxdata Favorit 100XS 6787/* Initialisation sequence for Maxdata Favorit 100XS
6519 * (adapted from Acer init verbs). 6788 * (adapted from Acer init verbs).
6520 */ 6789 */
6521static struct hda_verb alc260_favorit100_init_verbs[] = { 6790static const struct hda_verb alc260_favorit100_init_verbs[] = {
6522 /* GPIO 0 enables the output jack. 6791 /* GPIO 0 enables the output jack.
6523 * Turn this on and rely on the standard mute 6792 * Turn this on and rely on the standard mute
6524 * methods whenever the user wants to turn these outputs off. 6793 * methods whenever the user wants to turn these outputs off.
@@ -6598,7 +6867,7 @@ static struct hda_verb alc260_favorit100_init_verbs[] = {
6598 { } 6867 { }
6599}; 6868};
6600 6869
6601static struct hda_verb alc260_will_verbs[] = { 6870static const struct hda_verb alc260_will_verbs[] = {
6602 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6871 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6603 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6872 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6604 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 6873 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -6608,7 +6877,7 @@ static struct hda_verb alc260_will_verbs[] = {
6608 {} 6877 {}
6609}; 6878};
6610 6879
6611static struct hda_verb alc260_replacer_672v_verbs[] = { 6880static const struct hda_verb alc260_replacer_672v_verbs[] = {
6612 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6881 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6613 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6882 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6614 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, 6883 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
@@ -6650,7 +6919,7 @@ static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6650 alc260_replacer_672v_automute(codec); 6919 alc260_replacer_672v_automute(codec);
6651} 6920}
6652 6921
6653static struct hda_verb alc260_hp_dc7600_verbs[] = { 6922static const struct hda_verb alc260_hp_dc7600_verbs[] = {
6654 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 6923 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6655 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 6924 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6656 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6925 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -6668,17 +6937,17 @@ static struct hda_verb alc260_hp_dc7600_verbs[] = {
6668 * configuration. 6937 * configuration.
6669 */ 6938 */
6670#ifdef CONFIG_SND_DEBUG 6939#ifdef CONFIG_SND_DEBUG
6671static hda_nid_t alc260_test_dac_nids[1] = { 6940static const hda_nid_t alc260_test_dac_nids[1] = {
6672 0x02, 6941 0x02,
6673}; 6942};
6674static hda_nid_t alc260_test_adc_nids[2] = { 6943static const hda_nid_t alc260_test_adc_nids[2] = {
6675 0x04, 0x05, 6944 0x04, 0x05,
6676}; 6945};
6677/* For testing the ALC260, each input MUX needs its own definition since 6946/* For testing the ALC260, each input MUX needs its own definition since
6678 * the signal assignments are different. This assumes that the first ADC 6947 * the signal assignments are different. This assumes that the first ADC
6679 * is NID 0x04. 6948 * is NID 0x04.
6680 */ 6949 */
6681static struct hda_input_mux alc260_test_capture_sources[2] = { 6950static const struct hda_input_mux alc260_test_capture_sources[2] = {
6682 { 6951 {
6683 .num_items = 7, 6952 .num_items = 7,
6684 .items = { 6953 .items = {
@@ -6705,7 +6974,7 @@ static struct hda_input_mux alc260_test_capture_sources[2] = {
6705 }, 6974 },
6706 }, 6975 },
6707}; 6976};
6708static struct snd_kcontrol_new alc260_test_mixer[] = { 6977static const struct snd_kcontrol_new alc260_test_mixer[] = {
6709 /* Output driver widgets */ 6978 /* Output driver widgets */
6710 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 6979 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6711 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 6980 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
@@ -6769,7 +7038,7 @@ static struct snd_kcontrol_new alc260_test_mixer[] = {
6769 7038
6770 { } /* end */ 7039 { } /* end */
6771}; 7040};
6772static struct hda_verb alc260_test_init_verbs[] = { 7041static const struct hda_verb alc260_test_init_verbs[] = {
6773 /* Enable all GPIOs as outputs with an initial value of 0 */ 7042 /* Enable all GPIOs as outputs with an initial value of 0 */
6774 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 7043 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6775 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 7044 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
@@ -6907,7 +7176,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6907 7176
6908 spec->multiout.num_dacs = 1; 7177 spec->multiout.num_dacs = 1;
6909 spec->multiout.dac_nids = spec->private_dac_nids; 7178 spec->multiout.dac_nids = spec->private_dac_nids;
6910 spec->multiout.dac_nids[0] = 0x02; 7179 spec->private_dac_nids[0] = 0x02;
6911 7180
6912 nid = cfg->line_out_pins[0]; 7181 nid = cfg->line_out_pins[0];
6913 if (nid) { 7182 if (nid) {
@@ -7005,7 +7274,7 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec)
7005/* 7274/*
7006 * generic initialization of ADC, input mixers and output mixers 7275 * generic initialization of ADC, input mixers and output mixers
7007 */ 7276 */
7008static struct hda_verb alc260_volume_init_verbs[] = { 7277static const struct hda_verb alc260_volume_init_verbs[] = {
7009 /* 7278 /*
7010 * Unmute ADC0-1 and set the default input to mic-in 7279 * Unmute ADC0-1 and set the default input to mic-in
7011 */ 7280 */
@@ -7050,7 +7319,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
7050{ 7319{
7051 struct alc_spec *spec = codec->spec; 7320 struct alc_spec *spec = codec->spec;
7052 int err; 7321 int err;
7053 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 7322 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
7054 7323
7055 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 7324 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7056 alc260_ignore); 7325 alc260_ignore);
@@ -7095,7 +7364,7 @@ static void alc260_auto_init(struct hda_codec *codec)
7095} 7364}
7096 7365
7097#ifdef CONFIG_SND_HDA_POWER_SAVE 7366#ifdef CONFIG_SND_HDA_POWER_SAVE
7098static struct hda_amp_list alc260_loopbacks[] = { 7367static const struct hda_amp_list alc260_loopbacks[] = {
7099 { 0x07, HDA_INPUT, 0 }, 7368 { 0x07, HDA_INPUT, 0 },
7100 { 0x07, HDA_INPUT, 1 }, 7369 { 0x07, HDA_INPUT, 1 },
7101 { 0x07, HDA_INPUT, 2 }, 7370 { 0x07, HDA_INPUT, 2 },
@@ -7122,7 +7391,7 @@ static const struct alc_fixup alc260_fixups[] = {
7122 }, 7391 },
7123}; 7392};
7124 7393
7125static struct snd_pci_quirk alc260_fixup_tbl[] = { 7394static const struct snd_pci_quirk alc260_fixup_tbl[] = {
7126 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), 7395 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7127 {} 7396 {}
7128}; 7397};
@@ -7146,7 +7415,7 @@ static const char * const alc260_models[ALC260_MODEL_LAST] = {
7146 [ALC260_AUTO] = "auto", 7415 [ALC260_AUTO] = "auto",
7147}; 7416};
7148 7417
7149static struct snd_pci_quirk alc260_cfg_tbl[] = { 7418static const struct snd_pci_quirk alc260_cfg_tbl[] = {
7150 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 7419 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7151 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), 7420 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7152 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 7421 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
@@ -7170,7 +7439,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = {
7170 {} 7439 {}
7171}; 7440};
7172 7441
7173static struct alc_config_preset alc260_presets[] = { 7442static const struct alc_config_preset alc260_presets[] = {
7174 [ALC260_BASIC] = { 7443 [ALC260_BASIC] = {
7175 .mixers = { alc260_base_output_mixer, 7444 .mixers = { alc260_base_output_mixer,
7176 alc260_input_mixer }, 7445 alc260_input_mixer },
@@ -7195,8 +7464,9 @@ static struct alc_config_preset alc260_presets[] = {
7195 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7464 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7196 .channel_mode = alc260_modes, 7465 .channel_mode = alc260_modes,
7197 .input_mux = &alc260_capture_source, 7466 .input_mux = &alc260_capture_source,
7198 .unsol_event = alc260_hp_unsol_event, 7467 .unsol_event = alc_sku_unsol_event,
7199 .init_hook = alc260_hp_automute, 7468 .setup = alc260_hp_setup,
7469 .init_hook = alc_inithook,
7200 }, 7470 },
7201 [ALC260_HP_DC7600] = { 7471 [ALC260_HP_DC7600] = {
7202 .mixers = { alc260_hp_dc7600_mixer, 7472 .mixers = { alc260_hp_dc7600_mixer,
@@ -7210,8 +7480,9 @@ static struct alc_config_preset alc260_presets[] = {
7210 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7480 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7211 .channel_mode = alc260_modes, 7481 .channel_mode = alc260_modes,
7212 .input_mux = &alc260_capture_source, 7482 .input_mux = &alc260_capture_source,
7213 .unsol_event = alc260_hp_3012_unsol_event, 7483 .unsol_event = alc_sku_unsol_event,
7214 .init_hook = alc260_hp_3012_automute, 7484 .setup = alc260_hp_3012_setup,
7485 .init_hook = alc_inithook,
7215 }, 7486 },
7216 [ALC260_HP_3013] = { 7487 [ALC260_HP_3013] = {
7217 .mixers = { alc260_hp_3013_mixer, 7488 .mixers = { alc260_hp_3013_mixer,
@@ -7225,8 +7496,9 @@ static struct alc_config_preset alc260_presets[] = {
7225 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7496 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7226 .channel_mode = alc260_modes, 7497 .channel_mode = alc260_modes,
7227 .input_mux = &alc260_capture_source, 7498 .input_mux = &alc260_capture_source,
7228 .unsol_event = alc260_hp_3013_unsol_event, 7499 .unsol_event = alc_sku_unsol_event,
7229 .init_hook = alc260_hp_3013_automute, 7500 .setup = alc260_hp_3013_setup,
7501 .init_hook = alc_inithook,
7230 }, 7502 },
7231 [ALC260_FUJITSU_S702X] = { 7503 [ALC260_FUJITSU_S702X] = {
7232 .mixers = { alc260_fujitsu_mixer }, 7504 .mixers = { alc260_fujitsu_mixer },
@@ -7384,6 +7656,7 @@ static int patch_alc260(struct hda_codec *codec)
7384 codec->patch_ops = alc_patch_ops; 7656 codec->patch_ops = alc_patch_ops;
7385 if (board_config == ALC260_AUTO) 7657 if (board_config == ALC260_AUTO)
7386 spec->init_hook = alc260_auto_init; 7658 spec->init_hook = alc260_auto_init;
7659 spec->shutup = alc_eapd_shutup;
7387#ifdef CONFIG_SND_HDA_POWER_SAVE 7660#ifdef CONFIG_SND_HDA_POWER_SAVE
7388 if (!spec->loopback.amplist) 7661 if (!spec->loopback.amplist)
7389 spec->loopback.amplist = alc260_loopbacks; 7662 spec->loopback.amplist = alc260_loopbacks;
@@ -7411,12 +7684,12 @@ static int patch_alc260(struct hda_codec *codec)
7411#define ALC1200_DIGOUT_NID 0x10 7684#define ALC1200_DIGOUT_NID 0x10
7412 7685
7413 7686
7414static struct hda_channel_mode alc882_ch_modes[1] = { 7687static const struct hda_channel_mode alc882_ch_modes[1] = {
7415 { 8, NULL } 7688 { 8, NULL }
7416}; 7689};
7417 7690
7418/* DACs */ 7691/* DACs */
7419static hda_nid_t alc882_dac_nids[4] = { 7692static const hda_nid_t alc882_dac_nids[4] = {
7420 /* front, rear, clfe, rear_surr */ 7693 /* front, rear, clfe, rear_surr */
7421 0x02, 0x03, 0x04, 0x05 7694 0x02, 0x03, 0x04, 0x05
7422}; 7695};
@@ -7426,20 +7699,20 @@ static hda_nid_t alc882_dac_nids[4] = {
7426#define alc882_adc_nids alc880_adc_nids 7699#define alc882_adc_nids alc880_adc_nids
7427#define alc882_adc_nids_alt alc880_adc_nids_alt 7700#define alc882_adc_nids_alt alc880_adc_nids_alt
7428#define alc883_adc_nids alc882_adc_nids_alt 7701#define alc883_adc_nids alc882_adc_nids_alt
7429static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; 7702static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7430static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; 7703static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7431#define alc889_adc_nids alc880_adc_nids 7704#define alc889_adc_nids alc880_adc_nids
7432 7705
7433static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; 7706static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7434static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; 7707static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7435#define alc883_capsrc_nids alc882_capsrc_nids_alt 7708#define alc883_capsrc_nids alc882_capsrc_nids_alt
7436static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; 7709static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7437#define alc889_capsrc_nids alc882_capsrc_nids 7710#define alc889_capsrc_nids alc882_capsrc_nids
7438 7711
7439/* input MUX */ 7712/* input MUX */
7440/* FIXME: should be a matrix-type input source selection */ 7713/* FIXME: should be a matrix-type input source selection */
7441 7714
7442static struct hda_input_mux alc882_capture_source = { 7715static const struct hda_input_mux alc882_capture_source = {
7443 .num_items = 4, 7716 .num_items = 4,
7444 .items = { 7717 .items = {
7445 { "Mic", 0x0 }, 7718 { "Mic", 0x0 },
@@ -7451,7 +7724,7 @@ static struct hda_input_mux alc882_capture_source = {
7451 7724
7452#define alc883_capture_source alc882_capture_source 7725#define alc883_capture_source alc882_capture_source
7453 7726
7454static struct hda_input_mux alc889_capture_source = { 7727static const struct hda_input_mux alc889_capture_source = {
7455 .num_items = 3, 7728 .num_items = 3,
7456 .items = { 7729 .items = {
7457 { "Front Mic", 0x0 }, 7730 { "Front Mic", 0x0 },
@@ -7460,7 +7733,7 @@ static struct hda_input_mux alc889_capture_source = {
7460 }, 7733 },
7461}; 7734};
7462 7735
7463static struct hda_input_mux mb5_capture_source = { 7736static const struct hda_input_mux mb5_capture_source = {
7464 .num_items = 3, 7737 .num_items = 3,
7465 .items = { 7738 .items = {
7466 { "Mic", 0x1 }, 7739 { "Mic", 0x1 },
@@ -7469,7 +7742,7 @@ static struct hda_input_mux mb5_capture_source = {
7469 }, 7742 },
7470}; 7743};
7471 7744
7472static struct hda_input_mux macmini3_capture_source = { 7745static const struct hda_input_mux macmini3_capture_source = {
7473 .num_items = 2, 7746 .num_items = 2,
7474 .items = { 7747 .items = {
7475 { "Line", 0x2 }, 7748 { "Line", 0x2 },
@@ -7477,7 +7750,7 @@ static struct hda_input_mux macmini3_capture_source = {
7477 }, 7750 },
7478}; 7751};
7479 7752
7480static struct hda_input_mux alc883_3stack_6ch_intel = { 7753static const struct hda_input_mux alc883_3stack_6ch_intel = {
7481 .num_items = 4, 7754 .num_items = 4,
7482 .items = { 7755 .items = {
7483 { "Mic", 0x1 }, 7756 { "Mic", 0x1 },
@@ -7487,7 +7760,7 @@ static struct hda_input_mux alc883_3stack_6ch_intel = {
7487 }, 7760 },
7488}; 7761};
7489 7762
7490static struct hda_input_mux alc883_lenovo_101e_capture_source = { 7763static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
7491 .num_items = 2, 7764 .num_items = 2,
7492 .items = { 7765 .items = {
7493 { "Mic", 0x1 }, 7766 { "Mic", 0x1 },
@@ -7495,7 +7768,7 @@ static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7495 }, 7768 },
7496}; 7769};
7497 7770
7498static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { 7771static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7499 .num_items = 4, 7772 .num_items = 4,
7500 .items = { 7773 .items = {
7501 { "Mic", 0x0 }, 7774 { "Mic", 0x0 },
@@ -7505,7 +7778,7 @@ static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7505 }, 7778 },
7506}; 7779};
7507 7780
7508static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { 7781static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7509 .num_items = 2, 7782 .num_items = 2,
7510 .items = { 7783 .items = {
7511 { "Mic", 0x0 }, 7784 { "Mic", 0x0 },
@@ -7513,7 +7786,7 @@ static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7513 }, 7786 },
7514}; 7787};
7515 7788
7516static struct hda_input_mux alc883_lenovo_sky_capture_source = { 7789static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
7517 .num_items = 3, 7790 .num_items = 3,
7518 .items = { 7791 .items = {
7519 { "Mic", 0x0 }, 7792 { "Mic", 0x0 },
@@ -7522,7 +7795,7 @@ static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7522 }, 7795 },
7523}; 7796};
7524 7797
7525static struct hda_input_mux alc883_asus_eee1601_capture_source = { 7798static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
7526 .num_items = 2, 7799 .num_items = 2,
7527 .items = { 7800 .items = {
7528 { "Mic", 0x0 }, 7801 { "Mic", 0x0 },
@@ -7530,7 +7803,7 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7530 }, 7803 },
7531}; 7804};
7532 7805
7533static struct hda_input_mux alc889A_mb31_capture_source = { 7806static const struct hda_input_mux alc889A_mb31_capture_source = {
7534 .num_items = 2, 7807 .num_items = 2,
7535 .items = { 7808 .items = {
7536 { "Mic", 0x0 }, 7809 { "Mic", 0x0 },
@@ -7541,7 +7814,7 @@ static struct hda_input_mux alc889A_mb31_capture_source = {
7541 }, 7814 },
7542}; 7815};
7543 7816
7544static struct hda_input_mux alc889A_imac91_capture_source = { 7817static const struct hda_input_mux alc889A_imac91_capture_source = {
7545 .num_items = 2, 7818 .num_items = 2,
7546 .items = { 7819 .items = {
7547 { "Mic", 0x01 }, 7820 { "Mic", 0x01 },
@@ -7552,14 +7825,14 @@ static struct hda_input_mux alc889A_imac91_capture_source = {
7552/* 7825/*
7553 * 2ch mode 7826 * 2ch mode
7554 */ 7827 */
7555static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 7828static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7556 { 2, NULL } 7829 { 2, NULL }
7557}; 7830};
7558 7831
7559/* 7832/*
7560 * 2ch mode 7833 * 2ch mode
7561 */ 7834 */
7562static struct hda_verb alc882_3ST_ch2_init[] = { 7835static const struct hda_verb alc882_3ST_ch2_init[] = {
7563 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7836 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7564 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7837 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7565 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7838 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
@@ -7570,7 +7843,7 @@ static struct hda_verb alc882_3ST_ch2_init[] = {
7570/* 7843/*
7571 * 4ch mode 7844 * 4ch mode
7572 */ 7845 */
7573static struct hda_verb alc882_3ST_ch4_init[] = { 7846static const struct hda_verb alc882_3ST_ch4_init[] = {
7574 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7847 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7575 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7848 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7576 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7849 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -7582,7 +7855,7 @@ static struct hda_verb alc882_3ST_ch4_init[] = {
7582/* 7855/*
7583 * 6ch mode 7856 * 6ch mode
7584 */ 7857 */
7585static struct hda_verb alc882_3ST_ch6_init[] = { 7858static const struct hda_verb alc882_3ST_ch6_init[] = {
7586 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7859 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7587 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7860 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7588 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7861 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
@@ -7592,7 +7865,7 @@ static struct hda_verb alc882_3ST_ch6_init[] = {
7592 { } /* end */ 7865 { } /* end */
7593}; 7866};
7594 7867
7595static struct hda_channel_mode alc882_3ST_6ch_modes[3] = { 7868static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7596 { 2, alc882_3ST_ch2_init }, 7869 { 2, alc882_3ST_ch2_init },
7597 { 4, alc882_3ST_ch4_init }, 7870 { 4, alc882_3ST_ch4_init },
7598 { 6, alc882_3ST_ch6_init }, 7871 { 6, alc882_3ST_ch6_init },
@@ -7603,7 +7876,7 @@ static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7603/* 7876/*
7604 * 2ch mode 7877 * 2ch mode
7605 */ 7878 */
7606static struct hda_verb alc883_3ST_ch2_clevo_init[] = { 7879static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7607 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 7880 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7608 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7881 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7609 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7882 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
@@ -7615,7 +7888,7 @@ static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7615/* 7888/*
7616 * 4ch mode 7889 * 4ch mode
7617 */ 7890 */
7618static struct hda_verb alc883_3ST_ch4_clevo_init[] = { 7891static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7619 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7892 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7620 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7893 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7621 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7894 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
@@ -7628,7 +7901,7 @@ static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7628/* 7901/*
7629 * 6ch mode 7902 * 6ch mode
7630 */ 7903 */
7631static struct hda_verb alc883_3ST_ch6_clevo_init[] = { 7904static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7632 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7905 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7633 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7906 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7634 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7907 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
@@ -7639,7 +7912,7 @@ static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7639 { } /* end */ 7912 { } /* end */
7640}; 7913};
7641 7914
7642static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { 7915static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7643 { 2, alc883_3ST_ch2_clevo_init }, 7916 { 2, alc883_3ST_ch2_clevo_init },
7644 { 4, alc883_3ST_ch4_clevo_init }, 7917 { 4, alc883_3ST_ch4_clevo_init },
7645 { 6, alc883_3ST_ch6_clevo_init }, 7918 { 6, alc883_3ST_ch6_clevo_init },
@@ -7649,7 +7922,7 @@ static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7649/* 7922/*
7650 * 6ch mode 7923 * 6ch mode
7651 */ 7924 */
7652static struct hda_verb alc882_sixstack_ch6_init[] = { 7925static const struct hda_verb alc882_sixstack_ch6_init[] = {
7653 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7926 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7654 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7927 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7655 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7928 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -7660,7 +7933,7 @@ static struct hda_verb alc882_sixstack_ch6_init[] = {
7660/* 7933/*
7661 * 8ch mode 7934 * 8ch mode
7662 */ 7935 */
7663static struct hda_verb alc882_sixstack_ch8_init[] = { 7936static const struct hda_verb alc882_sixstack_ch8_init[] = {
7664 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7937 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7665 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7938 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7666 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7939 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -7668,7 +7941,7 @@ static struct hda_verb alc882_sixstack_ch8_init[] = {
7668 { } /* end */ 7941 { } /* end */
7669}; 7942};
7670 7943
7671static struct hda_channel_mode alc882_sixstack_modes[2] = { 7944static const struct hda_channel_mode alc882_sixstack_modes[2] = {
7672 { 6, alc882_sixstack_ch6_init }, 7945 { 6, alc882_sixstack_ch6_init },
7673 { 8, alc882_sixstack_ch8_init }, 7946 { 8, alc882_sixstack_ch8_init },
7674}; 7947};
@@ -7676,7 +7949,7 @@ static struct hda_channel_mode alc882_sixstack_modes[2] = {
7676 7949
7677/* Macbook Air 2,1 */ 7950/* Macbook Air 2,1 */
7678 7951
7679static struct hda_channel_mode alc885_mba21_ch_modes[1] = { 7952static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7680 { 2, NULL }, 7953 { 2, NULL },
7681}; 7954};
7682 7955
@@ -7687,7 +7960,7 @@ static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7687/* 7960/*
7688 * 2ch mode 7961 * 2ch mode
7689 */ 7962 */
7690static struct hda_verb alc885_mbp_ch2_init[] = { 7963static const struct hda_verb alc885_mbp_ch2_init[] = {
7691 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7964 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7692 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7965 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7693 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7966 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
@@ -7697,7 +7970,7 @@ static struct hda_verb alc885_mbp_ch2_init[] = {
7697/* 7970/*
7698 * 4ch mode 7971 * 4ch mode
7699 */ 7972 */
7700static struct hda_verb alc885_mbp_ch4_init[] = { 7973static const struct hda_verb alc885_mbp_ch4_init[] = {
7701 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7974 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7702 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7975 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7703 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7976 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
@@ -7706,7 +7979,7 @@ static struct hda_verb alc885_mbp_ch4_init[] = {
7706 { } /* end */ 7979 { } /* end */
7707}; 7980};
7708 7981
7709static struct hda_channel_mode alc885_mbp_4ch_modes[2] = { 7982static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7710 { 2, alc885_mbp_ch2_init }, 7983 { 2, alc885_mbp_ch2_init },
7711 { 4, alc885_mbp_ch4_init }, 7984 { 4, alc885_mbp_ch4_init },
7712}; 7985};
@@ -7716,7 +7989,7 @@ static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7716 * Speakers/Woofer/HP = Front 7989 * Speakers/Woofer/HP = Front
7717 * LineIn = Input 7990 * LineIn = Input
7718 */ 7991 */
7719static struct hda_verb alc885_mb5_ch2_init[] = { 7992static const struct hda_verb alc885_mb5_ch2_init[] = {
7720 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7993 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7721 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7994 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7722 { } /* end */ 7995 { } /* end */
@@ -7728,14 +8001,14 @@ static struct hda_verb alc885_mb5_ch2_init[] = {
7728 * Woofer = LFE 8001 * Woofer = LFE
7729 * LineIn = Surround 8002 * LineIn = Surround
7730 */ 8003 */
7731static struct hda_verb alc885_mb5_ch6_init[] = { 8004static const struct hda_verb alc885_mb5_ch6_init[] = {
7732 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8005 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7733 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8006 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7734 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 8007 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7735 { } /* end */ 8008 { } /* end */
7736}; 8009};
7737 8010
7738static struct hda_channel_mode alc885_mb5_6ch_modes[2] = { 8011static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7739 { 2, alc885_mb5_ch2_init }, 8012 { 2, alc885_mb5_ch2_init },
7740 { 6, alc885_mb5_ch6_init }, 8013 { 6, alc885_mb5_ch6_init },
7741}; 8014};
@@ -7745,7 +8018,7 @@ static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7745/* 8018/*
7746 * 2ch mode 8019 * 2ch mode
7747 */ 8020 */
7748static struct hda_verb alc883_4ST_ch2_init[] = { 8021static const struct hda_verb alc883_4ST_ch2_init[] = {
7749 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8022 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7750 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8023 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7751 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 8024 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
@@ -7758,7 +8031,7 @@ static struct hda_verb alc883_4ST_ch2_init[] = {
7758/* 8031/*
7759 * 4ch mode 8032 * 4ch mode
7760 */ 8033 */
7761static struct hda_verb alc883_4ST_ch4_init[] = { 8034static const struct hda_verb alc883_4ST_ch4_init[] = {
7762 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8035 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7763 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8036 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7764 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 8037 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
@@ -7772,7 +8045,7 @@ static struct hda_verb alc883_4ST_ch4_init[] = {
7772/* 8045/*
7773 * 6ch mode 8046 * 6ch mode
7774 */ 8047 */
7775static struct hda_verb alc883_4ST_ch6_init[] = { 8048static const struct hda_verb alc883_4ST_ch6_init[] = {
7776 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8049 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7777 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8050 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7778 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8051 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -7787,7 +8060,7 @@ static struct hda_verb alc883_4ST_ch6_init[] = {
7787/* 8060/*
7788 * 8ch mode 8061 * 8ch mode
7789 */ 8062 */
7790static struct hda_verb alc883_4ST_ch8_init[] = { 8063static const struct hda_verb alc883_4ST_ch8_init[] = {
7791 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8064 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7792 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8065 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7793 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 8066 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
@@ -7800,7 +8073,7 @@ static struct hda_verb alc883_4ST_ch8_init[] = {
7800 { } /* end */ 8073 { } /* end */
7801}; 8074};
7802 8075
7803static struct hda_channel_mode alc883_4ST_8ch_modes[4] = { 8076static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7804 { 2, alc883_4ST_ch2_init }, 8077 { 2, alc883_4ST_ch2_init },
7805 { 4, alc883_4ST_ch4_init }, 8078 { 4, alc883_4ST_ch4_init },
7806 { 6, alc883_4ST_ch6_init }, 8079 { 6, alc883_4ST_ch6_init },
@@ -7811,7 +8084,7 @@ static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7811/* 8084/*
7812 * 2ch mode 8085 * 2ch mode
7813 */ 8086 */
7814static struct hda_verb alc883_3ST_ch2_intel_init[] = { 8087static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
7815 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 8088 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7816 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 8089 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7817 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 8090 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
@@ -7822,7 +8095,7 @@ static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7822/* 8095/*
7823 * 4ch mode 8096 * 4ch mode
7824 */ 8097 */
7825static struct hda_verb alc883_3ST_ch4_intel_init[] = { 8098static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
7826 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 8099 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7827 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 8100 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7828 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8101 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -7834,7 +8107,7 @@ static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7834/* 8107/*
7835 * 6ch mode 8108 * 6ch mode
7836 */ 8109 */
7837static struct hda_verb alc883_3ST_ch6_intel_init[] = { 8110static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
7838 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8111 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7839 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8112 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7840 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, 8113 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
@@ -7844,7 +8117,7 @@ static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7844 { } /* end */ 8117 { } /* end */
7845}; 8118};
7846 8119
7847static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { 8120static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7848 { 2, alc883_3ST_ch2_intel_init }, 8121 { 2, alc883_3ST_ch2_intel_init },
7849 { 4, alc883_3ST_ch4_intel_init }, 8122 { 4, alc883_3ST_ch4_intel_init },
7850 { 6, alc883_3ST_ch6_intel_init }, 8123 { 6, alc883_3ST_ch6_intel_init },
@@ -7853,7 +8126,7 @@ static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7853/* 8126/*
7854 * 2ch mode 8127 * 2ch mode
7855 */ 8128 */
7856static struct hda_verb alc889_ch2_intel_init[] = { 8129static const struct hda_verb alc889_ch2_intel_init[] = {
7857 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8130 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7858 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8131 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7859 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8132 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
@@ -7866,7 +8139,7 @@ static struct hda_verb alc889_ch2_intel_init[] = {
7866/* 8139/*
7867 * 6ch mode 8140 * 6ch mode
7868 */ 8141 */
7869static struct hda_verb alc889_ch6_intel_init[] = { 8142static const struct hda_verb alc889_ch6_intel_init[] = {
7870 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8143 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7871 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 8144 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7872 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 8145 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
@@ -7879,7 +8152,7 @@ static struct hda_verb alc889_ch6_intel_init[] = {
7879/* 8152/*
7880 * 8ch mode 8153 * 8ch mode
7881 */ 8154 */
7882static struct hda_verb alc889_ch8_intel_init[] = { 8155static const struct hda_verb alc889_ch8_intel_init[] = {
7883 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8156 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7884 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 8157 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7885 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 8158 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
@@ -7890,7 +8163,7 @@ static struct hda_verb alc889_ch8_intel_init[] = {
7890 { } /* end */ 8163 { } /* end */
7891}; 8164};
7892 8165
7893static struct hda_channel_mode alc889_8ch_intel_modes[3] = { 8166static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7894 { 2, alc889_ch2_intel_init }, 8167 { 2, alc889_ch2_intel_init },
7895 { 6, alc889_ch6_intel_init }, 8168 { 6, alc889_ch6_intel_init },
7896 { 8, alc889_ch8_intel_init }, 8169 { 8, alc889_ch8_intel_init },
@@ -7899,7 +8172,7 @@ static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7899/* 8172/*
7900 * 6ch mode 8173 * 6ch mode
7901 */ 8174 */
7902static struct hda_verb alc883_sixstack_ch6_init[] = { 8175static const struct hda_verb alc883_sixstack_ch6_init[] = {
7903 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 8176 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7904 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8177 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7905 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8178 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -7910,7 +8183,7 @@ static struct hda_verb alc883_sixstack_ch6_init[] = {
7910/* 8183/*
7911 * 8ch mode 8184 * 8ch mode
7912 */ 8185 */
7913static struct hda_verb alc883_sixstack_ch8_init[] = { 8186static const struct hda_verb alc883_sixstack_ch8_init[] = {
7914 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8187 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7915 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8188 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7916 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8189 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -7918,7 +8191,7 @@ static struct hda_verb alc883_sixstack_ch8_init[] = {
7918 { } /* end */ 8191 { } /* end */
7919}; 8192};
7920 8193
7921static struct hda_channel_mode alc883_sixstack_modes[2] = { 8194static const struct hda_channel_mode alc883_sixstack_modes[2] = {
7922 { 6, alc883_sixstack_ch6_init }, 8195 { 6, alc883_sixstack_ch6_init },
7923 { 8, alc883_sixstack_ch8_init }, 8196 { 8, alc883_sixstack_ch8_init },
7924}; 8197};
@@ -7927,7 +8200,7 @@ static struct hda_channel_mode alc883_sixstack_modes[2] = {
7927/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 8200/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7928 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 8201 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7929 */ 8202 */
7930static struct snd_kcontrol_new alc882_base_mixer[] = { 8203static const struct snd_kcontrol_new alc882_base_mixer[] = {
7931 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8204 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7932 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8205 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7933 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8206 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -7954,14 +8227,14 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
7954 8227
7955/* Macbook Air 2,1 same control for HP and internal Speaker */ 8228/* Macbook Air 2,1 same control for HP and internal Speaker */
7956 8229
7957static struct snd_kcontrol_new alc885_mba21_mixer[] = { 8230static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
7958 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8231 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7959 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT), 8232 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7960 { } 8233 { }
7961}; 8234};
7962 8235
7963 8236
7964static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 8237static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7965 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8238 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7966 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 8239 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7967 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 8240 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
@@ -7976,7 +8249,7 @@ static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7976 { } /* end */ 8249 { } /* end */
7977}; 8250};
7978 8251
7979static struct snd_kcontrol_new alc885_mb5_mixer[] = { 8252static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
7980 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8253 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7981 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 8254 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7982 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 8255 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
@@ -7994,7 +8267,7 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7994 { } /* end */ 8267 { } /* end */
7995}; 8268};
7996 8269
7997static struct snd_kcontrol_new alc885_macmini3_mixer[] = { 8270static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7998 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8271 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7999 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 8272 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8000 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 8273 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
@@ -8009,14 +8282,14 @@ static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8009 { } /* end */ 8282 { } /* end */
8010}; 8283};
8011 8284
8012static struct snd_kcontrol_new alc885_imac91_mixer[] = { 8285static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
8013 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8286 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8014 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 8287 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8015 { } /* end */ 8288 { } /* end */
8016}; 8289};
8017 8290
8018 8291
8019static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 8292static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8020 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8293 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8021 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8294 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8022 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8295 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -8029,7 +8302,7 @@ static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8029 { } /* end */ 8302 { } /* end */
8030}; 8303};
8031 8304
8032static struct snd_kcontrol_new alc882_targa_mixer[] = { 8305static const struct snd_kcontrol_new alc882_targa_mixer[] = {
8033 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8306 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8034 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8307 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8035 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8308 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
@@ -8049,7 +8322,7 @@ static struct snd_kcontrol_new alc882_targa_mixer[] = {
8049/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? 8322/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8050 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c 8323 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8051 */ 8324 */
8052static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { 8325static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8053 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8326 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8054 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8327 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8055 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8328 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -8066,7 +8339,7 @@ static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8066 { } /* end */ 8339 { } /* end */
8067}; 8340};
8068 8341
8069static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { 8342static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8070 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8343 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8071 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8344 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8072 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8345 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -8080,7 +8353,7 @@ static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8080 { } /* end */ 8353 { } /* end */
8081}; 8354};
8082 8355
8083static struct snd_kcontrol_new alc882_chmode_mixer[] = { 8356static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
8084 { 8357 {
8085 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8358 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8086 .name = "Channel Mode", 8359 .name = "Channel Mode",
@@ -8091,7 +8364,7 @@ static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8091 { } /* end */ 8364 { } /* end */
8092}; 8365};
8093 8366
8094static struct hda_verb alc882_base_init_verbs[] = { 8367static const struct hda_verb alc882_base_init_verbs[] = {
8095 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8368 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8096 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8369 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8097 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
@@ -8153,7 +8426,7 @@ static struct hda_verb alc882_base_init_verbs[] = {
8153 { } 8426 { }
8154}; 8427};
8155 8428
8156static struct hda_verb alc882_adc1_init_verbs[] = { 8429static const struct hda_verb alc882_adc1_init_verbs[] = {
8157 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8430 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8158 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8431 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8159 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8432 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
@@ -8165,26 +8438,26 @@ static struct hda_verb alc882_adc1_init_verbs[] = {
8165 { } 8438 { }
8166}; 8439};
8167 8440
8168static struct hda_verb alc882_eapd_verbs[] = { 8441static const struct hda_verb alc882_eapd_verbs[] = {
8169 /* change to EAPD mode */ 8442 /* change to EAPD mode */
8170 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8443 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8171 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 8444 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8172 { } 8445 { }
8173}; 8446};
8174 8447
8175static struct hda_verb alc889_eapd_verbs[] = { 8448static const struct hda_verb alc889_eapd_verbs[] = {
8176 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8449 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8177 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8450 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8178 { } 8451 { }
8179}; 8452};
8180 8453
8181static struct hda_verb alc_hp15_unsol_verbs[] = { 8454static const struct hda_verb alc_hp15_unsol_verbs[] = {
8182 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 8455 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8183 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8456 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8184 {} 8457 {}
8185}; 8458};
8186 8459
8187static struct hda_verb alc885_init_verbs[] = { 8460static const struct hda_verb alc885_init_verbs[] = {
8188 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8461 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8189 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8462 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8190 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -8243,7 +8516,7 @@ static struct hda_verb alc885_init_verbs[] = {
8243 { } 8516 { }
8244}; 8517};
8245 8518
8246static struct hda_verb alc885_init_input_verbs[] = { 8519static const struct hda_verb alc885_init_input_verbs[] = {
8247 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8520 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8248 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 8521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8249 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 8522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
@@ -8252,7 +8525,7 @@ static struct hda_verb alc885_init_input_verbs[] = {
8252 8525
8253 8526
8254/* Unmute Selector 24h and set the default input to front mic */ 8527/* Unmute Selector 24h and set the default input to front mic */
8255static struct hda_verb alc889_init_input_verbs[] = { 8528static const struct hda_verb alc889_init_input_verbs[] = {
8256 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 8529 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8257 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8530 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8258 { } 8531 { }
@@ -8262,7 +8535,7 @@ static struct hda_verb alc889_init_input_verbs[] = {
8262#define alc883_init_verbs alc882_base_init_verbs 8535#define alc883_init_verbs alc882_base_init_verbs
8263 8536
8264/* Mac Pro test */ 8537/* Mac Pro test */
8265static struct snd_kcontrol_new alc882_macpro_mixer[] = { 8538static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
8266 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8539 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8267 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8540 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8268 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), 8541 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
@@ -8275,7 +8548,7 @@ static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8275 { } /* end */ 8548 { } /* end */
8276}; 8549};
8277 8550
8278static struct hda_verb alc882_macpro_init_verbs[] = { 8551static const struct hda_verb alc882_macpro_init_verbs[] = {
8279 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8552 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8280 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8553 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8281 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8554 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -8327,7 +8600,7 @@ static struct hda_verb alc882_macpro_init_verbs[] = {
8327}; 8600};
8328 8601
8329/* Macbook 5,1 */ 8602/* Macbook 5,1 */
8330static struct hda_verb alc885_mb5_init_verbs[] = { 8603static const struct hda_verb alc885_mb5_init_verbs[] = {
8331 /* DACs */ 8604 /* DACs */
8332 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8605 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8333 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8606 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -8376,7 +8649,7 @@ static struct hda_verb alc885_mb5_init_verbs[] = {
8376}; 8649};
8377 8650
8378/* Macmini 3,1 */ 8651/* Macmini 3,1 */
8379static struct hda_verb alc885_macmini3_init_verbs[] = { 8652static const struct hda_verb alc885_macmini3_init_verbs[] = {
8380 /* DACs */ 8653 /* DACs */
8381 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8654 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8382 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8655 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -8423,7 +8696,7 @@ static struct hda_verb alc885_macmini3_init_verbs[] = {
8423}; 8696};
8424 8697
8425 8698
8426static struct hda_verb alc885_mba21_init_verbs[] = { 8699static const struct hda_verb alc885_mba21_init_verbs[] = {
8427 /*Internal and HP Speaker Mixer*/ 8700 /*Internal and HP Speaker Mixer*/
8428 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8701 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8429 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -8446,7 +8719,7 @@ static struct hda_verb alc885_mba21_init_verbs[] = {
8446 8719
8447 8720
8448/* Macbook Pro rev3 */ 8721/* Macbook Pro rev3 */
8449static struct hda_verb alc885_mbp3_init_verbs[] = { 8722static const struct hda_verb alc885_mbp3_init_verbs[] = {
8450 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8723 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8451 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8452 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -8510,7 +8783,7 @@ static struct hda_verb alc885_mbp3_init_verbs[] = {
8510}; 8783};
8511 8784
8512/* iMac 9,1 */ 8785/* iMac 9,1 */
8513static struct hda_verb alc885_imac91_init_verbs[] = { 8786static const struct hda_verb alc885_imac91_init_verbs[] = {
8514 /* Internal Speaker Pin (0x0c) */ 8787 /* Internal Speaker Pin (0x0c) */
8515 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8788 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8516 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8789 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -8565,14 +8838,14 @@ static struct hda_verb alc885_imac91_init_verbs[] = {
8565}; 8838};
8566 8839
8567/* iMac 24 mixer. */ 8840/* iMac 24 mixer. */
8568static struct snd_kcontrol_new alc885_imac24_mixer[] = { 8841static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
8569 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8842 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8570 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), 8843 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8571 { } /* end */ 8844 { } /* end */
8572}; 8845};
8573 8846
8574/* iMac 24 init verbs. */ 8847/* iMac 24 init verbs. */
8575static struct hda_verb alc885_imac24_init_verbs[] = { 8848static const struct hda_verb alc885_imac24_init_verbs[] = {
8576 /* Internal speakers: output 0 (0x0c) */ 8849 /* Internal speakers: output 0 (0x0c) */
8577 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8850 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8578 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8851 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -8600,6 +8873,8 @@ static void alc885_imac24_setup(struct hda_codec *codec)
8600 spec->autocfg.hp_pins[0] = 0x14; 8873 spec->autocfg.hp_pins[0] = 0x14;
8601 spec->autocfg.speaker_pins[0] = 0x18; 8874 spec->autocfg.speaker_pins[0] = 0x18;
8602 spec->autocfg.speaker_pins[1] = 0x1a; 8875 spec->autocfg.speaker_pins[1] = 0x1a;
8876 spec->automute = 1;
8877 spec->automute_mode = ALC_AUTOMUTE_AMP;
8603} 8878}
8604 8879
8605#define alc885_mb5_setup alc885_imac24_setup 8880#define alc885_mb5_setup alc885_imac24_setup
@@ -8612,6 +8887,8 @@ static void alc885_mba21_setup(struct hda_codec *codec)
8612 8887
8613 spec->autocfg.hp_pins[0] = 0x14; 8888 spec->autocfg.hp_pins[0] = 0x14;
8614 spec->autocfg.speaker_pins[0] = 0x18; 8889 spec->autocfg.speaker_pins[0] = 0x18;
8890 spec->automute = 1;
8891 spec->automute_mode = ALC_AUTOMUTE_AMP;
8615} 8892}
8616 8893
8617 8894
@@ -8622,6 +8899,8 @@ static void alc885_mbp3_setup(struct hda_codec *codec)
8622 8899
8623 spec->autocfg.hp_pins[0] = 0x15; 8900 spec->autocfg.hp_pins[0] = 0x15;
8624 spec->autocfg.speaker_pins[0] = 0x14; 8901 spec->autocfg.speaker_pins[0] = 0x14;
8902 spec->automute = 1;
8903 spec->automute_mode = ALC_AUTOMUTE_AMP;
8625} 8904}
8626 8905
8627static void alc885_imac91_setup(struct hda_codec *codec) 8906static void alc885_imac91_setup(struct hda_codec *codec)
@@ -8631,9 +8910,11 @@ static void alc885_imac91_setup(struct hda_codec *codec)
8631 spec->autocfg.hp_pins[0] = 0x14; 8910 spec->autocfg.hp_pins[0] = 0x14;
8632 spec->autocfg.speaker_pins[0] = 0x18; 8911 spec->autocfg.speaker_pins[0] = 0x18;
8633 spec->autocfg.speaker_pins[1] = 0x1a; 8912 spec->autocfg.speaker_pins[1] = 0x1a;
8913 spec->automute = 1;
8914 spec->automute_mode = ALC_AUTOMUTE_AMP;
8634} 8915}
8635 8916
8636static struct hda_verb alc882_targa_verbs[] = { 8917static const struct hda_verb alc882_targa_verbs[] = {
8637 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8918 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8638 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8919 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8639 8920
@@ -8652,7 +8933,7 @@ static struct hda_verb alc882_targa_verbs[] = {
8652static void alc882_targa_automute(struct hda_codec *codec) 8933static void alc882_targa_automute(struct hda_codec *codec)
8653{ 8934{
8654 struct alc_spec *spec = codec->spec; 8935 struct alc_spec *spec = codec->spec;
8655 alc_automute_amp(codec); 8936 alc_hp_automute(codec);
8656 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 8937 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8657 spec->jack_present ? 1 : 3); 8938 spec->jack_present ? 1 : 3);
8658} 8939}
@@ -8663,6 +8944,8 @@ static void alc882_targa_setup(struct hda_codec *codec)
8663 8944
8664 spec->autocfg.hp_pins[0] = 0x14; 8945 spec->autocfg.hp_pins[0] = 0x14;
8665 spec->autocfg.speaker_pins[0] = 0x1b; 8946 spec->autocfg.speaker_pins[0] = 0x1b;
8947 spec->automute = 1;
8948 spec->automute_mode = ALC_AUTOMUTE_AMP;
8666} 8949}
8667 8950
8668static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 8951static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -8671,7 +8954,7 @@ static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8671 alc882_targa_automute(codec); 8954 alc882_targa_automute(codec);
8672} 8955}
8673 8956
8674static struct hda_verb alc882_asus_a7j_verbs[] = { 8957static const struct hda_verb alc882_asus_a7j_verbs[] = {
8675 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8958 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8676 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8677 8960
@@ -8689,7 +8972,7 @@ static struct hda_verb alc882_asus_a7j_verbs[] = {
8689 { } /* end */ 8972 { } /* end */
8690}; 8973};
8691 8974
8692static struct hda_verb alc882_asus_a7m_verbs[] = { 8975static const struct hda_verb alc882_asus_a7m_verbs[] = {
8693 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8976 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8694 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8977 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8695 8978
@@ -8750,13 +9033,13 @@ static void alc885_macpro_init_hook(struct hda_codec *codec)
8750static void alc885_imac24_init_hook(struct hda_codec *codec) 9033static void alc885_imac24_init_hook(struct hda_codec *codec)
8751{ 9034{
8752 alc885_macpro_init_hook(codec); 9035 alc885_macpro_init_hook(codec);
8753 alc_automute_amp(codec); 9036 alc_hp_automute(codec);
8754} 9037}
8755 9038
8756/* 9039/*
8757 * generic initialization of ADC, input mixers and output mixers 9040 * generic initialization of ADC, input mixers and output mixers
8758 */ 9041 */
8759static struct hda_verb alc883_auto_init_verbs[] = { 9042static const struct hda_verb alc883_auto_init_verbs[] = {
8760 /* 9043 /*
8761 * Unmute ADC0-2 and set the default input to mic-in 9044 * Unmute ADC0-2 and set the default input to mic-in
8762 */ 9045 */
@@ -8796,7 +9079,7 @@ static struct hda_verb alc883_auto_init_verbs[] = {
8796}; 9079};
8797 9080
8798/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ 9081/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8799static struct hda_verb alc889A_mb31_ch2_init[] = { 9082static const struct hda_verb alc889A_mb31_ch2_init[] = {
8800 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 9083 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8801 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 9084 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8802 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 9085 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
@@ -8805,7 +9088,7 @@ static struct hda_verb alc889A_mb31_ch2_init[] = {
8805}; 9088};
8806 9089
8807/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ 9090/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8808static struct hda_verb alc889A_mb31_ch4_init[] = { 9091static const struct hda_verb alc889A_mb31_ch4_init[] = {
8809 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 9092 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8810 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 9093 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8811 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 9094 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
@@ -8814,7 +9097,7 @@ static struct hda_verb alc889A_mb31_ch4_init[] = {
8814}; 9097};
8815 9098
8816/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ 9099/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8817static struct hda_verb alc889A_mb31_ch5_init[] = { 9100static const struct hda_verb alc889A_mb31_ch5_init[] = {
8818 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ 9101 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8819 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 9102 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8820 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 9103 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
@@ -8823,7 +9106,7 @@ static struct hda_verb alc889A_mb31_ch5_init[] = {
8823}; 9106};
8824 9107
8825/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ 9108/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8826static struct hda_verb alc889A_mb31_ch6_init[] = { 9109static const struct hda_verb alc889A_mb31_ch6_init[] = {
8827 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ 9110 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8828 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ 9111 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8829 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 9112 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
@@ -8831,14 +9114,14 @@ static struct hda_verb alc889A_mb31_ch6_init[] = {
8831 { } /* end */ 9114 { } /* end */
8832}; 9115};
8833 9116
8834static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { 9117static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8835 { 2, alc889A_mb31_ch2_init }, 9118 { 2, alc889A_mb31_ch2_init },
8836 { 4, alc889A_mb31_ch4_init }, 9119 { 4, alc889A_mb31_ch4_init },
8837 { 5, alc889A_mb31_ch5_init }, 9120 { 5, alc889A_mb31_ch5_init },
8838 { 6, alc889A_mb31_ch6_init }, 9121 { 6, alc889A_mb31_ch6_init },
8839}; 9122};
8840 9123
8841static struct hda_verb alc883_medion_eapd_verbs[] = { 9124static const struct hda_verb alc883_medion_eapd_verbs[] = {
8842 /* eanable EAPD on medion laptop */ 9125 /* eanable EAPD on medion laptop */
8843 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 9126 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8844 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 9127 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
@@ -8847,7 +9130,7 @@ static struct hda_verb alc883_medion_eapd_verbs[] = {
8847 9130
8848#define alc883_base_mixer alc882_base_mixer 9131#define alc883_base_mixer alc882_base_mixer
8849 9132
8850static struct snd_kcontrol_new alc883_mitac_mixer[] = { 9133static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
8851 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9134 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8852 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9135 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8853 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 9136 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
@@ -8864,7 +9147,7 @@ static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8864 { } /* end */ 9147 { } /* end */
8865}; 9148};
8866 9149
8867static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { 9150static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8868 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9151 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8869 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 9152 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8870 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9153 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -8878,7 +9161,7 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8878 { } /* end */ 9161 { } /* end */
8879}; 9162};
8880 9163
8881static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { 9164static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8882 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9165 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8883 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 9166 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8884 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9167 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -8892,7 +9175,7 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8892 { } /* end */ 9175 { } /* end */
8893}; 9176};
8894 9177
8895static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 9178static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8896 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9179 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8897 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9180 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8898 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9181 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
@@ -8909,7 +9192,7 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8909 { } /* end */ 9192 { } /* end */
8910}; 9193};
8911 9194
8912static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 9195static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8913 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9196 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8914 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9197 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8915 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9198 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -8932,7 +9215,7 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8932 { } /* end */ 9215 { } /* end */
8933}; 9216};
8934 9217
8935static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { 9218static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8936 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9219 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8937 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9220 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8938 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9221 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -8956,7 +9239,7 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8956 { } /* end */ 9239 { } /* end */
8957}; 9240};
8958 9241
8959static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { 9242static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8960 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9243 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8961 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9244 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8962 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9245 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -8980,7 +9263,7 @@ static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8980 { } /* end */ 9263 { } /* end */
8981}; 9264};
8982 9265
8983static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 9266static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
8984 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9267 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8985 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9268 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8986 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -9003,7 +9286,7 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9003 { } /* end */ 9286 { } /* end */
9004}; 9287};
9005 9288
9006static struct snd_kcontrol_new alc883_targa_mixer[] = { 9289static const struct snd_kcontrol_new alc883_targa_mixer[] = {
9007 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9290 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9008 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9291 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9009 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9292 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -9024,7 +9307,7 @@ static struct snd_kcontrol_new alc883_targa_mixer[] = {
9024 { } /* end */ 9307 { } /* end */
9025}; 9308};
9026 9309
9027static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { 9310static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9028 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9311 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9029 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9312 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9030 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9313 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -9040,7 +9323,7 @@ static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9040 { } /* end */ 9323 { } /* end */
9041}; 9324};
9042 9325
9043static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { 9326static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9044 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9327 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9045 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 9328 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9046 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9329 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
@@ -9049,7 +9332,7 @@ static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9049 { } /* end */ 9332 { } /* end */
9050}; 9333};
9051 9334
9052static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { 9335static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9053 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9336 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9054 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9337 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9055 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9338 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -9061,7 +9344,7 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9061 { } /* end */ 9344 { } /* end */
9062}; 9345};
9063 9346
9064static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { 9347static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9065 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9348 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9066 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 9349 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9067 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9350 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -9074,7 +9357,7 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9074 { } /* end */ 9357 { } /* end */
9075}; 9358};
9076 9359
9077static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { 9360static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9078 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9361 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9079 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9362 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9080 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9363 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -9084,7 +9367,7 @@ static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9084 { } /* end */ 9367 { } /* end */
9085}; 9368};
9086 9369
9087static struct hda_verb alc883_medion_wim2160_verbs[] = { 9370static const struct hda_verb alc883_medion_wim2160_verbs[] = {
9088 /* Unmute front mixer */ 9371 /* Unmute front mixer */
9089 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9090 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9373 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -9108,9 +9391,11 @@ static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9108 9391
9109 spec->autocfg.hp_pins[0] = 0x1a; 9392 spec->autocfg.hp_pins[0] = 0x1a;
9110 spec->autocfg.speaker_pins[0] = 0x15; 9393 spec->autocfg.speaker_pins[0] = 0x15;
9394 spec->automute = 1;
9395 spec->automute_mode = ALC_AUTOMUTE_AMP;
9111} 9396}
9112 9397
9113static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 9398static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9114 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9399 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9115 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9400 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9116 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9401 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -9122,7 +9407,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9122 { } /* end */ 9407 { } /* end */
9123}; 9408};
9124 9409
9125static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { 9410static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9126 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9411 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9127 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9412 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9128 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9413 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
@@ -9135,7 +9420,7 @@ static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9135 { } /* end */ 9420 { } /* end */
9136}; 9421};
9137 9422
9138static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { 9423static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9139 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9424 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9140 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9425 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9141 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 9426 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
@@ -9160,7 +9445,7 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9160 { } /* end */ 9445 { } /* end */
9161}; 9446};
9162 9447
9163static struct snd_kcontrol_new alc889A_mb31_mixer[] = { 9448static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9164 /* Output mixers */ 9449 /* Output mixers */
9165 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 9450 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9166 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 9451 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
@@ -9186,7 +9471,7 @@ static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9186 { } /* end */ 9471 { } /* end */
9187}; 9472};
9188 9473
9189static struct snd_kcontrol_new alc883_vaiott_mixer[] = { 9474static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9190 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9475 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9191 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9476 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9192 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9477 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -9196,7 +9481,7 @@ static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9196 { } /* end */ 9481 { } /* end */
9197}; 9482};
9198 9483
9199static struct hda_bind_ctls alc883_bind_cap_vol = { 9484static const struct hda_bind_ctls alc883_bind_cap_vol = {
9200 .ops = &snd_hda_bind_vol, 9485 .ops = &snd_hda_bind_vol,
9201 .values = { 9486 .values = {
9202 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 9487 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
@@ -9205,7 +9490,7 @@ static struct hda_bind_ctls alc883_bind_cap_vol = {
9205 }, 9490 },
9206}; 9491};
9207 9492
9208static struct hda_bind_ctls alc883_bind_cap_switch = { 9493static const struct hda_bind_ctls alc883_bind_cap_switch = {
9209 .ops = &snd_hda_bind_sw, 9494 .ops = &snd_hda_bind_sw,
9210 .values = { 9495 .values = {
9211 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 9496 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
@@ -9214,7 +9499,7 @@ static struct hda_bind_ctls alc883_bind_cap_switch = {
9214 }, 9499 },
9215}; 9500};
9216 9501
9217static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { 9502static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9218 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9503 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9219 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9504 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9220 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9505 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -9226,7 +9511,7 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9226 { } /* end */ 9511 { } /* end */
9227}; 9512};
9228 9513
9229static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { 9514static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9230 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), 9515 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9231 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), 9516 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9232 { 9517 {
@@ -9241,7 +9526,7 @@ static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9241 { } /* end */ 9526 { } /* end */
9242}; 9527};
9243 9528
9244static struct snd_kcontrol_new alc883_chmode_mixer[] = { 9529static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
9245 { 9530 {
9246 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9247 .name = "Channel Mode", 9532 .name = "Channel Mode",
@@ -9260,9 +9545,11 @@ static void alc883_mitac_setup(struct hda_codec *codec)
9260 spec->autocfg.hp_pins[0] = 0x15; 9545 spec->autocfg.hp_pins[0] = 0x15;
9261 spec->autocfg.speaker_pins[0] = 0x14; 9546 spec->autocfg.speaker_pins[0] = 0x14;
9262 spec->autocfg.speaker_pins[1] = 0x17; 9547 spec->autocfg.speaker_pins[1] = 0x17;
9548 spec->automute = 1;
9549 spec->automute_mode = ALC_AUTOMUTE_AMP;
9263} 9550}
9264 9551
9265static struct hda_verb alc883_mitac_verbs[] = { 9552static const struct hda_verb alc883_mitac_verbs[] = {
9266 /* HP */ 9553 /* HP */
9267 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9554 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9268 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9555 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -9277,7 +9564,7 @@ static struct hda_verb alc883_mitac_verbs[] = {
9277 { } /* end */ 9564 { } /* end */
9278}; 9565};
9279 9566
9280static struct hda_verb alc883_clevo_m540r_verbs[] = { 9567static const struct hda_verb alc883_clevo_m540r_verbs[] = {
9281 /* HP */ 9568 /* HP */
9282 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9569 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9283 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9570 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -9293,7 +9580,7 @@ static struct hda_verb alc883_clevo_m540r_verbs[] = {
9293 { } /* end */ 9580 { } /* end */
9294}; 9581};
9295 9582
9296static struct hda_verb alc883_clevo_m720_verbs[] = { 9583static const struct hda_verb alc883_clevo_m720_verbs[] = {
9297 /* HP */ 9584 /* HP */
9298 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9585 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9299 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9586 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -9308,7 +9595,7 @@ static struct hda_verb alc883_clevo_m720_verbs[] = {
9308 { } /* end */ 9595 { } /* end */
9309}; 9596};
9310 9597
9311static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { 9598static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9312 /* HP */ 9599 /* HP */
9313 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9600 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9314 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -9322,7 +9609,7 @@ static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9322 { } /* end */ 9609 { } /* end */
9323}; 9610};
9324 9611
9325static struct hda_verb alc883_targa_verbs[] = { 9612static const struct hda_verb alc883_targa_verbs[] = {
9326 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9327 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9328 9615
@@ -9351,14 +9638,14 @@ static struct hda_verb alc883_targa_verbs[] = {
9351 { } /* end */ 9638 { } /* end */
9352}; 9639};
9353 9640
9354static struct hda_verb alc883_lenovo_101e_verbs[] = { 9641static const struct hda_verb alc883_lenovo_101e_verbs[] = {
9355 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9642 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9356 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, 9643 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9357 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, 9644 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9358 { } /* end */ 9645 { } /* end */
9359}; 9646};
9360 9647
9361static struct hda_verb alc883_lenovo_nb0763_verbs[] = { 9648static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9362 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9649 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9363 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9650 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9364 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9651 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
@@ -9366,7 +9653,7 @@ static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9366 { } /* end */ 9653 { } /* end */
9367}; 9654};
9368 9655
9369static struct hda_verb alc888_lenovo_ms7195_verbs[] = { 9656static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9657 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9658 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9372 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9659 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -9375,7 +9662,7 @@ static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9375 { } /* end */ 9662 { } /* end */
9376}; 9663};
9377 9664
9378static struct hda_verb alc883_haier_w66_verbs[] = { 9665static const struct hda_verb alc883_haier_w66_verbs[] = {
9379 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9666 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9380 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9381 9668
@@ -9388,7 +9675,7 @@ static struct hda_verb alc883_haier_w66_verbs[] = {
9388 { } /* end */ 9675 { } /* end */
9389}; 9676};
9390 9677
9391static struct hda_verb alc888_lenovo_sky_verbs[] = { 9678static const struct hda_verb alc888_lenovo_sky_verbs[] = {
9392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9679 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9680 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9394 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9681 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -9400,12 +9687,12 @@ static struct hda_verb alc888_lenovo_sky_verbs[] = {
9400 { } /* end */ 9687 { } /* end */
9401}; 9688};
9402 9689
9403static struct hda_verb alc888_6st_dell_verbs[] = { 9690static const struct hda_verb alc888_6st_dell_verbs[] = {
9404 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9691 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9405 { } 9692 { }
9406}; 9693};
9407 9694
9408static struct hda_verb alc883_vaiott_verbs[] = { 9695static const struct hda_verb alc883_vaiott_verbs[] = {
9409 /* HP */ 9696 /* HP */
9410 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9697 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9411 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9698 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -9424,9 +9711,11 @@ static void alc888_3st_hp_setup(struct hda_codec *codec)
9424 spec->autocfg.speaker_pins[0] = 0x14; 9711 spec->autocfg.speaker_pins[0] = 0x14;
9425 spec->autocfg.speaker_pins[1] = 0x16; 9712 spec->autocfg.speaker_pins[1] = 0x16;
9426 spec->autocfg.speaker_pins[2] = 0x18; 9713 spec->autocfg.speaker_pins[2] = 0x18;
9714 spec->automute = 1;
9715 spec->automute_mode = ALC_AUTOMUTE_AMP;
9427} 9716}
9428 9717
9429static struct hda_verb alc888_3st_hp_verbs[] = { 9718static const struct hda_verb alc888_3st_hp_verbs[] = {
9430 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 9719 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9431 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 9720 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9432 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ 9721 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
@@ -9437,7 +9726,7 @@ static struct hda_verb alc888_3st_hp_verbs[] = {
9437/* 9726/*
9438 * 2ch mode 9727 * 2ch mode
9439 */ 9728 */
9440static struct hda_verb alc888_3st_hp_2ch_init[] = { 9729static const struct hda_verb alc888_3st_hp_2ch_init[] = {
9441 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9730 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9442 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9731 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9443 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 9732 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
@@ -9448,7 +9737,7 @@ static struct hda_verb alc888_3st_hp_2ch_init[] = {
9448/* 9737/*
9449 * 4ch mode 9738 * 4ch mode
9450 */ 9739 */
9451static struct hda_verb alc888_3st_hp_4ch_init[] = { 9740static const struct hda_verb alc888_3st_hp_4ch_init[] = {
9452 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9741 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9453 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9742 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9454 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9743 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -9460,7 +9749,7 @@ static struct hda_verb alc888_3st_hp_4ch_init[] = {
9460/* 9749/*
9461 * 6ch mode 9750 * 6ch mode
9462 */ 9751 */
9463static struct hda_verb alc888_3st_hp_6ch_init[] = { 9752static const struct hda_verb alc888_3st_hp_6ch_init[] = {
9464 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9753 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9465 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9754 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9466 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 9755 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
@@ -9470,39 +9759,21 @@ static struct hda_verb alc888_3st_hp_6ch_init[] = {
9470 { } /* end */ 9759 { } /* end */
9471}; 9760};
9472 9761
9473static struct hda_channel_mode alc888_3st_hp_modes[3] = { 9762static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
9474 { 2, alc888_3st_hp_2ch_init }, 9763 { 2, alc888_3st_hp_2ch_init },
9475 { 4, alc888_3st_hp_4ch_init }, 9764 { 4, alc888_3st_hp_4ch_init },
9476 { 6, alc888_3st_hp_6ch_init }, 9765 { 6, alc888_3st_hp_6ch_init },
9477}; 9766};
9478 9767
9479/* toggle front-jack and RCA according to the hp-jack state */ 9768static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
9480static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9481{ 9769{
9482 unsigned int present = snd_hda_jack_detect(codec, 0x1b); 9770 struct alc_spec *spec = codec->spec;
9483
9484 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9485 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9486 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9487 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9488}
9489
9490/* toggle RCA according to the front-jack state */
9491static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9492{
9493 unsigned int present = snd_hda_jack_detect(codec, 0x14);
9494
9495 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9496 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9497}
9498 9771
9499static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, 9772 spec->autocfg.hp_pins[0] = 0x1b;
9500 unsigned int res) 9773 spec->autocfg.line_out_pins[0] = 0x14;
9501{ 9774 spec->autocfg.speaker_pins[0] = 0x15;
9502 if ((res >> 26) == ALC880_HP_EVENT) 9775 spec->automute = 1;
9503 alc888_lenovo_ms7195_front_automute(codec); 9776 spec->automute_mode = ALC_AUTOMUTE_AMP;
9504 if ((res >> 26) == ALC880_FRONT_EVENT)
9505 alc888_lenovo_ms7195_rca_automute(codec);
9506} 9777}
9507 9778
9508/* toggle speaker-output according to the hp-jack state */ 9779/* toggle speaker-output according to the hp-jack state */
@@ -9512,6 +9783,8 @@ static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9512 9783
9513 spec->autocfg.hp_pins[0] = 0x14; 9784 spec->autocfg.hp_pins[0] = 0x14;
9514 spec->autocfg.speaker_pins[0] = 0x15; 9785 spec->autocfg.speaker_pins[0] = 0x15;
9786 spec->automute = 1;
9787 spec->automute_mode = ALC_AUTOMUTE_AMP;
9515} 9788}
9516 9789
9517/* toggle speaker-output according to the hp-jack state */ 9790/* toggle speaker-output according to the hp-jack state */
@@ -9524,11 +9797,13 @@ static void alc883_clevo_m720_setup(struct hda_codec *codec)
9524 9797
9525 spec->autocfg.hp_pins[0] = 0x15; 9798 spec->autocfg.hp_pins[0] = 0x15;
9526 spec->autocfg.speaker_pins[0] = 0x14; 9799 spec->autocfg.speaker_pins[0] = 0x14;
9800 spec->automute = 1;
9801 spec->automute_mode = ALC_AUTOMUTE_AMP;
9527} 9802}
9528 9803
9529static void alc883_clevo_m720_init_hook(struct hda_codec *codec) 9804static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9530{ 9805{
9531 alc_automute_amp(codec); 9806 alc_hp_automute(codec);
9532 alc88x_simple_mic_automute(codec); 9807 alc88x_simple_mic_automute(codec);
9533} 9808}
9534 9809
@@ -9540,7 +9815,7 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9540 alc88x_simple_mic_automute(codec); 9815 alc88x_simple_mic_automute(codec);
9541 break; 9816 break;
9542 default: 9817 default:
9543 alc_automute_amp_unsol_event(codec, res); 9818 alc_sku_unsol_event(codec, res);
9544 break; 9819 break;
9545 } 9820 }
9546} 9821}
@@ -9552,6 +9827,8 @@ static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9552 9827
9553 spec->autocfg.hp_pins[0] = 0x14; 9828 spec->autocfg.hp_pins[0] = 0x14;
9554 spec->autocfg.speaker_pins[0] = 0x15; 9829 spec->autocfg.speaker_pins[0] = 0x15;
9830 spec->automute = 1;
9831 spec->automute_mode = ALC_AUTOMUTE_AMP;
9555} 9832}
9556 9833
9557static void alc883_haier_w66_setup(struct hda_codec *codec) 9834static void alc883_haier_w66_setup(struct hda_codec *codec)
@@ -9560,33 +9837,21 @@ static void alc883_haier_w66_setup(struct hda_codec *codec)
9560 9837
9561 spec->autocfg.hp_pins[0] = 0x1b; 9838 spec->autocfg.hp_pins[0] = 0x1b;
9562 spec->autocfg.speaker_pins[0] = 0x14; 9839 spec->autocfg.speaker_pins[0] = 0x14;
9840 spec->automute = 1;
9841 spec->automute_mode = ALC_AUTOMUTE_AMP;
9563} 9842}
9564 9843
9565static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 9844static void alc883_lenovo_101e_setup(struct hda_codec *codec)
9566{ 9845{
9567 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0; 9846 struct alc_spec *spec = codec->spec;
9568
9569 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9570 HDA_AMP_MUTE, bits);
9571}
9572
9573static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9574{
9575 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
9576
9577 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9578 HDA_AMP_MUTE, bits);
9579 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9580 HDA_AMP_MUTE, bits);
9581}
9582 9847
9583static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, 9848 spec->autocfg.hp_pins[0] = 0x1b;
9584 unsigned int res) 9849 spec->autocfg.line_out_pins[0] = 0x14;
9585{ 9850 spec->autocfg.speaker_pins[0] = 0x15;
9586 if ((res >> 26) == ALC880_HP_EVENT) 9851 spec->automute = 1;
9587 alc883_lenovo_101e_all_automute(codec); 9852 spec->detect_line = 1;
9588 if ((res >> 26) == ALC880_FRONT_EVENT) 9853 spec->automute_lines = 1;
9589 alc883_lenovo_101e_ispeaker_automute(codec); 9854 spec->automute_mode = ALC_AUTOMUTE_AMP;
9590} 9855}
9591 9856
9592/* toggle speaker-output according to the hp-jack state */ 9857/* toggle speaker-output according to the hp-jack state */
@@ -9597,9 +9862,11 @@ static void alc883_acer_aspire_setup(struct hda_codec *codec)
9597 spec->autocfg.hp_pins[0] = 0x14; 9862 spec->autocfg.hp_pins[0] = 0x14;
9598 spec->autocfg.speaker_pins[0] = 0x15; 9863 spec->autocfg.speaker_pins[0] = 0x15;
9599 spec->autocfg.speaker_pins[1] = 0x16; 9864 spec->autocfg.speaker_pins[1] = 0x16;
9865 spec->automute = 1;
9866 spec->automute_mode = ALC_AUTOMUTE_AMP;
9600} 9867}
9601 9868
9602static struct hda_verb alc883_acer_eapd_verbs[] = { 9869static const struct hda_verb alc883_acer_eapd_verbs[] = {
9603 /* HP Pin: output 0 (0x0c) */ 9870 /* HP Pin: output 0 (0x0c) */
9604 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9871 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9605 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9872 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -9626,6 +9893,8 @@ static void alc888_6st_dell_setup(struct hda_codec *codec)
9626 spec->autocfg.speaker_pins[1] = 0x15; 9893 spec->autocfg.speaker_pins[1] = 0x15;
9627 spec->autocfg.speaker_pins[2] = 0x16; 9894 spec->autocfg.speaker_pins[2] = 0x16;
9628 spec->autocfg.speaker_pins[3] = 0x17; 9895 spec->autocfg.speaker_pins[3] = 0x17;
9896 spec->automute = 1;
9897 spec->automute_mode = ALC_AUTOMUTE_AMP;
9629} 9898}
9630 9899
9631static void alc888_lenovo_sky_setup(struct hda_codec *codec) 9900static void alc888_lenovo_sky_setup(struct hda_codec *codec)
@@ -9638,6 +9907,8 @@ static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9638 spec->autocfg.speaker_pins[2] = 0x16; 9907 spec->autocfg.speaker_pins[2] = 0x16;
9639 spec->autocfg.speaker_pins[3] = 0x17; 9908 spec->autocfg.speaker_pins[3] = 0x17;
9640 spec->autocfg.speaker_pins[4] = 0x1a; 9909 spec->autocfg.speaker_pins[4] = 0x1a;
9910 spec->automute = 1;
9911 spec->automute_mode = ALC_AUTOMUTE_AMP;
9641} 9912}
9642 9913
9643static void alc883_vaiott_setup(struct hda_codec *codec) 9914static void alc883_vaiott_setup(struct hda_codec *codec)
@@ -9647,9 +9918,11 @@ static void alc883_vaiott_setup(struct hda_codec *codec)
9647 spec->autocfg.hp_pins[0] = 0x15; 9918 spec->autocfg.hp_pins[0] = 0x15;
9648 spec->autocfg.speaker_pins[0] = 0x14; 9919 spec->autocfg.speaker_pins[0] = 0x14;
9649 spec->autocfg.speaker_pins[1] = 0x17; 9920 spec->autocfg.speaker_pins[1] = 0x17;
9921 spec->automute = 1;
9922 spec->automute_mode = ALC_AUTOMUTE_AMP;
9650} 9923}
9651 9924
9652static struct hda_verb alc888_asus_m90v_verbs[] = { 9925static const struct hda_verb alc888_asus_m90v_verbs[] = {
9653 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9926 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9654 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9927 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9655 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9928 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -9672,9 +9945,11 @@ static void alc883_mode2_setup(struct hda_codec *codec)
9672 spec->ext_mic.mux_idx = 0; 9945 spec->ext_mic.mux_idx = 0;
9673 spec->int_mic.mux_idx = 1; 9946 spec->int_mic.mux_idx = 1;
9674 spec->auto_mic = 1; 9947 spec->auto_mic = 1;
9948 spec->automute = 1;
9949 spec->automute_mode = ALC_AUTOMUTE_AMP;
9675} 9950}
9676 9951
9677static struct hda_verb alc888_asus_eee1601_verbs[] = { 9952static const struct hda_verb alc888_asus_eee1601_verbs[] = {
9678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9953 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9679 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9954 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9680 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9955 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -9693,10 +9968,10 @@ static void alc883_eee1601_inithook(struct hda_codec *codec)
9693 9968
9694 spec->autocfg.hp_pins[0] = 0x14; 9969 spec->autocfg.hp_pins[0] = 0x14;
9695 spec->autocfg.speaker_pins[0] = 0x1b; 9970 spec->autocfg.speaker_pins[0] = 0x1b;
9696 alc_automute_pin(codec); 9971 alc_hp_automute(codec);
9697} 9972}
9698 9973
9699static struct hda_verb alc889A_mb31_verbs[] = { 9974static const struct hda_verb alc889A_mb31_verbs[] = {
9700 /* Init rear pin (used as headphone output) */ 9975 /* Init rear pin (used as headphone output) */
9701 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ 9976 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9702 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ 9977 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
@@ -9742,11 +10017,11 @@ static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9742#define alc882_pcm_digital_playback alc880_pcm_digital_playback 10017#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9743#define alc882_pcm_digital_capture alc880_pcm_digital_capture 10018#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9744 10019
9745static hda_nid_t alc883_slave_dig_outs[] = { 10020static const hda_nid_t alc883_slave_dig_outs[] = {
9746 ALC1200_DIGOUT_NID, 0, 10021 ALC1200_DIGOUT_NID, 0,
9747}; 10022};
9748 10023
9749static hda_nid_t alc1200_slave_dig_outs[] = { 10024static const hda_nid_t alc1200_slave_dig_outs[] = {
9750 ALC883_DIGOUT_NID, 0, 10025 ALC883_DIGOUT_NID, 0,
9751}; 10026};
9752 10027
@@ -9805,7 +10080,7 @@ static const char * const alc882_models[ALC882_MODEL_LAST] = {
9805 [ALC882_AUTO] = "auto", 10080 [ALC882_AUTO] = "auto",
9806}; 10081};
9807 10082
9808static struct snd_pci_quirk alc882_cfg_tbl[] = { 10083static const struct snd_pci_quirk alc882_cfg_tbl[] = {
9809 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), 10084 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9810 10085
9811 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 10086 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
@@ -9932,7 +10207,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
9932}; 10207};
9933 10208
9934/* codec SSID table for Intel Mac */ 10209/* codec SSID table for Intel Mac */
9935static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { 10210static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9936 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3), 10211 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9937 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3), 10212 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9938 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), 10213 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
@@ -9959,7 +10234,7 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9959 {} /* terminator */ 10234 {} /* terminator */
9960}; 10235};
9961 10236
9962static struct alc_config_preset alc882_presets[] = { 10237static const struct alc_config_preset alc882_presets[] = {
9963 [ALC882_3ST_DIG] = { 10238 [ALC882_3ST_DIG] = {
9964 .mixers = { alc882_base_mixer }, 10239 .mixers = { alc882_base_mixer },
9965 .init_verbs = { alc882_base_init_verbs, 10240 .init_verbs = { alc882_base_init_verbs,
@@ -10015,9 +10290,9 @@ static struct alc_config_preset alc882_presets[] = {
10015 .channel_mode = alc885_mba21_ch_modes, 10290 .channel_mode = alc885_mba21_ch_modes,
10016 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 10291 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10017 .input_mux = &alc882_capture_source, 10292 .input_mux = &alc882_capture_source,
10018 .unsol_event = alc_automute_amp_unsol_event, 10293 .unsol_event = alc_sku_unsol_event,
10019 .setup = alc885_mba21_setup, 10294 .setup = alc885_mba21_setup,
10020 .init_hook = alc_automute_amp, 10295 .init_hook = alc_hp_automute,
10021 }, 10296 },
10022 [ALC885_MBP3] = { 10297 [ALC885_MBP3] = {
10023 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 10298 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
@@ -10031,9 +10306,9 @@ static struct alc_config_preset alc882_presets[] = {
10031 .input_mux = &alc882_capture_source, 10306 .input_mux = &alc882_capture_source,
10032 .dig_out_nid = ALC882_DIGOUT_NID, 10307 .dig_out_nid = ALC882_DIGOUT_NID,
10033 .dig_in_nid = ALC882_DIGIN_NID, 10308 .dig_in_nid = ALC882_DIGIN_NID,
10034 .unsol_event = alc_automute_amp_unsol_event, 10309 .unsol_event = alc_sku_unsol_event,
10035 .setup = alc885_mbp3_setup, 10310 .setup = alc885_mbp3_setup,
10036 .init_hook = alc_automute_amp, 10311 .init_hook = alc_hp_automute,
10037 }, 10312 },
10038 [ALC885_MB5] = { 10313 [ALC885_MB5] = {
10039 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, 10314 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
@@ -10046,9 +10321,9 @@ static struct alc_config_preset alc882_presets[] = {
10046 .input_mux = &mb5_capture_source, 10321 .input_mux = &mb5_capture_source,
10047 .dig_out_nid = ALC882_DIGOUT_NID, 10322 .dig_out_nid = ALC882_DIGOUT_NID,
10048 .dig_in_nid = ALC882_DIGIN_NID, 10323 .dig_in_nid = ALC882_DIGIN_NID,
10049 .unsol_event = alc_automute_amp_unsol_event, 10324 .unsol_event = alc_sku_unsol_event,
10050 .setup = alc885_mb5_setup, 10325 .setup = alc885_mb5_setup,
10051 .init_hook = alc_automute_amp, 10326 .init_hook = alc_hp_automute,
10052 }, 10327 },
10053 [ALC885_MACMINI3] = { 10328 [ALC885_MACMINI3] = {
10054 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer }, 10329 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
@@ -10061,9 +10336,9 @@ static struct alc_config_preset alc882_presets[] = {
10061 .input_mux = &macmini3_capture_source, 10336 .input_mux = &macmini3_capture_source,
10062 .dig_out_nid = ALC882_DIGOUT_NID, 10337 .dig_out_nid = ALC882_DIGOUT_NID,
10063 .dig_in_nid = ALC882_DIGIN_NID, 10338 .dig_in_nid = ALC882_DIGIN_NID,
10064 .unsol_event = alc_automute_amp_unsol_event, 10339 .unsol_event = alc_sku_unsol_event,
10065 .setup = alc885_macmini3_setup, 10340 .setup = alc885_macmini3_setup,
10066 .init_hook = alc_automute_amp, 10341 .init_hook = alc_hp_automute,
10067 }, 10342 },
10068 [ALC885_MACPRO] = { 10343 [ALC885_MACPRO] = {
10069 .mixers = { alc882_macpro_mixer }, 10344 .mixers = { alc882_macpro_mixer },
@@ -10087,7 +10362,7 @@ static struct alc_config_preset alc882_presets[] = {
10087 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 10362 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10088 .channel_mode = alc882_ch_modes, 10363 .channel_mode = alc882_ch_modes,
10089 .input_mux = &alc882_capture_source, 10364 .input_mux = &alc882_capture_source,
10090 .unsol_event = alc_automute_amp_unsol_event, 10365 .unsol_event = alc_sku_unsol_event,
10091 .setup = alc885_imac24_setup, 10366 .setup = alc885_imac24_setup,
10092 .init_hook = alc885_imac24_init_hook, 10367 .init_hook = alc885_imac24_init_hook,
10093 }, 10368 },
@@ -10102,9 +10377,9 @@ static struct alc_config_preset alc882_presets[] = {
10102 .input_mux = &alc889A_imac91_capture_source, 10377 .input_mux = &alc889A_imac91_capture_source,
10103 .dig_out_nid = ALC882_DIGOUT_NID, 10378 .dig_out_nid = ALC882_DIGOUT_NID,
10104 .dig_in_nid = ALC882_DIGIN_NID, 10379 .dig_in_nid = ALC882_DIGIN_NID,
10105 .unsol_event = alc_automute_amp_unsol_event, 10380 .unsol_event = alc_sku_unsol_event,
10106 .setup = alc885_imac91_setup, 10381 .setup = alc885_imac91_setup,
10107 .init_hook = alc_automute_amp, 10382 .init_hook = alc_hp_automute,
10108 }, 10383 },
10109 [ALC882_TARGA] = { 10384 [ALC882_TARGA] = {
10110 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 10385 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
@@ -10120,7 +10395,7 @@ static struct alc_config_preset alc882_presets[] = {
10120 .channel_mode = alc882_3ST_6ch_modes, 10395 .channel_mode = alc882_3ST_6ch_modes,
10121 .need_dac_fix = 1, 10396 .need_dac_fix = 1,
10122 .input_mux = &alc882_capture_source, 10397 .input_mux = &alc882_capture_source,
10123 .unsol_event = alc882_targa_unsol_event, 10398 .unsol_event = alc_sku_unsol_event,
10124 .setup = alc882_targa_setup, 10399 .setup = alc882_targa_setup,
10125 .init_hook = alc882_targa_automute, 10400 .init_hook = alc882_targa_automute,
10126 }, 10401 },
@@ -10214,8 +10489,8 @@ static struct alc_config_preset alc882_presets[] = {
10214 .capsrc_nids = alc889_capsrc_nids, 10489 .capsrc_nids = alc889_capsrc_nids,
10215 .input_mux = &alc889_capture_source, 10490 .input_mux = &alc889_capture_source,
10216 .setup = alc889_automute_setup, 10491 .setup = alc889_automute_setup,
10217 .init_hook = alc_automute_amp, 10492 .init_hook = alc_hp_automute,
10218 .unsol_event = alc_automute_amp_unsol_event, 10493 .unsol_event = alc_sku_unsol_event,
10219 .need_dac_fix = 1, 10494 .need_dac_fix = 1,
10220 }, 10495 },
10221 [ALC889_INTEL] = { 10496 [ALC889_INTEL] = {
@@ -10235,7 +10510,7 @@ static struct alc_config_preset alc882_presets[] = {
10235 .input_mux = &alc889_capture_source, 10510 .input_mux = &alc889_capture_source,
10236 .setup = alc889_automute_setup, 10511 .setup = alc889_automute_setup,
10237 .init_hook = alc889_intel_init_hook, 10512 .init_hook = alc889_intel_init_hook,
10238 .unsol_event = alc_automute_amp_unsol_event, 10513 .unsol_event = alc_sku_unsol_event,
10239 .need_dac_fix = 1, 10514 .need_dac_fix = 1,
10240 }, 10515 },
10241 [ALC883_6ST_DIG] = { 10516 [ALC883_6ST_DIG] = {
@@ -10324,9 +10599,9 @@ static struct alc_config_preset alc882_presets[] = {
10324 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10599 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10325 .channel_mode = alc883_3ST_2ch_modes, 10600 .channel_mode = alc883_3ST_2ch_modes,
10326 .input_mux = &alc883_capture_source, 10601 .input_mux = &alc883_capture_source,
10327 .unsol_event = alc_automute_amp_unsol_event, 10602 .unsol_event = alc_sku_unsol_event,
10328 .setup = alc883_acer_aspire_setup, 10603 .setup = alc883_acer_aspire_setup,
10329 .init_hook = alc_automute_amp, 10604 .init_hook = alc_hp_automute,
10330 }, 10605 },
10331 [ALC888_ACER_ASPIRE_4930G] = { 10606 [ALC888_ACER_ASPIRE_4930G] = {
10332 .mixers = { alc888_acer_aspire_4930g_mixer, 10607 .mixers = { alc888_acer_aspire_4930g_mixer,
@@ -10346,9 +10621,9 @@ static struct alc_config_preset alc882_presets[] = {
10346 .num_mux_defs = 10621 .num_mux_defs =
10347 ARRAY_SIZE(alc888_2_capture_sources), 10622 ARRAY_SIZE(alc888_2_capture_sources),
10348 .input_mux = alc888_2_capture_sources, 10623 .input_mux = alc888_2_capture_sources,
10349 .unsol_event = alc_automute_amp_unsol_event, 10624 .unsol_event = alc_sku_unsol_event,
10350 .setup = alc888_acer_aspire_4930g_setup, 10625 .setup = alc888_acer_aspire_4930g_setup,
10351 .init_hook = alc_automute_amp, 10626 .init_hook = alc_hp_automute,
10352 }, 10627 },
10353 [ALC888_ACER_ASPIRE_6530G] = { 10628 [ALC888_ACER_ASPIRE_6530G] = {
10354 .mixers = { alc888_acer_aspire_6530_mixer }, 10629 .mixers = { alc888_acer_aspire_6530_mixer },
@@ -10365,9 +10640,9 @@ static struct alc_config_preset alc882_presets[] = {
10365 .num_mux_defs = 10640 .num_mux_defs =
10366 ARRAY_SIZE(alc888_2_capture_sources), 10641 ARRAY_SIZE(alc888_2_capture_sources),
10367 .input_mux = alc888_acer_aspire_6530_sources, 10642 .input_mux = alc888_acer_aspire_6530_sources,
10368 .unsol_event = alc_automute_amp_unsol_event, 10643 .unsol_event = alc_sku_unsol_event,
10369 .setup = alc888_acer_aspire_6530g_setup, 10644 .setup = alc888_acer_aspire_6530g_setup,
10370 .init_hook = alc_automute_amp, 10645 .init_hook = alc_hp_automute,
10371 }, 10646 },
10372 [ALC888_ACER_ASPIRE_8930G] = { 10647 [ALC888_ACER_ASPIRE_8930G] = {
10373 .mixers = { alc889_acer_aspire_8930g_mixer, 10648 .mixers = { alc889_acer_aspire_8930g_mixer,
@@ -10388,9 +10663,9 @@ static struct alc_config_preset alc882_presets[] = {
10388 .num_mux_defs = 10663 .num_mux_defs =
10389 ARRAY_SIZE(alc889_capture_sources), 10664 ARRAY_SIZE(alc889_capture_sources),
10390 .input_mux = alc889_capture_sources, 10665 .input_mux = alc889_capture_sources,
10391 .unsol_event = alc_automute_amp_unsol_event, 10666 .unsol_event = alc_sku_unsol_event,
10392 .setup = alc889_acer_aspire_8930g_setup, 10667 .setup = alc889_acer_aspire_8930g_setup,
10393 .init_hook = alc_automute_amp, 10668 .init_hook = alc_hp_automute,
10394#ifdef CONFIG_SND_HDA_POWER_SAVE 10669#ifdef CONFIG_SND_HDA_POWER_SAVE
10395 .power_hook = alc_power_eapd, 10670 .power_hook = alc_power_eapd,
10396#endif 10671#endif
@@ -10411,9 +10686,9 @@ static struct alc_config_preset alc882_presets[] = {
10411 .need_dac_fix = 1, 10686 .need_dac_fix = 1,
10412 .const_channel_count = 6, 10687 .const_channel_count = 6,
10413 .input_mux = &alc883_capture_source, 10688 .input_mux = &alc883_capture_source,
10414 .unsol_event = alc_automute_amp_unsol_event, 10689 .unsol_event = alc_sku_unsol_event,
10415 .setup = alc888_acer_aspire_7730g_setup, 10690 .setup = alc888_acer_aspire_7730g_setup,
10416 .init_hook = alc_automute_amp, 10691 .init_hook = alc_hp_automute,
10417 }, 10692 },
10418 [ALC883_MEDION] = { 10693 [ALC883_MEDION] = {
10419 .mixers = { alc883_fivestack_mixer, 10694 .mixers = { alc883_fivestack_mixer,
@@ -10440,9 +10715,9 @@ static struct alc_config_preset alc882_presets[] = {
10440 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10715 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10441 .channel_mode = alc883_3ST_2ch_modes, 10716 .channel_mode = alc883_3ST_2ch_modes,
10442 .input_mux = &alc883_capture_source, 10717 .input_mux = &alc883_capture_source,
10443 .unsol_event = alc_automute_amp_unsol_event, 10718 .unsol_event = alc_sku_unsol_event,
10444 .setup = alc883_medion_wim2160_setup, 10719 .setup = alc883_medion_wim2160_setup,
10445 .init_hook = alc_automute_amp, 10720 .init_hook = alc_hp_automute,
10446 }, 10721 },
10447 [ALC883_LAPTOP_EAPD] = { 10722 [ALC883_LAPTOP_EAPD] = {
10448 .mixers = { alc883_base_mixer }, 10723 .mixers = { alc883_base_mixer },
@@ -10492,8 +10767,9 @@ static struct alc_config_preset alc882_presets[] = {
10492 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10767 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10493 .channel_mode = alc883_3ST_2ch_modes, 10768 .channel_mode = alc883_3ST_2ch_modes,
10494 .input_mux = &alc883_lenovo_101e_capture_source, 10769 .input_mux = &alc883_lenovo_101e_capture_source,
10495 .unsol_event = alc883_lenovo_101e_unsol_event, 10770 .setup = alc883_lenovo_101e_setup,
10496 .init_hook = alc883_lenovo_101e_all_automute, 10771 .unsol_event = alc_sku_unsol_event,
10772 .init_hook = alc_inithook,
10497 }, 10773 },
10498 [ALC883_LENOVO_NB0763] = { 10774 [ALC883_LENOVO_NB0763] = {
10499 .mixers = { alc883_lenovo_nb0763_mixer }, 10775 .mixers = { alc883_lenovo_nb0763_mixer },
@@ -10504,9 +10780,9 @@ static struct alc_config_preset alc882_presets[] = {
10504 .channel_mode = alc883_3ST_2ch_modes, 10780 .channel_mode = alc883_3ST_2ch_modes,
10505 .need_dac_fix = 1, 10781 .need_dac_fix = 1,
10506 .input_mux = &alc883_lenovo_nb0763_capture_source, 10782 .input_mux = &alc883_lenovo_nb0763_capture_source,
10507 .unsol_event = alc_automute_amp_unsol_event, 10783 .unsol_event = alc_sku_unsol_event,
10508 .setup = alc883_lenovo_nb0763_setup, 10784 .setup = alc883_lenovo_nb0763_setup,
10509 .init_hook = alc_automute_amp, 10785 .init_hook = alc_hp_automute,
10510 }, 10786 },
10511 [ALC888_LENOVO_MS7195_DIG] = { 10787 [ALC888_LENOVO_MS7195_DIG] = {
10512 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10788 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
@@ -10518,8 +10794,9 @@ static struct alc_config_preset alc882_presets[] = {
10518 .channel_mode = alc883_3ST_6ch_modes, 10794 .channel_mode = alc883_3ST_6ch_modes,
10519 .need_dac_fix = 1, 10795 .need_dac_fix = 1,
10520 .input_mux = &alc883_capture_source, 10796 .input_mux = &alc883_capture_source,
10521 .unsol_event = alc883_lenovo_ms7195_unsol_event, 10797 .unsol_event = alc_sku_unsol_event,
10522 .init_hook = alc888_lenovo_ms7195_front_automute, 10798 .setup = alc888_lenovo_ms7195_setup,
10799 .init_hook = alc_inithook,
10523 }, 10800 },
10524 [ALC883_HAIER_W66] = { 10801 [ALC883_HAIER_W66] = {
10525 .mixers = { alc883_targa_2ch_mixer}, 10802 .mixers = { alc883_targa_2ch_mixer},
@@ -10530,9 +10807,9 @@ static struct alc_config_preset alc882_presets[] = {
10530 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10807 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10531 .channel_mode = alc883_3ST_2ch_modes, 10808 .channel_mode = alc883_3ST_2ch_modes,
10532 .input_mux = &alc883_capture_source, 10809 .input_mux = &alc883_capture_source,
10533 .unsol_event = alc_automute_amp_unsol_event, 10810 .unsol_event = alc_sku_unsol_event,
10534 .setup = alc883_haier_w66_setup, 10811 .setup = alc883_haier_w66_setup,
10535 .init_hook = alc_automute_amp, 10812 .init_hook = alc_hp_automute,
10536 }, 10813 },
10537 [ALC888_3ST_HP] = { 10814 [ALC888_3ST_HP] = {
10538 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10815 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
@@ -10543,9 +10820,9 @@ static struct alc_config_preset alc882_presets[] = {
10543 .channel_mode = alc888_3st_hp_modes, 10820 .channel_mode = alc888_3st_hp_modes,
10544 .need_dac_fix = 1, 10821 .need_dac_fix = 1,
10545 .input_mux = &alc883_capture_source, 10822 .input_mux = &alc883_capture_source,
10546 .unsol_event = alc_automute_amp_unsol_event, 10823 .unsol_event = alc_sku_unsol_event,
10547 .setup = alc888_3st_hp_setup, 10824 .setup = alc888_3st_hp_setup,
10548 .init_hook = alc_automute_amp, 10825 .init_hook = alc_hp_automute,
10549 }, 10826 },
10550 [ALC888_6ST_DELL] = { 10827 [ALC888_6ST_DELL] = {
10551 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10828 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
@@ -10557,9 +10834,9 @@ static struct alc_config_preset alc882_presets[] = {
10557 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10834 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10558 .channel_mode = alc883_sixstack_modes, 10835 .channel_mode = alc883_sixstack_modes,
10559 .input_mux = &alc883_capture_source, 10836 .input_mux = &alc883_capture_source,
10560 .unsol_event = alc_automute_amp_unsol_event, 10837 .unsol_event = alc_sku_unsol_event,
10561 .setup = alc888_6st_dell_setup, 10838 .setup = alc888_6st_dell_setup,
10562 .init_hook = alc_automute_amp, 10839 .init_hook = alc_hp_automute,
10563 }, 10840 },
10564 [ALC883_MITAC] = { 10841 [ALC883_MITAC] = {
10565 .mixers = { alc883_mitac_mixer }, 10842 .mixers = { alc883_mitac_mixer },
@@ -10569,9 +10846,9 @@ static struct alc_config_preset alc882_presets[] = {
10569 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10846 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10570 .channel_mode = alc883_3ST_2ch_modes, 10847 .channel_mode = alc883_3ST_2ch_modes,
10571 .input_mux = &alc883_capture_source, 10848 .input_mux = &alc883_capture_source,
10572 .unsol_event = alc_automute_amp_unsol_event, 10849 .unsol_event = alc_sku_unsol_event,
10573 .setup = alc883_mitac_setup, 10850 .setup = alc883_mitac_setup,
10574 .init_hook = alc_automute_amp, 10851 .init_hook = alc_hp_automute,
10575 }, 10852 },
10576 [ALC883_FUJITSU_PI2515] = { 10853 [ALC883_FUJITSU_PI2515] = {
10577 .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, 10854 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
@@ -10583,9 +10860,9 @@ static struct alc_config_preset alc882_presets[] = {
10583 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10860 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10584 .channel_mode = alc883_3ST_2ch_modes, 10861 .channel_mode = alc883_3ST_2ch_modes,
10585 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10862 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10586 .unsol_event = alc_automute_amp_unsol_event, 10863 .unsol_event = alc_sku_unsol_event,
10587 .setup = alc883_2ch_fujitsu_pi2515_setup, 10864 .setup = alc883_2ch_fujitsu_pi2515_setup,
10588 .init_hook = alc_automute_amp, 10865 .init_hook = alc_hp_automute,
10589 }, 10866 },
10590 [ALC888_FUJITSU_XA3530] = { 10867 [ALC888_FUJITSU_XA3530] = {
10591 .mixers = { alc888_base_mixer, alc883_chmode_mixer }, 10868 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
@@ -10602,9 +10879,9 @@ static struct alc_config_preset alc882_presets[] = {
10602 .num_mux_defs = 10879 .num_mux_defs =
10603 ARRAY_SIZE(alc888_2_capture_sources), 10880 ARRAY_SIZE(alc888_2_capture_sources),
10604 .input_mux = alc888_2_capture_sources, 10881 .input_mux = alc888_2_capture_sources,
10605 .unsol_event = alc_automute_amp_unsol_event, 10882 .unsol_event = alc_sku_unsol_event,
10606 .setup = alc888_fujitsu_xa3530_setup, 10883 .setup = alc888_fujitsu_xa3530_setup,
10607 .init_hook = alc_automute_amp, 10884 .init_hook = alc_hp_automute,
10608 }, 10885 },
10609 [ALC888_LENOVO_SKY] = { 10886 [ALC888_LENOVO_SKY] = {
10610 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, 10887 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
@@ -10616,9 +10893,9 @@ static struct alc_config_preset alc882_presets[] = {
10616 .channel_mode = alc883_sixstack_modes, 10893 .channel_mode = alc883_sixstack_modes,
10617 .need_dac_fix = 1, 10894 .need_dac_fix = 1,
10618 .input_mux = &alc883_lenovo_sky_capture_source, 10895 .input_mux = &alc883_lenovo_sky_capture_source,
10619 .unsol_event = alc_automute_amp_unsol_event, 10896 .unsol_event = alc_sku_unsol_event,
10620 .setup = alc888_lenovo_sky_setup, 10897 .setup = alc888_lenovo_sky_setup,
10621 .init_hook = alc_automute_amp, 10898 .init_hook = alc_hp_automute,
10622 }, 10899 },
10623 [ALC888_ASUS_M90V] = { 10900 [ALC888_ASUS_M90V] = {
10624 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10901 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
@@ -10686,9 +10963,9 @@ static struct alc_config_preset alc882_presets[] = {
10686 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10963 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10687 .channel_mode = alc883_3ST_2ch_modes, 10964 .channel_mode = alc883_3ST_2ch_modes,
10688 .input_mux = &alc883_capture_source, 10965 .input_mux = &alc883_capture_source,
10689 .unsol_event = alc_automute_amp_unsol_event, 10966 .unsol_event = alc_sku_unsol_event,
10690 .setup = alc883_vaiott_setup, 10967 .setup = alc883_vaiott_setup,
10691 .init_hook = alc_automute_amp, 10968 .init_hook = alc_hp_automute,
10692 }, 10969 },
10693}; 10970};
10694 10971
@@ -10734,7 +11011,7 @@ static const struct alc_fixup alc882_fixups[] = {
10734 }, 11011 },
10735}; 11012};
10736 11013
10737static struct snd_pci_quirk alc882_fixup_tbl[] = { 11014static const struct snd_pci_quirk alc882_fixup_tbl[] = {
10738 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), 11015 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
10739 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), 11016 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
10740 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 11017 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
@@ -10842,6 +11119,11 @@ static void alc882_auto_init_input_src(struct hda_codec *codec)
10842 const struct hda_input_mux *imux; 11119 const struct hda_input_mux *imux;
10843 int conns, mute, idx, item; 11120 int conns, mute, idx, item;
10844 11121
11122 /* mute ADC */
11123 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11124 AC_VERB_SET_AMP_GAIN_MUTE,
11125 AMP_IN_MUTE(0));
11126
10845 conns = snd_hda_get_connections(codec, nid, conn_list, 11127 conns = snd_hda_get_connections(codec, nid, conn_list,
10846 ARRAY_SIZE(conn_list)); 11128 ARRAY_SIZE(conn_list));
10847 if (conns < 0) 11129 if (conns < 0)
@@ -10921,7 +11203,7 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec)
10921static int alc882_parse_auto_config(struct hda_codec *codec) 11203static int alc882_parse_auto_config(struct hda_codec *codec)
10922{ 11204{
10923 struct alc_spec *spec = codec->spec; 11205 struct alc_spec *spec = codec->spec;
10924 static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; 11206 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10925 int err; 11207 int err;
10926 11208
10927 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 11209 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
@@ -10934,6 +11216,9 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
10934 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 11216 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10935 if (err < 0) 11217 if (err < 0)
10936 return err; 11218 return err;
11219 err = alc_auto_add_multi_channel_mode(codec);
11220 if (err < 0)
11221 return err;
10937 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 11222 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10938 if (err < 0) 11223 if (err < 0)
10939 return err; 11224 return err;
@@ -11135,14 +11420,14 @@ static int patch_alc882(struct hda_codec *codec)
11135#define alc262_modes alc260_modes 11420#define alc262_modes alc260_modes
11136#define alc262_capture_source alc882_capture_source 11421#define alc262_capture_source alc882_capture_source
11137 11422
11138static hda_nid_t alc262_dmic_adc_nids[1] = { 11423static const hda_nid_t alc262_dmic_adc_nids[1] = {
11139 /* ADC0 */ 11424 /* ADC0 */
11140 0x09 11425 0x09
11141}; 11426};
11142 11427
11143static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; 11428static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11144 11429
11145static struct snd_kcontrol_new alc262_base_mixer[] = { 11430static const struct snd_kcontrol_new alc262_base_mixer[] = {
11146 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11431 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11147 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11432 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11148 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11433 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -11163,71 +11448,30 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
11163}; 11448};
11164 11449
11165/* update HP, line and mono-out pins according to the master switch */ 11450/* update HP, line and mono-out pins according to the master switch */
11166static void alc262_hp_master_update(struct hda_codec *codec) 11451#define alc262_hp_master_update alc260_hp_master_update
11167{
11168 struct alc_spec *spec = codec->spec;
11169 int val = spec->master_sw;
11170
11171 /* HP & line-out */
11172 snd_hda_codec_write_cache(codec, 0x1b, 0,
11173 AC_VERB_SET_PIN_WIDGET_CONTROL,
11174 val ? PIN_HP : 0);
11175 snd_hda_codec_write_cache(codec, 0x15, 0,
11176 AC_VERB_SET_PIN_WIDGET_CONTROL,
11177 val ? PIN_HP : 0);
11178 /* mono (speaker) depending on the HP jack sense */
11179 val = val && !spec->jack_present;
11180 snd_hda_codec_write_cache(codec, 0x16, 0,
11181 AC_VERB_SET_PIN_WIDGET_CONTROL,
11182 val ? PIN_OUT : 0);
11183}
11184 11452
11185static void alc262_hp_bpc_automute(struct hda_codec *codec) 11453static void alc262_hp_bpc_setup(struct hda_codec *codec)
11186{ 11454{
11187 struct alc_spec *spec = codec->spec; 11455 struct alc_spec *spec = codec->spec;
11188 11456
11189 spec->jack_present = snd_hda_jack_detect(codec, 0x1b); 11457 spec->autocfg.hp_pins[0] = 0x1b;
11190 alc262_hp_master_update(codec); 11458 spec->autocfg.speaker_pins[0] = 0x16;
11191} 11459 spec->automute = 1;
11192 11460 spec->automute_mode = ALC_AUTOMUTE_PIN;
11193static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11194{
11195 if ((res >> 26) != ALC880_HP_EVENT)
11196 return;
11197 alc262_hp_bpc_automute(codec);
11198} 11461}
11199 11462
11200static void alc262_hp_wildwest_automute(struct hda_codec *codec) 11463static void alc262_hp_wildwest_setup(struct hda_codec *codec)
11201{ 11464{
11202 struct alc_spec *spec = codec->spec; 11465 struct alc_spec *spec = codec->spec;
11203 11466
11204 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 11467 spec->autocfg.hp_pins[0] = 0x15;
11205 alc262_hp_master_update(codec); 11468 spec->autocfg.speaker_pins[0] = 0x16;
11206} 11469 spec->automute = 1;
11207 11470 spec->automute_mode = ALC_AUTOMUTE_PIN;
11208static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11209 unsigned int res)
11210{
11211 if ((res >> 26) != ALC880_HP_EVENT)
11212 return;
11213 alc262_hp_wildwest_automute(codec);
11214} 11471}
11215 11472
11216#define alc262_hp_master_sw_get alc260_hp_master_sw_get 11473#define alc262_hp_master_sw_get alc260_hp_master_sw_get
11217 11474#define alc262_hp_master_sw_put alc260_hp_master_sw_put
11218static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11219 struct snd_ctl_elem_value *ucontrol)
11220{
11221 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11222 struct alc_spec *spec = codec->spec;
11223 int val = !!*ucontrol->value.integer.value;
11224
11225 if (val == spec->master_sw)
11226 return 0;
11227 spec->master_sw = val;
11228 alc262_hp_master_update(codec);
11229 return 1;
11230}
11231 11475
11232#define ALC262_HP_MASTER_SWITCH \ 11476#define ALC262_HP_MASTER_SWITCH \
11233 { \ 11477 { \
@@ -11244,7 +11488,7 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11244 } 11488 }
11245 11489
11246 11490
11247static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 11491static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11248 ALC262_HP_MASTER_SWITCH, 11492 ALC262_HP_MASTER_SWITCH,
11249 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11493 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11250 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11494 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -11268,7 +11512,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11268 { } /* end */ 11512 { } /* end */
11269}; 11513};
11270 11514
11271static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 11515static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11272 ALC262_HP_MASTER_SWITCH, 11516 ALC262_HP_MASTER_SWITCH,
11273 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11517 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11274 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11518 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
@@ -11288,7 +11532,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11288 { } /* end */ 11532 { } /* end */
11289}; 11533};
11290 11534
11291static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 11535static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11292 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11536 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11293 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11537 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11294 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT), 11538 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
@@ -11302,9 +11546,11 @@ static void alc262_hp_t5735_setup(struct hda_codec *codec)
11302 11546
11303 spec->autocfg.hp_pins[0] = 0x15; 11547 spec->autocfg.hp_pins[0] = 0x15;
11304 spec->autocfg.speaker_pins[0] = 0x14; 11548 spec->autocfg.speaker_pins[0] = 0x14;
11549 spec->automute = 1;
11550 spec->automute_mode = ALC_AUTOMUTE_PIN;
11305} 11551}
11306 11552
11307static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { 11553static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11308 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11554 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11309 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11555 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11310 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11556 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -11315,7 +11561,7 @@ static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11315 { } /* end */ 11561 { } /* end */
11316}; 11562};
11317 11563
11318static struct hda_verb alc262_hp_t5735_verbs[] = { 11564static const struct hda_verb alc262_hp_t5735_verbs[] = {
11319 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11565 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11320 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11566 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11321 11567
@@ -11323,7 +11569,7 @@ static struct hda_verb alc262_hp_t5735_verbs[] = {
11323 { } 11569 { }
11324}; 11570};
11325 11571
11326static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { 11572static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11327 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11573 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11328 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11574 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11329 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 11575 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
@@ -11333,7 +11579,7 @@ static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11333 { } /* end */ 11579 { } /* end */
11334}; 11580};
11335 11581
11336static struct hda_verb alc262_hp_rp5700_verbs[] = { 11582static const struct hda_verb alc262_hp_rp5700_verbs[] = {
11337 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11583 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11338 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11584 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11339 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11585 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -11347,7 +11593,7 @@ static struct hda_verb alc262_hp_rp5700_verbs[] = {
11347 {} 11593 {}
11348}; 11594};
11349 11595
11350static struct hda_input_mux alc262_hp_rp5700_capture_source = { 11596static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
11351 .num_items = 1, 11597 .num_items = 1,
11352 .items = { 11598 .items = {
11353 { "Line", 0x1 }, 11599 { "Line", 0x1 },
@@ -11355,44 +11601,9 @@ static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11355}; 11601};
11356 11602
11357/* bind hp and internal speaker mute (with plug check) as master switch */ 11603/* bind hp and internal speaker mute (with plug check) as master switch */
11358static void alc262_hippo_master_update(struct hda_codec *codec) 11604#define alc262_hippo_master_update alc262_hp_master_update
11359{
11360 struct alc_spec *spec = codec->spec;
11361 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11362 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11363 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11364 unsigned int mute;
11365
11366 /* HP */
11367 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11368 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11369 HDA_AMP_MUTE, mute);
11370 /* mute internal speaker per jack sense */
11371 if (spec->jack_present)
11372 mute = HDA_AMP_MUTE;
11373 if (line_nid)
11374 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11375 HDA_AMP_MUTE, mute);
11376 if (speaker_nid && speaker_nid != line_nid)
11377 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
11378 HDA_AMP_MUTE, mute);
11379}
11380
11381#define alc262_hippo_master_sw_get alc262_hp_master_sw_get 11605#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11382 11606#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
11383static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11384 struct snd_ctl_elem_value *ucontrol)
11385{
11386 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11387 struct alc_spec *spec = codec->spec;
11388 int val = !!*ucontrol->value.integer.value;
11389
11390 if (val == spec->master_sw)
11391 return 0;
11392 spec->master_sw = val;
11393 alc262_hippo_master_update(codec);
11394 return 1;
11395}
11396 11607
11397#define ALC262_HIPPO_MASTER_SWITCH \ 11608#define ALC262_HIPPO_MASTER_SWITCH \
11398 { \ 11609 { \
@@ -11409,7 +11620,7 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11409 (SUBDEV_SPEAKER(0) << 16), \ 11620 (SUBDEV_SPEAKER(0) << 16), \
11410 } 11621 }
11411 11622
11412static struct snd_kcontrol_new alc262_hippo_mixer[] = { 11623static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
11413 ALC262_HIPPO_MASTER_SWITCH, 11624 ALC262_HIPPO_MASTER_SWITCH,
11414 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11625 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11415 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11626 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -11426,7 +11637,7 @@ static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11426 { } /* end */ 11637 { } /* end */
11427}; 11638};
11428 11639
11429static struct snd_kcontrol_new alc262_hippo1_mixer[] = { 11640static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11430 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11641 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11431 ALC262_HIPPO_MASTER_SWITCH, 11642 ALC262_HIPPO_MASTER_SWITCH,
11432 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11643 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -11443,28 +11654,14 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11443}; 11654};
11444 11655
11445/* mute/unmute internal speaker according to the hp jack and mute state */ 11656/* mute/unmute internal speaker according to the hp jack and mute state */
11446static void alc262_hippo_automute(struct hda_codec *codec)
11447{
11448 struct alc_spec *spec = codec->spec;
11449 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11450
11451 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
11452 alc262_hippo_master_update(codec);
11453}
11454
11455static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11456{
11457 if ((res >> 26) != ALC880_HP_EVENT)
11458 return;
11459 alc262_hippo_automute(codec);
11460}
11461
11462static void alc262_hippo_setup(struct hda_codec *codec) 11657static void alc262_hippo_setup(struct hda_codec *codec)
11463{ 11658{
11464 struct alc_spec *spec = codec->spec; 11659 struct alc_spec *spec = codec->spec;
11465 11660
11466 spec->autocfg.hp_pins[0] = 0x15; 11661 spec->autocfg.hp_pins[0] = 0x15;
11467 spec->autocfg.speaker_pins[0] = 0x14; 11662 spec->autocfg.speaker_pins[0] = 0x14;
11663 spec->automute = 1;
11664 spec->automute_mode = ALC_AUTOMUTE_AMP;
11468} 11665}
11469 11666
11470static void alc262_hippo1_setup(struct hda_codec *codec) 11667static void alc262_hippo1_setup(struct hda_codec *codec)
@@ -11473,10 +11670,12 @@ static void alc262_hippo1_setup(struct hda_codec *codec)
11473 11670
11474 spec->autocfg.hp_pins[0] = 0x1b; 11671 spec->autocfg.hp_pins[0] = 0x1b;
11475 spec->autocfg.speaker_pins[0] = 0x14; 11672 spec->autocfg.speaker_pins[0] = 0x14;
11673 spec->automute = 1;
11674 spec->automute_mode = ALC_AUTOMUTE_AMP;
11476} 11675}
11477 11676
11478 11677
11479static struct snd_kcontrol_new alc262_sony_mixer[] = { 11678static const struct snd_kcontrol_new alc262_sony_mixer[] = {
11480 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11679 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11481 ALC262_HIPPO_MASTER_SWITCH, 11680 ALC262_HIPPO_MASTER_SWITCH,
11482 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11681 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -11486,7 +11685,7 @@ static struct snd_kcontrol_new alc262_sony_mixer[] = {
11486 { } /* end */ 11685 { } /* end */
11487}; 11686};
11488 11687
11489static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 11688static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11490 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11689 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11491 ALC262_HIPPO_MASTER_SWITCH, 11690 ALC262_HIPPO_MASTER_SWITCH,
11492 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11691 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -11497,7 +11696,7 @@ static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11497 { } /* end */ 11696 { } /* end */
11498}; 11697};
11499 11698
11500static struct snd_kcontrol_new alc262_tyan_mixer[] = { 11699static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
11501 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11700 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11502 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11701 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11503 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), 11702 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
@@ -11513,7 +11712,7 @@ static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11513 { } /* end */ 11712 { } /* end */
11514}; 11713};
11515 11714
11516static struct hda_verb alc262_tyan_verbs[] = { 11715static const struct hda_verb alc262_tyan_verbs[] = {
11517 /* Headphone automute */ 11716 /* Headphone automute */
11518 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11717 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11519 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11718 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -11535,6 +11734,8 @@ static void alc262_tyan_setup(struct hda_codec *codec)
11535 11734
11536 spec->autocfg.hp_pins[0] = 0x1b; 11735 spec->autocfg.hp_pins[0] = 0x1b;
11537 spec->autocfg.speaker_pins[0] = 0x15; 11736 spec->autocfg.speaker_pins[0] = 0x15;
11737 spec->automute = 1;
11738 spec->automute_mode = ALC_AUTOMUTE_AMP;
11538} 11739}
11539 11740
11540 11741
@@ -11544,7 +11745,7 @@ static void alc262_tyan_setup(struct hda_codec *codec)
11544/* 11745/*
11545 * generic initialization of ADC, input mixers and output mixers 11746 * generic initialization of ADC, input mixers and output mixers
11546 */ 11747 */
11547static struct hda_verb alc262_init_verbs[] = { 11748static const struct hda_verb alc262_init_verbs[] = {
11548 /* 11749 /*
11549 * Unmute ADC0-2 and set the default input to mic-in 11750 * Unmute ADC0-2 and set the default input to mic-in
11550 */ 11751 */
@@ -11620,13 +11821,13 @@ static struct hda_verb alc262_init_verbs[] = {
11620 { } 11821 { }
11621}; 11822};
11622 11823
11623static struct hda_verb alc262_eapd_verbs[] = { 11824static const struct hda_verb alc262_eapd_verbs[] = {
11624 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11825 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11625 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11826 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11626 { } 11827 { }
11627}; 11828};
11628 11829
11629static struct hda_verb alc262_hippo1_unsol_verbs[] = { 11830static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
11630 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11831 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11631 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11832 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11632 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11833 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
@@ -11636,7 +11837,7 @@ static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11636 {} 11837 {}
11637}; 11838};
11638 11839
11639static struct hda_verb alc262_sony_unsol_verbs[] = { 11840static const struct hda_verb alc262_sony_unsol_verbs[] = {
11640 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11841 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11641 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11842 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11642 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic 11843 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
@@ -11646,7 +11847,7 @@ static struct hda_verb alc262_sony_unsol_verbs[] = {
11646 {} 11847 {}
11647}; 11848};
11648 11849
11649static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { 11850static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11650 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11851 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11651 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11852 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11652 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11853 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -11655,7 +11856,7 @@ static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11655 { } /* end */ 11856 { } /* end */
11656}; 11857};
11657 11858
11658static struct hda_verb alc262_toshiba_s06_verbs[] = { 11859static const struct hda_verb alc262_toshiba_s06_verbs[] = {
11659 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11860 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11660 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11861 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11661 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11862 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -11678,6 +11879,8 @@ static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11678 spec->int_mic.pin = 0x12; 11879 spec->int_mic.pin = 0x12;
11679 spec->int_mic.mux_idx = 9; 11880 spec->int_mic.mux_idx = 9;
11680 spec->auto_mic = 1; 11881 spec->auto_mic = 1;
11882 spec->automute = 1;
11883 spec->automute_mode = ALC_AUTOMUTE_PIN;
11681} 11884}
11682 11885
11683/* 11886/*
@@ -11687,7 +11890,7 @@ static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11687 * 0x18 = external mic 11890 * 0x18 = external mic
11688 */ 11891 */
11689 11892
11690static struct snd_kcontrol_new alc262_nec_mixer[] = { 11893static const struct snd_kcontrol_new alc262_nec_mixer[] = {
11691 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 11894 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11692 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), 11895 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11693 11896
@@ -11700,7 +11903,7 @@ static struct snd_kcontrol_new alc262_nec_mixer[] = {
11700 { } /* end */ 11903 { } /* end */
11701}; 11904};
11702 11905
11703static struct hda_verb alc262_nec_verbs[] = { 11906static const struct hda_verb alc262_nec_verbs[] = {
11704 /* Unmute Speaker */ 11907 /* Unmute Speaker */
11705 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11908 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11706 11909
@@ -11723,7 +11926,7 @@ static struct hda_verb alc262_nec_verbs[] = {
11723 11926
11724#define ALC_HP_EVENT 0x37 11927#define ALC_HP_EVENT 0x37
11725 11928
11726static struct hda_verb alc262_fujitsu_unsol_verbs[] = { 11929static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11727 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11930 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11728 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11931 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11729 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11932 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
@@ -11731,20 +11934,20 @@ static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11731 {} 11934 {}
11732}; 11935};
11733 11936
11734static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { 11937static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11735 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11938 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11736 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11939 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11737 {} 11940 {}
11738}; 11941};
11739 11942
11740static struct hda_verb alc262_lenovo_3000_init_verbs[] = { 11943static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11741 /* Front Mic pin: input vref at 50% */ 11944 /* Front Mic pin: input vref at 50% */
11742 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 11945 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11743 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11946 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11744 {} 11947 {}
11745}; 11948};
11746 11949
11747static struct hda_input_mux alc262_fujitsu_capture_source = { 11950static const struct hda_input_mux alc262_fujitsu_capture_source = {
11748 .num_items = 3, 11951 .num_items = 3,
11749 .items = { 11952 .items = {
11750 { "Mic", 0x0 }, 11953 { "Mic", 0x0 },
@@ -11753,7 +11956,7 @@ static struct hda_input_mux alc262_fujitsu_capture_source = {
11753 }, 11956 },
11754}; 11957};
11755 11958
11756static struct hda_input_mux alc262_HP_capture_source = { 11959static const struct hda_input_mux alc262_HP_capture_source = {
11757 .num_items = 5, 11960 .num_items = 5,
11758 .items = { 11961 .items = {
11759 { "Mic", 0x0 }, 11962 { "Mic", 0x0 },
@@ -11764,7 +11967,7 @@ static struct hda_input_mux alc262_HP_capture_source = {
11764 }, 11967 },
11765}; 11968};
11766 11969
11767static struct hda_input_mux alc262_HP_D7000_capture_source = { 11970static const struct hda_input_mux alc262_HP_D7000_capture_source = {
11768 .num_items = 4, 11971 .num_items = 4,
11769 .items = { 11972 .items = {
11770 { "Mic", 0x0 }, 11973 { "Mic", 0x0 },
@@ -11774,44 +11977,19 @@ static struct hda_input_mux alc262_HP_D7000_capture_source = {
11774 }, 11977 },
11775}; 11978};
11776 11979
11777/* mute/unmute internal speaker according to the hp jacks and mute state */ 11980static void alc262_fujitsu_setup(struct hda_codec *codec)
11778static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11779{ 11981{
11780 struct alc_spec *spec = codec->spec; 11982 struct alc_spec *spec = codec->spec;
11781 unsigned int mute;
11782
11783 if (force || !spec->sense_updated) {
11784 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11785 snd_hda_jack_detect(codec, 0x1b);
11786 spec->sense_updated = 1;
11787 }
11788 /* unmute internal speaker only if both HPs are unplugged and
11789 * master switch is on
11790 */
11791 if (spec->jack_present)
11792 mute = HDA_AMP_MUTE;
11793 else
11794 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11795 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11796 HDA_AMP_MUTE, mute);
11797}
11798
11799/* unsolicited event for HP jack sensing */
11800static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11801 unsigned int res)
11802{
11803 if ((res >> 26) != ALC_HP_EVENT)
11804 return;
11805 alc262_fujitsu_automute(codec, 1);
11806}
11807 11983
11808static void alc262_fujitsu_init_hook(struct hda_codec *codec) 11984 spec->autocfg.hp_pins[0] = 0x14;
11809{ 11985 spec->autocfg.hp_pins[1] = 0x1b;
11810 alc262_fujitsu_automute(codec, 1); 11986 spec->autocfg.speaker_pins[0] = 0x15;
11987 spec->automute = 1;
11988 spec->automute_mode = ALC_AUTOMUTE_AMP;
11811} 11989}
11812 11990
11813/* bind volumes of both NID 0x0c and 0x0d */ 11991/* bind volumes of both NID 0x0c and 0x0d */
11814static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 11992static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11815 .ops = &snd_hda_bind_vol, 11993 .ops = &snd_hda_bind_vol,
11816 .values = { 11994 .values = {
11817 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 11995 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
@@ -11820,78 +11998,15 @@ static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11820 }, 11998 },
11821}; 11999};
11822 12000
11823/* mute/unmute internal speaker according to the hp jack and mute state */ 12001static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11824static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11825{
11826 struct alc_spec *spec = codec->spec;
11827 unsigned int mute;
11828
11829 if (force || !spec->sense_updated) {
11830 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11831 spec->sense_updated = 1;
11832 }
11833 if (spec->jack_present) {
11834 /* mute internal speaker */
11835 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11836 HDA_AMP_MUTE, HDA_AMP_MUTE);
11837 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11838 HDA_AMP_MUTE, HDA_AMP_MUTE);
11839 } else {
11840 /* unmute internal speaker if necessary */
11841 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11842 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11843 HDA_AMP_MUTE, mute);
11844 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11845 HDA_AMP_MUTE, mute);
11846 }
11847}
11848
11849/* unsolicited event for HP jack sensing */
11850static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11851 unsigned int res)
11852{
11853 if ((res >> 26) != ALC_HP_EVENT)
11854 return;
11855 alc262_lenovo_3000_automute(codec, 1);
11856}
11857
11858static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11859 int dir, int idx, long *valp)
11860{
11861 int i, change = 0;
11862
11863 for (i = 0; i < 2; i++, valp++)
11864 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11865 HDA_AMP_MUTE,
11866 *valp ? 0 : HDA_AMP_MUTE);
11867 return change;
11868}
11869
11870/* bind hp and internal speaker mute (with plug check) */
11871static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11872 struct snd_ctl_elem_value *ucontrol)
11873{
11874 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11875 long *valp = ucontrol->value.integer.value;
11876 int change;
11877
11878 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11879 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11880 if (change)
11881 alc262_fujitsu_automute(codec, 0);
11882 return change;
11883}
11884
11885static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11886 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 12002 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11887 { 12003 {
11888 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12004 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11889 .name = "Master Playback Switch", 12005 .name = "Master Playback Switch",
11890 .subdevice = HDA_SUBDEV_AMP_FLAG, 12006 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11891 .info = snd_hda_mixer_amp_switch_info, 12007 .info = snd_ctl_boolean_mono_info,
11892 .get = snd_hda_mixer_amp_switch_get, 12008 .get = alc262_hp_master_sw_get,
11893 .put = alc262_fujitsu_master_sw_put, 12009 .put = alc262_hp_master_sw_put,
11894 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11895 }, 12010 },
11896 { 12011 {
11897 .iface = NID_MAPPING, 12012 .iface = NID_MAPPING,
@@ -11909,30 +12024,26 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11909 { } /* end */ 12024 { } /* end */
11910}; 12025};
11911 12026
11912/* bind hp and internal speaker mute (with plug check) */ 12027static void alc262_lenovo_3000_setup(struct hda_codec *codec)
11913static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11914 struct snd_ctl_elem_value *ucontrol)
11915{ 12028{
11916 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 12029 struct alc_spec *spec = codec->spec;
11917 long *valp = ucontrol->value.integer.value;
11918 int change;
11919 12030
11920 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); 12031 spec->autocfg.hp_pins[0] = 0x1b;
11921 if (change) 12032 spec->autocfg.speaker_pins[0] = 0x14;
11922 alc262_lenovo_3000_automute(codec, 0); 12033 spec->autocfg.speaker_pins[1] = 0x16;
11923 return change; 12034 spec->automute = 1;
12035 spec->automute_mode = ALC_AUTOMUTE_AMP;
11924} 12036}
11925 12037
11926static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { 12038static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11927 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 12039 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11928 { 12040 {
11929 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12041 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11930 .name = "Master Playback Switch", 12042 .name = "Master Playback Switch",
11931 .subdevice = HDA_SUBDEV_AMP_FLAG, 12043 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
11932 .info = snd_hda_mixer_amp_switch_info, 12044 .info = snd_ctl_boolean_mono_info,
11933 .get = snd_hda_mixer_amp_switch_get, 12045 .get = alc262_hp_master_sw_get,
11934 .put = alc262_lenovo_3000_master_sw_put, 12046 .put = alc262_hp_master_sw_put,
11935 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11936 }, 12047 },
11937 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 12048 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11938 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 12049 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
@@ -11945,7 +12056,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11945 { } /* end */ 12056 { } /* end */
11946}; 12057};
11947 12058
11948static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { 12059static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11949 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 12060 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11950 ALC262_HIPPO_MASTER_SWITCH, 12061 ALC262_HIPPO_MASTER_SWITCH,
11951 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 12062 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -11958,13 +12069,13 @@ static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11958}; 12069};
11959 12070
11960/* additional init verbs for Benq laptops */ 12071/* additional init verbs for Benq laptops */
11961static struct hda_verb alc262_EAPD_verbs[] = { 12072static const struct hda_verb alc262_EAPD_verbs[] = {
11962 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 12073 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11963 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 12074 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11964 {} 12075 {}
11965}; 12076};
11966 12077
11967static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { 12078static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11968 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12079 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11969 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12080 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11970 12081
@@ -11974,7 +12085,7 @@ static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11974}; 12085};
11975 12086
11976/* Samsung Q1 Ultra Vista model setup */ 12087/* Samsung Q1 Ultra Vista model setup */
11977static struct snd_kcontrol_new alc262_ultra_mixer[] = { 12088static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
11978 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 12089 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11979 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 12090 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11980 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 12091 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
@@ -11984,7 +12095,7 @@ static struct snd_kcontrol_new alc262_ultra_mixer[] = {
11984 { } /* end */ 12095 { } /* end */
11985}; 12096};
11986 12097
11987static struct hda_verb alc262_ultra_verbs[] = { 12098static const struct hda_verb alc262_ultra_verbs[] = {
11988 /* output mixer */ 12099 /* output mixer */
11989 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12100 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11990 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
@@ -12047,7 +12158,7 @@ static void alc262_ultra_unsol_event(struct hda_codec *codec,
12047 alc262_ultra_automute(codec); 12158 alc262_ultra_automute(codec);
12048} 12159}
12049 12160
12050static struct hda_input_mux alc262_ultra_capture_source = { 12161static const struct hda_input_mux alc262_ultra_capture_source = {
12051 .num_items = 2, 12162 .num_items = 2,
12052 .items = { 12163 .items = {
12053 { "Mic", 0x1 }, 12164 { "Mic", 0x1 },
@@ -12073,7 +12184,7 @@ static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12073 return ret; 12184 return ret;
12074} 12185}
12075 12186
12076static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { 12187static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12077 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 12188 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12078 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 12189 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12079 { 12190 {
@@ -12148,9 +12259,9 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12148 12259
12149 spec->multiout.num_dacs = 1; /* only use one dac */ 12260 spec->multiout.num_dacs = 1; /* only use one dac */
12150 spec->multiout.dac_nids = spec->private_dac_nids; 12261 spec->multiout.dac_nids = spec->private_dac_nids;
12151 spec->multiout.dac_nids[0] = 2; 12262 spec->private_dac_nids[0] = 2;
12152 12263
12153 pfx = alc_get_line_out_pfx(cfg, true); 12264 pfx = alc_get_line_out_pfx(spec, true);
12154 if (!pfx) 12265 if (!pfx)
12155 pfx = "Front"; 12266 pfx = "Front";
12156 for (i = 0; i < 2; i++) { 12267 for (i = 0; i < 2; i++) {
@@ -12204,7 +12315,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12204/* 12315/*
12205 * generic initialization of ADC, input mixers and output mixers 12316 * generic initialization of ADC, input mixers and output mixers
12206 */ 12317 */
12207static struct hda_verb alc262_volume_init_verbs[] = { 12318static const struct hda_verb alc262_volume_init_verbs[] = {
12208 /* 12319 /*
12209 * Unmute ADC0-2 and set the default input to mic-in 12320 * Unmute ADC0-2 and set the default input to mic-in
12210 */ 12321 */
@@ -12265,7 +12376,7 @@ static struct hda_verb alc262_volume_init_verbs[] = {
12265 { } 12376 { }
12266}; 12377};
12267 12378
12268static struct hda_verb alc262_HP_BPC_init_verbs[] = { 12379static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
12269 /* 12380 /*
12270 * Unmute ADC0-2 and set the default input to mic-in 12381 * Unmute ADC0-2 and set the default input to mic-in
12271 */ 12382 */
@@ -12369,7 +12480,7 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12369 { } 12480 { }
12370}; 12481};
12371 12482
12372static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { 12483static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12373 /* 12484 /*
12374 * Unmute ADC0-2 and set the default input to mic-in 12485 * Unmute ADC0-2 and set the default input to mic-in
12375 */ 12486 */
@@ -12465,7 +12576,7 @@ static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12465 { } 12576 { }
12466}; 12577};
12467 12578
12468static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { 12579static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12469 12580
12470 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ 12581 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12471 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12582 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
@@ -12501,7 +12612,7 @@ static const struct alc_fixup alc262_fixups[] = {
12501 }, 12612 },
12502}; 12613};
12503 12614
12504static struct snd_pci_quirk alc262_fixup_tbl[] = { 12615static const struct snd_pci_quirk alc262_fixup_tbl[] = {
12505 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270), 12616 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12506 {} 12617 {}
12507}; 12618};
@@ -12524,7 +12635,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
12524{ 12635{
12525 struct alc_spec *spec = codec->spec; 12636 struct alc_spec *spec = codec->spec;
12526 int err; 12637 int err;
12527 static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 12638 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12528 12639
12529 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 12640 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12530 alc262_ignore); 12641 alc262_ignore);
@@ -12609,7 +12720,7 @@ static const char * const alc262_models[ALC262_MODEL_LAST] = {
12609 [ALC262_AUTO] = "auto", 12720 [ALC262_AUTO] = "auto",
12610}; 12721};
12611 12722
12612static struct snd_pci_quirk alc262_cfg_tbl[] = { 12723static const struct snd_pci_quirk alc262_cfg_tbl[] = {
12613 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 12724 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12614 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), 12725 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12615 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", 12726 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
@@ -12661,7 +12772,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
12661 {} 12772 {}
12662}; 12773};
12663 12774
12664static struct alc_config_preset alc262_presets[] = { 12775static const struct alc_config_preset alc262_presets[] = {
12665 [ALC262_BASIC] = { 12776 [ALC262_BASIC] = {
12666 .mixers = { alc262_base_mixer }, 12777 .mixers = { alc262_base_mixer },
12667 .init_verbs = { alc262_init_verbs }, 12778 .init_verbs = { alc262_init_verbs },
@@ -12682,9 +12793,9 @@ static struct alc_config_preset alc262_presets[] = {
12682 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12793 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12683 .channel_mode = alc262_modes, 12794 .channel_mode = alc262_modes,
12684 .input_mux = &alc262_capture_source, 12795 .input_mux = &alc262_capture_source,
12685 .unsol_event = alc262_hippo_unsol_event, 12796 .unsol_event = alc_sku_unsol_event,
12686 .setup = alc262_hippo_setup, 12797 .setup = alc262_hippo_setup,
12687 .init_hook = alc262_hippo_automute, 12798 .init_hook = alc_inithook,
12688 }, 12799 },
12689 [ALC262_HIPPO_1] = { 12800 [ALC262_HIPPO_1] = {
12690 .mixers = { alc262_hippo1_mixer }, 12801 .mixers = { alc262_hippo1_mixer },
@@ -12696,9 +12807,9 @@ static struct alc_config_preset alc262_presets[] = {
12696 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12807 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12697 .channel_mode = alc262_modes, 12808 .channel_mode = alc262_modes,
12698 .input_mux = &alc262_capture_source, 12809 .input_mux = &alc262_capture_source,
12699 .unsol_event = alc262_hippo_unsol_event, 12810 .unsol_event = alc_sku_unsol_event,
12700 .setup = alc262_hippo1_setup, 12811 .setup = alc262_hippo1_setup,
12701 .init_hook = alc262_hippo_automute, 12812 .init_hook = alc_inithook,
12702 }, 12813 },
12703 [ALC262_FUJITSU] = { 12814 [ALC262_FUJITSU] = {
12704 .mixers = { alc262_fujitsu_mixer }, 12815 .mixers = { alc262_fujitsu_mixer },
@@ -12711,8 +12822,9 @@ static struct alc_config_preset alc262_presets[] = {
12711 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12822 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12712 .channel_mode = alc262_modes, 12823 .channel_mode = alc262_modes,
12713 .input_mux = &alc262_fujitsu_capture_source, 12824 .input_mux = &alc262_fujitsu_capture_source,
12714 .unsol_event = alc262_fujitsu_unsol_event, 12825 .unsol_event = alc_sku_unsol_event,
12715 .init_hook = alc262_fujitsu_init_hook, 12826 .setup = alc262_fujitsu_setup,
12827 .init_hook = alc_inithook,
12716 }, 12828 },
12717 [ALC262_HP_BPC] = { 12829 [ALC262_HP_BPC] = {
12718 .mixers = { alc262_HP_BPC_mixer }, 12830 .mixers = { alc262_HP_BPC_mixer },
@@ -12723,8 +12835,9 @@ static struct alc_config_preset alc262_presets[] = {
12723 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12835 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12724 .channel_mode = alc262_modes, 12836 .channel_mode = alc262_modes,
12725 .input_mux = &alc262_HP_capture_source, 12837 .input_mux = &alc262_HP_capture_source,
12726 .unsol_event = alc262_hp_bpc_unsol_event, 12838 .unsol_event = alc_sku_unsol_event,
12727 .init_hook = alc262_hp_bpc_automute, 12839 .setup = alc262_hp_bpc_setup,
12840 .init_hook = alc_inithook,
12728 }, 12841 },
12729 [ALC262_HP_BPC_D7000_WF] = { 12842 [ALC262_HP_BPC_D7000_WF] = {
12730 .mixers = { alc262_HP_BPC_WildWest_mixer }, 12843 .mixers = { alc262_HP_BPC_WildWest_mixer },
@@ -12735,8 +12848,9 @@ static struct alc_config_preset alc262_presets[] = {
12735 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12848 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12736 .channel_mode = alc262_modes, 12849 .channel_mode = alc262_modes,
12737 .input_mux = &alc262_HP_D7000_capture_source, 12850 .input_mux = &alc262_HP_D7000_capture_source,
12738 .unsol_event = alc262_hp_wildwest_unsol_event, 12851 .unsol_event = alc_sku_unsol_event,
12739 .init_hook = alc262_hp_wildwest_automute, 12852 .setup = alc262_hp_wildwest_setup,
12853 .init_hook = alc_inithook,
12740 }, 12854 },
12741 [ALC262_HP_BPC_D7000_WL] = { 12855 [ALC262_HP_BPC_D7000_WL] = {
12742 .mixers = { alc262_HP_BPC_WildWest_mixer, 12856 .mixers = { alc262_HP_BPC_WildWest_mixer,
@@ -12748,8 +12862,9 @@ static struct alc_config_preset alc262_presets[] = {
12748 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12862 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12749 .channel_mode = alc262_modes, 12863 .channel_mode = alc262_modes,
12750 .input_mux = &alc262_HP_D7000_capture_source, 12864 .input_mux = &alc262_HP_D7000_capture_source,
12751 .unsol_event = alc262_hp_wildwest_unsol_event, 12865 .unsol_event = alc_sku_unsol_event,
12752 .init_hook = alc262_hp_wildwest_automute, 12866 .setup = alc262_hp_wildwest_setup,
12867 .init_hook = alc_inithook,
12753 }, 12868 },
12754 [ALC262_HP_TC_T5735] = { 12869 [ALC262_HP_TC_T5735] = {
12755 .mixers = { alc262_hp_t5735_mixer }, 12870 .mixers = { alc262_hp_t5735_mixer },
@@ -12792,9 +12907,9 @@ static struct alc_config_preset alc262_presets[] = {
12792 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12907 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12793 .channel_mode = alc262_modes, 12908 .channel_mode = alc262_modes,
12794 .input_mux = &alc262_capture_source, 12909 .input_mux = &alc262_capture_source,
12795 .unsol_event = alc262_hippo_unsol_event, 12910 .unsol_event = alc_sku_unsol_event,
12796 .setup = alc262_hippo_setup, 12911 .setup = alc262_hippo_setup,
12797 .init_hook = alc262_hippo_automute, 12912 .init_hook = alc_inithook,
12798 }, 12913 },
12799 [ALC262_BENQ_T31] = { 12914 [ALC262_BENQ_T31] = {
12800 .mixers = { alc262_benq_t31_mixer }, 12915 .mixers = { alc262_benq_t31_mixer },
@@ -12806,9 +12921,9 @@ static struct alc_config_preset alc262_presets[] = {
12806 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12921 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12807 .channel_mode = alc262_modes, 12922 .channel_mode = alc262_modes,
12808 .input_mux = &alc262_capture_source, 12923 .input_mux = &alc262_capture_source,
12809 .unsol_event = alc262_hippo_unsol_event, 12924 .unsol_event = alc_sku_unsol_event,
12810 .setup = alc262_hippo_setup, 12925 .setup = alc262_hippo_setup,
12811 .init_hook = alc262_hippo_automute, 12926 .init_hook = alc_inithook,
12812 }, 12927 },
12813 [ALC262_ULTRA] = { 12928 [ALC262_ULTRA] = {
12814 .mixers = { alc262_ultra_mixer }, 12929 .mixers = { alc262_ultra_mixer },
@@ -12837,7 +12952,9 @@ static struct alc_config_preset alc262_presets[] = {
12837 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12952 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12838 .channel_mode = alc262_modes, 12953 .channel_mode = alc262_modes,
12839 .input_mux = &alc262_fujitsu_capture_source, 12954 .input_mux = &alc262_fujitsu_capture_source,
12840 .unsol_event = alc262_lenovo_3000_unsol_event, 12955 .unsol_event = alc_sku_unsol_event,
12956 .setup = alc262_lenovo_3000_setup,
12957 .init_hook = alc_inithook,
12841 }, 12958 },
12842 [ALC262_NEC] = { 12959 [ALC262_NEC] = {
12843 .mixers = { alc262_nec_mixer }, 12960 .mixers = { alc262_nec_mixer },
@@ -12874,9 +12991,9 @@ static struct alc_config_preset alc262_presets[] = {
12874 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12991 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12875 .channel_mode = alc262_modes, 12992 .channel_mode = alc262_modes,
12876 .input_mux = &alc262_capture_source, 12993 .input_mux = &alc262_capture_source,
12877 .unsol_event = alc262_hippo_unsol_event, 12994 .unsol_event = alc_sku_unsol_event,
12878 .setup = alc262_hippo_setup, 12995 .setup = alc262_hippo_setup,
12879 .init_hook = alc262_hippo_automute, 12996 .init_hook = alc_inithook,
12880 }, 12997 },
12881 [ALC262_TYAN] = { 12998 [ALC262_TYAN] = {
12882 .mixers = { alc262_tyan_mixer }, 12999 .mixers = { alc262_tyan_mixer },
@@ -12888,9 +13005,9 @@ static struct alc_config_preset alc262_presets[] = {
12888 .num_channel_mode = ARRAY_SIZE(alc262_modes), 13005 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12889 .channel_mode = alc262_modes, 13006 .channel_mode = alc262_modes,
12890 .input_mux = &alc262_capture_source, 13007 .input_mux = &alc262_capture_source,
12891 .unsol_event = alc_automute_amp_unsol_event, 13008 .unsol_event = alc_sku_unsol_event,
12892 .setup = alc262_tyan_setup, 13009 .setup = alc262_tyan_setup,
12893 .init_hook = alc_automute_amp, 13010 .init_hook = alc_hp_automute,
12894 }, 13011 },
12895}; 13012};
12896 13013
@@ -13011,6 +13128,7 @@ static int patch_alc262(struct hda_codec *codec)
13011 codec->patch_ops = alc_patch_ops; 13128 codec->patch_ops = alc_patch_ops;
13012 if (board_config == ALC262_AUTO) 13129 if (board_config == ALC262_AUTO)
13013 spec->init_hook = alc262_auto_init; 13130 spec->init_hook = alc262_auto_init;
13131 spec->shutup = alc_eapd_shutup;
13014 13132
13015 alc_init_jacks(codec); 13133 alc_init_jacks(codec);
13016#ifdef CONFIG_SND_HDA_POWER_SAVE 13134#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -13027,24 +13145,24 @@ static int patch_alc262(struct hda_codec *codec)
13027#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 13145#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13028#define alc268_modes alc260_modes 13146#define alc268_modes alc260_modes
13029 13147
13030static hda_nid_t alc268_dac_nids[2] = { 13148static const hda_nid_t alc268_dac_nids[2] = {
13031 /* front, hp */ 13149 /* front, hp */
13032 0x02, 0x03 13150 0x02, 0x03
13033}; 13151};
13034 13152
13035static hda_nid_t alc268_adc_nids[2] = { 13153static const hda_nid_t alc268_adc_nids[2] = {
13036 /* ADC0-1 */ 13154 /* ADC0-1 */
13037 0x08, 0x07 13155 0x08, 0x07
13038}; 13156};
13039 13157
13040static hda_nid_t alc268_adc_nids_alt[1] = { 13158static const hda_nid_t alc268_adc_nids_alt[1] = {
13041 /* ADC0 */ 13159 /* ADC0 */
13042 0x08 13160 0x08
13043}; 13161};
13044 13162
13045static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; 13163static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13046 13164
13047static struct snd_kcontrol_new alc268_base_mixer[] = { 13165static const struct snd_kcontrol_new alc268_base_mixer[] = {
13048 /* output mixer control */ 13166 /* output mixer control */
13049 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13167 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13050 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13168 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -13056,7 +13174,7 @@ static struct snd_kcontrol_new alc268_base_mixer[] = {
13056 { } 13174 { }
13057}; 13175};
13058 13176
13059static struct snd_kcontrol_new alc268_toshiba_mixer[] = { 13177static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13060 /* output mixer control */ 13178 /* output mixer control */
13061 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13179 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13062 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13180 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
@@ -13068,7 +13186,7 @@ static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13068}; 13186};
13069 13187
13070/* bind Beep switches of both NID 0x0f and 0x10 */ 13188/* bind Beep switches of both NID 0x0f and 0x10 */
13071static struct hda_bind_ctls alc268_bind_beep_sw = { 13189static const struct hda_bind_ctls alc268_bind_beep_sw = {
13072 .ops = &snd_hda_bind_sw, 13190 .ops = &snd_hda_bind_sw,
13073 .values = { 13191 .values = {
13074 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), 13192 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
@@ -13077,27 +13195,27 @@ static struct hda_bind_ctls alc268_bind_beep_sw = {
13077 }, 13195 },
13078}; 13196};
13079 13197
13080static struct snd_kcontrol_new alc268_beep_mixer[] = { 13198static const struct snd_kcontrol_new alc268_beep_mixer[] = {
13081 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), 13199 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13082 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), 13200 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13083 { } 13201 { }
13084}; 13202};
13085 13203
13086static struct hda_verb alc268_eapd_verbs[] = { 13204static const struct hda_verb alc268_eapd_verbs[] = {
13087 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13205 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13088 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13206 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13089 { } 13207 { }
13090}; 13208};
13091 13209
13092/* Toshiba specific */ 13210/* Toshiba specific */
13093static struct hda_verb alc268_toshiba_verbs[] = { 13211static const struct hda_verb alc268_toshiba_verbs[] = {
13094 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13212 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13095 { } /* end */ 13213 { } /* end */
13096}; 13214};
13097 13215
13098/* Acer specific */ 13216/* Acer specific */
13099/* bind volumes of both NID 0x02 and 0x03 */ 13217/* bind volumes of both NID 0x02 and 0x03 */
13100static struct hda_bind_ctls alc268_acer_bind_master_vol = { 13218static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
13101 .ops = &snd_hda_bind_vol, 13219 .ops = &snd_hda_bind_vol,
13102 .values = { 13220 .values = {
13103 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 13221 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
@@ -13106,66 +13224,44 @@ static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13106 }, 13224 },
13107}; 13225};
13108 13226
13109/* mute/unmute internal speaker according to the hp jack and mute state */ 13227static void alc268_acer_setup(struct hda_codec *codec)
13110static void alc268_acer_automute(struct hda_codec *codec, int force)
13111{ 13228{
13112 struct alc_spec *spec = codec->spec; 13229 struct alc_spec *spec = codec->spec;
13113 unsigned int mute;
13114 13230
13115 if (force || !spec->sense_updated) { 13231 spec->autocfg.hp_pins[0] = 0x14;
13116 spec->jack_present = snd_hda_jack_detect(codec, 0x14); 13232 spec->autocfg.speaker_pins[0] = 0x15;
13117 spec->sense_updated = 1; 13233 spec->automute = 1;
13118 } 13234 spec->automute_mode = ALC_AUTOMUTE_AMP;
13119 if (spec->jack_present)
13120 mute = HDA_AMP_MUTE; /* mute internal speaker */
13121 else /* unmute internal speaker if necessary */
13122 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13123 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13124 HDA_AMP_MUTE, mute);
13125} 13235}
13126 13236
13237#define alc268_acer_master_sw_get alc262_hp_master_sw_get
13238#define alc268_acer_master_sw_put alc262_hp_master_sw_put
13127 13239
13128/* bind hp and internal speaker mute (with plug check) */ 13240static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13129static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13130 struct snd_ctl_elem_value *ucontrol)
13131{
13132 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13133 long *valp = ucontrol->value.integer.value;
13134 int change;
13135
13136 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
13137 if (change)
13138 alc268_acer_automute(codec, 0);
13139 return change;
13140}
13141
13142static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13143 /* output mixer control */ 13241 /* output mixer control */
13144 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13242 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13145 { 13243 {
13146 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13147 .name = "Master Playback Switch", 13245 .name = "Master Playback Switch",
13148 .subdevice = HDA_SUBDEV_AMP_FLAG, 13246 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13149 .info = snd_hda_mixer_amp_switch_info, 13247 .info = snd_ctl_boolean_mono_info,
13150 .get = snd_hda_mixer_amp_switch_get, 13248 .get = alc268_acer_master_sw_get,
13151 .put = alc268_acer_master_sw_put, 13249 .put = alc268_acer_master_sw_put,
13152 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13153 }, 13250 },
13154 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), 13251 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13155 { } 13252 { }
13156}; 13253};
13157 13254
13158static struct snd_kcontrol_new alc268_acer_mixer[] = { 13255static const struct snd_kcontrol_new alc268_acer_mixer[] = {
13159 /* output mixer control */ 13256 /* output mixer control */
13160 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13257 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13161 { 13258 {
13162 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13259 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13163 .name = "Master Playback Switch", 13260 .name = "Master Playback Switch",
13164 .subdevice = HDA_SUBDEV_AMP_FLAG, 13261 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13165 .info = snd_hda_mixer_amp_switch_info, 13262 .info = snd_ctl_boolean_mono_info,
13166 .get = snd_hda_mixer_amp_switch_get, 13263 .get = alc268_acer_master_sw_get,
13167 .put = alc268_acer_master_sw_put, 13264 .put = alc268_acer_master_sw_put,
13168 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13169 }, 13265 },
13170 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13266 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13171 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 13267 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
@@ -13173,24 +13269,23 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
13173 { } 13269 { }
13174}; 13270};
13175 13271
13176static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { 13272static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13177 /* output mixer control */ 13273 /* output mixer control */
13178 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13274 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13179 { 13275 {
13180 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13276 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13181 .name = "Master Playback Switch", 13277 .name = "Master Playback Switch",
13182 .subdevice = HDA_SUBDEV_AMP_FLAG, 13278 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13183 .info = snd_hda_mixer_amp_switch_info, 13279 .info = snd_ctl_boolean_mono_info,
13184 .get = snd_hda_mixer_amp_switch_get, 13280 .get = alc268_acer_master_sw_get,
13185 .put = alc268_acer_master_sw_put, 13281 .put = alc268_acer_master_sw_put,
13186 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13187 }, 13282 },
13188 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13283 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13189 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), 13284 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13190 { } 13285 { }
13191}; 13286};
13192 13287
13193static struct hda_verb alc268_acer_aspire_one_verbs[] = { 13288static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
13194 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13289 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13195 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13196 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13291 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
@@ -13200,7 +13295,7 @@ static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13200 { } 13295 { }
13201}; 13296};
13202 13297
13203static struct hda_verb alc268_acer_verbs[] = { 13298static const struct hda_verb alc268_acer_verbs[] = {
13204 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ 13299 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13205 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13300 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13206 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13301 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -13212,53 +13307,16 @@ static struct hda_verb alc268_acer_verbs[] = {
13212}; 13307};
13213 13308
13214/* unsolicited event for HP jack sensing */ 13309/* unsolicited event for HP jack sensing */
13215#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
13216#define alc268_toshiba_setup alc262_hippo_setup 13310#define alc268_toshiba_setup alc262_hippo_setup
13217#define alc268_toshiba_automute alc262_hippo_automute
13218
13219static void alc268_acer_unsol_event(struct hda_codec *codec,
13220 unsigned int res)
13221{
13222 if ((res >> 26) != ALC880_HP_EVENT)
13223 return;
13224 alc268_acer_automute(codec, 1);
13225}
13226
13227static void alc268_acer_init_hook(struct hda_codec *codec)
13228{
13229 alc268_acer_automute(codec, 1);
13230}
13231
13232/* toggle speaker-output according to the hp-jack state */
13233static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13234{
13235 unsigned int present;
13236 unsigned char bits;
13237
13238 present = snd_hda_jack_detect(codec, 0x15);
13239 bits = present ? HDA_AMP_MUTE : 0;
13240 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
13241 HDA_AMP_MUTE, bits);
13242 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
13243 HDA_AMP_MUTE, bits);
13244}
13245
13246static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13247 unsigned int res)
13248{
13249 switch (res >> 26) {
13250 case ALC880_HP_EVENT:
13251 alc268_aspire_one_speaker_automute(codec);
13252 break;
13253 case ALC880_MIC_EVENT:
13254 alc_mic_automute(codec);
13255 break;
13256 }
13257}
13258 13311
13259static void alc268_acer_lc_setup(struct hda_codec *codec) 13312static void alc268_acer_lc_setup(struct hda_codec *codec)
13260{ 13313{
13261 struct alc_spec *spec = codec->spec; 13314 struct alc_spec *spec = codec->spec;
13315 spec->autocfg.hp_pins[0] = 0x15;
13316 spec->autocfg.speaker_pins[0] = 0x14;
13317 spec->automute_mixer_nid[0] = 0x0f;
13318 spec->automute = 1;
13319 spec->automute_mode = ALC_AUTOMUTE_MIXER;
13262 spec->ext_mic.pin = 0x18; 13320 spec->ext_mic.pin = 0x18;
13263 spec->ext_mic.mux_idx = 0; 13321 spec->ext_mic.mux_idx = 0;
13264 spec->int_mic.pin = 0x12; 13322 spec->int_mic.pin = 0x12;
@@ -13266,13 +13324,7 @@ static void alc268_acer_lc_setup(struct hda_codec *codec)
13266 spec->auto_mic = 1; 13324 spec->auto_mic = 1;
13267} 13325}
13268 13326
13269static void alc268_acer_lc_init_hook(struct hda_codec *codec) 13327static const struct snd_kcontrol_new alc268_dell_mixer[] = {
13270{
13271 alc268_aspire_one_speaker_automute(codec);
13272 alc_mic_automute(codec);
13273}
13274
13275static struct snd_kcontrol_new alc268_dell_mixer[] = {
13276 /* output mixer control */ 13328 /* output mixer control */
13277 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13329 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13278 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13330 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -13283,7 +13335,7 @@ static struct snd_kcontrol_new alc268_dell_mixer[] = {
13283 { } 13335 { }
13284}; 13336};
13285 13337
13286static struct hda_verb alc268_dell_verbs[] = { 13338static const struct hda_verb alc268_dell_verbs[] = {
13287 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13339 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13288 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13340 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13289 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13341 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
@@ -13303,9 +13355,11 @@ static void alc268_dell_setup(struct hda_codec *codec)
13303 spec->int_mic.pin = 0x19; 13355 spec->int_mic.pin = 0x19;
13304 spec->int_mic.mux_idx = 1; 13356 spec->int_mic.mux_idx = 1;
13305 spec->auto_mic = 1; 13357 spec->auto_mic = 1;
13358 spec->automute = 1;
13359 spec->automute_mode = ALC_AUTOMUTE_PIN;
13306} 13360}
13307 13361
13308static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { 13362static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13309 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13363 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13310 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13364 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13311 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13365 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
@@ -13317,7 +13371,7 @@ static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13317 { } 13371 { }
13318}; 13372};
13319 13373
13320static struct hda_verb alc267_quanta_il1_verbs[] = { 13374static const struct hda_verb alc267_quanta_il1_verbs[] = {
13321 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13375 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13322 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 13376 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13323 { } 13377 { }
@@ -13333,12 +13387,14 @@ static void alc267_quanta_il1_setup(struct hda_codec *codec)
13333 spec->int_mic.pin = 0x19; 13387 spec->int_mic.pin = 0x19;
13334 spec->int_mic.mux_idx = 1; 13388 spec->int_mic.mux_idx = 1;
13335 spec->auto_mic = 1; 13389 spec->auto_mic = 1;
13390 spec->automute = 1;
13391 spec->automute_mode = ALC_AUTOMUTE_PIN;
13336} 13392}
13337 13393
13338/* 13394/*
13339 * generic initialization of ADC, input mixers and output mixers 13395 * generic initialization of ADC, input mixers and output mixers
13340 */ 13396 */
13341static struct hda_verb alc268_base_init_verbs[] = { 13397static const struct hda_verb alc268_base_init_verbs[] = {
13342 /* Unmute DAC0-1 and set vol = 0 */ 13398 /* Unmute DAC0-1 and set vol = 0 */
13343 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13399 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13344 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13400 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -13386,7 +13442,7 @@ static struct hda_verb alc268_base_init_verbs[] = {
13386/* 13442/*
13387 * generic initialization of ADC, input mixers and output mixers 13443 * generic initialization of ADC, input mixers and output mixers
13388 */ 13444 */
13389static struct hda_verb alc268_volume_init_verbs[] = { 13445static const struct hda_verb alc268_volume_init_verbs[] = {
13390 /* set output DAC */ 13446 /* set output DAC */
13391 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13447 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13392 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13448 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -13412,20 +13468,20 @@ static struct hda_verb alc268_volume_init_verbs[] = {
13412 { } 13468 { }
13413}; 13469};
13414 13470
13415static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { 13471static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13416 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13472 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13417 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13473 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13418 { } /* end */ 13474 { } /* end */
13419}; 13475};
13420 13476
13421static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 13477static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13422 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13478 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13423 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13479 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13424 _DEFINE_CAPSRC(1), 13480 _DEFINE_CAPSRC(1),
13425 { } /* end */ 13481 { } /* end */
13426}; 13482};
13427 13483
13428static struct snd_kcontrol_new alc268_capture_mixer[] = { 13484static const struct snd_kcontrol_new alc268_capture_mixer[] = {
13429 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13485 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13430 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13486 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13431 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 13487 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
@@ -13434,7 +13490,7 @@ static struct snd_kcontrol_new alc268_capture_mixer[] = {
13434 { } /* end */ 13490 { } /* end */
13435}; 13491};
13436 13492
13437static struct hda_input_mux alc268_capture_source = { 13493static const struct hda_input_mux alc268_capture_source = {
13438 .num_items = 4, 13494 .num_items = 4,
13439 .items = { 13495 .items = {
13440 { "Mic", 0x0 }, 13496 { "Mic", 0x0 },
@@ -13444,7 +13500,7 @@ static struct hda_input_mux alc268_capture_source = {
13444 }, 13500 },
13445}; 13501};
13446 13502
13447static struct hda_input_mux alc268_acer_capture_source = { 13503static const struct hda_input_mux alc268_acer_capture_source = {
13448 .num_items = 3, 13504 .num_items = 3,
13449 .items = { 13505 .items = {
13450 { "Mic", 0x0 }, 13506 { "Mic", 0x0 },
@@ -13453,7 +13509,7 @@ static struct hda_input_mux alc268_acer_capture_source = {
13453 }, 13509 },
13454}; 13510};
13455 13511
13456static struct hda_input_mux alc268_acer_dmic_capture_source = { 13512static const struct hda_input_mux alc268_acer_dmic_capture_source = {
13457 .num_items = 3, 13513 .num_items = 3,
13458 .items = { 13514 .items = {
13459 { "Mic", 0x0 }, 13515 { "Mic", 0x0 },
@@ -13463,7 +13519,7 @@ static struct hda_input_mux alc268_acer_dmic_capture_source = {
13463}; 13519};
13464 13520
13465#ifdef CONFIG_SND_DEBUG 13521#ifdef CONFIG_SND_DEBUG
13466static struct snd_kcontrol_new alc268_test_mixer[] = { 13522static const struct snd_kcontrol_new alc268_test_mixer[] = {
13467 /* Volume widgets */ 13523 /* Volume widgets */
13468 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13524 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13469 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13525 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -13542,7 +13598,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13542 HDA_OUTPUT)); 13598 HDA_OUTPUT));
13543 if (err < 0) 13599 if (err < 0)
13544 return err; 13600 return err;
13545 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 13601 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
13546 } 13602 }
13547 13603
13548 if (nid != 0x16) 13604 if (nid != 0x16)
@@ -13715,7 +13771,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
13715{ 13771{
13716 struct alc_spec *spec = codec->spec; 13772 struct alc_spec *spec = codec->spec;
13717 int err; 13773 int err;
13718 static hda_nid_t alc268_ignore[] = { 0 }; 13774 static const hda_nid_t alc268_ignore[] = { 0 };
13719 13775
13720 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 13776 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13721 alc268_ignore); 13777 alc268_ignore);
@@ -13795,7 +13851,7 @@ static const char * const alc268_models[ALC268_MODEL_LAST] = {
13795 [ALC268_AUTO] = "auto", 13851 [ALC268_AUTO] = "auto",
13796}; 13852};
13797 13853
13798static struct snd_pci_quirk alc268_cfg_tbl[] = { 13854static const struct snd_pci_quirk alc268_cfg_tbl[] = {
13799 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER), 13855 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13800 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), 13856 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13801 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), 13857 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
@@ -13820,7 +13876,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
13820}; 13876};
13821 13877
13822/* Toshiba laptops have no unique PCI SSID but only codec SSID */ 13878/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13823static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { 13879static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13824 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO), 13880 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13825 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO), 13881 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13826 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05", 13882 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
@@ -13828,7 +13884,7 @@ static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13828 {} 13884 {}
13829}; 13885};
13830 13886
13831static struct alc_config_preset alc268_presets[] = { 13887static const struct alc_config_preset alc268_presets[] = {
13832 [ALC267_QUANTA_IL1] = { 13888 [ALC267_QUANTA_IL1] = {
13833 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer, 13889 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13834 alc268_capture_nosrc_mixer }, 13890 alc268_capture_nosrc_mixer },
@@ -13874,9 +13930,9 @@ static struct alc_config_preset alc268_presets[] = {
13874 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13930 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13875 .channel_mode = alc268_modes, 13931 .channel_mode = alc268_modes,
13876 .input_mux = &alc268_capture_source, 13932 .input_mux = &alc268_capture_source,
13877 .unsol_event = alc268_toshiba_unsol_event, 13933 .unsol_event = alc_sku_unsol_event,
13878 .setup = alc268_toshiba_setup, 13934 .setup = alc268_toshiba_setup,
13879 .init_hook = alc268_toshiba_automute, 13935 .init_hook = alc_inithook,
13880 }, 13936 },
13881 [ALC268_ACER] = { 13937 [ALC268_ACER] = {
13882 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, 13938 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
@@ -13892,8 +13948,9 @@ static struct alc_config_preset alc268_presets[] = {
13892 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13948 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13893 .channel_mode = alc268_modes, 13949 .channel_mode = alc268_modes,
13894 .input_mux = &alc268_acer_capture_source, 13950 .input_mux = &alc268_acer_capture_source,
13895 .unsol_event = alc268_acer_unsol_event, 13951 .unsol_event = alc_sku_unsol_event,
13896 .init_hook = alc268_acer_init_hook, 13952 .setup = alc268_acer_setup,
13953 .init_hook = alc_inithook,
13897 }, 13954 },
13898 [ALC268_ACER_DMIC] = { 13955 [ALC268_ACER_DMIC] = {
13899 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, 13956 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
@@ -13909,8 +13966,9 @@ static struct alc_config_preset alc268_presets[] = {
13909 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13966 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13910 .channel_mode = alc268_modes, 13967 .channel_mode = alc268_modes,
13911 .input_mux = &alc268_acer_dmic_capture_source, 13968 .input_mux = &alc268_acer_dmic_capture_source,
13912 .unsol_event = alc268_acer_unsol_event, 13969 .unsol_event = alc_sku_unsol_event,
13913 .init_hook = alc268_acer_init_hook, 13970 .setup = alc268_acer_setup,
13971 .init_hook = alc_inithook,
13914 }, 13972 },
13915 [ALC268_ACER_ASPIRE_ONE] = { 13973 [ALC268_ACER_ASPIRE_ONE] = {
13916 .mixers = { alc268_acer_aspire_one_mixer, 13974 .mixers = { alc268_acer_aspire_one_mixer,
@@ -13926,9 +13984,9 @@ static struct alc_config_preset alc268_presets[] = {
13926 .hp_nid = 0x03, 13984 .hp_nid = 0x03,
13927 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13985 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13928 .channel_mode = alc268_modes, 13986 .channel_mode = alc268_modes,
13929 .unsol_event = alc268_acer_lc_unsol_event, 13987 .unsol_event = alc_sku_unsol_event,
13930 .setup = alc268_acer_lc_setup, 13988 .setup = alc268_acer_lc_setup,
13931 .init_hook = alc268_acer_lc_init_hook, 13989 .init_hook = alc_inithook,
13932 }, 13990 },
13933 [ALC268_DELL] = { 13991 [ALC268_DELL] = {
13934 .mixers = { alc268_dell_mixer, alc268_beep_mixer, 13992 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
@@ -13962,8 +14020,9 @@ static struct alc_config_preset alc268_presets[] = {
13962 .num_channel_mode = ARRAY_SIZE(alc268_modes), 14020 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13963 .channel_mode = alc268_modes, 14021 .channel_mode = alc268_modes,
13964 .input_mux = &alc268_capture_source, 14022 .input_mux = &alc268_capture_source,
14023 .unsol_event = alc_sku_unsol_event,
13965 .setup = alc268_toshiba_setup, 14024 .setup = alc268_toshiba_setup,
13966 .init_hook = alc268_toshiba_automute, 14025 .init_hook = alc_inithook,
13967 }, 14026 },
13968#ifdef CONFIG_SND_DEBUG 14027#ifdef CONFIG_SND_DEBUG
13969 [ALC268_TEST] = { 14028 [ALC268_TEST] = {
@@ -14085,6 +14144,7 @@ static int patch_alc268(struct hda_codec *codec)
14085 codec->patch_ops = alc_patch_ops; 14144 codec->patch_ops = alc_patch_ops;
14086 if (board_config == ALC268_AUTO) 14145 if (board_config == ALC268_AUTO)
14087 spec->init_hook = alc268_auto_init; 14146 spec->init_hook = alc268_auto_init;
14147 spec->shutup = alc_eapd_shutup;
14088 14148
14089 alc_init_jacks(codec); 14149 alc_init_jacks(codec);
14090 14150
@@ -14098,32 +14158,32 @@ static int patch_alc268(struct hda_codec *codec)
14098 14158
14099#define alc269_dac_nids alc260_dac_nids 14159#define alc269_dac_nids alc260_dac_nids
14100 14160
14101static hda_nid_t alc269_adc_nids[1] = { 14161static const hda_nid_t alc269_adc_nids[1] = {
14102 /* ADC1 */ 14162 /* ADC1 */
14103 0x08, 14163 0x08,
14104}; 14164};
14105 14165
14106static hda_nid_t alc269_capsrc_nids[1] = { 14166static const hda_nid_t alc269_capsrc_nids[1] = {
14107 0x23, 14167 0x23,
14108}; 14168};
14109 14169
14110static hda_nid_t alc269vb_adc_nids[1] = { 14170static const hda_nid_t alc269vb_adc_nids[1] = {
14111 /* ADC1 */ 14171 /* ADC1 */
14112 0x09, 14172 0x09,
14113}; 14173};
14114 14174
14115static hda_nid_t alc269vb_capsrc_nids[1] = { 14175static const hda_nid_t alc269vb_capsrc_nids[1] = {
14116 0x22, 14176 0x22,
14117}; 14177};
14118 14178
14119static hda_nid_t alc269_adc_candidates[] = { 14179static const hda_nid_t alc269_adc_candidates[] = {
14120 0x08, 0x09, 0x07, 0x11, 14180 0x08, 0x09, 0x07, 0x11,
14121}; 14181};
14122 14182
14123#define alc269_modes alc260_modes 14183#define alc269_modes alc260_modes
14124#define alc269_capture_source alc880_lg_lw_capture_source 14184#define alc269_capture_source alc880_lg_lw_capture_source
14125 14185
14126static struct snd_kcontrol_new alc269_base_mixer[] = { 14186static const struct snd_kcontrol_new alc269_base_mixer[] = {
14127 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14187 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14128 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14188 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14129 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 14189 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
@@ -14139,7 +14199,7 @@ static struct snd_kcontrol_new alc269_base_mixer[] = {
14139 { } /* end */ 14199 { } /* end */
14140}; 14200};
14141 14201
14142static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { 14202static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14143 /* output mixer control */ 14203 /* output mixer control */
14144 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 14204 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14145 { 14205 {
@@ -14160,7 +14220,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14160 { } 14220 { }
14161}; 14221};
14162 14222
14163static struct snd_kcontrol_new alc269_lifebook_mixer[] = { 14223static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14164 /* output mixer control */ 14224 /* output mixer control */
14165 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 14225 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14166 { 14226 {
@@ -14184,7 +14244,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14184 { } 14244 { }
14185}; 14245};
14186 14246
14187static struct snd_kcontrol_new alc269_laptop_mixer[] = { 14247static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
14188 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14248 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14189 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14249 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14190 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14250 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -14192,7 +14252,7 @@ static struct snd_kcontrol_new alc269_laptop_mixer[] = {
14192 { } /* end */ 14252 { } /* end */
14193}; 14253};
14194 14254
14195static struct snd_kcontrol_new alc269vb_laptop_mixer[] = { 14255static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14196 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14256 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14197 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14257 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14198 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 14258 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
@@ -14200,14 +14260,14 @@ static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14200 { } /* end */ 14260 { } /* end */
14201}; 14261};
14202 14262
14203static struct snd_kcontrol_new alc269_asus_mixer[] = { 14263static const struct snd_kcontrol_new alc269_asus_mixer[] = {
14204 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14264 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14205 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT), 14265 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14206 { } /* end */ 14266 { } /* end */
14207}; 14267};
14208 14268
14209/* capture mixer elements */ 14269/* capture mixer elements */
14210static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { 14270static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14211 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14271 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14212 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14272 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14213 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14273 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
@@ -14215,14 +14275,14 @@ static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14215 { } /* end */ 14275 { } /* end */
14216}; 14276};
14217 14277
14218static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { 14278static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14219 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14279 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14220 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14280 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14221 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14281 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14222 { } /* end */ 14282 { } /* end */
14223}; 14283};
14224 14284
14225static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { 14285static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14226 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14286 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14227 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14287 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14228 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14288 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
@@ -14230,7 +14290,7 @@ static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14230 { } /* end */ 14290 { } /* end */
14231}; 14291};
14232 14292
14233static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { 14293static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14234 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14294 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14235 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14295 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14296 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
@@ -14240,7 +14300,7 @@ static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14240/* FSC amilo */ 14300/* FSC amilo */
14241#define alc269_fujitsu_mixer alc269_laptop_mixer 14301#define alc269_fujitsu_mixer alc269_laptop_mixer
14242 14302
14243static struct hda_verb alc269_quanta_fl1_verbs[] = { 14303static const struct hda_verb alc269_quanta_fl1_verbs[] = {
14244 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14304 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14245 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14305 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14246 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14306 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -14250,7 +14310,7 @@ static struct hda_verb alc269_quanta_fl1_verbs[] = {
14250 { } 14310 { }
14251}; 14311};
14252 14312
14253static struct hda_verb alc269_lifebook_verbs[] = { 14313static const struct hda_verb alc269_lifebook_verbs[] = {
14254 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14314 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14255 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 14315 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14256 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14316 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -14267,15 +14327,7 @@ static struct hda_verb alc269_lifebook_verbs[] = {
14267/* toggle speaker-output according to the hp-jack state */ 14327/* toggle speaker-output according to the hp-jack state */
14268static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) 14328static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14269{ 14329{
14270 unsigned int present; 14330 alc_hp_automute(codec);
14271 unsigned char bits;
14272
14273 present = snd_hda_jack_detect(codec, 0x15);
14274 bits = present ? HDA_AMP_MUTE : 0;
14275 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14276 HDA_AMP_MUTE, bits);
14277 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14278 HDA_AMP_MUTE, bits);
14279 14331
14280 snd_hda_codec_write(codec, 0x20, 0, 14332 snd_hda_codec_write(codec, 0x20, 0,
14281 AC_VERB_SET_COEF_INDEX, 0x0c); 14333 AC_VERB_SET_COEF_INDEX, 0x0c);
@@ -14288,34 +14340,8 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14288 AC_VERB_SET_PROC_COEF, 0x480); 14340 AC_VERB_SET_PROC_COEF, 0x480);
14289} 14341}
14290 14342
14291/* toggle speaker-output according to the hp-jacks state */ 14343#define alc269_lifebook_speaker_automute \
14292static void alc269_lifebook_speaker_automute(struct hda_codec *codec) 14344 alc269_quanta_fl1_speaker_automute
14293{
14294 unsigned int present;
14295 unsigned char bits;
14296
14297 /* Check laptop headphone socket */
14298 present = snd_hda_jack_detect(codec, 0x15);
14299
14300 /* Check port replicator headphone socket */
14301 present |= snd_hda_jack_detect(codec, 0x1a);
14302
14303 bits = present ? HDA_AMP_MUTE : 0;
14304 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14305 HDA_AMP_MUTE, bits);
14306 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14307 HDA_AMP_MUTE, bits);
14308
14309 snd_hda_codec_write(codec, 0x20, 0,
14310 AC_VERB_SET_COEF_INDEX, 0x0c);
14311 snd_hda_codec_write(codec, 0x20, 0,
14312 AC_VERB_SET_PROC_COEF, 0x680);
14313
14314 snd_hda_codec_write(codec, 0x20, 0,
14315 AC_VERB_SET_COEF_INDEX, 0x0c);
14316 snd_hda_codec_write(codec, 0x20, 0,
14317 AC_VERB_SET_PROC_COEF, 0x480);
14318}
14319 14345
14320static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) 14346static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14321{ 14347{
@@ -14364,6 +14390,9 @@ static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14364 struct alc_spec *spec = codec->spec; 14390 struct alc_spec *spec = codec->spec;
14365 spec->autocfg.hp_pins[0] = 0x15; 14391 spec->autocfg.hp_pins[0] = 0x15;
14366 spec->autocfg.speaker_pins[0] = 0x14; 14392 spec->autocfg.speaker_pins[0] = 0x14;
14393 spec->automute_mixer_nid[0] = 0x0c;
14394 spec->automute = 1;
14395 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14367 spec->ext_mic.pin = 0x18; 14396 spec->ext_mic.pin = 0x18;
14368 spec->ext_mic.mux_idx = 0; 14397 spec->ext_mic.mux_idx = 0;
14369 spec->int_mic.pin = 0x19; 14398 spec->int_mic.pin = 0x19;
@@ -14377,13 +14406,24 @@ static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14377 alc_mic_automute(codec); 14406 alc_mic_automute(codec);
14378} 14407}
14379 14408
14409static void alc269_lifebook_setup(struct hda_codec *codec)
14410{
14411 struct alc_spec *spec = codec->spec;
14412 spec->autocfg.hp_pins[0] = 0x15;
14413 spec->autocfg.hp_pins[1] = 0x1a;
14414 spec->autocfg.speaker_pins[0] = 0x14;
14415 spec->automute_mixer_nid[0] = 0x0c;
14416 spec->automute = 1;
14417 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14418}
14419
14380static void alc269_lifebook_init_hook(struct hda_codec *codec) 14420static void alc269_lifebook_init_hook(struct hda_codec *codec)
14381{ 14421{
14382 alc269_lifebook_speaker_automute(codec); 14422 alc269_lifebook_speaker_automute(codec);
14383 alc269_lifebook_mic_autoswitch(codec); 14423 alc269_lifebook_mic_autoswitch(codec);
14384} 14424}
14385 14425
14386static struct hda_verb alc269_laptop_dmic_init_verbs[] = { 14426static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14387 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14427 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14388 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 14428 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14389 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14429 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -14394,7 +14434,7 @@ static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14394 {} 14434 {}
14395}; 14435};
14396 14436
14397static struct hda_verb alc269_laptop_amic_init_verbs[] = { 14437static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
14398 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14438 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14399 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 14439 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14400 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14440 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -14404,7 +14444,7 @@ static struct hda_verb alc269_laptop_amic_init_verbs[] = {
14404 {} 14444 {}
14405}; 14445};
14406 14446
14407static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { 14447static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14408 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14448 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14409 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06}, 14449 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14410 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14450 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -14415,7 +14455,7 @@ static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14415 {} 14455 {}
14416}; 14456};
14417 14457
14418static struct hda_verb alc269vb_laptop_amic_init_verbs[] = { 14458static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14419 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14459 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14420 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, 14460 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14421 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14461 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -14426,7 +14466,7 @@ static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14426 {} 14466 {}
14427}; 14467};
14428 14468
14429static struct hda_verb alc271_acer_dmic_verbs[] = { 14469static const struct hda_verb alc271_acer_dmic_verbs[] = {
14430 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, 14470 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14431 {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, 14471 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14432 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14472 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -14440,42 +14480,14 @@ static struct hda_verb alc271_acer_dmic_verbs[] = {
14440 { } 14480 { }
14441}; 14481};
14442 14482
14443/* toggle speaker-output according to the hp-jack state */
14444static void alc269_speaker_automute(struct hda_codec *codec)
14445{
14446 struct alc_spec *spec = codec->spec;
14447 unsigned int nid = spec->autocfg.hp_pins[0];
14448 unsigned int present;
14449 unsigned char bits;
14450
14451 present = snd_hda_jack_detect(codec, nid);
14452 bits = present ? HDA_AMP_MUTE : 0;
14453 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14454 HDA_AMP_MUTE, bits);
14455 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14456 HDA_AMP_MUTE, bits);
14457 snd_hda_input_jack_report(codec, nid);
14458}
14459
14460/* unsolicited event for HP jack sensing */
14461static void alc269_laptop_unsol_event(struct hda_codec *codec,
14462 unsigned int res)
14463{
14464 switch (res >> 26) {
14465 case ALC880_HP_EVENT:
14466 alc269_speaker_automute(codec);
14467 break;
14468 case ALC880_MIC_EVENT:
14469 alc_mic_automute(codec);
14470 break;
14471 }
14472}
14473
14474static void alc269_laptop_amic_setup(struct hda_codec *codec) 14483static void alc269_laptop_amic_setup(struct hda_codec *codec)
14475{ 14484{
14476 struct alc_spec *spec = codec->spec; 14485 struct alc_spec *spec = codec->spec;
14477 spec->autocfg.hp_pins[0] = 0x15; 14486 spec->autocfg.hp_pins[0] = 0x15;
14478 spec->autocfg.speaker_pins[0] = 0x14; 14487 spec->autocfg.speaker_pins[0] = 0x14;
14488 spec->automute_mixer_nid[0] = 0x0c;
14489 spec->automute = 1;
14490 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14479 spec->ext_mic.pin = 0x18; 14491 spec->ext_mic.pin = 0x18;
14480 spec->ext_mic.mux_idx = 0; 14492 spec->ext_mic.mux_idx = 0;
14481 spec->int_mic.pin = 0x19; 14493 spec->int_mic.pin = 0x19;
@@ -14488,6 +14500,9 @@ static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14488 struct alc_spec *spec = codec->spec; 14500 struct alc_spec *spec = codec->spec;
14489 spec->autocfg.hp_pins[0] = 0x15; 14501 spec->autocfg.hp_pins[0] = 0x15;
14490 spec->autocfg.speaker_pins[0] = 0x14; 14502 spec->autocfg.speaker_pins[0] = 0x14;
14503 spec->automute_mixer_nid[0] = 0x0c;
14504 spec->automute = 1;
14505 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14491 spec->ext_mic.pin = 0x18; 14506 spec->ext_mic.pin = 0x18;
14492 spec->ext_mic.mux_idx = 0; 14507 spec->ext_mic.mux_idx = 0;
14493 spec->int_mic.pin = 0x12; 14508 spec->int_mic.pin = 0x12;
@@ -14500,6 +14515,9 @@ static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14500 struct alc_spec *spec = codec->spec; 14515 struct alc_spec *spec = codec->spec;
14501 spec->autocfg.hp_pins[0] = 0x21; 14516 spec->autocfg.hp_pins[0] = 0x21;
14502 spec->autocfg.speaker_pins[0] = 0x14; 14517 spec->autocfg.speaker_pins[0] = 0x14;
14518 spec->automute_mixer_nid[0] = 0x0c;
14519 spec->automute = 1;
14520 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14503 spec->ext_mic.pin = 0x18; 14521 spec->ext_mic.pin = 0x18;
14504 spec->ext_mic.mux_idx = 0; 14522 spec->ext_mic.mux_idx = 0;
14505 spec->int_mic.pin = 0x19; 14523 spec->int_mic.pin = 0x19;
@@ -14512,6 +14530,9 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14512 struct alc_spec *spec = codec->spec; 14530 struct alc_spec *spec = codec->spec;
14513 spec->autocfg.hp_pins[0] = 0x21; 14531 spec->autocfg.hp_pins[0] = 0x21;
14514 spec->autocfg.speaker_pins[0] = 0x14; 14532 spec->autocfg.speaker_pins[0] = 0x14;
14533 spec->automute_mixer_nid[0] = 0x0c;
14534 spec->automute = 1;
14535 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14515 spec->ext_mic.pin = 0x18; 14536 spec->ext_mic.pin = 0x18;
14516 spec->ext_mic.mux_idx = 0; 14537 spec->ext_mic.mux_idx = 0;
14517 spec->int_mic.pin = 0x12; 14538 spec->int_mic.pin = 0x12;
@@ -14519,16 +14540,10 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14519 spec->auto_mic = 1; 14540 spec->auto_mic = 1;
14520} 14541}
14521 14542
14522static void alc269_laptop_inithook(struct hda_codec *codec)
14523{
14524 alc269_speaker_automute(codec);
14525 alc_mic_automute(codec);
14526}
14527
14528/* 14543/*
14529 * generic initialization of ADC, input mixers and output mixers 14544 * generic initialization of ADC, input mixers and output mixers
14530 */ 14545 */
14531static struct hda_verb alc269_init_verbs[] = { 14546static const struct hda_verb alc269_init_verbs[] = {
14532 /* 14547 /*
14533 * Unmute ADC0 and set the default input to mic-in 14548 * Unmute ADC0 and set the default input to mic-in
14534 */ 14549 */
@@ -14571,7 +14586,7 @@ static struct hda_verb alc269_init_verbs[] = {
14571 { } 14586 { }
14572}; 14587};
14573 14588
14574static struct hda_verb alc269vb_init_verbs[] = { 14589static const struct hda_verb alc269vb_init_verbs[] = {
14575 /* 14590 /*
14576 * Unmute ADC0 and set the default input to mic-in 14591 * Unmute ADC0 and set the default input to mic-in
14577 */ 14592 */
@@ -14629,7 +14644,7 @@ static struct hda_verb alc269vb_init_verbs[] = {
14629#define alc269_pcm_digital_playback alc880_pcm_digital_playback 14644#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14630#define alc269_pcm_digital_capture alc880_pcm_digital_capture 14645#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14631 14646
14632static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 14647static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14633 .substreams = 1, 14648 .substreams = 1,
14634 .channels_min = 2, 14649 .channels_min = 2,
14635 .channels_max = 8, 14650 .channels_max = 8,
@@ -14642,7 +14657,7 @@ static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14642 }, 14657 },
14643}; 14658};
14644 14659
14645static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { 14660static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14646 .substreams = 1, 14661 .substreams = 1,
14647 .channels_min = 2, 14662 .channels_min = 2,
14648 .channels_max = 2, 14663 .channels_max = 2,
@@ -14726,7 +14741,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
14726{ 14741{
14727 struct alc_spec *spec = codec->spec; 14742 struct alc_spec *spec = codec->spec;
14728 int err; 14743 int err;
14729 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 14744 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14730 14745
14731 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 14746 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14732 alc269_ignore); 14747 alc269_ignore);
@@ -14796,7 +14811,6 @@ static void alc269_auto_init(struct hda_codec *codec)
14796 alc_inithook(codec); 14811 alc_inithook(codec);
14797} 14812}
14798 14813
14799#ifdef SND_HDA_NEEDS_RESUME
14800static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) 14814static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14801{ 14815{
14802 int val = alc_read_coef_idx(codec, 0x04); 14816 int val = alc_read_coef_idx(codec, 0x04);
@@ -14807,25 +14821,17 @@ static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14807 alc_write_coef_idx(codec, 0x04, val); 14821 alc_write_coef_idx(codec, 0x04, val);
14808} 14822}
14809 14823
14810#ifdef CONFIG_SND_HDA_POWER_SAVE 14824static void alc269_shutup(struct hda_codec *codec)
14811static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14812{ 14825{
14813 struct alc_spec *spec = codec->spec;
14814
14815 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) 14826 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14816 alc269_toggle_power_output(codec, 0); 14827 alc269_toggle_power_output(codec, 0);
14817 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 14828 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14818 alc269_toggle_power_output(codec, 0); 14829 alc269_toggle_power_output(codec, 0);
14819 msleep(150); 14830 msleep(150);
14820 } 14831 }
14821
14822 alc_shutup(codec);
14823 if (spec && spec->power_hook)
14824 spec->power_hook(codec);
14825 return 0;
14826} 14832}
14827#endif /* CONFIG_SND_HDA_POWER_SAVE */
14828 14833
14834#ifdef SND_HDA_NEEDS_RESUME
14829static int alc269_resume(struct hda_codec *codec) 14835static int alc269_resume(struct hda_codec *codec)
14830{ 14836{
14831 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 14837 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
@@ -14864,7 +14870,7 @@ static void alc269_fixup_hweq(struct hda_codec *codec,
14864static void alc271_fixup_dmic(struct hda_codec *codec, 14870static void alc271_fixup_dmic(struct hda_codec *codec,
14865 const struct alc_fixup *fix, int action) 14871 const struct alc_fixup *fix, int action)
14866{ 14872{
14867 static struct hda_verb verbs[] = { 14873 static const struct hda_verb verbs[] = {
14868 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, 14874 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14869 {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, 14875 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14870 {} 14876 {}
@@ -14947,7 +14953,7 @@ static const struct alc_fixup alc269_fixups[] = {
14947 }, 14953 },
14948}; 14954};
14949 14955
14950static struct snd_pci_quirk alc269_fixup_tbl[] = { 14956static const struct snd_pci_quirk alc269_fixup_tbl[] = {
14951 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), 14957 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14952 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 14958 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14953 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 14959 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
@@ -14978,7 +14984,7 @@ static const char * const alc269_models[ALC269_MODEL_LAST] = {
14978 [ALC269_AUTO] = "auto", 14984 [ALC269_AUTO] = "auto",
14979}; 14985};
14980 14986
14981static struct snd_pci_quirk alc269_cfg_tbl[] = { 14987static const struct snd_pci_quirk alc269_cfg_tbl[] = {
14982 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 14988 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14983 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER), 14989 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
14984 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 14990 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
@@ -15036,7 +15042,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = {
15036 {} 15042 {}
15037}; 15043};
15038 15044
15039static struct alc_config_preset alc269_presets[] = { 15045static const struct alc_config_preset alc269_presets[] = {
15040 [ALC269_BASIC] = { 15046 [ALC269_BASIC] = {
15041 .mixers = { alc269_base_mixer }, 15047 .mixers = { alc269_base_mixer },
15042 .init_verbs = { alc269_init_verbs }, 15048 .init_verbs = { alc269_init_verbs },
@@ -15070,9 +15076,9 @@ static struct alc_config_preset alc269_presets[] = {
15070 .hp_nid = 0x03, 15076 .hp_nid = 0x03,
15071 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15077 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15072 .channel_mode = alc269_modes, 15078 .channel_mode = alc269_modes,
15073 .unsol_event = alc269_laptop_unsol_event, 15079 .unsol_event = alc_sku_unsol_event,
15074 .setup = alc269_laptop_amic_setup, 15080 .setup = alc269_laptop_amic_setup,
15075 .init_hook = alc269_laptop_inithook, 15081 .init_hook = alc_inithook,
15076 }, 15082 },
15077 [ALC269_DMIC] = { 15083 [ALC269_DMIC] = {
15078 .mixers = { alc269_laptop_mixer }, 15084 .mixers = { alc269_laptop_mixer },
@@ -15084,9 +15090,9 @@ static struct alc_config_preset alc269_presets[] = {
15084 .hp_nid = 0x03, 15090 .hp_nid = 0x03,
15085 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15091 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15086 .channel_mode = alc269_modes, 15092 .channel_mode = alc269_modes,
15087 .unsol_event = alc269_laptop_unsol_event, 15093 .unsol_event = alc_sku_unsol_event,
15088 .setup = alc269_laptop_dmic_setup, 15094 .setup = alc269_laptop_dmic_setup,
15089 .init_hook = alc269_laptop_inithook, 15095 .init_hook = alc_inithook,
15090 }, 15096 },
15091 [ALC269VB_AMIC] = { 15097 [ALC269VB_AMIC] = {
15092 .mixers = { alc269vb_laptop_mixer }, 15098 .mixers = { alc269vb_laptop_mixer },
@@ -15098,9 +15104,9 @@ static struct alc_config_preset alc269_presets[] = {
15098 .hp_nid = 0x03, 15104 .hp_nid = 0x03,
15099 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15105 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15100 .channel_mode = alc269_modes, 15106 .channel_mode = alc269_modes,
15101 .unsol_event = alc269_laptop_unsol_event, 15107 .unsol_event = alc_sku_unsol_event,
15102 .setup = alc269vb_laptop_amic_setup, 15108 .setup = alc269vb_laptop_amic_setup,
15103 .init_hook = alc269_laptop_inithook, 15109 .init_hook = alc_inithook,
15104 }, 15110 },
15105 [ALC269VB_DMIC] = { 15111 [ALC269VB_DMIC] = {
15106 .mixers = { alc269vb_laptop_mixer }, 15112 .mixers = { alc269vb_laptop_mixer },
@@ -15112,9 +15118,9 @@ static struct alc_config_preset alc269_presets[] = {
15112 .hp_nid = 0x03, 15118 .hp_nid = 0x03,
15113 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15119 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15114 .channel_mode = alc269_modes, 15120 .channel_mode = alc269_modes,
15115 .unsol_event = alc269_laptop_unsol_event, 15121 .unsol_event = alc_sku_unsol_event,
15116 .setup = alc269vb_laptop_dmic_setup, 15122 .setup = alc269vb_laptop_dmic_setup,
15117 .init_hook = alc269_laptop_inithook, 15123 .init_hook = alc_inithook,
15118 }, 15124 },
15119 [ALC269_FUJITSU] = { 15125 [ALC269_FUJITSU] = {
15120 .mixers = { alc269_fujitsu_mixer }, 15126 .mixers = { alc269_fujitsu_mixer },
@@ -15126,9 +15132,9 @@ static struct alc_config_preset alc269_presets[] = {
15126 .hp_nid = 0x03, 15132 .hp_nid = 0x03,
15127 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15133 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15128 .channel_mode = alc269_modes, 15134 .channel_mode = alc269_modes,
15129 .unsol_event = alc269_laptop_unsol_event, 15135 .unsol_event = alc_sku_unsol_event,
15130 .setup = alc269_laptop_dmic_setup, 15136 .setup = alc269_laptop_dmic_setup,
15131 .init_hook = alc269_laptop_inithook, 15137 .init_hook = alc_inithook,
15132 }, 15138 },
15133 [ALC269_LIFEBOOK] = { 15139 [ALC269_LIFEBOOK] = {
15134 .mixers = { alc269_lifebook_mixer }, 15140 .mixers = { alc269_lifebook_mixer },
@@ -15140,6 +15146,7 @@ static struct alc_config_preset alc269_presets[] = {
15140 .channel_mode = alc269_modes, 15146 .channel_mode = alc269_modes,
15141 .input_mux = &alc269_capture_source, 15147 .input_mux = &alc269_capture_source,
15142 .unsol_event = alc269_lifebook_unsol_event, 15148 .unsol_event = alc269_lifebook_unsol_event,
15149 .setup = alc269_lifebook_setup,
15143 .init_hook = alc269_lifebook_init_hook, 15150 .init_hook = alc269_lifebook_init_hook,
15144 }, 15151 },
15145 [ALC271_ACER] = { 15152 [ALC271_ACER] = {
@@ -15185,14 +15192,21 @@ static int alc269_fill_coef(struct hda_codec *codec)
15185 val = alc_read_coef_idx(codec, 0xd); 15192 val = alc_read_coef_idx(codec, 0xd);
15186 if ((val & 0x0c00) >> 10 != 0x1) { 15193 if ((val & 0x0c00) >> 10 != 0x1) {
15187 /* Capless ramp up clock control */ 15194 /* Capless ramp up clock control */
15188 alc_write_coef_idx(codec, 0xd, val | 1<<10); 15195 alc_write_coef_idx(codec, 0xd, val | (1<<10));
15189 } 15196 }
15190 val = alc_read_coef_idx(codec, 0x17); 15197 val = alc_read_coef_idx(codec, 0x17);
15191 if ((val & 0x01c0) >> 6 != 0x4) { 15198 if ((val & 0x01c0) >> 6 != 0x4) {
15192 /* Class D power on reset */ 15199 /* Class D power on reset */
15193 alc_write_coef_idx(codec, 0x17, val | 1<<7); 15200 alc_write_coef_idx(codec, 0x17, val | (1<<7));
15194 } 15201 }
15195 } 15202 }
15203
15204 val = alc_read_coef_idx(codec, 0xd); /* Class D */
15205 alc_write_coef_idx(codec, 0xd, val | (1<<14));
15206
15207 val = alc_read_coef_idx(codec, 0x4); /* HP */
15208 alc_write_coef_idx(codec, 0x4, val | (1<<11));
15209
15196 return 0; 15210 return 0;
15197} 15211}
15198 15212
@@ -15313,14 +15327,12 @@ static int patch_alc269(struct hda_codec *codec)
15313 spec->vmaster_nid = 0x02; 15327 spec->vmaster_nid = 0x02;
15314 15328
15315 codec->patch_ops = alc_patch_ops; 15329 codec->patch_ops = alc_patch_ops;
15316#ifdef CONFIG_SND_HDA_POWER_SAVE
15317 codec->patch_ops.suspend = alc269_suspend;
15318#endif
15319#ifdef SND_HDA_NEEDS_RESUME 15330#ifdef SND_HDA_NEEDS_RESUME
15320 codec->patch_ops.resume = alc269_resume; 15331 codec->patch_ops.resume = alc269_resume;
15321#endif 15332#endif
15322 if (board_config == ALC269_AUTO) 15333 if (board_config == ALC269_AUTO)
15323 spec->init_hook = alc269_auto_init; 15334 spec->init_hook = alc269_auto_init;
15335 spec->shutup = alc269_shutup;
15324 15336
15325 alc_init_jacks(codec); 15337 alc_init_jacks(codec);
15326#ifdef CONFIG_SND_HDA_POWER_SAVE 15338#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -15341,7 +15353,7 @@ static int patch_alc269(struct hda_codec *codec)
15341 * set the path ways for 2 channel output 15353 * set the path ways for 2 channel output
15342 * need to set the codec line out and mic 1 pin widgets to inputs 15354 * need to set the codec line out and mic 1 pin widgets to inputs
15343 */ 15355 */
15344static struct hda_verb alc861_threestack_ch2_init[] = { 15356static const struct hda_verb alc861_threestack_ch2_init[] = {
15345 /* set pin widget 1Ah (line in) for input */ 15357 /* set pin widget 1Ah (line in) for input */
15346 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15358 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15347 /* set pin widget 18h (mic1/2) for input, for mic also enable 15359 /* set pin widget 18h (mic1/2) for input, for mic also enable
@@ -15360,7 +15372,7 @@ static struct hda_verb alc861_threestack_ch2_init[] = {
15360 * 6ch mode 15372 * 6ch mode
15361 * need to set the codec line out and mic 1 pin widgets to outputs 15373 * need to set the codec line out and mic 1 pin widgets to outputs
15362 */ 15374 */
15363static struct hda_verb alc861_threestack_ch6_init[] = { 15375static const struct hda_verb alc861_threestack_ch6_init[] = {
15364 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 15376 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15365 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15377 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15366 /* set pin widget 18h (mic1) for output (CLFE)*/ 15378 /* set pin widget 18h (mic1) for output (CLFE)*/
@@ -15377,30 +15389,30 @@ static struct hda_verb alc861_threestack_ch6_init[] = {
15377 { } /* end */ 15389 { } /* end */
15378}; 15390};
15379 15391
15380static struct hda_channel_mode alc861_threestack_modes[2] = { 15392static const struct hda_channel_mode alc861_threestack_modes[2] = {
15381 { 2, alc861_threestack_ch2_init }, 15393 { 2, alc861_threestack_ch2_init },
15382 { 6, alc861_threestack_ch6_init }, 15394 { 6, alc861_threestack_ch6_init },
15383}; 15395};
15384/* Set mic1 as input and unmute the mixer */ 15396/* Set mic1 as input and unmute the mixer */
15385static struct hda_verb alc861_uniwill_m31_ch2_init[] = { 15397static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15386 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15398 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15387 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 15399 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15388 { } /* end */ 15400 { } /* end */
15389}; 15401};
15390/* Set mic1 as output and mute mixer */ 15402/* Set mic1 as output and mute mixer */
15391static struct hda_verb alc861_uniwill_m31_ch4_init[] = { 15403static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15392 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15404 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15393 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 15405 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15394 { } /* end */ 15406 { } /* end */
15395}; 15407};
15396 15408
15397static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { 15409static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15398 { 2, alc861_uniwill_m31_ch2_init }, 15410 { 2, alc861_uniwill_m31_ch2_init },
15399 { 4, alc861_uniwill_m31_ch4_init }, 15411 { 4, alc861_uniwill_m31_ch4_init },
15400}; 15412};
15401 15413
15402/* Set mic1 and line-in as input and unmute the mixer */ 15414/* Set mic1 and line-in as input and unmute the mixer */
15403static struct hda_verb alc861_asus_ch2_init[] = { 15415static const struct hda_verb alc861_asus_ch2_init[] = {
15404 /* set pin widget 1Ah (line in) for input */ 15416 /* set pin widget 1Ah (line in) for input */
15405 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15417 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15406 /* set pin widget 18h (mic1/2) for input, for mic also enable 15418 /* set pin widget 18h (mic1/2) for input, for mic also enable
@@ -15416,7 +15428,7 @@ static struct hda_verb alc861_asus_ch2_init[] = {
15416 { } /* end */ 15428 { } /* end */
15417}; 15429};
15418/* Set mic1 nad line-in as output and mute mixer */ 15430/* Set mic1 nad line-in as output and mute mixer */
15419static struct hda_verb alc861_asus_ch6_init[] = { 15431static const struct hda_verb alc861_asus_ch6_init[] = {
15420 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 15432 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15421 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15433 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15422 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 15434 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
@@ -15434,14 +15446,14 @@ static struct hda_verb alc861_asus_ch6_init[] = {
15434 { } /* end */ 15446 { } /* end */
15435}; 15447};
15436 15448
15437static struct hda_channel_mode alc861_asus_modes[2] = { 15449static const struct hda_channel_mode alc861_asus_modes[2] = {
15438 { 2, alc861_asus_ch2_init }, 15450 { 2, alc861_asus_ch2_init },
15439 { 6, alc861_asus_ch6_init }, 15451 { 6, alc861_asus_ch6_init },
15440}; 15452};
15441 15453
15442/* patch-ALC861 */ 15454/* patch-ALC861 */
15443 15455
15444static struct snd_kcontrol_new alc861_base_mixer[] = { 15456static const struct snd_kcontrol_new alc861_base_mixer[] = {
15445 /* output mixer control */ 15457 /* output mixer control */
15446 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15458 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15447 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15459 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
@@ -15464,7 +15476,7 @@ static struct snd_kcontrol_new alc861_base_mixer[] = {
15464 { } /* end */ 15476 { } /* end */
15465}; 15477};
15466 15478
15467static struct snd_kcontrol_new alc861_3ST_mixer[] = { 15479static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
15468 /* output mixer control */ 15480 /* output mixer control */
15469 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15481 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15470 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15482 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
@@ -15495,7 +15507,7 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15495 { } /* end */ 15507 { } /* end */
15496}; 15508};
15497 15509
15498static struct snd_kcontrol_new alc861_toshiba_mixer[] = { 15510static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15499 /* output mixer control */ 15511 /* output mixer control */
15500 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15512 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15501 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
@@ -15504,7 +15516,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15504 { } /* end */ 15516 { } /* end */
15505}; 15517};
15506 15518
15507static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 15519static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15508 /* output mixer control */ 15520 /* output mixer control */
15509 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15521 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15510 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15522 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
@@ -15535,7 +15547,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15535 { } /* end */ 15547 { } /* end */
15536}; 15548};
15537 15549
15538static struct snd_kcontrol_new alc861_asus_mixer[] = { 15550static const struct snd_kcontrol_new alc861_asus_mixer[] = {
15539 /* output mixer control */ 15551 /* output mixer control */
15540 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15552 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15541 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15553 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
@@ -15567,7 +15579,7 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = {
15567}; 15579};
15568 15580
15569/* additional mixer */ 15581/* additional mixer */
15570static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { 15582static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15571 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15583 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15572 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15584 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15573 { } 15585 { }
@@ -15576,7 +15588,7 @@ static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15576/* 15588/*
15577 * generic initialization of ADC, input mixers and output mixers 15589 * generic initialization of ADC, input mixers and output mixers
15578 */ 15590 */
15579static struct hda_verb alc861_base_init_verbs[] = { 15591static const struct hda_verb alc861_base_init_verbs[] = {
15580 /* 15592 /*
15581 * Unmute ADC0 and set the default input to mic-in 15593 * Unmute ADC0 and set the default input to mic-in
15582 */ 15594 */
@@ -15642,7 +15654,7 @@ static struct hda_verb alc861_base_init_verbs[] = {
15642 { } 15654 { }
15643}; 15655};
15644 15656
15645static struct hda_verb alc861_threestack_init_verbs[] = { 15657static const struct hda_verb alc861_threestack_init_verbs[] = {
15646 /* 15658 /*
15647 * Unmute ADC0 and set the default input to mic-in 15659 * Unmute ADC0 and set the default input to mic-in
15648 */ 15660 */
@@ -15703,7 +15715,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = {
15703 { } 15715 { }
15704}; 15716};
15705 15717
15706static struct hda_verb alc861_uniwill_m31_init_verbs[] = { 15718static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15707 /* 15719 /*
15708 * Unmute ADC0 and set the default input to mic-in 15720 * Unmute ADC0 and set the default input to mic-in
15709 */ 15721 */
@@ -15765,7 +15777,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15765 { } 15777 { }
15766}; 15778};
15767 15779
15768static struct hda_verb alc861_asus_init_verbs[] = { 15780static const struct hda_verb alc861_asus_init_verbs[] = {
15769 /* 15781 /*
15770 * Unmute ADC0 and set the default input to mic-in 15782 * Unmute ADC0 and set the default input to mic-in
15771 */ 15783 */
@@ -15831,7 +15843,7 @@ static struct hda_verb alc861_asus_init_verbs[] = {
15831}; 15843};
15832 15844
15833/* additional init verbs for ASUS laptops */ 15845/* additional init verbs for ASUS laptops */
15834static struct hda_verb alc861_asus_laptop_init_verbs[] = { 15846static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
15835 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ 15847 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15836 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ 15848 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15837 { } 15849 { }
@@ -15840,7 +15852,7 @@ static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15840/* 15852/*
15841 * generic initialization of ADC, input mixers and output mixers 15853 * generic initialization of ADC, input mixers and output mixers
15842 */ 15854 */
15843static struct hda_verb alc861_auto_init_verbs[] = { 15855static const struct hda_verb alc861_auto_init_verbs[] = {
15844 /* 15856 /*
15845 * Unmute ADC0 and set the default input to mic-in 15857 * Unmute ADC0 and set the default input to mic-in
15846 */ 15858 */
@@ -15889,7 +15901,7 @@ static struct hda_verb alc861_auto_init_verbs[] = {
15889 { } 15901 { }
15890}; 15902};
15891 15903
15892static struct hda_verb alc861_toshiba_init_verbs[] = { 15904static const struct hda_verb alc861_toshiba_init_verbs[] = {
15893 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15905 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15894 15906
15895 { } 15907 { }
@@ -15922,26 +15934,26 @@ static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15922 15934
15923#define ALC861_DIGOUT_NID 0x07 15935#define ALC861_DIGOUT_NID 0x07
15924 15936
15925static struct hda_channel_mode alc861_8ch_modes[1] = { 15937static const struct hda_channel_mode alc861_8ch_modes[1] = {
15926 { 8, NULL } 15938 { 8, NULL }
15927}; 15939};
15928 15940
15929static hda_nid_t alc861_dac_nids[4] = { 15941static const hda_nid_t alc861_dac_nids[4] = {
15930 /* front, surround, clfe, side */ 15942 /* front, surround, clfe, side */
15931 0x03, 0x06, 0x05, 0x04 15943 0x03, 0x06, 0x05, 0x04
15932}; 15944};
15933 15945
15934static hda_nid_t alc660_dac_nids[3] = { 15946static const hda_nid_t alc660_dac_nids[3] = {
15935 /* front, clfe, surround */ 15947 /* front, clfe, surround */
15936 0x03, 0x05, 0x06 15948 0x03, 0x05, 0x06
15937}; 15949};
15938 15950
15939static hda_nid_t alc861_adc_nids[1] = { 15951static const hda_nid_t alc861_adc_nids[1] = {
15940 /* ADC0-2 */ 15952 /* ADC0-2 */
15941 0x08, 15953 0x08,
15942}; 15954};
15943 15955
15944static struct hda_input_mux alc861_capture_source = { 15956static const struct hda_input_mux alc861_capture_source = {
15945 .num_items = 5, 15957 .num_items = 5,
15946 .items = { 15958 .items = {
15947 { "Mic", 0x0 }, 15959 { "Mic", 0x0 },
@@ -15991,7 +16003,7 @@ static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
15991 dac = alc861_look_for_dac(codec, nid); 16003 dac = alc861_look_for_dac(codec, nid);
15992 if (!dac) 16004 if (!dac)
15993 continue; 16005 continue;
15994 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 16006 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
15995 } 16007 }
15996 return 0; 16008 return 0;
15997} 16009}
@@ -16014,11 +16026,15 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
16014 static const char * const chname[4] = { 16026 static const char * const chname[4] = {
16015 "Front", "Surround", NULL /*CLFE*/, "Side" 16027 "Front", "Surround", NULL /*CLFE*/, "Side"
16016 }; 16028 };
16017 const char *pfx = alc_get_line_out_pfx(cfg, true); 16029 const char *pfx = alc_get_line_out_pfx(spec, true);
16018 hda_nid_t nid; 16030 hda_nid_t nid;
16019 int i, err; 16031 int i, err, noutputs;
16020 16032
16021 for (i = 0; i < cfg->line_outs; i++) { 16033 noutputs = cfg->line_outs;
16034 if (spec->multi_ios > 0)
16035 noutputs += spec->multi_ios;
16036
16037 for (i = 0; i < noutputs; i++) {
16022 nid = spec->multiout.dac_nids[i]; 16038 nid = spec->multiout.dac_nids[i];
16023 if (!nid) 16039 if (!nid)
16024 continue; 16040 continue;
@@ -16151,7 +16167,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
16151{ 16167{
16152 struct alc_spec *spec = codec->spec; 16168 struct alc_spec *spec = codec->spec;
16153 int err; 16169 int err;
16154 static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 16170 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16155 16171
16156 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 16172 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16157 alc861_ignore); 16173 alc861_ignore);
@@ -16163,6 +16179,9 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
16163 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg); 16179 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
16164 if (err < 0) 16180 if (err < 0)
16165 return err; 16181 return err;
16182 err = alc_auto_add_multi_channel_mode(codec);
16183 if (err < 0)
16184 return err;
16166 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg); 16185 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
16167 if (err < 0) 16186 if (err < 0)
16168 return err; 16187 return err;
@@ -16207,7 +16226,7 @@ static void alc861_auto_init(struct hda_codec *codec)
16207} 16226}
16208 16227
16209#ifdef CONFIG_SND_HDA_POWER_SAVE 16228#ifdef CONFIG_SND_HDA_POWER_SAVE
16210static struct hda_amp_list alc861_loopbacks[] = { 16229static const struct hda_amp_list alc861_loopbacks[] = {
16211 { 0x15, HDA_INPUT, 0 }, 16230 { 0x15, HDA_INPUT, 0 },
16212 { 0x15, HDA_INPUT, 1 }, 16231 { 0x15, HDA_INPUT, 1 },
16213 { 0x15, HDA_INPUT, 2 }, 16232 { 0x15, HDA_INPUT, 2 },
@@ -16232,7 +16251,7 @@ static const char * const alc861_models[ALC861_MODEL_LAST] = {
16232 [ALC861_AUTO] = "auto", 16251 [ALC861_AUTO] = "auto",
16233}; 16252};
16234 16253
16235static struct snd_pci_quirk alc861_cfg_tbl[] = { 16254static const struct snd_pci_quirk alc861_cfg_tbl[] = {
16236 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), 16255 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
16237 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 16256 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16238 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 16257 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
@@ -16256,7 +16275,7 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = {
16256 {} 16275 {}
16257}; 16276};
16258 16277
16259static struct alc_config_preset alc861_presets[] = { 16278static const struct alc_config_preset alc861_presets[] = {
16260 [ALC861_3ST] = { 16279 [ALC861_3ST] = {
16261 .mixers = { alc861_3ST_mixer }, 16280 .mixers = { alc861_3ST_mixer },
16262 .init_verbs = { alc861_threestack_init_verbs }, 16281 .init_verbs = { alc861_threestack_init_verbs },
@@ -16379,7 +16398,7 @@ static const struct alc_fixup alc861_fixups[] = {
16379 }, 16398 },
16380}; 16399};
16381 16400
16382static struct snd_pci_quirk alc861_fixup_tbl[] = { 16401static const struct snd_pci_quirk alc861_fixup_tbl[] = {
16383 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 16402 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16384 {} 16403 {}
16385}; 16404};
@@ -16472,7 +16491,7 @@ static int patch_alc861(struct hda_codec *codec)
16472 */ 16491 */
16473#define ALC861VD_DIGOUT_NID 0x06 16492#define ALC861VD_DIGOUT_NID 0x06
16474 16493
16475static hda_nid_t alc861vd_dac_nids[4] = { 16494static const hda_nid_t alc861vd_dac_nids[4] = {
16476 /* front, surr, clfe, side surr */ 16495 /* front, surr, clfe, side surr */
16477 0x02, 0x03, 0x04, 0x05 16496 0x02, 0x03, 0x04, 0x05
16478}; 16497};
@@ -16484,21 +16503,21 @@ static hda_nid_t alc861vd_dac_nids[4] = {
16484 * - and it is the same as in 861vd. 16503 * - and it is the same as in 861vd.
16485 * adc_nids in ALC660vd are (is) the same as in 861vd 16504 * adc_nids in ALC660vd are (is) the same as in 861vd
16486 */ 16505 */
16487static hda_nid_t alc660vd_dac_nids[3] = { 16506static const hda_nid_t alc660vd_dac_nids[3] = {
16488 /* front, rear, clfe, rear_surr */ 16507 /* front, rear, clfe, rear_surr */
16489 0x02, 0x04, 0x03 16508 0x02, 0x04, 0x03
16490}; 16509};
16491 16510
16492static hda_nid_t alc861vd_adc_nids[1] = { 16511static const hda_nid_t alc861vd_adc_nids[1] = {
16493 /* ADC0 */ 16512 /* ADC0 */
16494 0x09, 16513 0x09,
16495}; 16514};
16496 16515
16497static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; 16516static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16498 16517
16499/* input MUX */ 16518/* input MUX */
16500/* FIXME: should be a matrix-type input source selection */ 16519/* FIXME: should be a matrix-type input source selection */
16501static struct hda_input_mux alc861vd_capture_source = { 16520static const struct hda_input_mux alc861vd_capture_source = {
16502 .num_items = 4, 16521 .num_items = 4,
16503 .items = { 16522 .items = {
16504 { "Mic", 0x0 }, 16523 { "Mic", 0x0 },
@@ -16508,7 +16527,7 @@ static struct hda_input_mux alc861vd_capture_source = {
16508 }, 16527 },
16509}; 16528};
16510 16529
16511static struct hda_input_mux alc861vd_dallas_capture_source = { 16530static const struct hda_input_mux alc861vd_dallas_capture_source = {
16512 .num_items = 2, 16531 .num_items = 2,
16513 .items = { 16532 .items = {
16514 { "Mic", 0x0 }, 16533 { "Mic", 0x0 },
@@ -16516,7 +16535,7 @@ static struct hda_input_mux alc861vd_dallas_capture_source = {
16516 }, 16535 },
16517}; 16536};
16518 16537
16519static struct hda_input_mux alc861vd_hp_capture_source = { 16538static const struct hda_input_mux alc861vd_hp_capture_source = {
16520 .num_items = 2, 16539 .num_items = 2,
16521 .items = { 16540 .items = {
16522 { "Front Mic", 0x0 }, 16541 { "Front Mic", 0x0 },
@@ -16527,14 +16546,14 @@ static struct hda_input_mux alc861vd_hp_capture_source = {
16527/* 16546/*
16528 * 2ch mode 16547 * 2ch mode
16529 */ 16548 */
16530static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { 16549static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16531 { 2, NULL } 16550 { 2, NULL }
16532}; 16551};
16533 16552
16534/* 16553/*
16535 * 6ch mode 16554 * 6ch mode
16536 */ 16555 */
16537static struct hda_verb alc861vd_6stack_ch6_init[] = { 16556static const struct hda_verb alc861vd_6stack_ch6_init[] = {
16538 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 16557 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16539 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16558 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16540 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16559 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -16545,7 +16564,7 @@ static struct hda_verb alc861vd_6stack_ch6_init[] = {
16545/* 16564/*
16546 * 8ch mode 16565 * 8ch mode
16547 */ 16566 */
16548static struct hda_verb alc861vd_6stack_ch8_init[] = { 16567static const struct hda_verb alc861vd_6stack_ch8_init[] = {
16549 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16568 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16550 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16569 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16551 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16570 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -16553,12 +16572,12 @@ static struct hda_verb alc861vd_6stack_ch8_init[] = {
16553 { } /* end */ 16572 { } /* end */
16554}; 16573};
16555 16574
16556static struct hda_channel_mode alc861vd_6stack_modes[2] = { 16575static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
16557 { 6, alc861vd_6stack_ch6_init }, 16576 { 6, alc861vd_6stack_ch6_init },
16558 { 8, alc861vd_6stack_ch8_init }, 16577 { 8, alc861vd_6stack_ch8_init },
16559}; 16578};
16560 16579
16561static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { 16580static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16562 { 16581 {
16563 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 16582 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16564 .name = "Channel Mode", 16583 .name = "Channel Mode",
@@ -16572,7 +16591,7 @@ static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16572/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 16591/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16573 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 16592 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16574 */ 16593 */
16575static struct snd_kcontrol_new alc861vd_6st_mixer[] = { 16594static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16576 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16595 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16577 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16596 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16578 16597
@@ -16608,7 +16627,7 @@ static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16608 { } /* end */ 16627 { } /* end */
16609}; 16628};
16610 16629
16611static struct snd_kcontrol_new alc861vd_3st_mixer[] = { 16630static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16612 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16631 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16613 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16632 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16614 16633
@@ -16631,7 +16650,7 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16631 { } /* end */ 16650 { } /* end */
16632}; 16651};
16633 16652
16634static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { 16653static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16635 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16654 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16636 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ 16655 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16637 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 16656 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -16655,7 +16674,7 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16655/* Pin assignment: Speaker=0x14, HP = 0x15, 16674/* Pin assignment: Speaker=0x14, HP = 0x15,
16656 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d 16675 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16657 */ 16676 */
16658static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 16677static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16659 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16678 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16660 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 16679 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16661 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16680 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -16672,7 +16691,7 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16672/* Pin assignment: Speaker=0x14, Line-out = 0x15, 16691/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16673 * Front Mic=0x18, ATAPI Mic = 0x19, 16692 * Front Mic=0x18, ATAPI Mic = 0x19,
16674 */ 16693 */
16675static struct snd_kcontrol_new alc861vd_hp_mixer[] = { 16694static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16676 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16695 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16677 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16696 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16678 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16697 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -16688,7 +16707,7 @@ static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16688/* 16707/*
16689 * generic initialization of ADC, input mixers and output mixers 16708 * generic initialization of ADC, input mixers and output mixers
16690 */ 16709 */
16691static struct hda_verb alc861vd_volume_init_verbs[] = { 16710static const struct hda_verb alc861vd_volume_init_verbs[] = {
16692 /* 16711 /*
16693 * Unmute ADC0 and set the default input to mic-in 16712 * Unmute ADC0 and set the default input to mic-in
16694 */ 16713 */
@@ -16738,7 +16757,7 @@ static struct hda_verb alc861vd_volume_init_verbs[] = {
16738 * 3-stack pin configuration: 16757 * 3-stack pin configuration:
16739 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 16758 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16740 */ 16759 */
16741static struct hda_verb alc861vd_3stack_init_verbs[] = { 16760static const struct hda_verb alc861vd_3stack_init_verbs[] = {
16742 /* 16761 /*
16743 * Set pin mode and muting 16762 * Set pin mode and muting
16744 */ 16763 */
@@ -16769,7 +16788,7 @@ static struct hda_verb alc861vd_3stack_init_verbs[] = {
16769/* 16788/*
16770 * 6-stack pin configuration: 16789 * 6-stack pin configuration:
16771 */ 16790 */
16772static struct hda_verb alc861vd_6stack_init_verbs[] = { 16791static const struct hda_verb alc861vd_6stack_init_verbs[] = {
16773 /* 16792 /*
16774 * Set pin mode and muting 16793 * Set pin mode and muting
16775 */ 16794 */
@@ -16810,18 +16829,18 @@ static struct hda_verb alc861vd_6stack_init_verbs[] = {
16810 { } 16829 { }
16811}; 16830};
16812 16831
16813static struct hda_verb alc861vd_eapd_verbs[] = { 16832static const struct hda_verb alc861vd_eapd_verbs[] = {
16814 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16833 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16815 { } 16834 { }
16816}; 16835};
16817 16836
16818static struct hda_verb alc660vd_eapd_verbs[] = { 16837static const struct hda_verb alc660vd_eapd_verbs[] = {
16819 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16838 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16820 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16839 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16821 { } 16840 { }
16822}; 16841};
16823 16842
16824static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 16843static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16825 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16844 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16826 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16827 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 16846 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
@@ -16835,11 +16854,13 @@ static void alc861vd_lenovo_setup(struct hda_codec *codec)
16835 struct alc_spec *spec = codec->spec; 16854 struct alc_spec *spec = codec->spec;
16836 spec->autocfg.hp_pins[0] = 0x1b; 16855 spec->autocfg.hp_pins[0] = 0x1b;
16837 spec->autocfg.speaker_pins[0] = 0x14; 16856 spec->autocfg.speaker_pins[0] = 0x14;
16857 spec->automute = 1;
16858 spec->automute_mode = ALC_AUTOMUTE_AMP;
16838} 16859}
16839 16860
16840static void alc861vd_lenovo_init_hook(struct hda_codec *codec) 16861static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16841{ 16862{
16842 alc_automute_amp(codec); 16863 alc_hp_automute(codec);
16843 alc88x_simple_mic_automute(codec); 16864 alc88x_simple_mic_automute(codec);
16844} 16865}
16845 16866
@@ -16851,12 +16872,12 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16851 alc88x_simple_mic_automute(codec); 16872 alc88x_simple_mic_automute(codec);
16852 break; 16873 break;
16853 default: 16874 default:
16854 alc_automute_amp_unsol_event(codec, res); 16875 alc_sku_unsol_event(codec, res);
16855 break; 16876 break;
16856 } 16877 }
16857} 16878}
16858 16879
16859static struct hda_verb alc861vd_dallas_verbs[] = { 16880static const struct hda_verb alc861vd_dallas_verbs[] = {
16860 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16881 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16861 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16882 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16862 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16883 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -16908,6 +16929,8 @@ static void alc861vd_dallas_setup(struct hda_codec *codec)
16908 16929
16909 spec->autocfg.hp_pins[0] = 0x15; 16930 spec->autocfg.hp_pins[0] = 0x15;
16910 spec->autocfg.speaker_pins[0] = 0x14; 16931 spec->autocfg.speaker_pins[0] = 0x14;
16932 spec->automute = 1;
16933 spec->automute_mode = ALC_AUTOMUTE_AMP;
16911} 16934}
16912 16935
16913#ifdef CONFIG_SND_HDA_POWER_SAVE 16936#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -16936,7 +16959,7 @@ static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16936 [ALC861VD_AUTO] = "auto", 16959 [ALC861VD_AUTO] = "auto",
16937}; 16960};
16938 16961
16939static struct snd_pci_quirk alc861vd_cfg_tbl[] = { 16962static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16940 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 16963 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16941 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 16964 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16942 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 16965 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
@@ -16955,7 +16978,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16955 {} 16978 {}
16956}; 16979};
16957 16980
16958static struct alc_config_preset alc861vd_presets[] = { 16981static const struct alc_config_preset alc861vd_presets[] = {
16959 [ALC660VD_3ST] = { 16982 [ALC660VD_3ST] = {
16960 .mixers = { alc861vd_3st_mixer }, 16983 .mixers = { alc861vd_3st_mixer },
16961 .init_verbs = { alc861vd_volume_init_verbs, 16984 .init_verbs = { alc861vd_volume_init_verbs,
@@ -17032,9 +17055,9 @@ static struct alc_config_preset alc861vd_presets[] = {
17032 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17055 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17033 .channel_mode = alc861vd_3stack_2ch_modes, 17056 .channel_mode = alc861vd_3stack_2ch_modes,
17034 .input_mux = &alc861vd_dallas_capture_source, 17057 .input_mux = &alc861vd_dallas_capture_source,
17035 .unsol_event = alc_automute_amp_unsol_event, 17058 .unsol_event = alc_sku_unsol_event,
17036 .setup = alc861vd_dallas_setup, 17059 .setup = alc861vd_dallas_setup,
17037 .init_hook = alc_automute_amp, 17060 .init_hook = alc_hp_automute,
17038 }, 17061 },
17039 [ALC861VD_HP] = { 17062 [ALC861VD_HP] = {
17040 .mixers = { alc861vd_hp_mixer }, 17063 .mixers = { alc861vd_hp_mixer },
@@ -17045,9 +17068,9 @@ static struct alc_config_preset alc861vd_presets[] = {
17045 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17068 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17046 .channel_mode = alc861vd_3stack_2ch_modes, 17069 .channel_mode = alc861vd_3stack_2ch_modes,
17047 .input_mux = &alc861vd_hp_capture_source, 17070 .input_mux = &alc861vd_hp_capture_source,
17048 .unsol_event = alc_automute_amp_unsol_event, 17071 .unsol_event = alc_sku_unsol_event,
17049 .setup = alc861vd_dallas_setup, 17072 .setup = alc861vd_dallas_setup,
17050 .init_hook = alc_automute_amp, 17073 .init_hook = alc_hp_automute,
17051 }, 17074 },
17052 [ALC660VD_ASUS_V1S] = { 17075 [ALC660VD_ASUS_V1S] = {
17053 .mixers = { alc861vd_lenovo_mixer }, 17076 .mixers = { alc861vd_lenovo_mixer },
@@ -17146,11 +17169,15 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17146 static const char * const chname[4] = { 17169 static const char * const chname[4] = {
17147 "Front", "Surround", "CLFE", "Side" 17170 "Front", "Surround", "CLFE", "Side"
17148 }; 17171 };
17149 const char *pfx = alc_get_line_out_pfx(cfg, true); 17172 const char *pfx = alc_get_line_out_pfx(spec, true);
17150 hda_nid_t nid_v, nid_s; 17173 hda_nid_t nid_v, nid_s;
17151 int i, err; 17174 int i, err, noutputs;
17152 17175
17153 for (i = 0; i < cfg->line_outs; i++) { 17176 noutputs = cfg->line_outs;
17177 if (spec->multi_ios > 0)
17178 noutputs += spec->multi_ios;
17179
17180 for (i = 0; i < noutputs; i++) {
17154 if (!spec->multiout.dac_nids[i]) 17181 if (!spec->multiout.dac_nids[i])
17155 continue; 17182 continue;
17156 nid_v = alc861vd_idx_to_mixer_vol( 17183 nid_v = alc861vd_idx_to_mixer_vol(
@@ -17263,7 +17290,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
17263{ 17290{
17264 struct alc_spec *spec = codec->spec; 17291 struct alc_spec *spec = codec->spec;
17265 int err; 17292 int err;
17266 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 17293 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17267 17294
17268 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 17295 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17269 alc861vd_ignore); 17296 alc861vd_ignore);
@@ -17275,6 +17302,9 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
17275 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 17302 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17276 if (err < 0) 17303 if (err < 0)
17277 return err; 17304 return err;
17305 err = alc_auto_add_multi_channel_mode(codec);
17306 if (err < 0)
17307 return err;
17278 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); 17308 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17279 if (err < 0) 17309 if (err < 0)
17280 return err; 17310 return err;
@@ -17343,7 +17373,7 @@ static const struct alc_fixup alc861vd_fixups[] = {
17343 }, 17373 },
17344}; 17374};
17345 17375
17346static struct snd_pci_quirk alc861vd_fixup_tbl[] = { 17376static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17347 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), 17377 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17348 {} 17378 {}
17349}; 17379};
@@ -17426,6 +17456,7 @@ static int patch_alc861vd(struct hda_codec *codec)
17426 17456
17427 if (board_config == ALC861VD_AUTO) 17457 if (board_config == ALC861VD_AUTO)
17428 spec->init_hook = alc861vd_auto_init; 17458 spec->init_hook = alc861vd_auto_init;
17459 spec->shutup = alc_eapd_shutup;
17429#ifdef CONFIG_SND_HDA_POWER_SAVE 17460#ifdef CONFIG_SND_HDA_POWER_SAVE
17430 if (!spec->loopback.amplist) 17461 if (!spec->loopback.amplist)
17431 spec->loopback.amplist = alc861vd_loopbacks; 17462 spec->loopback.amplist = alc861vd_loopbacks;
@@ -17448,32 +17479,32 @@ static int patch_alc861vd(struct hda_codec *codec)
17448#define ALC662_DIGOUT_NID 0x06 17479#define ALC662_DIGOUT_NID 0x06
17449#define ALC662_DIGIN_NID 0x0a 17480#define ALC662_DIGIN_NID 0x0a
17450 17481
17451static hda_nid_t alc662_dac_nids[4] = { 17482static const hda_nid_t alc662_dac_nids[3] = {
17452 /* front, rear, clfe, rear_surr */ 17483 /* front, rear, clfe */
17453 0x02, 0x03, 0x04 17484 0x02, 0x03, 0x04
17454}; 17485};
17455 17486
17456static hda_nid_t alc272_dac_nids[2] = { 17487static const hda_nid_t alc272_dac_nids[2] = {
17457 0x02, 0x03 17488 0x02, 0x03
17458}; 17489};
17459 17490
17460static hda_nid_t alc662_adc_nids[2] = { 17491static const hda_nid_t alc662_adc_nids[2] = {
17461 /* ADC1-2 */ 17492 /* ADC1-2 */
17462 0x09, 0x08 17493 0x09, 0x08
17463}; 17494};
17464 17495
17465static hda_nid_t alc272_adc_nids[1] = { 17496static const hda_nid_t alc272_adc_nids[1] = {
17466 /* ADC1-2 */ 17497 /* ADC1-2 */
17467 0x08, 17498 0x08,
17468}; 17499};
17469 17500
17470static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; 17501static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17471static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; 17502static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17472 17503
17473 17504
17474/* input MUX */ 17505/* input MUX */
17475/* FIXME: should be a matrix-type input source selection */ 17506/* FIXME: should be a matrix-type input source selection */
17476static struct hda_input_mux alc662_capture_source = { 17507static const struct hda_input_mux alc662_capture_source = {
17477 .num_items = 4, 17508 .num_items = 4,
17478 .items = { 17509 .items = {
17479 { "Mic", 0x0 }, 17510 { "Mic", 0x0 },
@@ -17483,7 +17514,7 @@ static struct hda_input_mux alc662_capture_source = {
17483 }, 17514 },
17484}; 17515};
17485 17516
17486static struct hda_input_mux alc662_lenovo_101e_capture_source = { 17517static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
17487 .num_items = 2, 17518 .num_items = 2,
17488 .items = { 17519 .items = {
17489 { "Mic", 0x1 }, 17520 { "Mic", 0x1 },
@@ -17491,7 +17522,7 @@ static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17491 }, 17522 },
17492}; 17523};
17493 17524
17494static struct hda_input_mux alc663_capture_source = { 17525static const struct hda_input_mux alc663_capture_source = {
17495 .num_items = 3, 17526 .num_items = 3,
17496 .items = { 17527 .items = {
17497 { "Mic", 0x0 }, 17528 { "Mic", 0x0 },
@@ -17501,7 +17532,7 @@ static struct hda_input_mux alc663_capture_source = {
17501}; 17532};
17502 17533
17503#if 0 /* set to 1 for testing other input sources below */ 17534#if 0 /* set to 1 for testing other input sources below */
17504static struct hda_input_mux alc272_nc10_capture_source = { 17535static const struct hda_input_mux alc272_nc10_capture_source = {
17505 .num_items = 16, 17536 .num_items = 16,
17506 .items = { 17537 .items = {
17507 { "Autoselect Mic", 0x0 }, 17538 { "Autoselect Mic", 0x0 },
@@ -17527,14 +17558,14 @@ static struct hda_input_mux alc272_nc10_capture_source = {
17527/* 17558/*
17528 * 2ch mode 17559 * 2ch mode
17529 */ 17560 */
17530static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { 17561static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17531 { 2, NULL } 17562 { 2, NULL }
17532}; 17563};
17533 17564
17534/* 17565/*
17535 * 2ch mode 17566 * 2ch mode
17536 */ 17567 */
17537static struct hda_verb alc662_3ST_ch2_init[] = { 17568static const struct hda_verb alc662_3ST_ch2_init[] = {
17538 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 17569 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17539 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 17570 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17540 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 17571 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
@@ -17545,7 +17576,7 @@ static struct hda_verb alc662_3ST_ch2_init[] = {
17545/* 17576/*
17546 * 6ch mode 17577 * 6ch mode
17547 */ 17578 */
17548static struct hda_verb alc662_3ST_ch6_init[] = { 17579static const struct hda_verb alc662_3ST_ch6_init[] = {
17549 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17580 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17550 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 17581 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17551 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 17582 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
@@ -17555,7 +17586,7 @@ static struct hda_verb alc662_3ST_ch6_init[] = {
17555 { } /* end */ 17586 { } /* end */
17556}; 17587};
17557 17588
17558static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { 17589static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17559 { 2, alc662_3ST_ch2_init }, 17590 { 2, alc662_3ST_ch2_init },
17560 { 6, alc662_3ST_ch6_init }, 17591 { 6, alc662_3ST_ch6_init },
17561}; 17592};
@@ -17563,7 +17594,7 @@ static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17563/* 17594/*
17564 * 2ch mode 17595 * 2ch mode
17565 */ 17596 */
17566static struct hda_verb alc662_sixstack_ch6_init[] = { 17597static const struct hda_verb alc662_sixstack_ch6_init[] = {
17567 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 17598 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17568 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 17599 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17569 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17600 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -17573,14 +17604,14 @@ static struct hda_verb alc662_sixstack_ch6_init[] = {
17573/* 17604/*
17574 * 6ch mode 17605 * 6ch mode
17575 */ 17606 */
17576static struct hda_verb alc662_sixstack_ch8_init[] = { 17607static const struct hda_verb alc662_sixstack_ch8_init[] = {
17577 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17608 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17578 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17609 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17579 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17610 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17580 { } /* end */ 17611 { } /* end */
17581}; 17612};
17582 17613
17583static struct hda_channel_mode alc662_5stack_modes[2] = { 17614static const struct hda_channel_mode alc662_5stack_modes[2] = {
17584 { 2, alc662_sixstack_ch6_init }, 17615 { 2, alc662_sixstack_ch6_init },
17585 { 6, alc662_sixstack_ch8_init }, 17616 { 6, alc662_sixstack_ch8_init },
17586}; 17617};
@@ -17589,7 +17620,7 @@ static struct hda_channel_mode alc662_5stack_modes[2] = {
17589 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 17620 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17590 */ 17621 */
17591 17622
17592static struct snd_kcontrol_new alc662_base_mixer[] = { 17623static const struct snd_kcontrol_new alc662_base_mixer[] = {
17593 /* output mixer control */ 17624 /* output mixer control */
17594 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 17625 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
17595 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17626 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
@@ -17613,7 +17644,7 @@ static struct snd_kcontrol_new alc662_base_mixer[] = {
17613 { } /* end */ 17644 { } /* end */
17614}; 17645};
17615 17646
17616static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { 17647static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17617 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17648 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17618 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17649 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17619 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
@@ -17628,7 +17659,7 @@ static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17628 { } /* end */ 17659 { } /* end */
17629}; 17660};
17630 17661
17631static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { 17662static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17632 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17663 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17633 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17664 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17634 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17665 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -17649,7 +17680,7 @@ static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17649 { } /* end */ 17680 { } /* end */
17650}; 17681};
17651 17682
17652static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { 17683static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17653 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17684 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17654 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 17685 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17655 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17686 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -17662,7 +17693,7 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17662 { } /* end */ 17693 { } /* end */
17663}; 17694};
17664 17695
17665static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { 17696static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17666 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17697 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17667 ALC262_HIPPO_MASTER_SWITCH, 17698 ALC262_HIPPO_MASTER_SWITCH,
17668 17699
@@ -17676,7 +17707,7 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17676 { } /* end */ 17707 { } /* end */
17677}; 17708};
17678 17709
17679static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { 17710static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17680 ALC262_HIPPO_MASTER_SWITCH, 17711 ALC262_HIPPO_MASTER_SWITCH,
17681 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17712 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17682 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17713 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -17690,7 +17721,7 @@ static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17690 { } /* end */ 17721 { } /* end */
17691}; 17722};
17692 17723
17693static struct hda_bind_ctls alc663_asus_bind_master_vol = { 17724static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
17694 .ops = &snd_hda_bind_vol, 17725 .ops = &snd_hda_bind_vol,
17695 .values = { 17726 .values = {
17696 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17727 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
@@ -17699,7 +17730,7 @@ static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17699 }, 17730 },
17700}; 17731};
17701 17732
17702static struct hda_bind_ctls alc663_asus_one_bind_switch = { 17733static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
17703 .ops = &snd_hda_bind_sw, 17734 .ops = &snd_hda_bind_sw,
17704 .values = { 17735 .values = {
17705 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17736 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
@@ -17708,7 +17739,7 @@ static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17708 }, 17739 },
17709}; 17740};
17710 17741
17711static struct snd_kcontrol_new alc663_m51va_mixer[] = { 17742static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
17712 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17743 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17713 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), 17744 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17714 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17745 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -17716,7 +17747,7 @@ static struct snd_kcontrol_new alc663_m51va_mixer[] = {
17716 { } /* end */ 17747 { } /* end */
17717}; 17748};
17718 17749
17719static struct hda_bind_ctls alc663_asus_tree_bind_switch = { 17750static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17720 .ops = &snd_hda_bind_sw, 17751 .ops = &snd_hda_bind_sw,
17721 .values = { 17752 .values = {
17722 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17753 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
@@ -17726,7 +17757,7 @@ static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17726 }, 17757 },
17727}; 17758};
17728 17759
17729static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { 17760static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17730 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17761 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17731 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), 17762 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17763 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -17737,7 +17768,7 @@ static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17737 { } /* end */ 17768 { } /* end */
17738}; 17769};
17739 17770
17740static struct hda_bind_ctls alc663_asus_four_bind_switch = { 17771static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
17741 .ops = &snd_hda_bind_sw, 17772 .ops = &snd_hda_bind_sw,
17742 .values = { 17773 .values = {
17743 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17774 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
@@ -17747,7 +17778,7 @@ static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17747 }, 17778 },
17748}; 17779};
17749 17780
17750static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { 17781static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17751 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17782 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17752 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), 17783 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17753 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17784 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -17757,7 +17788,7 @@ static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17757 { } /* end */ 17788 { } /* end */
17758}; 17789};
17759 17790
17760static struct snd_kcontrol_new alc662_1bjd_mixer[] = { 17791static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17761 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17792 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17762 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17793 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17763 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17794 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
@@ -17768,7 +17799,7 @@ static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17768 { } /* end */ 17799 { } /* end */
17769}; 17800};
17770 17801
17771static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { 17802static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17772 .ops = &snd_hda_bind_vol, 17803 .ops = &snd_hda_bind_vol,
17773 .values = { 17804 .values = {
17774 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17805 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
@@ -17777,7 +17808,7 @@ static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17777 }, 17808 },
17778}; 17809};
17779 17810
17780static struct hda_bind_ctls alc663_asus_two_bind_switch = { 17811static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
17781 .ops = &snd_hda_bind_sw, 17812 .ops = &snd_hda_bind_sw,
17782 .values = { 17813 .values = {
17783 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17814 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
@@ -17786,7 +17817,7 @@ static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17786 }, 17817 },
17787}; 17818};
17788 17819
17789static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { 17820static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17790 HDA_BIND_VOL("Master Playback Volume", 17821 HDA_BIND_VOL("Master Playback Volume",
17791 &alc663_asus_two_bind_master_vol), 17822 &alc663_asus_two_bind_master_vol),
17792 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17823 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
@@ -17797,7 +17828,7 @@ static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17797 { } /* end */ 17828 { } /* end */
17798}; 17829};
17799 17830
17800static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { 17831static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17801 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17832 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17802 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17833 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17803 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17834 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -17807,7 +17838,7 @@ static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17807 { } /* end */ 17838 { } /* end */
17808}; 17839};
17809 17840
17810static struct snd_kcontrol_new alc663_g71v_mixer[] = { 17841static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
17811 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17842 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17812 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17843 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17813 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17844 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -17821,7 +17852,7 @@ static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17821 { } /* end */ 17852 { } /* end */
17822}; 17853};
17823 17854
17824static struct snd_kcontrol_new alc663_g50v_mixer[] = { 17855static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
17825 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17856 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17826 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17857 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17827 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17858 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
@@ -17835,7 +17866,7 @@ static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17835 { } /* end */ 17866 { } /* end */
17836}; 17867};
17837 17868
17838static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { 17869static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17839 .ops = &snd_hda_bind_sw, 17870 .ops = &snd_hda_bind_sw,
17840 .values = { 17871 .values = {
17841 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17872 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
@@ -17847,7 +17878,7 @@ static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17847 }, 17878 },
17848}; 17879};
17849 17880
17850static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { 17881static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17851 .ops = &snd_hda_bind_sw, 17882 .ops = &snd_hda_bind_sw,
17852 .values = { 17883 .values = {
17853 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17884 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
@@ -17856,7 +17887,7 @@ static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17856 }, 17887 },
17857}; 17888};
17858 17889
17859static struct snd_kcontrol_new alc663_mode7_mixer[] = { 17890static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
17860 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17891 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17861 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17892 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17862 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17893 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
@@ -17869,7 +17900,7 @@ static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17869 { } /* end */ 17900 { } /* end */
17870}; 17901};
17871 17902
17872static struct snd_kcontrol_new alc663_mode8_mixer[] = { 17903static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
17873 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17904 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17874 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17905 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17875 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17906 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
@@ -17881,7 +17912,7 @@ static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17881}; 17912};
17882 17913
17883 17914
17884static struct snd_kcontrol_new alc662_chmode_mixer[] = { 17915static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
17885 { 17916 {
17886 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 17917 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17887 .name = "Channel Mode", 17918 .name = "Channel Mode",
@@ -17892,7 +17923,7 @@ static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17892 { } /* end */ 17923 { } /* end */
17893}; 17924};
17894 17925
17895static struct hda_verb alc662_init_verbs[] = { 17926static const struct hda_verb alc662_init_verbs[] = {
17896 /* ADC: mute amp left and right */ 17927 /* ADC: mute amp left and right */
17897 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17928 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17898 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 17929 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -17938,55 +17969,36 @@ static struct hda_verb alc662_init_verbs[] = {
17938 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17969 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17939 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17970 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17940 17971
17941 /* always trun on EAPD */
17942 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17943 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17944
17945 { }
17946};
17947
17948static struct hda_verb alc663_init_verbs[] = {
17949 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17950 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17951 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17952 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17953 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17954 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17955 { } 17972 { }
17956}; 17973};
17957 17974
17958static struct hda_verb alc272_init_verbs[] = { 17975static const struct hda_verb alc662_eapd_init_verbs[] = {
17959 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17976 /* always trun on EAPD */
17960 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17977 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17961 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17978 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17962 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17963 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17964 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17965 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17966 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17967 { } 17979 { }
17968}; 17980};
17969 17981
17970static struct hda_verb alc662_sue_init_verbs[] = { 17982static const struct hda_verb alc662_sue_init_verbs[] = {
17971 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 17983 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17972 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 17984 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17973 {} 17985 {}
17974}; 17986};
17975 17987
17976static struct hda_verb alc662_eeepc_sue_init_verbs[] = { 17988static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17977 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17989 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17978 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17990 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17979 {} 17991 {}
17980}; 17992};
17981 17993
17982/* Set Unsolicited Event*/ 17994/* Set Unsolicited Event*/
17983static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { 17995static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17984 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17996 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17985 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17997 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17986 {} 17998 {}
17987}; 17999};
17988 18000
17989static struct hda_verb alc663_m51va_init_verbs[] = { 18001static const struct hda_verb alc663_m51va_init_verbs[] = {
17990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18002 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17991 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18003 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17992 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18004 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -17999,7 +18011,7 @@ static struct hda_verb alc663_m51va_init_verbs[] = {
17999 {} 18011 {}
18000}; 18012};
18001 18013
18002static struct hda_verb alc663_21jd_amic_init_verbs[] = { 18014static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
18003 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18015 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18004 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18016 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18005 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18017 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
@@ -18010,7 +18022,7 @@ static struct hda_verb alc663_21jd_amic_init_verbs[] = {
18010 {} 18022 {}
18011}; 18023};
18012 18024
18013static struct hda_verb alc662_1bjd_amic_init_verbs[] = { 18025static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
18014 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18026 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18015 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18027 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18016 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18028 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -18022,7 +18034,7 @@ static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
18022 {} 18034 {}
18023}; 18035};
18024 18036
18025static struct hda_verb alc663_15jd_amic_init_verbs[] = { 18037static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
18026 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18038 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18027 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18039 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18028 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18040 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
@@ -18033,7 +18045,7 @@ static struct hda_verb alc663_15jd_amic_init_verbs[] = {
18033 {} 18045 {}
18034}; 18046};
18035 18047
18036static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { 18048static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18037 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18049 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18038 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18050 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18039 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18051 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -18049,7 +18061,7 @@ static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18049 {} 18061 {}
18050}; 18062};
18051 18063
18052static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { 18064static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18053 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18065 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18054 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18066 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18055 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18067 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -18065,7 +18077,7 @@ static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18065 {} 18077 {}
18066}; 18078};
18067 18079
18068static struct hda_verb alc663_g71v_init_verbs[] = { 18080static const struct hda_verb alc663_g71v_init_verbs[] = {
18069 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18081 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18070 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 18082 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18071 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ 18083 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
@@ -18080,7 +18092,7 @@ static struct hda_verb alc663_g71v_init_verbs[] = {
18080 {} 18092 {}
18081}; 18093};
18082 18094
18083static struct hda_verb alc663_g50v_init_verbs[] = { 18095static const struct hda_verb alc663_g50v_init_verbs[] = {
18084 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18096 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18085 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18097 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18086 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 18098 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
@@ -18090,7 +18102,7 @@ static struct hda_verb alc663_g50v_init_verbs[] = {
18090 {} 18102 {}
18091}; 18103};
18092 18104
18093static struct hda_verb alc662_ecs_init_verbs[] = { 18105static const struct hda_verb alc662_ecs_init_verbs[] = {
18094 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, 18106 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18095 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18107 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18096 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18108 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
@@ -18098,7 +18110,7 @@ static struct hda_verb alc662_ecs_init_verbs[] = {
18098 {} 18110 {}
18099}; 18111};
18100 18112
18101static struct hda_verb alc272_dell_zm1_init_verbs[] = { 18113static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
18102 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18114 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18103 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18115 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18104 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18116 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -18113,7 +18125,7 @@ static struct hda_verb alc272_dell_zm1_init_verbs[] = {
18113 {} 18125 {}
18114}; 18126};
18115 18127
18116static struct hda_verb alc272_dell_init_verbs[] = { 18128static const struct hda_verb alc272_dell_init_verbs[] = {
18117 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18129 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18118 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18130 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18119 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18131 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -18128,7 +18140,7 @@ static struct hda_verb alc272_dell_init_verbs[] = {
18128 {} 18140 {}
18129}; 18141};
18130 18142
18131static struct hda_verb alc663_mode7_init_verbs[] = { 18143static const struct hda_verb alc663_mode7_init_verbs[] = {
18132 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18144 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18133 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18145 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18134 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 18146 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -18147,7 +18159,7 @@ static struct hda_verb alc663_mode7_init_verbs[] = {
18147 {} 18159 {}
18148}; 18160};
18149 18161
18150static struct hda_verb alc663_mode8_init_verbs[] = { 18162static const struct hda_verb alc663_mode8_init_verbs[] = {
18151 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18163 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18152 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18164 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18153 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18165 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -18167,61 +18179,29 @@ static struct hda_verb alc663_mode8_init_verbs[] = {
18167 {} 18179 {}
18168}; 18180};
18169 18181
18170static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { 18182static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18171 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 18183 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18172 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 18184 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18173 { } /* end */ 18185 { } /* end */
18174}; 18186};
18175 18187
18176static struct snd_kcontrol_new alc272_auto_capture_mixer[] = { 18188static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18177 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 18189 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18178 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 18190 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18179 { } /* end */ 18191 { } /* end */
18180}; 18192};
18181 18193
18182static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 18194static void alc662_lenovo_101e_setup(struct hda_codec *codec)
18183{
18184 unsigned int present;
18185 unsigned char bits;
18186
18187 present = snd_hda_jack_detect(codec, 0x14);
18188 bits = present ? HDA_AMP_MUTE : 0;
18189
18190 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18191 HDA_AMP_MUTE, bits);
18192}
18193
18194static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
18195{
18196 unsigned int present;
18197 unsigned char bits;
18198
18199 present = snd_hda_jack_detect(codec, 0x1b);
18200 bits = present ? HDA_AMP_MUTE : 0;
18201
18202 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18203 HDA_AMP_MUTE, bits);
18204 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18205 HDA_AMP_MUTE, bits);
18206}
18207
18208static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
18209 unsigned int res)
18210{ 18195{
18211 if ((res >> 26) == ALC880_HP_EVENT) 18196 struct alc_spec *spec = codec->spec;
18212 alc662_lenovo_101e_all_automute(codec);
18213 if ((res >> 26) == ALC880_FRONT_EVENT)
18214 alc662_lenovo_101e_ispeaker_automute(codec);
18215}
18216 18197
18217/* unsolicited event for HP jack sensing */ 18198 spec->autocfg.hp_pins[0] = 0x1b;
18218static void alc662_eeepc_unsol_event(struct hda_codec *codec, 18199 spec->autocfg.line_out_pins[0] = 0x14;
18219 unsigned int res) 18200 spec->autocfg.speaker_pins[0] = 0x15;
18220{ 18201 spec->automute = 1;
18221 if ((res >> 26) == ALC880_MIC_EVENT) 18202 spec->detect_line = 1;
18222 alc_mic_automute(codec); 18203 spec->automute_lines = 1;
18223 else 18204 spec->automute_mode = ALC_AUTOMUTE_AMP;
18224 alc262_hippo_unsol_event(codec, res);
18225} 18205}
18226 18206
18227static void alc662_eeepc_setup(struct hda_codec *codec) 18207static void alc662_eeepc_setup(struct hda_codec *codec)
@@ -18236,180 +18216,24 @@ static void alc662_eeepc_setup(struct hda_codec *codec)
18236 spec->auto_mic = 1; 18216 spec->auto_mic = 1;
18237} 18217}
18238 18218
18239static void alc662_eeepc_inithook(struct hda_codec *codec)
18240{
18241 alc262_hippo_automute(codec);
18242 alc_mic_automute(codec);
18243}
18244
18245static void alc662_eeepc_ep20_setup(struct hda_codec *codec) 18219static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
18246{ 18220{
18247 struct alc_spec *spec = codec->spec; 18221 struct alc_spec *spec = codec->spec;
18248 18222
18249 spec->autocfg.hp_pins[0] = 0x14; 18223 spec->autocfg.hp_pins[0] = 0x14;
18250 spec->autocfg.speaker_pins[0] = 0x1b; 18224 spec->autocfg.speaker_pins[0] = 0x1b;
18251} 18225 spec->automute = 1;
18252 18226 spec->automute_mode = ALC_AUTOMUTE_AMP;
18253#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18254
18255static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18256{
18257 unsigned int present;
18258 unsigned char bits;
18259
18260 present = snd_hda_jack_detect(codec, 0x21);
18261 bits = present ? HDA_AMP_MUTE : 0;
18262 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18263 HDA_AMP_MUTE, bits);
18264 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18265 HDA_AMP_MUTE, bits);
18266}
18267
18268static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18269{
18270 unsigned int present;
18271 unsigned char bits;
18272
18273 present = snd_hda_jack_detect(codec, 0x21);
18274 bits = present ? HDA_AMP_MUTE : 0;
18275 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18276 HDA_AMP_MUTE, bits);
18277 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18278 HDA_AMP_MUTE, bits);
18279 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
18280 HDA_AMP_MUTE, bits);
18281 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
18282 HDA_AMP_MUTE, bits);
18283}
18284
18285static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18286{
18287 unsigned int present;
18288 unsigned char bits;
18289
18290 present = snd_hda_jack_detect(codec, 0x15);
18291 bits = present ? HDA_AMP_MUTE : 0;
18292 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18293 HDA_AMP_MUTE, bits);
18294 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18295 HDA_AMP_MUTE, bits);
18296 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
18297 HDA_AMP_MUTE, bits);
18298 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
18299 HDA_AMP_MUTE, bits);
18300}
18301
18302static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18303{
18304 unsigned int present;
18305 unsigned char bits;
18306
18307 present = snd_hda_jack_detect(codec, 0x1b);
18308 bits = present ? 0 : PIN_OUT;
18309 snd_hda_codec_write(codec, 0x14, 0,
18310 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18311}
18312
18313static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18314{
18315 unsigned int present1, present2;
18316
18317 present1 = snd_hda_jack_detect(codec, 0x21);
18318 present2 = snd_hda_jack_detect(codec, 0x15);
18319
18320 if (present1 || present2) {
18321 snd_hda_codec_write_cache(codec, 0x14, 0,
18322 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18323 } else {
18324 snd_hda_codec_write_cache(codec, 0x14, 0,
18325 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18326 }
18327}
18328
18329static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18330{
18331 unsigned int present1, present2;
18332
18333 present1 = snd_hda_jack_detect(codec, 0x1b);
18334 present2 = snd_hda_jack_detect(codec, 0x15);
18335
18336 if (present1 || present2) {
18337 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18338 HDA_AMP_MUTE, HDA_AMP_MUTE);
18339 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18340 HDA_AMP_MUTE, HDA_AMP_MUTE);
18341 } else {
18342 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18343 HDA_AMP_MUTE, 0);
18344 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18345 HDA_AMP_MUTE, 0);
18346 }
18347}
18348
18349static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18350{
18351 unsigned int present1, present2;
18352
18353 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18354 AC_VERB_GET_PIN_SENSE, 0)
18355 & AC_PINSENSE_PRESENCE;
18356 present2 = snd_hda_codec_read(codec, 0x21, 0,
18357 AC_VERB_GET_PIN_SENSE, 0)
18358 & AC_PINSENSE_PRESENCE;
18359
18360 if (present1 || present2) {
18361 snd_hda_codec_write_cache(codec, 0x14, 0,
18362 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18363 snd_hda_codec_write_cache(codec, 0x17, 0,
18364 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18365 } else {
18366 snd_hda_codec_write_cache(codec, 0x14, 0,
18367 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18368 snd_hda_codec_write_cache(codec, 0x17, 0,
18369 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18370 }
18371}
18372
18373static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18374{
18375 unsigned int present1, present2;
18376
18377 present1 = snd_hda_codec_read(codec, 0x21, 0,
18378 AC_VERB_GET_PIN_SENSE, 0)
18379 & AC_PINSENSE_PRESENCE;
18380 present2 = snd_hda_codec_read(codec, 0x15, 0,
18381 AC_VERB_GET_PIN_SENSE, 0)
18382 & AC_PINSENSE_PRESENCE;
18383
18384 if (present1 || present2) {
18385 snd_hda_codec_write_cache(codec, 0x14, 0,
18386 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18387 snd_hda_codec_write_cache(codec, 0x17, 0,
18388 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18389 } else {
18390 snd_hda_codec_write_cache(codec, 0x14, 0,
18391 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18392 snd_hda_codec_write_cache(codec, 0x17, 0,
18393 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18394 }
18395}
18396
18397static void alc663_m51va_unsol_event(struct hda_codec *codec,
18398 unsigned int res)
18399{
18400 switch (res >> 26) {
18401 case ALC880_HP_EVENT:
18402 alc663_m51va_speaker_automute(codec);
18403 break;
18404 case ALC880_MIC_EVENT:
18405 alc_mic_automute(codec);
18406 break;
18407 }
18408} 18227}
18409 18228
18410static void alc663_m51va_setup(struct hda_codec *codec) 18229static void alc663_m51va_setup(struct hda_codec *codec)
18411{ 18230{
18412 struct alc_spec *spec = codec->spec; 18231 struct alc_spec *spec = codec->spec;
18232 spec->autocfg.hp_pins[0] = 0x21;
18233 spec->autocfg.speaker_pins[0] = 0x14;
18234 spec->automute_mixer_nid[0] = 0x0c;
18235 spec->automute = 1;
18236 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18413 spec->ext_mic.pin = 0x18; 18237 spec->ext_mic.pin = 0x18;
18414 spec->ext_mic.mux_idx = 0; 18238 spec->ext_mic.mux_idx = 0;
18415 spec->int_mic.pin = 0x12; 18239 spec->int_mic.pin = 0x12;
@@ -18417,18 +18241,15 @@ static void alc663_m51va_setup(struct hda_codec *codec)
18417 spec->auto_mic = 1; 18241 spec->auto_mic = 1;
18418} 18242}
18419 18243
18420static void alc663_m51va_inithook(struct hda_codec *codec)
18421{
18422 alc663_m51va_speaker_automute(codec);
18423 alc_mic_automute(codec);
18424}
18425
18426/* ***************** Mode1 ******************************/ 18244/* ***************** Mode1 ******************************/
18427#define alc663_mode1_unsol_event alc663_m51va_unsol_event
18428
18429static void alc663_mode1_setup(struct hda_codec *codec) 18245static void alc663_mode1_setup(struct hda_codec *codec)
18430{ 18246{
18431 struct alc_spec *spec = codec->spec; 18247 struct alc_spec *spec = codec->spec;
18248 spec->autocfg.hp_pins[0] = 0x21;
18249 spec->autocfg.speaker_pins[0] = 0x14;
18250 spec->automute_mixer_nid[0] = 0x0c;
18251 spec->automute = 1;
18252 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18432 spec->ext_mic.pin = 0x18; 18253 spec->ext_mic.pin = 0x18;
18433 spec->ext_mic.mux_idx = 0; 18254 spec->ext_mic.mux_idx = 0;
18434 spec->int_mic.pin = 0x19; 18255 spec->int_mic.pin = 0x19;
@@ -18436,229 +18257,144 @@ static void alc663_mode1_setup(struct hda_codec *codec)
18436 spec->auto_mic = 1; 18257 spec->auto_mic = 1;
18437} 18258}
18438 18259
18439#define alc663_mode1_inithook alc663_m51va_inithook
18440
18441/* ***************** Mode2 ******************************/ 18260/* ***************** Mode2 ******************************/
18442static void alc662_mode2_unsol_event(struct hda_codec *codec, 18261static void alc662_mode2_setup(struct hda_codec *codec)
18443 unsigned int res)
18444{ 18262{
18445 switch (res >> 26) { 18263 struct alc_spec *spec = codec->spec;
18446 case ALC880_HP_EVENT: 18264 spec->autocfg.hp_pins[0] = 0x1b;
18447 alc662_f5z_speaker_automute(codec); 18265 spec->autocfg.speaker_pins[0] = 0x14;
18448 break; 18266 spec->automute = 1;
18449 case ALC880_MIC_EVENT: 18267 spec->automute_mode = ALC_AUTOMUTE_PIN;
18450 alc_mic_automute(codec); 18268 spec->ext_mic.pin = 0x18;
18451 break; 18269 spec->ext_mic.mux_idx = 0;
18452 } 18270 spec->int_mic.pin = 0x19;
18271 spec->int_mic.mux_idx = 1;
18272 spec->auto_mic = 1;
18453} 18273}
18454 18274
18455#define alc662_mode2_setup alc663_mode1_setup
18456
18457static void alc662_mode2_inithook(struct hda_codec *codec)
18458{
18459 alc662_f5z_speaker_automute(codec);
18460 alc_mic_automute(codec);
18461}
18462/* ***************** Mode3 ******************************/ 18275/* ***************** Mode3 ******************************/
18463static void alc663_mode3_unsol_event(struct hda_codec *codec, 18276static void alc663_mode3_setup(struct hda_codec *codec)
18464 unsigned int res)
18465{ 18277{
18466 switch (res >> 26) { 18278 struct alc_spec *spec = codec->spec;
18467 case ALC880_HP_EVENT: 18279 spec->autocfg.hp_pins[0] = 0x21;
18468 alc663_two_hp_m1_speaker_automute(codec); 18280 spec->autocfg.hp_pins[0] = 0x15;
18469 break; 18281 spec->autocfg.speaker_pins[0] = 0x14;
18470 case ALC880_MIC_EVENT: 18282 spec->automute = 1;
18471 alc_mic_automute(codec); 18283 spec->automute_mode = ALC_AUTOMUTE_PIN;
18472 break; 18284 spec->ext_mic.pin = 0x18;
18473 } 18285 spec->ext_mic.mux_idx = 0;
18286 spec->int_mic.pin = 0x19;
18287 spec->int_mic.mux_idx = 1;
18288 spec->auto_mic = 1;
18474} 18289}
18475 18290
18476#define alc663_mode3_setup alc663_mode1_setup
18477
18478static void alc663_mode3_inithook(struct hda_codec *codec)
18479{
18480 alc663_two_hp_m1_speaker_automute(codec);
18481 alc_mic_automute(codec);
18482}
18483/* ***************** Mode4 ******************************/ 18291/* ***************** Mode4 ******************************/
18484static void alc663_mode4_unsol_event(struct hda_codec *codec, 18292static void alc663_mode4_setup(struct hda_codec *codec)
18485 unsigned int res)
18486{ 18293{
18487 switch (res >> 26) { 18294 struct alc_spec *spec = codec->spec;
18488 case ALC880_HP_EVENT: 18295 spec->autocfg.hp_pins[0] = 0x21;
18489 alc663_21jd_two_speaker_automute(codec); 18296 spec->autocfg.speaker_pins[0] = 0x14;
18490 break; 18297 spec->autocfg.speaker_pins[1] = 0x16;
18491 case ALC880_MIC_EVENT: 18298 spec->automute_mixer_nid[0] = 0x0c;
18492 alc_mic_automute(codec); 18299 spec->automute_mixer_nid[1] = 0x0e;
18493 break; 18300 spec->automute = 1;
18494 } 18301 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18302 spec->ext_mic.pin = 0x18;
18303 spec->ext_mic.mux_idx = 0;
18304 spec->int_mic.pin = 0x19;
18305 spec->int_mic.mux_idx = 1;
18306 spec->auto_mic = 1;
18495} 18307}
18496 18308
18497#define alc663_mode4_setup alc663_mode1_setup
18498
18499static void alc663_mode4_inithook(struct hda_codec *codec)
18500{
18501 alc663_21jd_two_speaker_automute(codec);
18502 alc_mic_automute(codec);
18503}
18504/* ***************** Mode5 ******************************/ 18309/* ***************** Mode5 ******************************/
18505static void alc663_mode5_unsol_event(struct hda_codec *codec, 18310static void alc663_mode5_setup(struct hda_codec *codec)
18506 unsigned int res)
18507{ 18311{
18508 switch (res >> 26) { 18312 struct alc_spec *spec = codec->spec;
18509 case ALC880_HP_EVENT: 18313 spec->autocfg.hp_pins[0] = 0x15;
18510 alc663_15jd_two_speaker_automute(codec); 18314 spec->autocfg.speaker_pins[0] = 0x14;
18511 break; 18315 spec->autocfg.speaker_pins[1] = 0x16;
18512 case ALC880_MIC_EVENT: 18316 spec->automute_mixer_nid[0] = 0x0c;
18513 alc_mic_automute(codec); 18317 spec->automute_mixer_nid[1] = 0x0e;
18514 break; 18318 spec->automute = 1;
18515 } 18319 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18320 spec->ext_mic.pin = 0x18;
18321 spec->ext_mic.mux_idx = 0;
18322 spec->int_mic.pin = 0x19;
18323 spec->int_mic.mux_idx = 1;
18324 spec->auto_mic = 1;
18516} 18325}
18517 18326
18518#define alc663_mode5_setup alc663_mode1_setup
18519
18520static void alc663_mode5_inithook(struct hda_codec *codec)
18521{
18522 alc663_15jd_two_speaker_automute(codec);
18523 alc_mic_automute(codec);
18524}
18525/* ***************** Mode6 ******************************/ 18327/* ***************** Mode6 ******************************/
18526static void alc663_mode6_unsol_event(struct hda_codec *codec, 18328static void alc663_mode6_setup(struct hda_codec *codec)
18527 unsigned int res)
18528{ 18329{
18529 switch (res >> 26) { 18330 struct alc_spec *spec = codec->spec;
18530 case ALC880_HP_EVENT: 18331 spec->autocfg.hp_pins[0] = 0x1b;
18531 alc663_two_hp_m2_speaker_automute(codec); 18332 spec->autocfg.hp_pins[0] = 0x15;
18532 break; 18333 spec->autocfg.speaker_pins[0] = 0x14;
18533 case ALC880_MIC_EVENT: 18334 spec->automute_mixer_nid[0] = 0x0c;
18534 alc_mic_automute(codec); 18335 spec->automute = 1;
18535 break; 18336 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18536 } 18337 spec->ext_mic.pin = 0x18;
18537} 18338 spec->ext_mic.mux_idx = 0;
18538 18339 spec->int_mic.pin = 0x19;
18539#define alc663_mode6_setup alc663_mode1_setup 18340 spec->int_mic.mux_idx = 1;
18540 18341 spec->auto_mic = 1;
18541static void alc663_mode6_inithook(struct hda_codec *codec)
18542{
18543 alc663_two_hp_m2_speaker_automute(codec);
18544 alc_mic_automute(codec);
18545} 18342}
18546 18343
18547/* ***************** Mode7 ******************************/ 18344/* ***************** Mode7 ******************************/
18548static void alc663_mode7_unsol_event(struct hda_codec *codec, 18345static void alc663_mode7_setup(struct hda_codec *codec)
18549 unsigned int res)
18550{
18551 switch (res >> 26) {
18552 case ALC880_HP_EVENT:
18553 alc663_two_hp_m7_speaker_automute(codec);
18554 break;
18555 case ALC880_MIC_EVENT:
18556 alc_mic_automute(codec);
18557 break;
18558 }
18559}
18560
18561#define alc663_mode7_setup alc663_mode1_setup
18562
18563static void alc663_mode7_inithook(struct hda_codec *codec)
18564{ 18346{
18565 alc663_two_hp_m7_speaker_automute(codec); 18347 struct alc_spec *spec = codec->spec;
18566 alc_mic_automute(codec); 18348 spec->autocfg.hp_pins[0] = 0x1b;
18349 spec->autocfg.hp_pins[0] = 0x21;
18350 spec->autocfg.speaker_pins[0] = 0x14;
18351 spec->autocfg.speaker_pins[0] = 0x17;
18352 spec->automute = 1;
18353 spec->automute_mode = ALC_AUTOMUTE_PIN;
18354 spec->ext_mic.pin = 0x18;
18355 spec->ext_mic.mux_idx = 0;
18356 spec->int_mic.pin = 0x19;
18357 spec->int_mic.mux_idx = 1;
18358 spec->auto_mic = 1;
18567} 18359}
18568 18360
18569/* ***************** Mode8 ******************************/ 18361/* ***************** Mode8 ******************************/
18570static void alc663_mode8_unsol_event(struct hda_codec *codec, 18362static void alc663_mode8_setup(struct hda_codec *codec)
18571 unsigned int res)
18572{
18573 switch (res >> 26) {
18574 case ALC880_HP_EVENT:
18575 alc663_two_hp_m8_speaker_automute(codec);
18576 break;
18577 case ALC880_MIC_EVENT:
18578 alc_mic_automute(codec);
18579 break;
18580 }
18581}
18582
18583#define alc663_mode8_setup alc663_m51va_setup
18584
18585static void alc663_mode8_inithook(struct hda_codec *codec)
18586{
18587 alc663_two_hp_m8_speaker_automute(codec);
18588 alc_mic_automute(codec);
18589}
18590
18591static void alc663_g71v_hp_automute(struct hda_codec *codec)
18592{
18593 unsigned int present;
18594 unsigned char bits;
18595
18596 present = snd_hda_jack_detect(codec, 0x21);
18597 bits = present ? HDA_AMP_MUTE : 0;
18598 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18599 HDA_AMP_MUTE, bits);
18600 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18601 HDA_AMP_MUTE, bits);
18602}
18603
18604static void alc663_g71v_front_automute(struct hda_codec *codec)
18605{
18606 unsigned int present;
18607 unsigned char bits;
18608
18609 present = snd_hda_jack_detect(codec, 0x15);
18610 bits = present ? HDA_AMP_MUTE : 0;
18611 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18612 HDA_AMP_MUTE, bits);
18613}
18614
18615static void alc663_g71v_unsol_event(struct hda_codec *codec,
18616 unsigned int res)
18617{ 18363{
18618 switch (res >> 26) { 18364 struct alc_spec *spec = codec->spec;
18619 case ALC880_HP_EVENT: 18365 spec->autocfg.hp_pins[0] = 0x21;
18620 alc663_g71v_hp_automute(codec); 18366 spec->autocfg.hp_pins[1] = 0x15;
18621 break; 18367 spec->autocfg.speaker_pins[0] = 0x14;
18622 case ALC880_FRONT_EVENT: 18368 spec->autocfg.speaker_pins[0] = 0x17;
18623 alc663_g71v_front_automute(codec); 18369 spec->automute = 1;
18624 break; 18370 spec->automute_mode = ALC_AUTOMUTE_PIN;
18625 case ALC880_MIC_EVENT: 18371 spec->ext_mic.pin = 0x18;
18626 alc_mic_automute(codec); 18372 spec->ext_mic.mux_idx = 0;
18627 break; 18373 spec->int_mic.pin = 0x12;
18628 } 18374 spec->int_mic.mux_idx = 9;
18629} 18375 spec->auto_mic = 1;
18630
18631#define alc663_g71v_setup alc663_m51va_setup
18632
18633static void alc663_g71v_inithook(struct hda_codec *codec)
18634{
18635 alc663_g71v_front_automute(codec);
18636 alc663_g71v_hp_automute(codec);
18637 alc_mic_automute(codec);
18638} 18376}
18639 18377
18640static void alc663_g50v_unsol_event(struct hda_codec *codec, 18378static void alc663_g71v_setup(struct hda_codec *codec)
18641 unsigned int res)
18642{ 18379{
18643 switch (res >> 26) { 18380 struct alc_spec *spec = codec->spec;
18644 case ALC880_HP_EVENT: 18381 spec->autocfg.hp_pins[0] = 0x21;
18645 alc663_m51va_speaker_automute(codec); 18382 spec->autocfg.line_out_pins[0] = 0x15;
18646 break; 18383 spec->autocfg.speaker_pins[0] = 0x14;
18647 case ALC880_MIC_EVENT: 18384 spec->automute = 1;
18648 alc_mic_automute(codec); 18385 spec->automute_mode = ALC_AUTOMUTE_AMP;
18649 break; 18386 spec->detect_line = 1;
18650 } 18387 spec->automute_lines = 1;
18388 spec->ext_mic.pin = 0x18;
18389 spec->ext_mic.mux_idx = 0;
18390 spec->int_mic.pin = 0x12;
18391 spec->int_mic.mux_idx = 9;
18392 spec->auto_mic = 1;
18651} 18393}
18652 18394
18653#define alc663_g50v_setup alc663_m51va_setup 18395#define alc663_g50v_setup alc663_m51va_setup
18654 18396
18655static void alc663_g50v_inithook(struct hda_codec *codec) 18397static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
18656{
18657 alc663_m51va_speaker_automute(codec);
18658 alc_mic_automute(codec);
18659}
18660
18661static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18662 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18398 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18663 ALC262_HIPPO_MASTER_SWITCH, 18399 ALC262_HIPPO_MASTER_SWITCH,
18664 18400
@@ -18672,7 +18408,7 @@ static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18672 { } /* end */ 18408 { } /* end */
18673}; 18409};
18674 18410
18675static struct snd_kcontrol_new alc272_nc10_mixer[] = { 18411static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
18676 /* Master Playback automatically created from Speaker and Headphone */ 18412 /* Master Playback automatically created from Speaker and Headphone */
18677 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18413 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18678 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 18414 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -18707,7 +18443,7 @@ static const char * const alc662_models[ALC662_MODEL_LAST] = {
18707 [ALC662_3ST_2ch_DIG] = "3stack-dig", 18443 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18708 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 18444 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18709 [ALC662_3ST_6ch] = "3stack-6ch", 18445 [ALC662_3ST_6ch] = "3stack-6ch",
18710 [ALC662_5ST_DIG] = "6stack-dig", 18446 [ALC662_5ST_DIG] = "5stack-dig",
18711 [ALC662_LENOVO_101E] = "lenovo-101e", 18447 [ALC662_LENOVO_101E] = "lenovo-101e",
18712 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", 18448 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18713 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", 18449 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
@@ -18730,7 +18466,7 @@ static const char * const alc662_models[ALC662_MODEL_LAST] = {
18730 [ALC662_AUTO] = "auto", 18466 [ALC662_AUTO] = "auto",
18731}; 18467};
18732 18468
18733static struct snd_pci_quirk alc662_cfg_tbl[] = { 18469static const struct snd_pci_quirk alc662_cfg_tbl[] = {
18734 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), 18470 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18735 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), 18471 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18736 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), 18472 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
@@ -18812,10 +18548,10 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
18812 {} 18548 {}
18813}; 18549};
18814 18550
18815static struct alc_config_preset alc662_presets[] = { 18551static const struct alc_config_preset alc662_presets[] = {
18816 [ALC662_3ST_2ch_DIG] = { 18552 [ALC662_3ST_2ch_DIG] = {
18817 .mixers = { alc662_3ST_2ch_mixer }, 18553 .mixers = { alc662_3ST_2ch_mixer },
18818 .init_verbs = { alc662_init_verbs }, 18554 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18819 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18555 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18820 .dac_nids = alc662_dac_nids, 18556 .dac_nids = alc662_dac_nids,
18821 .dig_out_nid = ALC662_DIGOUT_NID, 18557 .dig_out_nid = ALC662_DIGOUT_NID,
@@ -18826,7 +18562,7 @@ static struct alc_config_preset alc662_presets[] = {
18826 }, 18562 },
18827 [ALC662_3ST_6ch_DIG] = { 18563 [ALC662_3ST_6ch_DIG] = {
18828 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18564 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18829 .init_verbs = { alc662_init_verbs }, 18565 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18830 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18566 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18831 .dac_nids = alc662_dac_nids, 18567 .dac_nids = alc662_dac_nids,
18832 .dig_out_nid = ALC662_DIGOUT_NID, 18568 .dig_out_nid = ALC662_DIGOUT_NID,
@@ -18838,7 +18574,7 @@ static struct alc_config_preset alc662_presets[] = {
18838 }, 18574 },
18839 [ALC662_3ST_6ch] = { 18575 [ALC662_3ST_6ch] = {
18840 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18576 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18841 .init_verbs = { alc662_init_verbs }, 18577 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18842 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18578 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18843 .dac_nids = alc662_dac_nids, 18579 .dac_nids = alc662_dac_nids,
18844 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18580 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
@@ -18848,7 +18584,7 @@ static struct alc_config_preset alc662_presets[] = {
18848 }, 18584 },
18849 [ALC662_5ST_DIG] = { 18585 [ALC662_5ST_DIG] = {
18850 .mixers = { alc662_base_mixer, alc662_chmode_mixer }, 18586 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
18851 .init_verbs = { alc662_init_verbs }, 18587 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18852 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18588 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18853 .dac_nids = alc662_dac_nids, 18589 .dac_nids = alc662_dac_nids,
18854 .dig_out_nid = ALC662_DIGOUT_NID, 18590 .dig_out_nid = ALC662_DIGOUT_NID,
@@ -18859,104 +18595,120 @@ static struct alc_config_preset alc662_presets[] = {
18859 }, 18595 },
18860 [ALC662_LENOVO_101E] = { 18596 [ALC662_LENOVO_101E] = {
18861 .mixers = { alc662_lenovo_101e_mixer }, 18597 .mixers = { alc662_lenovo_101e_mixer },
18862 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, 18598 .init_verbs = { alc662_init_verbs,
18599 alc662_eapd_init_verbs,
18600 alc662_sue_init_verbs },
18863 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18601 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18864 .dac_nids = alc662_dac_nids, 18602 .dac_nids = alc662_dac_nids,
18865 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18603 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18866 .channel_mode = alc662_3ST_2ch_modes, 18604 .channel_mode = alc662_3ST_2ch_modes,
18867 .input_mux = &alc662_lenovo_101e_capture_source, 18605 .input_mux = &alc662_lenovo_101e_capture_source,
18868 .unsol_event = alc662_lenovo_101e_unsol_event, 18606 .unsol_event = alc_sku_unsol_event,
18869 .init_hook = alc662_lenovo_101e_all_automute, 18607 .setup = alc662_lenovo_101e_setup,
18608 .init_hook = alc_inithook,
18870 }, 18609 },
18871 [ALC662_ASUS_EEEPC_P701] = { 18610 [ALC662_ASUS_EEEPC_P701] = {
18872 .mixers = { alc662_eeepc_p701_mixer }, 18611 .mixers = { alc662_eeepc_p701_mixer },
18873 .init_verbs = { alc662_init_verbs, 18612 .init_verbs = { alc662_init_verbs,
18613 alc662_eapd_init_verbs,
18874 alc662_eeepc_sue_init_verbs }, 18614 alc662_eeepc_sue_init_verbs },
18875 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18615 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18876 .dac_nids = alc662_dac_nids, 18616 .dac_nids = alc662_dac_nids,
18877 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18617 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18878 .channel_mode = alc662_3ST_2ch_modes, 18618 .channel_mode = alc662_3ST_2ch_modes,
18879 .unsol_event = alc662_eeepc_unsol_event, 18619 .unsol_event = alc_sku_unsol_event,
18880 .setup = alc662_eeepc_setup, 18620 .setup = alc662_eeepc_setup,
18881 .init_hook = alc662_eeepc_inithook, 18621 .init_hook = alc_inithook,
18882 }, 18622 },
18883 [ALC662_ASUS_EEEPC_EP20] = { 18623 [ALC662_ASUS_EEEPC_EP20] = {
18884 .mixers = { alc662_eeepc_ep20_mixer, 18624 .mixers = { alc662_eeepc_ep20_mixer,
18885 alc662_chmode_mixer }, 18625 alc662_chmode_mixer },
18886 .init_verbs = { alc662_init_verbs, 18626 .init_verbs = { alc662_init_verbs,
18627 alc662_eapd_init_verbs,
18887 alc662_eeepc_ep20_sue_init_verbs }, 18628 alc662_eeepc_ep20_sue_init_verbs },
18888 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18629 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18889 .dac_nids = alc662_dac_nids, 18630 .dac_nids = alc662_dac_nids,
18890 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18631 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18891 .channel_mode = alc662_3ST_6ch_modes, 18632 .channel_mode = alc662_3ST_6ch_modes,
18892 .input_mux = &alc662_lenovo_101e_capture_source, 18633 .input_mux = &alc662_lenovo_101e_capture_source,
18893 .unsol_event = alc662_eeepc_unsol_event, 18634 .unsol_event = alc_sku_unsol_event,
18894 .setup = alc662_eeepc_ep20_setup, 18635 .setup = alc662_eeepc_ep20_setup,
18895 .init_hook = alc662_eeepc_ep20_inithook, 18636 .init_hook = alc_inithook,
18896 }, 18637 },
18897 [ALC662_ECS] = { 18638 [ALC662_ECS] = {
18898 .mixers = { alc662_ecs_mixer }, 18639 .mixers = { alc662_ecs_mixer },
18899 .init_verbs = { alc662_init_verbs, 18640 .init_verbs = { alc662_init_verbs,
18641 alc662_eapd_init_verbs,
18900 alc662_ecs_init_verbs }, 18642 alc662_ecs_init_verbs },
18901 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18643 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18902 .dac_nids = alc662_dac_nids, 18644 .dac_nids = alc662_dac_nids,
18903 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18645 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18904 .channel_mode = alc662_3ST_2ch_modes, 18646 .channel_mode = alc662_3ST_2ch_modes,
18905 .unsol_event = alc662_eeepc_unsol_event, 18647 .unsol_event = alc_sku_unsol_event,
18906 .setup = alc662_eeepc_setup, 18648 .setup = alc662_eeepc_setup,
18907 .init_hook = alc662_eeepc_inithook, 18649 .init_hook = alc_inithook,
18908 }, 18650 },
18909 [ALC663_ASUS_M51VA] = { 18651 [ALC663_ASUS_M51VA] = {
18910 .mixers = { alc663_m51va_mixer }, 18652 .mixers = { alc663_m51va_mixer },
18911 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 18653 .init_verbs = { alc662_init_verbs,
18654 alc662_eapd_init_verbs,
18655 alc663_m51va_init_verbs },
18912 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18656 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18913 .dac_nids = alc662_dac_nids, 18657 .dac_nids = alc662_dac_nids,
18914 .dig_out_nid = ALC662_DIGOUT_NID, 18658 .dig_out_nid = ALC662_DIGOUT_NID,
18915 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18659 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18916 .channel_mode = alc662_3ST_2ch_modes, 18660 .channel_mode = alc662_3ST_2ch_modes,
18917 .unsol_event = alc663_m51va_unsol_event, 18661 .unsol_event = alc_sku_unsol_event,
18918 .setup = alc663_m51va_setup, 18662 .setup = alc663_m51va_setup,
18919 .init_hook = alc663_m51va_inithook, 18663 .init_hook = alc_inithook,
18920 }, 18664 },
18921 [ALC663_ASUS_G71V] = { 18665 [ALC663_ASUS_G71V] = {
18922 .mixers = { alc663_g71v_mixer }, 18666 .mixers = { alc663_g71v_mixer },
18923 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, 18667 .init_verbs = { alc662_init_verbs,
18668 alc662_eapd_init_verbs,
18669 alc663_g71v_init_verbs },
18924 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18670 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18925 .dac_nids = alc662_dac_nids, 18671 .dac_nids = alc662_dac_nids,
18926 .dig_out_nid = ALC662_DIGOUT_NID, 18672 .dig_out_nid = ALC662_DIGOUT_NID,
18927 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18673 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18928 .channel_mode = alc662_3ST_2ch_modes, 18674 .channel_mode = alc662_3ST_2ch_modes,
18929 .unsol_event = alc663_g71v_unsol_event, 18675 .unsol_event = alc_sku_unsol_event,
18930 .setup = alc663_g71v_setup, 18676 .setup = alc663_g71v_setup,
18931 .init_hook = alc663_g71v_inithook, 18677 .init_hook = alc_inithook,
18932 }, 18678 },
18933 [ALC663_ASUS_H13] = { 18679 [ALC663_ASUS_H13] = {
18934 .mixers = { alc663_m51va_mixer }, 18680 .mixers = { alc663_m51va_mixer },
18935 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 18681 .init_verbs = { alc662_init_verbs,
18682 alc662_eapd_init_verbs,
18683 alc663_m51va_init_verbs },
18936 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18684 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18937 .dac_nids = alc662_dac_nids, 18685 .dac_nids = alc662_dac_nids,
18938 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18686 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18939 .channel_mode = alc662_3ST_2ch_modes, 18687 .channel_mode = alc662_3ST_2ch_modes,
18940 .unsol_event = alc663_m51va_unsol_event, 18688 .setup = alc663_m51va_setup,
18941 .init_hook = alc663_m51va_inithook, 18689 .unsol_event = alc_sku_unsol_event,
18690 .init_hook = alc_inithook,
18942 }, 18691 },
18943 [ALC663_ASUS_G50V] = { 18692 [ALC663_ASUS_G50V] = {
18944 .mixers = { alc663_g50v_mixer }, 18693 .mixers = { alc663_g50v_mixer },
18945 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, 18694 .init_verbs = { alc662_init_verbs,
18695 alc662_eapd_init_verbs,
18696 alc663_g50v_init_verbs },
18946 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18697 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18947 .dac_nids = alc662_dac_nids, 18698 .dac_nids = alc662_dac_nids,
18948 .dig_out_nid = ALC662_DIGOUT_NID, 18699 .dig_out_nid = ALC662_DIGOUT_NID,
18949 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18700 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18950 .channel_mode = alc662_3ST_6ch_modes, 18701 .channel_mode = alc662_3ST_6ch_modes,
18951 .input_mux = &alc663_capture_source, 18702 .input_mux = &alc663_capture_source,
18952 .unsol_event = alc663_g50v_unsol_event, 18703 .unsol_event = alc_sku_unsol_event,
18953 .setup = alc663_g50v_setup, 18704 .setup = alc663_g50v_setup,
18954 .init_hook = alc663_g50v_inithook, 18705 .init_hook = alc_inithook,
18955 }, 18706 },
18956 [ALC663_ASUS_MODE1] = { 18707 [ALC663_ASUS_MODE1] = {
18957 .mixers = { alc663_m51va_mixer }, 18708 .mixers = { alc663_m51va_mixer },
18958 .cap_mixer = alc662_auto_capture_mixer, 18709 .cap_mixer = alc662_auto_capture_mixer,
18959 .init_verbs = { alc662_init_verbs, 18710 .init_verbs = { alc662_init_verbs,
18711 alc662_eapd_init_verbs,
18960 alc663_21jd_amic_init_verbs }, 18712 alc663_21jd_amic_init_verbs },
18961 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18713 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18962 .hp_nid = 0x03, 18714 .hp_nid = 0x03,
@@ -18964,28 +18716,30 @@ static struct alc_config_preset alc662_presets[] = {
18964 .dig_out_nid = ALC662_DIGOUT_NID, 18716 .dig_out_nid = ALC662_DIGOUT_NID,
18965 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18717 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18966 .channel_mode = alc662_3ST_2ch_modes, 18718 .channel_mode = alc662_3ST_2ch_modes,
18967 .unsol_event = alc663_mode1_unsol_event, 18719 .unsol_event = alc_sku_unsol_event,
18968 .setup = alc663_mode1_setup, 18720 .setup = alc663_mode1_setup,
18969 .init_hook = alc663_mode1_inithook, 18721 .init_hook = alc_inithook,
18970 }, 18722 },
18971 [ALC662_ASUS_MODE2] = { 18723 [ALC662_ASUS_MODE2] = {
18972 .mixers = { alc662_1bjd_mixer }, 18724 .mixers = { alc662_1bjd_mixer },
18973 .cap_mixer = alc662_auto_capture_mixer, 18725 .cap_mixer = alc662_auto_capture_mixer,
18974 .init_verbs = { alc662_init_verbs, 18726 .init_verbs = { alc662_init_verbs,
18727 alc662_eapd_init_verbs,
18975 alc662_1bjd_amic_init_verbs }, 18728 alc662_1bjd_amic_init_verbs },
18976 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18729 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18977 .dac_nids = alc662_dac_nids, 18730 .dac_nids = alc662_dac_nids,
18978 .dig_out_nid = ALC662_DIGOUT_NID, 18731 .dig_out_nid = ALC662_DIGOUT_NID,
18979 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18732 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18980 .channel_mode = alc662_3ST_2ch_modes, 18733 .channel_mode = alc662_3ST_2ch_modes,
18981 .unsol_event = alc662_mode2_unsol_event, 18734 .unsol_event = alc_sku_unsol_event,
18982 .setup = alc662_mode2_setup, 18735 .setup = alc662_mode2_setup,
18983 .init_hook = alc662_mode2_inithook, 18736 .init_hook = alc_inithook,
18984 }, 18737 },
18985 [ALC663_ASUS_MODE3] = { 18738 [ALC663_ASUS_MODE3] = {
18986 .mixers = { alc663_two_hp_m1_mixer }, 18739 .mixers = { alc663_two_hp_m1_mixer },
18987 .cap_mixer = alc662_auto_capture_mixer, 18740 .cap_mixer = alc662_auto_capture_mixer,
18988 .init_verbs = { alc662_init_verbs, 18741 .init_verbs = { alc662_init_verbs,
18742 alc662_eapd_init_verbs,
18989 alc663_two_hp_amic_m1_init_verbs }, 18743 alc663_two_hp_amic_m1_init_verbs },
18990 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18744 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18991 .hp_nid = 0x03, 18745 .hp_nid = 0x03,
@@ -18993,14 +18747,15 @@ static struct alc_config_preset alc662_presets[] = {
18993 .dig_out_nid = ALC662_DIGOUT_NID, 18747 .dig_out_nid = ALC662_DIGOUT_NID,
18994 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18748 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18995 .channel_mode = alc662_3ST_2ch_modes, 18749 .channel_mode = alc662_3ST_2ch_modes,
18996 .unsol_event = alc663_mode3_unsol_event, 18750 .unsol_event = alc_sku_unsol_event,
18997 .setup = alc663_mode3_setup, 18751 .setup = alc663_mode3_setup,
18998 .init_hook = alc663_mode3_inithook, 18752 .init_hook = alc_inithook,
18999 }, 18753 },
19000 [ALC663_ASUS_MODE4] = { 18754 [ALC663_ASUS_MODE4] = {
19001 .mixers = { alc663_asus_21jd_clfe_mixer }, 18755 .mixers = { alc663_asus_21jd_clfe_mixer },
19002 .cap_mixer = alc662_auto_capture_mixer, 18756 .cap_mixer = alc662_auto_capture_mixer,
19003 .init_verbs = { alc662_init_verbs, 18757 .init_verbs = { alc662_init_verbs,
18758 alc662_eapd_init_verbs,
19004 alc663_21jd_amic_init_verbs}, 18759 alc663_21jd_amic_init_verbs},
19005 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18760 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19006 .hp_nid = 0x03, 18761 .hp_nid = 0x03,
@@ -19008,14 +18763,15 @@ static struct alc_config_preset alc662_presets[] = {
19008 .dig_out_nid = ALC662_DIGOUT_NID, 18763 .dig_out_nid = ALC662_DIGOUT_NID,
19009 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18764 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19010 .channel_mode = alc662_3ST_2ch_modes, 18765 .channel_mode = alc662_3ST_2ch_modes,
19011 .unsol_event = alc663_mode4_unsol_event, 18766 .unsol_event = alc_sku_unsol_event,
19012 .setup = alc663_mode4_setup, 18767 .setup = alc663_mode4_setup,
19013 .init_hook = alc663_mode4_inithook, 18768 .init_hook = alc_inithook,
19014 }, 18769 },
19015 [ALC663_ASUS_MODE5] = { 18770 [ALC663_ASUS_MODE5] = {
19016 .mixers = { alc663_asus_15jd_clfe_mixer }, 18771 .mixers = { alc663_asus_15jd_clfe_mixer },
19017 .cap_mixer = alc662_auto_capture_mixer, 18772 .cap_mixer = alc662_auto_capture_mixer,
19018 .init_verbs = { alc662_init_verbs, 18773 .init_verbs = { alc662_init_verbs,
18774 alc662_eapd_init_verbs,
19019 alc663_15jd_amic_init_verbs }, 18775 alc663_15jd_amic_init_verbs },
19020 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18776 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19021 .hp_nid = 0x03, 18777 .hp_nid = 0x03,
@@ -19023,14 +18779,15 @@ static struct alc_config_preset alc662_presets[] = {
19023 .dig_out_nid = ALC662_DIGOUT_NID, 18779 .dig_out_nid = ALC662_DIGOUT_NID,
19024 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18780 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19025 .channel_mode = alc662_3ST_2ch_modes, 18781 .channel_mode = alc662_3ST_2ch_modes,
19026 .unsol_event = alc663_mode5_unsol_event, 18782 .unsol_event = alc_sku_unsol_event,
19027 .setup = alc663_mode5_setup, 18783 .setup = alc663_mode5_setup,
19028 .init_hook = alc663_mode5_inithook, 18784 .init_hook = alc_inithook,
19029 }, 18785 },
19030 [ALC663_ASUS_MODE6] = { 18786 [ALC663_ASUS_MODE6] = {
19031 .mixers = { alc663_two_hp_m2_mixer }, 18787 .mixers = { alc663_two_hp_m2_mixer },
19032 .cap_mixer = alc662_auto_capture_mixer, 18788 .cap_mixer = alc662_auto_capture_mixer,
19033 .init_verbs = { alc662_init_verbs, 18789 .init_verbs = { alc662_init_verbs,
18790 alc662_eapd_init_verbs,
19034 alc663_two_hp_amic_m2_init_verbs }, 18791 alc663_two_hp_amic_m2_init_verbs },
19035 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18792 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19036 .hp_nid = 0x03, 18793 .hp_nid = 0x03,
@@ -19038,14 +18795,15 @@ static struct alc_config_preset alc662_presets[] = {
19038 .dig_out_nid = ALC662_DIGOUT_NID, 18795 .dig_out_nid = ALC662_DIGOUT_NID,
19039 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18796 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19040 .channel_mode = alc662_3ST_2ch_modes, 18797 .channel_mode = alc662_3ST_2ch_modes,
19041 .unsol_event = alc663_mode6_unsol_event, 18798 .unsol_event = alc_sku_unsol_event,
19042 .setup = alc663_mode6_setup, 18799 .setup = alc663_mode6_setup,
19043 .init_hook = alc663_mode6_inithook, 18800 .init_hook = alc_inithook,
19044 }, 18801 },
19045 [ALC663_ASUS_MODE7] = { 18802 [ALC663_ASUS_MODE7] = {
19046 .mixers = { alc663_mode7_mixer }, 18803 .mixers = { alc663_mode7_mixer },
19047 .cap_mixer = alc662_auto_capture_mixer, 18804 .cap_mixer = alc662_auto_capture_mixer,
19048 .init_verbs = { alc662_init_verbs, 18805 .init_verbs = { alc662_init_verbs,
18806 alc662_eapd_init_verbs,
19049 alc663_mode7_init_verbs }, 18807 alc663_mode7_init_verbs },
19050 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18808 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19051 .hp_nid = 0x03, 18809 .hp_nid = 0x03,
@@ -19053,14 +18811,15 @@ static struct alc_config_preset alc662_presets[] = {
19053 .dig_out_nid = ALC662_DIGOUT_NID, 18811 .dig_out_nid = ALC662_DIGOUT_NID,
19054 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18812 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19055 .channel_mode = alc662_3ST_2ch_modes, 18813 .channel_mode = alc662_3ST_2ch_modes,
19056 .unsol_event = alc663_mode7_unsol_event, 18814 .unsol_event = alc_sku_unsol_event,
19057 .setup = alc663_mode7_setup, 18815 .setup = alc663_mode7_setup,
19058 .init_hook = alc663_mode7_inithook, 18816 .init_hook = alc_inithook,
19059 }, 18817 },
19060 [ALC663_ASUS_MODE8] = { 18818 [ALC663_ASUS_MODE8] = {
19061 .mixers = { alc663_mode8_mixer }, 18819 .mixers = { alc663_mode8_mixer },
19062 .cap_mixer = alc662_auto_capture_mixer, 18820 .cap_mixer = alc662_auto_capture_mixer,
19063 .init_verbs = { alc662_init_verbs, 18821 .init_verbs = { alc662_init_verbs,
18822 alc662_eapd_init_verbs,
19064 alc663_mode8_init_verbs }, 18823 alc663_mode8_init_verbs },
19065 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18824 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19066 .hp_nid = 0x03, 18825 .hp_nid = 0x03,
@@ -19068,52 +18827,57 @@ static struct alc_config_preset alc662_presets[] = {
19068 .dig_out_nid = ALC662_DIGOUT_NID, 18827 .dig_out_nid = ALC662_DIGOUT_NID,
19069 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18828 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19070 .channel_mode = alc662_3ST_2ch_modes, 18829 .channel_mode = alc662_3ST_2ch_modes,
19071 .unsol_event = alc663_mode8_unsol_event, 18830 .unsol_event = alc_sku_unsol_event,
19072 .setup = alc663_mode8_setup, 18831 .setup = alc663_mode8_setup,
19073 .init_hook = alc663_mode8_inithook, 18832 .init_hook = alc_inithook,
19074 }, 18833 },
19075 [ALC272_DELL] = { 18834 [ALC272_DELL] = {
19076 .mixers = { alc663_m51va_mixer }, 18835 .mixers = { alc663_m51va_mixer },
19077 .cap_mixer = alc272_auto_capture_mixer, 18836 .cap_mixer = alc272_auto_capture_mixer,
19078 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs }, 18837 .init_verbs = { alc662_init_verbs,
18838 alc662_eapd_init_verbs,
18839 alc272_dell_init_verbs },
19079 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18840 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19080 .dac_nids = alc662_dac_nids, 18841 .dac_nids = alc272_dac_nids,
19081 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18842 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19082 .adc_nids = alc272_adc_nids, 18843 .adc_nids = alc272_adc_nids,
19083 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), 18844 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
19084 .capsrc_nids = alc272_capsrc_nids, 18845 .capsrc_nids = alc272_capsrc_nids,
19085 .channel_mode = alc662_3ST_2ch_modes, 18846 .channel_mode = alc662_3ST_2ch_modes,
19086 .unsol_event = alc663_m51va_unsol_event, 18847 .unsol_event = alc_sku_unsol_event,
19087 .setup = alc663_m51va_setup, 18848 .setup = alc663_m51va_setup,
19088 .init_hook = alc663_m51va_inithook, 18849 .init_hook = alc_inithook,
19089 }, 18850 },
19090 [ALC272_DELL_ZM1] = { 18851 [ALC272_DELL_ZM1] = {
19091 .mixers = { alc663_m51va_mixer }, 18852 .mixers = { alc663_m51va_mixer },
19092 .cap_mixer = alc662_auto_capture_mixer, 18853 .cap_mixer = alc662_auto_capture_mixer,
19093 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs }, 18854 .init_verbs = { alc662_init_verbs,
18855 alc662_eapd_init_verbs,
18856 alc272_dell_zm1_init_verbs },
19094 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18857 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19095 .dac_nids = alc662_dac_nids, 18858 .dac_nids = alc272_dac_nids,
19096 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18859 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19097 .adc_nids = alc662_adc_nids, 18860 .adc_nids = alc662_adc_nids,
19098 .num_adc_nids = 1, 18861 .num_adc_nids = 1,
19099 .capsrc_nids = alc662_capsrc_nids, 18862 .capsrc_nids = alc662_capsrc_nids,
19100 .channel_mode = alc662_3ST_2ch_modes, 18863 .channel_mode = alc662_3ST_2ch_modes,
19101 .unsol_event = alc663_m51va_unsol_event, 18864 .unsol_event = alc_sku_unsol_event,
19102 .setup = alc663_m51va_setup, 18865 .setup = alc663_m51va_setup,
19103 .init_hook = alc663_m51va_inithook, 18866 .init_hook = alc_inithook,
19104 }, 18867 },
19105 [ALC272_SAMSUNG_NC10] = { 18868 [ALC272_SAMSUNG_NC10] = {
19106 .mixers = { alc272_nc10_mixer }, 18869 .mixers = { alc272_nc10_mixer },
19107 .init_verbs = { alc662_init_verbs, 18870 .init_verbs = { alc662_init_verbs,
18871 alc662_eapd_init_verbs,
19108 alc663_21jd_amic_init_verbs }, 18872 alc663_21jd_amic_init_verbs },
19109 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18873 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19110 .dac_nids = alc272_dac_nids, 18874 .dac_nids = alc272_dac_nids,
19111 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18875 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19112 .channel_mode = alc662_3ST_2ch_modes, 18876 .channel_mode = alc662_3ST_2ch_modes,
19113 /*.input_mux = &alc272_nc10_capture_source,*/ 18877 /*.input_mux = &alc272_nc10_capture_source,*/
19114 .unsol_event = alc663_mode4_unsol_event, 18878 .unsol_event = alc_sku_unsol_event,
19115 .setup = alc663_mode4_setup, 18879 .setup = alc663_mode4_setup,
19116 .init_hook = alc663_mode4_inithook, 18880 .init_hook = alc_inithook,
19117 }, 18881 },
19118}; 18882};
19119 18883
@@ -19123,45 +18887,79 @@ static struct alc_config_preset alc662_presets[] = {
19123 */ 18887 */
19124 18888
19125/* convert from MIX nid to DAC */ 18889/* convert from MIX nid to DAC */
19126static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid) 18890static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
19127{ 18891{
19128 if (nid == 0x0f) 18892 hda_nid_t list[5];
19129 return 0x02; 18893 int i, num;
19130 else if (nid >= 0x0c && nid <= 0x0e) 18894
19131 return nid - 0x0c + 0x02; 18895 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
19132 else if (nid == 0x26) /* ALC887-VD has this DAC too */ 18896 for (i = 0; i < num; i++) {
19133 return 0x25; 18897 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
19134 else 18898 return list[i];
19135 return 0; 18899 }
18900 return 0;
18901}
18902
18903/* go down to the selector widget before the mixer */
18904static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18905{
18906 hda_nid_t srcs[5];
18907 int num = snd_hda_get_connections(codec, pin, srcs,
18908 ARRAY_SIZE(srcs));
18909 if (num != 1 ||
18910 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18911 return pin;
18912 return srcs[0];
19136} 18913}
19137 18914
19138/* get MIX nid connected to the given pin targeted to DAC */ 18915/* get MIX nid connected to the given pin targeted to DAC */
19139static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, 18916static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
19140 hda_nid_t dac) 18917 hda_nid_t dac)
19141{ 18918{
19142 hda_nid_t mix[5]; 18919 hda_nid_t mix[5];
19143 int i, num; 18920 int i, num;
19144 18921
18922 pin = alc_go_down_to_selector(codec, pin);
19145 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); 18923 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
19146 for (i = 0; i < num; i++) { 18924 for (i = 0; i < num; i++) {
19147 if (alc662_mix_to_dac(mix[i]) == dac) 18925 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
19148 return mix[i]; 18926 return mix[i];
19149 } 18927 }
19150 return 0; 18928 return 0;
19151} 18929}
19152 18930
18931/* select the connection from pin to DAC if needed */
18932static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18933 hda_nid_t dac)
18934{
18935 hda_nid_t mix[5];
18936 int i, num;
18937
18938 pin = alc_go_down_to_selector(codec, pin);
18939 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18940 if (num < 2)
18941 return 0;
18942 for (i = 0; i < num; i++) {
18943 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18944 snd_hda_codec_update_cache(codec, pin, 0,
18945 AC_VERB_SET_CONNECT_SEL, i);
18946 return 0;
18947 }
18948 }
18949 return 0;
18950}
18951
19153/* look for an empty DAC slot */ 18952/* look for an empty DAC slot */
19154static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 18953static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
19155{ 18954{
19156 struct alc_spec *spec = codec->spec; 18955 struct alc_spec *spec = codec->spec;
19157 hda_nid_t srcs[5]; 18956 hda_nid_t srcs[5];
19158 int i, j, num; 18957 int i, j, num;
19159 18958
18959 pin = alc_go_down_to_selector(codec, pin);
19160 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); 18960 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19161 if (num < 0)
19162 return 0;
19163 for (i = 0; i < num; i++) { 18961 for (i = 0; i < num; i++) {
19164 hda_nid_t nid = alc662_mix_to_dac(srcs[i]); 18962 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
19165 if (!nid) 18963 if (!nid)
19166 continue; 18964 continue;
19167 for (j = 0; j < spec->multiout.num_dacs; j++) 18965 for (j = 0; j < spec->multiout.num_dacs; j++)
@@ -19183,10 +18981,10 @@ static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19183 18981
19184 spec->multiout.dac_nids = spec->private_dac_nids; 18982 spec->multiout.dac_nids = spec->private_dac_nids;
19185 for (i = 0; i < cfg->line_outs; i++) { 18983 for (i = 0; i < cfg->line_outs; i++) {
19186 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]); 18984 dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
19187 if (!dac) 18985 if (!dac)
19188 continue; 18986 continue;
19189 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 18987 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19190 } 18988 }
19191 return 0; 18989 return 0;
19192} 18990}
@@ -19222,15 +19020,23 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19222 static const char * const chname[4] = { 19020 static const char * const chname[4] = {
19223 "Front", "Surround", NULL /*CLFE*/, "Side" 19021 "Front", "Surround", NULL /*CLFE*/, "Side"
19224 }; 19022 };
19225 const char *pfx = alc_get_line_out_pfx(cfg, true); 19023 const char *pfx = alc_get_line_out_pfx(spec, true);
19226 hda_nid_t nid, mix; 19024 hda_nid_t nid, mix, pin;
19227 int i, err; 19025 int i, err, noutputs;
19228 19026
19229 for (i = 0; i < cfg->line_outs; i++) { 19027 noutputs = cfg->line_outs;
19028 if (spec->multi_ios > 0)
19029 noutputs += spec->multi_ios;
19030
19031 for (i = 0; i < noutputs; i++) {
19230 nid = spec->multiout.dac_nids[i]; 19032 nid = spec->multiout.dac_nids[i];
19231 if (!nid) 19033 if (!nid)
19232 continue; 19034 continue;
19233 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); 19035 if (i >= cfg->line_outs)
19036 pin = spec->multi_io[i - 1].pin;
19037 else
19038 pin = cfg->line_out_pins[i];
19039 mix = alc_auto_dac_to_mix(codec, pin, nid);
19234 if (!mix) 19040 if (!mix)
19235 continue; 19041 continue;
19236 if (!pfx && i == 2) { 19042 if (!pfx && i == 2) {
@@ -19276,7 +19082,7 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
19276 19082
19277 if (!pin) 19083 if (!pin)
19278 return 0; 19084 return 0;
19279 nid = alc662_look_for_dac(codec, pin); 19085 nid = alc_auto_look_for_dac(codec, pin);
19280 if (!nid) { 19086 if (!nid) {
19281 /* the corresponding DAC is already occupied */ 19087 /* the corresponding DAC is already occupied */
19282 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) 19088 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
@@ -19286,7 +19092,7 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
19286 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 19092 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
19287 } 19093 }
19288 19094
19289 mix = alc662_dac_to_mix(codec, pin, nid); 19095 mix = alc_auto_dac_to_mix(codec, pin, nid);
19290 if (!mix) 19096 if (!mix)
19291 return 0; 19097 return 0;
19292 err = alc662_add_vol_ctl(spec, pfx, nid, 3); 19098 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
@@ -19310,14 +19116,21 @@ static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19310 hda_nid_t srcs[HDA_MAX_CONNECTIONS]; 19116 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
19311 19117
19312 alc_set_pin_output(codec, nid, pin_type); 19118 alc_set_pin_output(codec, nid, pin_type);
19313 /* need the manual connection? */
19314 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); 19119 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19315 if (num <= 1)
19316 return;
19317 for (i = 0; i < num; i++) { 19120 for (i = 0; i < num; i++) {
19318 if (alc662_mix_to_dac(srcs[i]) != dac) 19121 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
19319 continue; 19122 continue;
19320 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); 19123 /* need the manual connection? */
19124 if (num > 1)
19125 snd_hda_codec_write(codec, nid, 0,
19126 AC_VERB_SET_CONNECT_SEL, i);
19127 /* unmute mixer widget inputs */
19128 snd_hda_codec_write(codec, srcs[i], 0,
19129 AC_VERB_SET_AMP_GAIN_MUTE,
19130 AMP_IN_UNMUTE(0));
19131 snd_hda_codec_write(codec, srcs[i], 0,
19132 AC_VERB_SET_AMP_GAIN_MUTE,
19133 AMP_IN_UNMUTE(1));
19321 return; 19134 return;
19322 } 19135 }
19323} 19136}
@@ -19374,11 +19187,164 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec)
19374 19187
19375#define alc662_auto_init_input_src alc882_auto_init_input_src 19188#define alc662_auto_init_input_src alc882_auto_init_input_src
19376 19189
19190/*
19191 * multi-io helper
19192 */
19193static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19194 unsigned int location)
19195{
19196 struct alc_spec *spec = codec->spec;
19197 struct auto_pin_cfg *cfg = &spec->autocfg;
19198 int type, i, num_pins = 0;
19199
19200 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19201 for (i = 0; i < cfg->num_inputs; i++) {
19202 hda_nid_t nid = cfg->inputs[i].pin;
19203 hda_nid_t dac;
19204 unsigned int defcfg, caps;
19205 if (cfg->inputs[i].type != type)
19206 continue;
19207 defcfg = snd_hda_codec_get_pincfg(codec, nid);
19208 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19209 continue;
19210 if (location && get_defcfg_location(defcfg) != location)
19211 continue;
19212 caps = snd_hda_query_pin_caps(codec, nid);
19213 if (!(caps & AC_PINCAP_OUT))
19214 continue;
19215 dac = alc_auto_look_for_dac(codec, nid);
19216 if (!dac)
19217 continue;
19218 spec->multi_io[num_pins].pin = nid;
19219 spec->multi_io[num_pins].dac = dac;
19220 num_pins++;
19221 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19222 }
19223 }
19224 spec->multiout.num_dacs = 1;
19225 if (num_pins < 2)
19226 return 0;
19227 return num_pins;
19228}
19229
19230static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19231 struct snd_ctl_elem_info *uinfo)
19232{
19233 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19234 struct alc_spec *spec = codec->spec;
19235
19236 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19237 uinfo->count = 1;
19238 uinfo->value.enumerated.items = spec->multi_ios + 1;
19239 if (uinfo->value.enumerated.item > spec->multi_ios)
19240 uinfo->value.enumerated.item = spec->multi_ios;
19241 sprintf(uinfo->value.enumerated.name, "%dch",
19242 (uinfo->value.enumerated.item + 1) * 2);
19243 return 0;
19244}
19245
19246static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19247 struct snd_ctl_elem_value *ucontrol)
19248{
19249 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19250 struct alc_spec *spec = codec->spec;
19251 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19252 return 0;
19253}
19254
19255static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19256{
19257 struct alc_spec *spec = codec->spec;
19258 hda_nid_t nid = spec->multi_io[idx].pin;
19259
19260 if (!spec->multi_io[idx].ctl_in)
19261 spec->multi_io[idx].ctl_in =
19262 snd_hda_codec_read(codec, nid, 0,
19263 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19264 if (output) {
19265 snd_hda_codec_update_cache(codec, nid, 0,
19266 AC_VERB_SET_PIN_WIDGET_CONTROL,
19267 PIN_OUT);
19268 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19269 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19270 HDA_AMP_MUTE, 0);
19271 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19272 } else {
19273 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19274 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19275 HDA_AMP_MUTE, HDA_AMP_MUTE);
19276 snd_hda_codec_update_cache(codec, nid, 0,
19277 AC_VERB_SET_PIN_WIDGET_CONTROL,
19278 spec->multi_io[idx].ctl_in);
19279 }
19280 return 0;
19281}
19282
19283static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19284 struct snd_ctl_elem_value *ucontrol)
19285{
19286 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19287 struct alc_spec *spec = codec->spec;
19288 int i, ch;
19289
19290 ch = ucontrol->value.enumerated.item[0];
19291 if (ch < 0 || ch > spec->multi_ios)
19292 return -EINVAL;
19293 if (ch == (spec->ext_channel_count - 1) / 2)
19294 return 0;
19295 spec->ext_channel_count = (ch + 1) * 2;
19296 for (i = 0; i < spec->multi_ios; i++)
19297 alc_set_multi_io(codec, i, i < ch);
19298 spec->multiout.max_channels = spec->ext_channel_count;
19299 return 1;
19300}
19301
19302static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
19303 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19304 .name = "Channel Mode",
19305 .info = alc_auto_ch_mode_info,
19306 .get = alc_auto_ch_mode_get,
19307 .put = alc_auto_ch_mode_put,
19308};
19309
19310static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
19311{
19312 struct alc_spec *spec = codec->spec;
19313 struct auto_pin_cfg *cfg = &spec->autocfg;
19314 unsigned int location, defcfg;
19315 int num_pins;
19316
19317 if (cfg->line_outs != 1 ||
19318 cfg->line_out_type != AUTO_PIN_LINE_OUT)
19319 return 0;
19320
19321 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19322 location = get_defcfg_location(defcfg);
19323
19324 num_pins = alc_auto_fill_multi_ios(codec, location);
19325 if (num_pins > 0) {
19326 struct snd_kcontrol_new *knew;
19327
19328 knew = alc_kcontrol_new(spec);
19329 if (!knew)
19330 return -ENOMEM;
19331 *knew = alc_auto_channel_mode_enum;
19332 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19333 if (!knew->name)
19334 return -ENOMEM;
19335
19336 spec->multi_ios = num_pins;
19337 spec->ext_channel_count = 2;
19338 spec->multiout.num_dacs = num_pins + 1;
19339 }
19340 return 0;
19341}
19342
19377static int alc662_parse_auto_config(struct hda_codec *codec) 19343static int alc662_parse_auto_config(struct hda_codec *codec)
19378{ 19344{
19379 struct alc_spec *spec = codec->spec; 19345 struct alc_spec *spec = codec->spec;
19380 int err; 19346 int err;
19381 static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 19347 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19382 19348
19383 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 19349 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19384 alc662_ignore); 19350 alc662_ignore);
@@ -19390,6 +19356,9 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
19390 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg); 19356 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
19391 if (err < 0) 19357 if (err < 0)
19392 return err; 19358 return err;
19359 err = alc_auto_add_multi_channel_mode(codec);
19360 if (err < 0)
19361 return err;
19393 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg); 19362 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
19394 if (err < 0) 19363 if (err < 0)
19395 return err; 19364 return err;
@@ -19420,14 +19389,6 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
19420 spec->num_mux_defs = 1; 19389 spec->num_mux_defs = 1;
19421 spec->input_mux = &spec->private_imux[0]; 19390 spec->input_mux = &spec->private_imux[0];
19422 19391
19423 add_verb(spec, alc662_init_verbs);
19424 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19425 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19426 add_verb(spec, alc663_init_verbs);
19427
19428 if (codec->vendor_id == 0x10ec0272)
19429 add_verb(spec, alc272_init_verbs);
19430
19431 err = alc_auto_add_mic_boost(codec); 19392 err = alc_auto_add_mic_boost(codec);
19432 if (err < 0) 19393 if (err < 0)
19433 return err; 19394 return err;
@@ -19508,7 +19469,7 @@ static const struct alc_fixup alc662_fixups[] = {
19508 }, 19469 },
19509}; 19470};
19510 19471
19511static struct snd_pci_quirk alc662_fixup_tbl[] = { 19472static const struct snd_pci_quirk alc662_fixup_tbl[] = {
19512 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), 19473 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
19513 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), 19474 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
19514 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 19475 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
@@ -19626,6 +19587,7 @@ static int patch_alc662(struct hda_codec *codec)
19626 codec->patch_ops = alc_patch_ops; 19587 codec->patch_ops = alc_patch_ops;
19627 if (board_config == ALC662_AUTO) 19588 if (board_config == ALC662_AUTO)
19628 spec->init_hook = alc662_auto_init; 19589 spec->init_hook = alc662_auto_init;
19590 spec->shutup = alc_eapd_shutup;
19629 19591
19630 alc_init_jacks(codec); 19592 alc_init_jacks(codec);
19631 19593
@@ -19654,6 +19616,15 @@ static int patch_alc888(struct hda_codec *codec)
19654 return patch_alc882(codec); 19616 return patch_alc882(codec);
19655} 19617}
19656 19618
19619static int patch_alc899(struct hda_codec *codec)
19620{
19621 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19622 kfree(codec->chip_name);
19623 codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19624 }
19625 return patch_alc882(codec);
19626}
19627
19657/* 19628/*
19658 * ALC680 support 19629 * ALC680 support
19659 */ 19630 */
@@ -19661,12 +19632,12 @@ static int patch_alc888(struct hda_codec *codec)
19661#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID 19632#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19662#define alc680_modes alc260_modes 19633#define alc680_modes alc260_modes
19663 19634
19664static hda_nid_t alc680_dac_nids[3] = { 19635static const hda_nid_t alc680_dac_nids[3] = {
19665 /* Lout1, Lout2, hp */ 19636 /* Lout1, Lout2, hp */
19666 0x02, 0x03, 0x04 19637 0x02, 0x03, 0x04
19667}; 19638};
19668 19639
19669static hda_nid_t alc680_adc_nids[3] = { 19640static const hda_nid_t alc680_adc_nids[3] = {
19670 /* ADC0-2 */ 19641 /* ADC0-2 */
19671 /* DMIC, MIC, Line-in*/ 19642 /* DMIC, MIC, Line-in*/
19672 0x07, 0x08, 0x09 19643 0x07, 0x08, 0x09
@@ -19686,8 +19657,7 @@ static void alc680_rec_autoswitch(struct hda_codec *codec)
19686 19657
19687 for (i = 0; i < cfg->num_inputs; i++) { 19658 for (i = 0; i < cfg->num_inputs; i++) {
19688 nid = cfg->inputs[i].pin; 19659 nid = cfg->inputs[i].pin;
19689 if (!(snd_hda_query_pin_caps(codec, nid) & 19660 if (!is_jack_detectable(codec, nid))
19690 AC_PINCAP_PRES_DETECT))
19691 continue; 19661 continue;
19692 if (snd_hda_jack_detect(codec, nid)) { 19662 if (snd_hda_jack_detect(codec, nid)) {
19693 if (cfg->inputs[i].type < type_found) { 19663 if (cfg->inputs[i].type < type_found) {
@@ -19734,7 +19704,7 @@ static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19734 return 0; 19704 return 0;
19735} 19705}
19736 19706
19737static struct hda_pcm_stream alc680_pcm_analog_auto_capture = { 19707static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19738 .substreams = 1, /* can be overridden */ 19708 .substreams = 1, /* can be overridden */
19739 .channels_min = 2, 19709 .channels_min = 2,
19740 .channels_max = 2, 19710 .channels_max = 2,
@@ -19745,7 +19715,7 @@ static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19745 }, 19715 },
19746}; 19716};
19747 19717
19748static struct snd_kcontrol_new alc680_base_mixer[] = { 19718static const struct snd_kcontrol_new alc680_base_mixer[] = {
19749 /* output mixer control */ 19719 /* output mixer control */
19750 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 19720 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19751 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 19721 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -19757,7 +19727,7 @@ static struct snd_kcontrol_new alc680_base_mixer[] = {
19757 { } 19727 { }
19758}; 19728};
19759 19729
19760static struct hda_bind_ctls alc680_bind_cap_vol = { 19730static const struct hda_bind_ctls alc680_bind_cap_vol = {
19761 .ops = &snd_hda_bind_vol, 19731 .ops = &snd_hda_bind_vol,
19762 .values = { 19732 .values = {
19763 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), 19733 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
@@ -19767,7 +19737,7 @@ static struct hda_bind_ctls alc680_bind_cap_vol = {
19767 }, 19737 },
19768}; 19738};
19769 19739
19770static struct hda_bind_ctls alc680_bind_cap_switch = { 19740static const struct hda_bind_ctls alc680_bind_cap_switch = {
19771 .ops = &snd_hda_bind_sw, 19741 .ops = &snd_hda_bind_sw,
19772 .values = { 19742 .values = {
19773 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), 19743 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
@@ -19777,7 +19747,7 @@ static struct hda_bind_ctls alc680_bind_cap_switch = {
19777 }, 19747 },
19778}; 19748};
19779 19749
19780static struct snd_kcontrol_new alc680_master_capture_mixer[] = { 19750static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19781 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol), 19751 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19782 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch), 19752 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19783 { } /* end */ 19753 { } /* end */
@@ -19786,7 +19756,7 @@ static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19786/* 19756/*
19787 * generic initialization of ADC, input mixers and output mixers 19757 * generic initialization of ADC, input mixers and output mixers
19788 */ 19758 */
19789static struct hda_verb alc680_init_verbs[] = { 19759static const struct hda_verb alc680_init_verbs[] = {
19790 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19760 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19791 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19761 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19792 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19762 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -19824,20 +19794,22 @@ static void alc680_base_setup(struct hda_codec *codec)
19824 spec->autocfg.inputs[0].type = AUTO_PIN_MIC; 19794 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19825 spec->autocfg.inputs[1].pin = 0x19; 19795 spec->autocfg.inputs[1].pin = 0x19;
19826 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN; 19796 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19797 spec->automute = 1;
19798 spec->automute_mode = ALC_AUTOMUTE_AMP;
19827} 19799}
19828 19800
19829static void alc680_unsol_event(struct hda_codec *codec, 19801static void alc680_unsol_event(struct hda_codec *codec,
19830 unsigned int res) 19802 unsigned int res)
19831{ 19803{
19832 if ((res >> 26) == ALC880_HP_EVENT) 19804 if ((res >> 26) == ALC880_HP_EVENT)
19833 alc_automute_amp(codec); 19805 alc_hp_automute(codec);
19834 if ((res >> 26) == ALC880_MIC_EVENT) 19806 if ((res >> 26) == ALC880_MIC_EVENT)
19835 alc680_rec_autoswitch(codec); 19807 alc680_rec_autoswitch(codec);
19836} 19808}
19837 19809
19838static void alc680_inithook(struct hda_codec *codec) 19810static void alc680_inithook(struct hda_codec *codec)
19839{ 19811{
19840 alc_automute_amp(codec); 19812 alc_hp_automute(codec);
19841 alc680_rec_autoswitch(codec); 19813 alc680_rec_autoswitch(codec);
19842} 19814}
19843 19815
@@ -19874,7 +19846,7 @@ static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19874 19846
19875 if (err < 0) 19847 if (err < 0)
19876 return err; 19848 return err;
19877 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 19849 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19878 } 19850 }
19879 19851
19880 return 0; 19852 return 0;
@@ -19960,7 +19932,7 @@ static int alc680_parse_auto_config(struct hda_codec *codec)
19960{ 19932{
19961 struct alc_spec *spec = codec->spec; 19933 struct alc_spec *spec = codec->spec;
19962 int err; 19934 int err;
19963 static hda_nid_t alc680_ignore[] = { 0 }; 19935 static const hda_nid_t alc680_ignore[] = { 0 };
19964 19936
19965 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 19937 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19966 alc680_ignore); 19938 alc680_ignore);
@@ -20018,12 +19990,12 @@ static const char * const alc680_models[ALC680_MODEL_LAST] = {
20018 [ALC680_AUTO] = "auto", 19990 [ALC680_AUTO] = "auto",
20019}; 19991};
20020 19992
20021static struct snd_pci_quirk alc680_cfg_tbl[] = { 19993static const struct snd_pci_quirk alc680_cfg_tbl[] = {
20022 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE), 19994 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
20023 {} 19995 {}
20024}; 19996};
20025 19997
20026static struct alc_config_preset alc680_presets[] = { 19998static const struct alc_config_preset alc680_presets[] = {
20027 [ALC680_BASE] = { 19999 [ALC680_BASE] = {
20028 .mixers = { alc680_base_mixer }, 20000 .mixers = { alc680_base_mixer },
20029 .cap_mixer = alc680_master_capture_mixer, 20001 .cap_mixer = alc680_master_capture_mixer,
@@ -20104,7 +20076,8 @@ static int patch_alc680(struct hda_codec *codec)
20104/* 20076/*
20105 * patch entries 20077 * patch entries
20106 */ 20078 */
20107static struct hda_codec_preset snd_hda_preset_realtek[] = { 20079static const struct hda_codec_preset snd_hda_preset_realtek[] = {
20080 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
20108 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 20081 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
20109 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 20082 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
20110 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 20083 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
@@ -20113,6 +20086,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
20113 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, 20086 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
20114 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, 20087 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
20115 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, 20088 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
20089 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
20116 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 20090 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
20117 .patch = patch_alc861 }, 20091 .patch = patch_alc861 },
20118 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 20092 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
@@ -20140,6 +20114,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
20140 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, 20114 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
20141 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, 20115 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
20142 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, 20116 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
20117 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
20143 {} /* terminator */ 20118 {} /* terminator */
20144}; 20119};
20145 20120
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index f419ee8d75f0..2f55f32876fa 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -130,7 +130,7 @@ static int si3054_switch_put(struct snd_kcontrol *kcontrol,
130} 130}
131 131
132 132
133static struct snd_kcontrol_new si3054_modem_mixer[] = { 133static const struct snd_kcontrol_new si3054_modem_mixer[] = {
134 SI3054_KCONTROL("Off-hook Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_OH), 134 SI3054_KCONTROL("Off-hook Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_OH),
135 SI3054_KCONTROL("Caller ID Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_CID), 135 SI3054_KCONTROL("Caller ID Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_CID),
136 {} 136 {}
@@ -181,7 +181,7 @@ static int si3054_pcm_open(struct hda_pcm_stream *hinfo,
181} 181}
182 182
183 183
184static struct hda_pcm_stream si3054_pcm = { 184static const struct hda_pcm_stream si3054_pcm = {
185 .substreams = 1, 185 .substreams = 1,
186 .channels_min = 1, 186 .channels_min = 1,
187 .channels_max = 1, 187 .channels_max = 1,
@@ -200,12 +200,13 @@ static int si3054_build_pcms(struct hda_codec *codec)
200{ 200{
201 struct si3054_spec *spec = codec->spec; 201 struct si3054_spec *spec = codec->spec;
202 struct hda_pcm *info = &spec->pcm; 202 struct hda_pcm *info = &spec->pcm;
203 si3054_pcm.nid = codec->mfg;
204 codec->num_pcms = 1; 203 codec->num_pcms = 1;
205 codec->pcm_info = info; 204 codec->pcm_info = info;
206 info->name = "Si3054 Modem"; 205 info->name = "Si3054 Modem";
207 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm; 206 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm;
208 info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm; 207 info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm;
208 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = codec->mfg;
209 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = codec->mfg;
209 info->pcm_type = HDA_PCM_TYPE_MODEM; 210 info->pcm_type = HDA_PCM_TYPE_MODEM;
210 return 0; 211 return 0;
211} 212}
@@ -263,7 +264,7 @@ static void si3054_free(struct hda_codec *codec)
263/* 264/*
264 */ 265 */
265 266
266static struct hda_codec_ops si3054_patch_ops = { 267static const struct hda_codec_ops si3054_patch_ops = {
267 .build_controls = si3054_build_controls, 268 .build_controls = si3054_build_controls,
268 .build_pcms = si3054_build_pcms, 269 .build_pcms = si3054_build_pcms,
269 .init = si3054_init, 270 .init = si3054_init,
@@ -283,7 +284,7 @@ static int patch_si3054(struct hda_codec *codec)
283/* 284/*
284 * patch entries 285 * patch entries
285 */ 286 */
286static struct hda_codec_preset snd_hda_preset_si3054[] = { 287static const struct hda_codec_preset snd_hda_preset_si3054[] = {
287 { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 }, 288 { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 },
288 { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 }, 289 { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 },
289 { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 }, 290 { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 94d19c03a7f4..7f81cc2274f3 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -217,15 +217,15 @@ struct sigmatel_spec {
217 unsigned int stream_delay; 217 unsigned int stream_delay;
218 218
219 /* analog loopback */ 219 /* analog loopback */
220 struct snd_kcontrol_new *aloopback_ctl; 220 const struct snd_kcontrol_new *aloopback_ctl;
221 unsigned char aloopback_mask; 221 unsigned char aloopback_mask;
222 unsigned char aloopback_shift; 222 unsigned char aloopback_shift;
223 223
224 /* power management */ 224 /* power management */
225 unsigned int num_pwrs; 225 unsigned int num_pwrs;
226 unsigned int *pwr_mapping; 226 const unsigned int *pwr_mapping;
227 hda_nid_t *pwr_nids; 227 const hda_nid_t *pwr_nids;
228 hda_nid_t *dac_list; 228 const hda_nid_t *dac_list;
229 229
230 /* events */ 230 /* events */
231 struct snd_array events; 231 struct snd_array events;
@@ -241,20 +241,20 @@ struct sigmatel_spec {
241 int volume_offset; 241 int volume_offset;
242 242
243 /* capture */ 243 /* capture */
244 hda_nid_t *adc_nids; 244 const hda_nid_t *adc_nids;
245 unsigned int num_adcs; 245 unsigned int num_adcs;
246 hda_nid_t *mux_nids; 246 const hda_nid_t *mux_nids;
247 unsigned int num_muxes; 247 unsigned int num_muxes;
248 hda_nid_t *dmic_nids; 248 const hda_nid_t *dmic_nids;
249 unsigned int num_dmics; 249 unsigned int num_dmics;
250 hda_nid_t *dmux_nids; 250 const hda_nid_t *dmux_nids;
251 unsigned int num_dmuxes; 251 unsigned int num_dmuxes;
252 hda_nid_t *smux_nids; 252 const hda_nid_t *smux_nids;
253 unsigned int num_smuxes; 253 unsigned int num_smuxes;
254 unsigned int num_analog_muxes; 254 unsigned int num_analog_muxes;
255 255
256 unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */ 256 const unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */
257 unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */ 257 const unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */
258 unsigned int num_caps; /* number of capture volume/switch elements */ 258 unsigned int num_caps; /* number of capture volume/switch elements */
259 259
260 struct sigmatel_mic_route ext_mic; 260 struct sigmatel_mic_route ext_mic;
@@ -269,12 +269,12 @@ struct sigmatel_spec {
269 hda_nid_t digbeep_nid; 269 hda_nid_t digbeep_nid;
270 270
271 /* pin widgets */ 271 /* pin widgets */
272 hda_nid_t *pin_nids; 272 const hda_nid_t *pin_nids;
273 unsigned int num_pins; 273 unsigned int num_pins;
274 274
275 /* codec specific stuff */ 275 /* codec specific stuff */
276 struct hda_verb *init; 276 const struct hda_verb *init;
277 struct snd_kcontrol_new *mixer; 277 const struct snd_kcontrol_new *mixer;
278 278
279 /* capture source */ 279 /* capture source */
280 struct hda_input_mux *dinput_mux; 280 struct hda_input_mux *dinput_mux;
@@ -317,52 +317,52 @@ struct sigmatel_spec {
317 hda_nid_t auto_dmic_nids[MAX_DMICS_NUM]; 317 hda_nid_t auto_dmic_nids[MAX_DMICS_NUM];
318}; 318};
319 319
320static hda_nid_t stac9200_adc_nids[1] = { 320static const hda_nid_t stac9200_adc_nids[1] = {
321 0x03, 321 0x03,
322}; 322};
323 323
324static hda_nid_t stac9200_mux_nids[1] = { 324static const hda_nid_t stac9200_mux_nids[1] = {
325 0x0c, 325 0x0c,
326}; 326};
327 327
328static hda_nid_t stac9200_dac_nids[1] = { 328static const hda_nid_t stac9200_dac_nids[1] = {
329 0x02, 329 0x02,
330}; 330};
331 331
332static hda_nid_t stac92hd73xx_pwr_nids[8] = { 332static const hda_nid_t stac92hd73xx_pwr_nids[8] = {
333 0x0a, 0x0b, 0x0c, 0xd, 0x0e, 333 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
334 0x0f, 0x10, 0x11 334 0x0f, 0x10, 0x11
335}; 335};
336 336
337static hda_nid_t stac92hd73xx_slave_dig_outs[2] = { 337static const hda_nid_t stac92hd73xx_slave_dig_outs[2] = {
338 0x26, 0, 338 0x26, 0,
339}; 339};
340 340
341static hda_nid_t stac92hd73xx_adc_nids[2] = { 341static const hda_nid_t stac92hd73xx_adc_nids[2] = {
342 0x1a, 0x1b 342 0x1a, 0x1b
343}; 343};
344 344
345#define STAC92HD73XX_NUM_DMICS 2 345#define STAC92HD73XX_NUM_DMICS 2
346static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { 346static const hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
347 0x13, 0x14, 0 347 0x13, 0x14, 0
348}; 348};
349 349
350#define STAC92HD73_DAC_COUNT 5 350#define STAC92HD73_DAC_COUNT 5
351 351
352static hda_nid_t stac92hd73xx_mux_nids[2] = { 352static const hda_nid_t stac92hd73xx_mux_nids[2] = {
353 0x20, 0x21, 353 0x20, 0x21,
354}; 354};
355 355
356static hda_nid_t stac92hd73xx_dmux_nids[2] = { 356static const hda_nid_t stac92hd73xx_dmux_nids[2] = {
357 0x20, 0x21, 357 0x20, 0x21,
358}; 358};
359 359
360static hda_nid_t stac92hd73xx_smux_nids[2] = { 360static const hda_nid_t stac92hd73xx_smux_nids[2] = {
361 0x22, 0x23, 361 0x22, 0x23,
362}; 362};
363 363
364#define STAC92HD73XX_NUM_CAPS 2 364#define STAC92HD73XX_NUM_CAPS 2
365static unsigned long stac92hd73xx_capvols[] = { 365static const unsigned long stac92hd73xx_capvols[] = {
366 HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT), 366 HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT),
367 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 367 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
368}; 368};
@@ -370,137 +370,141 @@ static unsigned long stac92hd73xx_capvols[] = {
370 370
371#define STAC92HD83_DAC_COUNT 3 371#define STAC92HD83_DAC_COUNT 3
372 372
373static hda_nid_t stac92hd83xxx_pwr_nids[4] = { 373static const hda_nid_t stac92hd83xxx_pwr_nids[4] = {
374 0xa, 0xb, 0xd, 0xe, 374 0xa, 0xb, 0xd, 0xe,
375}; 375};
376 376
377static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { 377static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = {
378 0x1e, 0, 378 0x1e, 0,
379}; 379};
380 380
381static unsigned int stac92hd83xxx_pwr_mapping[4] = { 381static const unsigned int stac92hd83xxx_pwr_mapping[4] = {
382 0x03, 0x0c, 0x20, 0x40, 382 0x03, 0x0c, 0x20, 0x40,
383}; 383};
384 384
385static hda_nid_t stac92hd83xxx_dmic_nids[] = { 385static const hda_nid_t stac92hd83xxx_dmic_nids[] = {
386 0x11, 0x20, 386 0x11, 0x20,
387}; 387};
388 388
389static hda_nid_t stac92hd71bxx_pwr_nids[3] = { 389static const hda_nid_t stac92hd71bxx_pwr_nids[3] = {
390 0x0a, 0x0d, 0x0f 390 0x0a, 0x0d, 0x0f
391}; 391};
392 392
393static hda_nid_t stac92hd71bxx_adc_nids[2] = { 393static const hda_nid_t stac92hd71bxx_adc_nids[2] = {
394 0x12, 0x13, 394 0x12, 0x13,
395}; 395};
396 396
397static hda_nid_t stac92hd71bxx_mux_nids[2] = { 397static const hda_nid_t stac92hd71bxx_mux_nids[2] = {
398 0x1a, 0x1b 398 0x1a, 0x1b
399}; 399};
400 400
401static hda_nid_t stac92hd71bxx_dmux_nids[2] = { 401static const hda_nid_t stac92hd71bxx_dmux_nids[2] = {
402 0x1c, 0x1d, 402 0x1c, 0x1d,
403}; 403};
404 404
405static hda_nid_t stac92hd71bxx_smux_nids[2] = { 405static const hda_nid_t stac92hd71bxx_smux_nids[2] = {
406 0x24, 0x25, 406 0x24, 0x25,
407}; 407};
408 408
409#define STAC92HD71BXX_NUM_DMICS 2 409#define STAC92HD71BXX_NUM_DMICS 2
410static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { 410static const hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
411 0x18, 0x19, 0 411 0x18, 0x19, 0
412}; 412};
413 413
414static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = { 414static const hda_nid_t stac92hd71bxx_dmic_5port_nids[STAC92HD71BXX_NUM_DMICS] = {
415 0x18, 0
416};
417
418static const hda_nid_t stac92hd71bxx_slave_dig_outs[2] = {
415 0x22, 0 419 0x22, 0
416}; 420};
417 421
418#define STAC92HD71BXX_NUM_CAPS 2 422#define STAC92HD71BXX_NUM_CAPS 2
419static unsigned long stac92hd71bxx_capvols[] = { 423static const unsigned long stac92hd71bxx_capvols[] = {
420 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), 424 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
421 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), 425 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
422}; 426};
423#define stac92hd71bxx_capsws stac92hd71bxx_capvols 427#define stac92hd71bxx_capsws stac92hd71bxx_capvols
424 428
425static hda_nid_t stac925x_adc_nids[1] = { 429static const hda_nid_t stac925x_adc_nids[1] = {
426 0x03, 430 0x03,
427}; 431};
428 432
429static hda_nid_t stac925x_mux_nids[1] = { 433static const hda_nid_t stac925x_mux_nids[1] = {
430 0x0f, 434 0x0f,
431}; 435};
432 436
433static hda_nid_t stac925x_dac_nids[1] = { 437static const hda_nid_t stac925x_dac_nids[1] = {
434 0x02, 438 0x02,
435}; 439};
436 440
437#define STAC925X_NUM_DMICS 1 441#define STAC925X_NUM_DMICS 1
438static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = { 442static const hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
439 0x15, 0 443 0x15, 0
440}; 444};
441 445
442static hda_nid_t stac925x_dmux_nids[1] = { 446static const hda_nid_t stac925x_dmux_nids[1] = {
443 0x14, 447 0x14,
444}; 448};
445 449
446static unsigned long stac925x_capvols[] = { 450static const unsigned long stac925x_capvols[] = {
447 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), 451 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
448}; 452};
449static unsigned long stac925x_capsws[] = { 453static const unsigned long stac925x_capsws[] = {
450 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 454 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
451}; 455};
452 456
453static hda_nid_t stac922x_adc_nids[2] = { 457static const hda_nid_t stac922x_adc_nids[2] = {
454 0x06, 0x07, 458 0x06, 0x07,
455}; 459};
456 460
457static hda_nid_t stac922x_mux_nids[2] = { 461static const hda_nid_t stac922x_mux_nids[2] = {
458 0x12, 0x13, 462 0x12, 0x13,
459}; 463};
460 464
461#define STAC922X_NUM_CAPS 2 465#define STAC922X_NUM_CAPS 2
462static unsigned long stac922x_capvols[] = { 466static const unsigned long stac922x_capvols[] = {
463 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT), 467 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT),
464 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), 468 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
465}; 469};
466#define stac922x_capsws stac922x_capvols 470#define stac922x_capsws stac922x_capvols
467 471
468static hda_nid_t stac927x_slave_dig_outs[2] = { 472static const hda_nid_t stac927x_slave_dig_outs[2] = {
469 0x1f, 0, 473 0x1f, 0,
470}; 474};
471 475
472static hda_nid_t stac927x_adc_nids[3] = { 476static const hda_nid_t stac927x_adc_nids[3] = {
473 0x07, 0x08, 0x09 477 0x07, 0x08, 0x09
474}; 478};
475 479
476static hda_nid_t stac927x_mux_nids[3] = { 480static const hda_nid_t stac927x_mux_nids[3] = {
477 0x15, 0x16, 0x17 481 0x15, 0x16, 0x17
478}; 482};
479 483
480static hda_nid_t stac927x_smux_nids[1] = { 484static const hda_nid_t stac927x_smux_nids[1] = {
481 0x21, 485 0x21,
482}; 486};
483 487
484static hda_nid_t stac927x_dac_nids[6] = { 488static const hda_nid_t stac927x_dac_nids[6] = {
485 0x02, 0x03, 0x04, 0x05, 0x06, 0 489 0x02, 0x03, 0x04, 0x05, 0x06, 0
486}; 490};
487 491
488static hda_nid_t stac927x_dmux_nids[1] = { 492static const hda_nid_t stac927x_dmux_nids[1] = {
489 0x1b, 493 0x1b,
490}; 494};
491 495
492#define STAC927X_NUM_DMICS 2 496#define STAC927X_NUM_DMICS 2
493static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = { 497static const hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = {
494 0x13, 0x14, 0 498 0x13, 0x14, 0
495}; 499};
496 500
497#define STAC927X_NUM_CAPS 3 501#define STAC927X_NUM_CAPS 3
498static unsigned long stac927x_capvols[] = { 502static const unsigned long stac927x_capvols[] = {
499 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), 503 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
500 HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT), 504 HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT),
501 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT), 505 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT),
502}; 506};
503static unsigned long stac927x_capsws[] = { 507static const unsigned long stac927x_capsws[] = {
504 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 508 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
505 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), 509 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
506 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), 510 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
@@ -511,77 +515,77 @@ static const char * const stac927x_spdif_labels[5] = {
511 "Analog Mux 2", "Analog Mux 3" 515 "Analog Mux 2", "Analog Mux 3"
512}; 516};
513 517
514static hda_nid_t stac9205_adc_nids[2] = { 518static const hda_nid_t stac9205_adc_nids[2] = {
515 0x12, 0x13 519 0x12, 0x13
516}; 520};
517 521
518static hda_nid_t stac9205_mux_nids[2] = { 522static const hda_nid_t stac9205_mux_nids[2] = {
519 0x19, 0x1a 523 0x19, 0x1a
520}; 524};
521 525
522static hda_nid_t stac9205_dmux_nids[1] = { 526static const hda_nid_t stac9205_dmux_nids[1] = {
523 0x1d, 527 0x1d,
524}; 528};
525 529
526static hda_nid_t stac9205_smux_nids[1] = { 530static const hda_nid_t stac9205_smux_nids[1] = {
527 0x21, 531 0x21,
528}; 532};
529 533
530#define STAC9205_NUM_DMICS 2 534#define STAC9205_NUM_DMICS 2
531static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { 535static const hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
532 0x17, 0x18, 0 536 0x17, 0x18, 0
533}; 537};
534 538
535#define STAC9205_NUM_CAPS 2 539#define STAC9205_NUM_CAPS 2
536static unsigned long stac9205_capvols[] = { 540static const unsigned long stac9205_capvols[] = {
537 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT), 541 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT),
538 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT), 542 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT),
539}; 543};
540static unsigned long stac9205_capsws[] = { 544static const unsigned long stac9205_capsws[] = {
541 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), 545 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
542 HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT), 546 HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT),
543}; 547};
544 548
545static hda_nid_t stac9200_pin_nids[8] = { 549static const hda_nid_t stac9200_pin_nids[8] = {
546 0x08, 0x09, 0x0d, 0x0e, 550 0x08, 0x09, 0x0d, 0x0e,
547 0x0f, 0x10, 0x11, 0x12, 551 0x0f, 0x10, 0x11, 0x12,
548}; 552};
549 553
550static hda_nid_t stac925x_pin_nids[8] = { 554static const hda_nid_t stac925x_pin_nids[8] = {
551 0x07, 0x08, 0x0a, 0x0b, 555 0x07, 0x08, 0x0a, 0x0b,
552 0x0c, 0x0d, 0x10, 0x11, 556 0x0c, 0x0d, 0x10, 0x11,
553}; 557};
554 558
555static hda_nid_t stac922x_pin_nids[10] = { 559static const hda_nid_t stac922x_pin_nids[10] = {
556 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 560 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
557 0x0f, 0x10, 0x11, 0x15, 0x1b, 561 0x0f, 0x10, 0x11, 0x15, 0x1b,
558}; 562};
559 563
560static hda_nid_t stac92hd73xx_pin_nids[13] = { 564static const hda_nid_t stac92hd73xx_pin_nids[13] = {
561 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 565 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
562 0x0f, 0x10, 0x11, 0x12, 0x13, 566 0x0f, 0x10, 0x11, 0x12, 0x13,
563 0x14, 0x22, 0x23 567 0x14, 0x22, 0x23
564}; 568};
565 569
566#define STAC92HD71BXX_NUM_PINS 13 570#define STAC92HD71BXX_NUM_PINS 13
567static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { 571static const hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = {
568 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 572 0x0a, 0x0b, 0x0c, 0x0d, 0x00,
569 0x00, 0x14, 0x18, 0x19, 0x1e, 573 0x00, 0x14, 0x18, 0x19, 0x1e,
570 0x1f, 0x20, 0x27 574 0x1f, 0x20, 0x27
571}; 575};
572static hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = { 576static const hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = {
573 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 577 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
574 0x0f, 0x14, 0x18, 0x19, 0x1e, 578 0x0f, 0x14, 0x18, 0x19, 0x1e,
575 0x1f, 0x20, 0x27 579 0x1f, 0x20, 0x27
576}; 580};
577 581
578static hda_nid_t stac927x_pin_nids[14] = { 582static const hda_nid_t stac927x_pin_nids[14] = {
579 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 583 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
580 0x0f, 0x10, 0x11, 0x12, 0x13, 584 0x0f, 0x10, 0x11, 0x12, 0x13,
581 0x14, 0x21, 0x22, 0x23, 585 0x14, 0x21, 0x22, 0x23,
582}; 586};
583 587
584static hda_nid_t stac9205_pin_nids[12] = { 588static const hda_nid_t stac9205_pin_nids[12] = {
585 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 589 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
586 0x0f, 0x14, 0x16, 0x17, 0x18, 590 0x0f, 0x14, 0x16, 0x17, 0x18,
587 0x21, 0x22, 591 0x21, 0x22,
@@ -841,45 +845,45 @@ static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
841 return 1; 845 return 1;
842} 846}
843 847
844static struct hda_verb stac9200_core_init[] = { 848static const struct hda_verb stac9200_core_init[] = {
845 /* set dac0mux for dac converter */ 849 /* set dac0mux for dac converter */
846 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 850 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
847 {} 851 {}
848}; 852};
849 853
850static struct hda_verb stac9200_eapd_init[] = { 854static const struct hda_verb stac9200_eapd_init[] = {
851 /* set dac0mux for dac converter */ 855 /* set dac0mux for dac converter */
852 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 856 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
853 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 857 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
854 {} 858 {}
855}; 859};
856 860
857static struct hda_verb dell_eq_core_init[] = { 861static const struct hda_verb dell_eq_core_init[] = {
858 /* set master volume to max value without distortion 862 /* set master volume to max value without distortion
859 * and direct control */ 863 * and direct control */
860 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, 864 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
861 {} 865 {}
862}; 866};
863 867
864static struct hda_verb stac92hd73xx_core_init[] = { 868static const struct hda_verb stac92hd73xx_core_init[] = {
865 /* set master volume and direct control */ 869 /* set master volume and direct control */
866 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 870 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
867 {} 871 {}
868}; 872};
869 873
870static struct hda_verb stac92hd83xxx_core_init[] = { 874static const struct hda_verb stac92hd83xxx_core_init[] = {
871 /* power state controls amps */ 875 /* power state controls amps */
872 { 0x01, AC_VERB_SET_EAPD, 1 << 2}, 876 { 0x01, AC_VERB_SET_EAPD, 1 << 2},
873 {} 877 {}
874}; 878};
875 879
876static struct hda_verb stac92hd71bxx_core_init[] = { 880static const struct hda_verb stac92hd71bxx_core_init[] = {
877 /* set master volume and direct control */ 881 /* set master volume and direct control */
878 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 882 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
879 {} 883 {}
880}; 884};
881 885
882static struct hda_verb stac92hd71bxx_unmute_core_init[] = { 886static const struct hda_verb stac92hd71bxx_unmute_core_init[] = {
883 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ 887 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */
884 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 888 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
885 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 889 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -887,7 +891,7 @@ static struct hda_verb stac92hd71bxx_unmute_core_init[] = {
887 {} 891 {}
888}; 892};
889 893
890static struct hda_verb stac925x_core_init[] = { 894static const struct hda_verb stac925x_core_init[] = {
891 /* set dac0mux for dac converter */ 895 /* set dac0mux for dac converter */
892 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, 896 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
893 /* mute the master volume */ 897 /* mute the master volume */
@@ -895,13 +899,13 @@ static struct hda_verb stac925x_core_init[] = {
895 {} 899 {}
896}; 900};
897 901
898static struct hda_verb stac922x_core_init[] = { 902static const struct hda_verb stac922x_core_init[] = {
899 /* set master volume and direct control */ 903 /* set master volume and direct control */
900 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 904 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
901 {} 905 {}
902}; 906};
903 907
904static struct hda_verb d965_core_init[] = { 908static const struct hda_verb d965_core_init[] = {
905 /* set master volume and direct control */ 909 /* set master volume and direct control */
906 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 910 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
907 /* unmute node 0x1b */ 911 /* unmute node 0x1b */
@@ -911,7 +915,7 @@ static struct hda_verb d965_core_init[] = {
911 {} 915 {}
912}; 916};
913 917
914static struct hda_verb dell_3st_core_init[] = { 918static const struct hda_verb dell_3st_core_init[] = {
915 /* don't set delta bit */ 919 /* don't set delta bit */
916 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f}, 920 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
917 /* unmute node 0x1b */ 921 /* unmute node 0x1b */
@@ -921,7 +925,7 @@ static struct hda_verb dell_3st_core_init[] = {
921 {} 925 {}
922}; 926};
923 927
924static struct hda_verb stac927x_core_init[] = { 928static const struct hda_verb stac927x_core_init[] = {
925 /* set master volume and direct control */ 929 /* set master volume and direct control */
926 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 930 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
927 /* enable analog pc beep path */ 931 /* enable analog pc beep path */
@@ -929,7 +933,7 @@ static struct hda_verb stac927x_core_init[] = {
929 {} 933 {}
930}; 934};
931 935
932static struct hda_verb stac927x_volknob_core_init[] = { 936static const struct hda_verb stac927x_volknob_core_init[] = {
933 /* don't set delta bit */ 937 /* don't set delta bit */
934 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f}, 938 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
935 /* enable analog pc beep path */ 939 /* enable analog pc beep path */
@@ -937,7 +941,7 @@ static struct hda_verb stac927x_volknob_core_init[] = {
937 {} 941 {}
938}; 942};
939 943
940static struct hda_verb stac9205_core_init[] = { 944static const struct hda_verb stac9205_core_init[] = {
941 /* set master volume and direct control */ 945 /* set master volume and direct control */
942 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 946 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
943 /* enable analog pc beep path */ 947 /* enable analog pc beep path */
@@ -977,7 +981,7 @@ static struct hda_verb stac9205_core_init[] = {
977 .private_value = nid, \ 981 .private_value = nid, \
978 } 982 }
979 983
980static struct snd_kcontrol_new stac9200_mixer[] = { 984static const struct snd_kcontrol_new stac9200_mixer[] = {
981 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xb, 0, HDA_OUTPUT), 985 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
982 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), 986 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
983 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), 987 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
@@ -985,38 +989,38 @@ static struct snd_kcontrol_new stac9200_mixer[] = {
985 { } /* end */ 989 { } /* end */
986}; 990};
987 991
988static struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = { 992static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = {
989 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), 993 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
990 {} 994 {}
991}; 995};
992 996
993static struct snd_kcontrol_new stac92hd73xx_8ch_loopback[] = { 997static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback[] = {
994 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4), 998 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4),
995 {} 999 {}
996}; 1000};
997 1001
998static struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = { 1002static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = {
999 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5), 1003 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5),
1000 {} 1004 {}
1001}; 1005};
1002 1006
1003 1007
1004static struct snd_kcontrol_new stac92hd71bxx_loopback[] = { 1008static const struct snd_kcontrol_new stac92hd71bxx_loopback[] = {
1005 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) 1009 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2)
1006}; 1010};
1007 1011
1008static struct snd_kcontrol_new stac925x_mixer[] = { 1012static const struct snd_kcontrol_new stac925x_mixer[] = {
1009 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xe, 0, HDA_OUTPUT), 1013 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xe, 0, HDA_OUTPUT),
1010 HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), 1014 HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT),
1011 { } /* end */ 1015 { } /* end */
1012}; 1016};
1013 1017
1014static struct snd_kcontrol_new stac9205_loopback[] = { 1018static const struct snd_kcontrol_new stac9205_loopback[] = {
1015 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), 1019 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1),
1016 {} 1020 {}
1017}; 1021};
1018 1022
1019static struct snd_kcontrol_new stac927x_loopback[] = { 1023static const struct snd_kcontrol_new stac927x_loopback[] = {
1020 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), 1024 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1),
1021 {} 1025 {}
1022}; 1026};
@@ -1182,16 +1186,16 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1182 return 0; 1186 return 0;
1183} 1187}
1184 1188
1185static unsigned int ref9200_pin_configs[8] = { 1189static const unsigned int ref9200_pin_configs[8] = {
1186 0x01c47010, 0x01447010, 0x0221401f, 0x01114010, 1190 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
1187 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, 1191 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
1188}; 1192};
1189 1193
1190static unsigned int gateway9200_m4_pin_configs[8] = { 1194static const unsigned int gateway9200_m4_pin_configs[8] = {
1191 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, 1195 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010,
1192 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, 1196 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3,
1193}; 1197};
1194static unsigned int gateway9200_m4_2_pin_configs[8] = { 1198static const unsigned int gateway9200_m4_2_pin_configs[8] = {
1195 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, 1199 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010,
1196 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, 1200 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3,
1197}; 1201};
@@ -1202,7 +1206,7 @@ static unsigned int gateway9200_m4_2_pin_configs[8] = {
1202 102801DE 1206 102801DE
1203 102801E8 1207 102801E8
1204*/ 1208*/
1205static unsigned int dell9200_d21_pin_configs[8] = { 1209static const unsigned int dell9200_d21_pin_configs[8] = {
1206 0x400001f0, 0x400001f1, 0x02214030, 0x01014010, 1210 0x400001f0, 0x400001f1, 0x02214030, 0x01014010,
1207 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, 1211 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
1208}; 1212};
@@ -1212,7 +1216,7 @@ static unsigned int dell9200_d21_pin_configs[8] = {
1212 102801C0 1216 102801C0
1213 102801C1 1217 102801C1
1214*/ 1218*/
1215static unsigned int dell9200_d22_pin_configs[8] = { 1219static const unsigned int dell9200_d22_pin_configs[8] = {
1216 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, 1220 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
1217 0x01813020, 0x02a19021, 0x90100140, 0x400001f2, 1221 0x01813020, 0x02a19021, 0x90100140, 0x400001f2,
1218}; 1222};
@@ -1226,7 +1230,7 @@ static unsigned int dell9200_d22_pin_configs[8] = {
1226 102801DA 1230 102801DA
1227 102801E3 1231 102801E3
1228*/ 1232*/
1229static unsigned int dell9200_d23_pin_configs[8] = { 1233static const unsigned int dell9200_d23_pin_configs[8] = {
1230 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, 1234 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
1231 0x01813020, 0x01a19021, 0x90100140, 0x400001f2, 1235 0x01813020, 0x01a19021, 0x90100140, 0x400001f2,
1232}; 1236};
@@ -1237,7 +1241,7 @@ static unsigned int dell9200_d23_pin_configs[8] = {
1237 102801B5 (Dell Inspiron 630m) 1241 102801B5 (Dell Inspiron 630m)
1238 102801D8 (Dell Inspiron 640m) 1242 102801D8 (Dell Inspiron 640m)
1239*/ 1243*/
1240static unsigned int dell9200_m21_pin_configs[8] = { 1244static const unsigned int dell9200_m21_pin_configs[8] = {
1241 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310, 1245 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310,
1242 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd, 1246 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd,
1243}; 1247};
@@ -1250,7 +1254,7 @@ static unsigned int dell9200_m21_pin_configs[8] = {
1250 102801D4 1254 102801D4
1251 102801D6 1255 102801D6
1252*/ 1256*/
1253static unsigned int dell9200_m22_pin_configs[8] = { 1257static const unsigned int dell9200_m22_pin_configs[8] = {
1254 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310, 1258 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310,
1255 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc, 1259 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc,
1256}; 1260};
@@ -1260,7 +1264,7 @@ static unsigned int dell9200_m22_pin_configs[8] = {
1260 102801CE (Dell XPS M1710) 1264 102801CE (Dell XPS M1710)
1261 102801CF (Dell Precision M90) 1265 102801CF (Dell Precision M90)
1262*/ 1266*/
1263static unsigned int dell9200_m23_pin_configs[8] = { 1267static const unsigned int dell9200_m23_pin_configs[8] = {
1264 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310, 1268 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310,
1265 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc, 1269 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc,
1266}; 1270};
@@ -1272,7 +1276,7 @@ static unsigned int dell9200_m23_pin_configs[8] = {
1272 102801CB (Dell Latitude 120L) 1276 102801CB (Dell Latitude 120L)
1273 102801D3 1277 102801D3
1274*/ 1278*/
1275static unsigned int dell9200_m24_pin_configs[8] = { 1279static const unsigned int dell9200_m24_pin_configs[8] = {
1276 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310, 1280 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310,
1277 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe, 1281 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe,
1278}; 1282};
@@ -1283,7 +1287,7 @@ static unsigned int dell9200_m24_pin_configs[8] = {
1283 102801EE 1287 102801EE
1284 102801EF 1288 102801EF
1285*/ 1289*/
1286static unsigned int dell9200_m25_pin_configs[8] = { 1290static const unsigned int dell9200_m25_pin_configs[8] = {
1287 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, 1291 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
1288 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd, 1292 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd,
1289}; 1293};
@@ -1293,7 +1297,7 @@ static unsigned int dell9200_m25_pin_configs[8] = {
1293 102801F5 (Dell Inspiron 1501) 1297 102801F5 (Dell Inspiron 1501)
1294 102801F6 1298 102801F6
1295*/ 1299*/
1296static unsigned int dell9200_m26_pin_configs[8] = { 1300static const unsigned int dell9200_m26_pin_configs[8] = {
1297 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310, 1301 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310,
1298 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe, 1302 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe,
1299}; 1303};
@@ -1302,18 +1306,18 @@ static unsigned int dell9200_m26_pin_configs[8] = {
1302 STAC 9200-32 1306 STAC 9200-32
1303 102801CD (Dell Inspiron E1705/9400) 1307 102801CD (Dell Inspiron E1705/9400)
1304*/ 1308*/
1305static unsigned int dell9200_m27_pin_configs[8] = { 1309static const unsigned int dell9200_m27_pin_configs[8] = {
1306 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, 1310 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
1307 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc, 1311 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc,
1308}; 1312};
1309 1313
1310static unsigned int oqo9200_pin_configs[8] = { 1314static const unsigned int oqo9200_pin_configs[8] = {
1311 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210, 1315 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210,
1312 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3, 1316 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3,
1313}; 1317};
1314 1318
1315 1319
1316static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { 1320static const unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
1317 [STAC_REF] = ref9200_pin_configs, 1321 [STAC_REF] = ref9200_pin_configs,
1318 [STAC_9200_OQO] = oqo9200_pin_configs, 1322 [STAC_9200_OQO] = oqo9200_pin_configs,
1319 [STAC_9200_DELL_D21] = dell9200_d21_pin_configs, 1323 [STAC_9200_DELL_D21] = dell9200_d21_pin_configs,
@@ -1350,7 +1354,7 @@ static const char * const stac9200_models[STAC_9200_MODELS] = {
1350 [STAC_9200_PANASONIC] = "panasonic", 1354 [STAC_9200_PANASONIC] = "panasonic",
1351}; 1355};
1352 1356
1353static struct snd_pci_quirk stac9200_cfg_tbl[] = { 1357static const struct snd_pci_quirk stac9200_cfg_tbl[] = {
1354 /* SigmaTel reference board */ 1358 /* SigmaTel reference board */
1355 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1359 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1356 "DFI LanParty", STAC_REF), 1360 "DFI LanParty", STAC_REF),
@@ -1426,47 +1430,47 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = {
1426 {} /* terminator */ 1430 {} /* terminator */
1427}; 1431};
1428 1432
1429static unsigned int ref925x_pin_configs[8] = { 1433static const unsigned int ref925x_pin_configs[8] = {
1430 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, 1434 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
1431 0x90a70320, 0x02214210, 0x01019020, 0x9033032e, 1435 0x90a70320, 0x02214210, 0x01019020, 0x9033032e,
1432}; 1436};
1433 1437
1434static unsigned int stac925xM1_pin_configs[8] = { 1438static const unsigned int stac925xM1_pin_configs[8] = {
1435 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 1439 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1436 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, 1440 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
1437}; 1441};
1438 1442
1439static unsigned int stac925xM1_2_pin_configs[8] = { 1443static const unsigned int stac925xM1_2_pin_configs[8] = {
1440 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 1444 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1441 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, 1445 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
1442}; 1446};
1443 1447
1444static unsigned int stac925xM2_pin_configs[8] = { 1448static const unsigned int stac925xM2_pin_configs[8] = {
1445 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 1449 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1446 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, 1450 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
1447}; 1451};
1448 1452
1449static unsigned int stac925xM2_2_pin_configs[8] = { 1453static const unsigned int stac925xM2_2_pin_configs[8] = {
1450 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 1454 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1451 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, 1455 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
1452}; 1456};
1453 1457
1454static unsigned int stac925xM3_pin_configs[8] = { 1458static const unsigned int stac925xM3_pin_configs[8] = {
1455 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 1459 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1456 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3, 1460 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3,
1457}; 1461};
1458 1462
1459static unsigned int stac925xM5_pin_configs[8] = { 1463static const unsigned int stac925xM5_pin_configs[8] = {
1460 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 1464 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1461 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, 1465 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
1462}; 1466};
1463 1467
1464static unsigned int stac925xM6_pin_configs[8] = { 1468static const unsigned int stac925xM6_pin_configs[8] = {
1465 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 1469 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1466 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320, 1470 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320,
1467}; 1471};
1468 1472
1469static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { 1473static const unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
1470 [STAC_REF] = ref925x_pin_configs, 1474 [STAC_REF] = ref925x_pin_configs,
1471 [STAC_M1] = stac925xM1_pin_configs, 1475 [STAC_M1] = stac925xM1_pin_configs,
1472 [STAC_M1_2] = stac925xM1_2_pin_configs, 1476 [STAC_M1_2] = stac925xM1_2_pin_configs,
@@ -1489,7 +1493,7 @@ static const char * const stac925x_models[STAC_925x_MODELS] = {
1489 [STAC_M6] = "m6", 1493 [STAC_M6] = "m6",
1490}; 1494};
1491 1495
1492static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { 1496static const struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = {
1493 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2), 1497 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2),
1494 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5), 1498 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5),
1495 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1), 1499 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1),
@@ -1503,7 +1507,7 @@ static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = {
1503 {} /* terminator */ 1507 {} /* terminator */
1504}; 1508};
1505 1509
1506static struct snd_pci_quirk stac925x_cfg_tbl[] = { 1510static const struct snd_pci_quirk stac925x_cfg_tbl[] = {
1507 /* SigmaTel reference board */ 1511 /* SigmaTel reference board */
1508 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), 1512 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
1509 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF), 1513 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF),
@@ -1515,33 +1519,33 @@ static struct snd_pci_quirk stac925x_cfg_tbl[] = {
1515 {} /* terminator */ 1519 {} /* terminator */
1516}; 1520};
1517 1521
1518static unsigned int ref92hd73xx_pin_configs[13] = { 1522static const unsigned int ref92hd73xx_pin_configs[13] = {
1519 0x02214030, 0x02a19040, 0x01a19020, 0x02214030, 1523 0x02214030, 0x02a19040, 0x01a19020, 0x02214030,
1520 0x0181302e, 0x01014010, 0x01014020, 0x01014030, 1524 0x0181302e, 0x01014010, 0x01014020, 0x01014030,
1521 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050, 1525 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050,
1522 0x01452050, 1526 0x01452050,
1523}; 1527};
1524 1528
1525static unsigned int dell_m6_pin_configs[13] = { 1529static const unsigned int dell_m6_pin_configs[13] = {
1526 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110, 1530 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110,
1527 0x03a11020, 0x0321101f, 0x4f0000f0, 0x4f0000f0, 1531 0x03a11020, 0x0321101f, 0x4f0000f0, 0x4f0000f0,
1528 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, 1532 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0,
1529 0x4f0000f0, 1533 0x4f0000f0,
1530}; 1534};
1531 1535
1532static unsigned int alienware_m17x_pin_configs[13] = { 1536static const unsigned int alienware_m17x_pin_configs[13] = {
1533 0x0321101f, 0x0321101f, 0x03a11020, 0x03014020, 1537 0x0321101f, 0x0321101f, 0x03a11020, 0x03014020,
1534 0x90170110, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0, 1538 0x90170110, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0,
1535 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, 1539 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0,
1536 0x904601b0, 1540 0x904601b0,
1537}; 1541};
1538 1542
1539static unsigned int intel_dg45id_pin_configs[13] = { 1543static const unsigned int intel_dg45id_pin_configs[13] = {
1540 0x02214230, 0x02A19240, 0x01013214, 0x01014210, 1544 0x02214230, 0x02A19240, 0x01013214, 0x01014210,
1541 0x01A19250, 0x01011212, 0x01016211 1545 0x01A19250, 0x01011212, 0x01016211
1542}; 1546};
1543 1547
1544static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { 1548static const unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
1545 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, 1549 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs,
1546 [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, 1550 [STAC_DELL_M6_AMIC] = dell_m6_pin_configs,
1547 [STAC_DELL_M6_DMIC] = dell_m6_pin_configs, 1551 [STAC_DELL_M6_DMIC] = dell_m6_pin_configs,
@@ -1563,7 +1567,7 @@ static const char * const stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
1563 [STAC_ALIENWARE_M17X] = "alienware", 1567 [STAC_ALIENWARE_M17X] = "alienware",
1564}; 1568};
1565 1569
1566static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { 1570static const struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1567 /* SigmaTel reference board */ 1571 /* SigmaTel reference board */
1568 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1572 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1569 "DFI LanParty", STAC_92HD73XX_REF), 1573 "DFI LanParty", STAC_92HD73XX_REF),
@@ -1600,11 +1604,11 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1600 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe, 1604 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
1601 "Dell Studio XPS 1645", STAC_DELL_M6_BOTH), 1605 "Dell Studio XPS 1645", STAC_DELL_M6_BOTH),
1602 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413, 1606 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
1603 "Dell Studio 1558", STAC_DELL_M6_BOTH), 1607 "Dell Studio 1558", STAC_DELL_M6_DMIC),
1604 {} /* terminator */ 1608 {} /* terminator */
1605}; 1609};
1606 1610
1607static struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { 1611static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = {
1608 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1, 1612 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
1609 "Alienware M17x", STAC_ALIENWARE_M17X), 1613 "Alienware M17x", STAC_ALIENWARE_M17X),
1610 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, 1614 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
@@ -1612,25 +1616,25 @@ static struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = {
1612 {} /* terminator */ 1616 {} /* terminator */
1613}; 1617};
1614 1618
1615static unsigned int ref92hd83xxx_pin_configs[10] = { 1619static const unsigned int ref92hd83xxx_pin_configs[10] = {
1616 0x02214030, 0x02211010, 0x02a19020, 0x02170130, 1620 0x02214030, 0x02211010, 0x02a19020, 0x02170130,
1617 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, 1621 0x01014050, 0x01819040, 0x01014020, 0x90a3014e,
1618 0x01451160, 0x98560170, 1622 0x01451160, 0x98560170,
1619}; 1623};
1620 1624
1621static unsigned int dell_s14_pin_configs[10] = { 1625static const unsigned int dell_s14_pin_configs[10] = {
1622 0x0221403f, 0x0221101f, 0x02a19020, 0x90170110, 1626 0x0221403f, 0x0221101f, 0x02a19020, 0x90170110,
1623 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160, 1627 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160,
1624 0x40f000f0, 0x40f000f0, 1628 0x40f000f0, 0x40f000f0,
1625}; 1629};
1626 1630
1627static unsigned int hp_dv7_4000_pin_configs[10] = { 1631static const unsigned int hp_dv7_4000_pin_configs[10] = {
1628 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, 1632 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110,
1629 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, 1633 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140,
1630 0x40f000f0, 0x40f000f0, 1634 0x40f000f0, 0x40f000f0,
1631}; 1635};
1632 1636
1633static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { 1637static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
1634 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, 1638 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
1635 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, 1639 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
1636 [STAC_DELL_S14] = dell_s14_pin_configs, 1640 [STAC_DELL_S14] = dell_s14_pin_configs,
@@ -1646,7 +1650,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1646 [STAC_HP_DV7_4000] = "hp-dv7-4000", 1650 [STAC_HP_DV7_4000] = "hp-dv7-4000",
1647}; 1651};
1648 1652
1649static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { 1653static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1650 /* SigmaTel reference board */ 1654 /* SigmaTel reference board */
1651 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1655 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1652 "DFI LanParty", STAC_92HD83XXX_REF), 1656 "DFI LanParty", STAC_92HD83XXX_REF),
@@ -1659,35 +1663,35 @@ static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1659 {} /* terminator */ 1663 {} /* terminator */
1660}; 1664};
1661 1665
1662static unsigned int ref92hd71bxx_pin_configs[STAC92HD71BXX_NUM_PINS] = { 1666static const unsigned int ref92hd71bxx_pin_configs[STAC92HD71BXX_NUM_PINS] = {
1663 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, 1667 0x02214030, 0x02a19040, 0x01a19020, 0x01014010,
1664 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, 1668 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0,
1665 0x90a000f0, 0x01452050, 0x01452050, 0x00000000, 1669 0x90a000f0, 0x01452050, 0x01452050, 0x00000000,
1666 0x00000000 1670 0x00000000
1667}; 1671};
1668 1672
1669static unsigned int dell_m4_1_pin_configs[STAC92HD71BXX_NUM_PINS] = { 1673static const unsigned int dell_m4_1_pin_configs[STAC92HD71BXX_NUM_PINS] = {
1670 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, 1674 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110,
1671 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, 1675 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0,
1672 0x40f000f0, 0x4f0000f0, 0x4f0000f0, 0x00000000, 1676 0x40f000f0, 0x4f0000f0, 0x4f0000f0, 0x00000000,
1673 0x00000000 1677 0x00000000
1674}; 1678};
1675 1679
1676static unsigned int dell_m4_2_pin_configs[STAC92HD71BXX_NUM_PINS] = { 1680static const unsigned int dell_m4_2_pin_configs[STAC92HD71BXX_NUM_PINS] = {
1677 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, 1681 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
1678 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, 1682 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0,
1679 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, 1683 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000,
1680 0x00000000 1684 0x00000000
1681}; 1685};
1682 1686
1683static unsigned int dell_m4_3_pin_configs[STAC92HD71BXX_NUM_PINS] = { 1687static const unsigned int dell_m4_3_pin_configs[STAC92HD71BXX_NUM_PINS] = {
1684 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, 1688 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
1685 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0, 1689 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0,
1686 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, 1690 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000,
1687 0x00000000 1691 0x00000000
1688}; 1692};
1689 1693
1690static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { 1694static const unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
1691 [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, 1695 [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs,
1692 [STAC_DELL_M4_1] = dell_m4_1_pin_configs, 1696 [STAC_DELL_M4_1] = dell_m4_1_pin_configs,
1693 [STAC_DELL_M4_2] = dell_m4_2_pin_configs, 1697 [STAC_DELL_M4_2] = dell_m4_2_pin_configs,
@@ -1712,7 +1716,7 @@ static const char * const stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
1712 [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr", 1716 [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr",
1713}; 1717};
1714 1718
1715static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { 1719static const struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1716 /* SigmaTel reference board */ 1720 /* SigmaTel reference board */
1717 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1721 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1718 "DFI LanParty", STAC_92HD71BXX_REF), 1722 "DFI LanParty", STAC_92HD71BXX_REF),
@@ -1769,7 +1773,7 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1769 {} /* terminator */ 1773 {} /* terminator */
1770}; 1774};
1771 1775
1772static unsigned int ref922x_pin_configs[10] = { 1776static const unsigned int ref922x_pin_configs[10] = {
1773 0x01014010, 0x01016011, 0x01012012, 0x0221401f, 1777 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
1774 0x01813122, 0x01011014, 0x01441030, 0x01c41030, 1778 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
1775 0x40000100, 0x40000100, 1779 0x40000100, 0x40000100,
@@ -1783,7 +1787,7 @@ static unsigned int ref922x_pin_configs[10] = {
1783 102801D1 1787 102801D1
1784 102801D2 1788 102801D2
1785*/ 1789*/
1786static unsigned int dell_922x_d81_pin_configs[10] = { 1790static const unsigned int dell_922x_d81_pin_configs[10] = {
1787 0x02214030, 0x01a19021, 0x01111012, 0x01114010, 1791 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
1788 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1, 1792 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1,
1789 0x01813122, 0x400001f2, 1793 0x01813122, 0x400001f2,
@@ -1794,7 +1798,7 @@ static unsigned int dell_922x_d81_pin_configs[10] = {
1794 102801AC 1798 102801AC
1795 102801D0 1799 102801D0
1796*/ 1800*/
1797static unsigned int dell_922x_d82_pin_configs[10] = { 1801static const unsigned int dell_922x_d82_pin_configs[10] = {
1798 0x02214030, 0x01a19021, 0x01111012, 0x01114010, 1802 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
1799 0x02a19020, 0x01117011, 0x01451140, 0x400001f0, 1803 0x02a19020, 0x01117011, 0x01451140, 0x400001f0,
1800 0x01813122, 0x400001f1, 1804 0x01813122, 0x400001f1,
@@ -1804,7 +1808,7 @@ static unsigned int dell_922x_d82_pin_configs[10] = {
1804 STAC 922X pin configs for 1808 STAC 922X pin configs for
1805 102801BF 1809 102801BF
1806*/ 1810*/
1807static unsigned int dell_922x_m81_pin_configs[10] = { 1811static const unsigned int dell_922x_m81_pin_configs[10] = {
1808 0x0321101f, 0x01112024, 0x01111222, 0x91174220, 1812 0x0321101f, 0x01112024, 0x01111222, 0x91174220,
1809 0x03a11050, 0x01116221, 0x90a70330, 0x01452340, 1813 0x03a11050, 0x01116221, 0x90a70330, 0x01452340,
1810 0x40C003f1, 0x405003f0, 1814 0x40C003f1, 0x405003f0,
@@ -1814,61 +1818,61 @@ static unsigned int dell_922x_m81_pin_configs[10] = {
1814 STAC 9221 A1 pin configs for 1818 STAC 9221 A1 pin configs for
1815 102801D7 (Dell XPS M1210) 1819 102801D7 (Dell XPS M1210)
1816*/ 1820*/
1817static unsigned int dell_922x_m82_pin_configs[10] = { 1821static const unsigned int dell_922x_m82_pin_configs[10] = {
1818 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310, 1822 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310,
1819 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, 1823 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2,
1820 0x508003f3, 0x405003f4, 1824 0x508003f3, 0x405003f4,
1821}; 1825};
1822 1826
1823static unsigned int d945gtp3_pin_configs[10] = { 1827static const unsigned int d945gtp3_pin_configs[10] = {
1824 0x0221401f, 0x01a19022, 0x01813021, 0x01014010, 1828 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
1825 0x40000100, 0x40000100, 0x40000100, 0x40000100, 1829 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1826 0x02a19120, 0x40000100, 1830 0x02a19120, 0x40000100,
1827}; 1831};
1828 1832
1829static unsigned int d945gtp5_pin_configs[10] = { 1833static const unsigned int d945gtp5_pin_configs[10] = {
1830 0x0221401f, 0x01011012, 0x01813024, 0x01014010, 1834 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
1831 0x01a19021, 0x01016011, 0x01452130, 0x40000100, 1835 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
1832 0x02a19320, 0x40000100, 1836 0x02a19320, 0x40000100,
1833}; 1837};
1834 1838
1835static unsigned int intel_mac_v1_pin_configs[10] = { 1839static const unsigned int intel_mac_v1_pin_configs[10] = {
1836 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd, 1840 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd,
1837 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240, 1841 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240,
1838 0x400000fc, 0x400000fb, 1842 0x400000fc, 0x400000fb,
1839}; 1843};
1840 1844
1841static unsigned int intel_mac_v2_pin_configs[10] = { 1845static const unsigned int intel_mac_v2_pin_configs[10] = {
1842 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, 1846 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
1843 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa, 1847 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa,
1844 0x400000fc, 0x400000fb, 1848 0x400000fc, 0x400000fb,
1845}; 1849};
1846 1850
1847static unsigned int intel_mac_v3_pin_configs[10] = { 1851static const unsigned int intel_mac_v3_pin_configs[10] = {
1848 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, 1852 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
1849 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240, 1853 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240,
1850 0x400000fc, 0x400000fb, 1854 0x400000fc, 0x400000fb,
1851}; 1855};
1852 1856
1853static unsigned int intel_mac_v4_pin_configs[10] = { 1857static const unsigned int intel_mac_v4_pin_configs[10] = {
1854 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, 1858 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
1855 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, 1859 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
1856 0x400000fc, 0x400000fb, 1860 0x400000fc, 0x400000fb,
1857}; 1861};
1858 1862
1859static unsigned int intel_mac_v5_pin_configs[10] = { 1863static const unsigned int intel_mac_v5_pin_configs[10] = {
1860 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, 1864 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
1861 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, 1865 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
1862 0x400000fc, 0x400000fb, 1866 0x400000fc, 0x400000fb,
1863}; 1867};
1864 1868
1865static unsigned int ecs202_pin_configs[10] = { 1869static const unsigned int ecs202_pin_configs[10] = {
1866 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010, 1870 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010,
1867 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1, 1871 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1,
1868 0x9037012e, 0x40e000f2, 1872 0x9037012e, 0x40e000f2,
1869}; 1873};
1870 1874
1871static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { 1875static const unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
1872 [STAC_D945_REF] = ref922x_pin_configs, 1876 [STAC_D945_REF] = ref922x_pin_configs,
1873 [STAC_D945GTP3] = d945gtp3_pin_configs, 1877 [STAC_D945GTP3] = d945gtp3_pin_configs,
1874 [STAC_D945GTP5] = d945gtp5_pin_configs, 1878 [STAC_D945GTP5] = d945gtp5_pin_configs,
@@ -1917,7 +1921,7 @@ static const char * const stac922x_models[STAC_922X_MODELS] = {
1917 [STAC_922X_DELL_M82] = "dell-m82", 1921 [STAC_922X_DELL_M82] = "dell-m82",
1918}; 1922};
1919 1923
1920static struct snd_pci_quirk stac922x_cfg_tbl[] = { 1924static const struct snd_pci_quirk stac922x_cfg_tbl[] = {
1921 /* SigmaTel reference board */ 1925 /* SigmaTel reference board */
1922 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1926 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1923 "DFI LanParty", STAC_D945_REF), 1927 "DFI LanParty", STAC_D945_REF),
@@ -2008,42 +2012,42 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = {
2008 {} /* terminator */ 2012 {} /* terminator */
2009}; 2013};
2010 2014
2011static unsigned int ref927x_pin_configs[14] = { 2015static const unsigned int ref927x_pin_configs[14] = {
2012 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, 2016 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
2013 0x01a19040, 0x01011012, 0x01016011, 0x0101201f, 2017 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
2014 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070, 2018 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
2015 0x01c42190, 0x40000100, 2019 0x01c42190, 0x40000100,
2016}; 2020};
2017 2021
2018static unsigned int d965_3st_pin_configs[14] = { 2022static const unsigned int d965_3st_pin_configs[14] = {
2019 0x0221401f, 0x02a19120, 0x40000100, 0x01014011, 2023 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
2020 0x01a19021, 0x01813024, 0x40000100, 0x40000100, 2024 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
2021 0x40000100, 0x40000100, 0x40000100, 0x40000100, 2025 0x40000100, 0x40000100, 0x40000100, 0x40000100,
2022 0x40000100, 0x40000100 2026 0x40000100, 0x40000100
2023}; 2027};
2024 2028
2025static unsigned int d965_5st_pin_configs[14] = { 2029static const unsigned int d965_5st_pin_configs[14] = {
2026 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, 2030 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
2027 0x01a19040, 0x01011012, 0x01016011, 0x40000100, 2031 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
2028 0x40000100, 0x40000100, 0x40000100, 0x01442070, 2032 0x40000100, 0x40000100, 0x40000100, 0x01442070,
2029 0x40000100, 0x40000100 2033 0x40000100, 0x40000100
2030}; 2034};
2031 2035
2032static unsigned int d965_5st_no_fp_pin_configs[14] = { 2036static const unsigned int d965_5st_no_fp_pin_configs[14] = {
2033 0x40000100, 0x40000100, 0x0181304e, 0x01014010, 2037 0x40000100, 0x40000100, 0x0181304e, 0x01014010,
2034 0x01a19040, 0x01011012, 0x01016011, 0x40000100, 2038 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
2035 0x40000100, 0x40000100, 0x40000100, 0x01442070, 2039 0x40000100, 0x40000100, 0x40000100, 0x01442070,
2036 0x40000100, 0x40000100 2040 0x40000100, 0x40000100
2037}; 2041};
2038 2042
2039static unsigned int dell_3st_pin_configs[14] = { 2043static const unsigned int dell_3st_pin_configs[14] = {
2040 0x02211230, 0x02a11220, 0x01a19040, 0x01114210, 2044 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
2041 0x01111212, 0x01116211, 0x01813050, 0x01112214, 2045 0x01111212, 0x01116211, 0x01813050, 0x01112214,
2042 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb, 2046 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb,
2043 0x40c003fc, 0x40000100 2047 0x40c003fc, 0x40000100
2044}; 2048};
2045 2049
2046static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { 2050static const unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
2047 [STAC_D965_REF_NO_JD] = ref927x_pin_configs, 2051 [STAC_D965_REF_NO_JD] = ref927x_pin_configs,
2048 [STAC_D965_REF] = ref927x_pin_configs, 2052 [STAC_D965_REF] = ref927x_pin_configs,
2049 [STAC_D965_3ST] = d965_3st_pin_configs, 2053 [STAC_D965_3ST] = d965_3st_pin_configs,
@@ -2066,7 +2070,7 @@ static const char * const stac927x_models[STAC_927X_MODELS] = {
2066 [STAC_927X_VOLKNOB] = "volknob", 2070 [STAC_927X_VOLKNOB] = "volknob",
2067}; 2071};
2068 2072
2069static struct snd_pci_quirk stac927x_cfg_tbl[] = { 2073static const struct snd_pci_quirk stac927x_cfg_tbl[] = {
2070 /* SigmaTel reference board */ 2074 /* SigmaTel reference board */
2071 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 2075 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2072 "DFI LanParty", STAC_D965_REF), 2076 "DFI LanParty", STAC_D965_REF),
@@ -2104,7 +2108,7 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
2104 {} /* terminator */ 2108 {} /* terminator */
2105}; 2109};
2106 2110
2107static unsigned int ref9205_pin_configs[12] = { 2111static const unsigned int ref9205_pin_configs[12] = {
2108 0x40000100, 0x40000100, 0x01016011, 0x01014010, 2112 0x40000100, 0x40000100, 0x01016011, 0x01014010,
2109 0x01813122, 0x01a19021, 0x01019020, 0x40000100, 2113 0x01813122, 0x01a19021, 0x01019020, 0x40000100,
2110 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030 2114 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
@@ -2121,7 +2125,7 @@ static unsigned int ref9205_pin_configs[12] = {
2121 10280228 (Dell Vostro 1500) 2125 10280228 (Dell Vostro 1500)
2122 10280229 (Dell Vostro 1700) 2126 10280229 (Dell Vostro 1700)
2123*/ 2127*/
2124static unsigned int dell_9205_m42_pin_configs[12] = { 2128static const unsigned int dell_9205_m42_pin_configs[12] = {
2125 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310, 2129 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
2126 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9, 2130 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9,
2127 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE, 2131 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE,
@@ -2137,19 +2141,19 @@ static unsigned int dell_9205_m42_pin_configs[12] = {
2137 10280200 2141 10280200
2138 10280201 2142 10280201
2139*/ 2143*/
2140static unsigned int dell_9205_m43_pin_configs[12] = { 2144static const unsigned int dell_9205_m43_pin_configs[12] = {
2141 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310, 2145 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310,
2142 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9, 2146 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9,
2143 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8, 2147 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8,
2144}; 2148};
2145 2149
2146static unsigned int dell_9205_m44_pin_configs[12] = { 2150static const unsigned int dell_9205_m44_pin_configs[12] = {
2147 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310, 2151 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310,
2148 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9, 2152 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9,
2149 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe, 2153 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe,
2150}; 2154};
2151 2155
2152static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { 2156static const unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
2153 [STAC_9205_REF] = ref9205_pin_configs, 2157 [STAC_9205_REF] = ref9205_pin_configs,
2154 [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs, 2158 [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs,
2155 [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs, 2159 [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs,
@@ -2166,7 +2170,7 @@ static const char * const stac9205_models[STAC_9205_MODELS] = {
2166 [STAC_9205_EAPD] = "eapd", 2170 [STAC_9205_EAPD] = "eapd",
2167}; 2171};
2168 2172
2169static struct snd_pci_quirk stac9205_cfg_tbl[] = { 2173static const struct snd_pci_quirk stac9205_cfg_tbl[] = {
2170 /* SigmaTel reference board */ 2174 /* SigmaTel reference board */
2171 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 2175 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2172 "DFI LanParty", STAC_9205_REF), 2176 "DFI LanParty", STAC_9205_REF),
@@ -2214,7 +2218,7 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = {
2214}; 2218};
2215 2219
2216static void stac92xx_set_config_regs(struct hda_codec *codec, 2220static void stac92xx_set_config_regs(struct hda_codec *codec,
2217 unsigned int *pincfgs) 2221 const unsigned int *pincfgs)
2218{ 2222{
2219 int i; 2223 int i;
2220 struct sigmatel_spec *spec = codec->spec; 2224 struct sigmatel_spec *spec = codec->spec;
@@ -2334,7 +2338,7 @@ static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2334 return 0; 2338 return 0;
2335} 2339}
2336 2340
2337static struct hda_pcm_stream stac92xx_pcm_digital_playback = { 2341static const struct hda_pcm_stream stac92xx_pcm_digital_playback = {
2338 .substreams = 1, 2342 .substreams = 1,
2339 .channels_min = 2, 2343 .channels_min = 2,
2340 .channels_max = 2, 2344 .channels_max = 2,
@@ -2347,14 +2351,14 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
2347 }, 2351 },
2348}; 2352};
2349 2353
2350static struct hda_pcm_stream stac92xx_pcm_digital_capture = { 2354static const struct hda_pcm_stream stac92xx_pcm_digital_capture = {
2351 .substreams = 1, 2355 .substreams = 1,
2352 .channels_min = 2, 2356 .channels_min = 2,
2353 .channels_max = 2, 2357 .channels_max = 2,
2354 /* NID is set in stac92xx_build_pcms */ 2358 /* NID is set in stac92xx_build_pcms */
2355}; 2359};
2356 2360
2357static struct hda_pcm_stream stac92xx_pcm_analog_playback = { 2361static const struct hda_pcm_stream stac92xx_pcm_analog_playback = {
2358 .substreams = 1, 2362 .substreams = 1,
2359 .channels_min = 2, 2363 .channels_min = 2,
2360 .channels_max = 8, 2364 .channels_max = 8,
@@ -2366,7 +2370,7 @@ static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
2366 }, 2370 },
2367}; 2371};
2368 2372
2369static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = { 2373static const struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
2370 .substreams = 1, 2374 .substreams = 1,
2371 .channels_min = 2, 2375 .channels_min = 2,
2372 .channels_max = 2, 2376 .channels_max = 2,
@@ -2378,7 +2382,7 @@ static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
2378 }, 2382 },
2379}; 2383};
2380 2384
2381static struct hda_pcm_stream stac92xx_pcm_analog_capture = { 2385static const struct hda_pcm_stream stac92xx_pcm_analog_capture = {
2382 .channels_min = 2, 2386 .channels_min = 2,
2383 .channels_max = 2, 2387 .channels_max = 2,
2384 /* NID + .substreams is set in stac92xx_build_pcms */ 2388 /* NID + .substreams is set in stac92xx_build_pcms */
@@ -2487,7 +2491,7 @@ static int stac92xx_dc_bias_info(struct snd_kcontrol *kcontrol,
2487 struct snd_ctl_elem_info *uinfo) 2491 struct snd_ctl_elem_info *uinfo)
2488{ 2492{
2489 int i; 2493 int i;
2490 static char *texts[] = { 2494 static const char * const texts[] = {
2491 "Mic In", "Line In", "Line Out" 2495 "Mic In", "Line In", "Line Out"
2492 }; 2496 };
2493 2497
@@ -2556,7 +2560,7 @@ static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol,
2556static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol, 2560static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol,
2557 struct snd_ctl_elem_info *uinfo) 2561 struct snd_ctl_elem_info *uinfo)
2558{ 2562{
2559 static char *texts[2]; 2563 char *texts[2];
2560 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2564 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2561 struct sigmatel_spec *spec = codec->spec; 2565 struct sigmatel_spec *spec = codec->spec;
2562 2566
@@ -2687,7 +2691,7 @@ enum {
2687 STAC_CTL_WIDGET_DC_BIAS 2691 STAC_CTL_WIDGET_DC_BIAS
2688}; 2692};
2689 2693
2690static struct snd_kcontrol_new stac92xx_control_templates[] = { 2694static const struct snd_kcontrol_new stac92xx_control_templates[] = {
2691 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2695 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2692 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2696 HDA_CODEC_MUTE(NULL, 0, 0, 0),
2693 HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0), 2697 HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0),
@@ -2701,7 +2705,7 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = {
2701/* add dynamic controls */ 2705/* add dynamic controls */
2702static struct snd_kcontrol_new * 2706static struct snd_kcontrol_new *
2703stac_control_new(struct sigmatel_spec *spec, 2707stac_control_new(struct sigmatel_spec *spec,
2704 struct snd_kcontrol_new *ktemp, 2708 const struct snd_kcontrol_new *ktemp,
2705 const char *name, 2709 const char *name,
2706 unsigned int subdev) 2710 unsigned int subdev)
2707{ 2711{
@@ -2724,7 +2728,7 @@ stac_control_new(struct sigmatel_spec *spec,
2724} 2728}
2725 2729
2726static int stac92xx_add_control_temp(struct sigmatel_spec *spec, 2730static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
2727 struct snd_kcontrol_new *ktemp, 2731 const struct snd_kcontrol_new *ktemp,
2728 int idx, const char *name, 2732 int idx, const char *name,
2729 unsigned long val) 2733 unsigned long val)
2730{ 2734{
@@ -2754,7 +2758,7 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
2754 return stac92xx_add_control_idx(spec, type, 0, name, val); 2758 return stac92xx_add_control_idx(spec, type, 0, name, val);
2755} 2759}
2756 2760
2757static struct snd_kcontrol_new stac_input_src_temp = { 2761static const struct snd_kcontrol_new stac_input_src_temp = {
2758 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2762 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2759 .name = "Input Source", 2763 .name = "Input Source",
2760 .info = stac92xx_mux_enum_info, 2764 .info = stac92xx_mux_enum_info,
@@ -3072,7 +3076,8 @@ static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
3072 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); 3076 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
3073 return 1; 3077 return 1;
3074 } else { 3078 } else {
3075 spec->multiout.dac_nids[spec->multiout.num_dacs] = nid; 3079 snd_BUG_ON(spec->multiout.dac_nids != spec->dac_nids);
3080 spec->dac_nids[spec->multiout.num_dacs] = nid;
3076 spec->multiout.num_dacs++; 3081 spec->multiout.num_dacs++;
3077 } 3082 }
3078 return 0; 3083 return 0;
@@ -3109,8 +3114,7 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
3109 3114
3110 for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) { 3115 for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) {
3111 if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) { 3116 if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) {
3112 wid_caps = get_wcaps(codec, pins[i]); 3117 if (is_jack_detectable(codec, pins[i]))
3113 if (wid_caps & AC_WCAP_UNSOL_CAP)
3114 spec->hp_detect = 1; 3118 spec->hp_detect = 1;
3115 } 3119 }
3116 nid = dac_nids[i]; 3120 nid = dac_nids[i];
@@ -3309,7 +3313,7 @@ static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
3309 return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]); 3313 return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]);
3310} 3314}
3311 3315
3312static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = { 3316static const struct snd_kcontrol_new stac92xx_dig_beep_ctrl = {
3313 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3317 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3314 .info = stac92xx_dig_beep_switch_info, 3318 .info = stac92xx_dig_beep_switch_info,
3315 .get = stac92xx_dig_beep_switch_get, 3319 .get = stac92xx_dig_beep_switch_get,
@@ -3516,14 +3520,18 @@ static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid,
3516 hda_nid_t *fixed, hda_nid_t *ext, hda_nid_t *dock) 3520 hda_nid_t *fixed, hda_nid_t *ext, hda_nid_t *dock)
3517{ 3521{
3518 unsigned int cfg; 3522 unsigned int cfg;
3523 unsigned int type;
3519 3524
3520 if (!nid) 3525 if (!nid)
3521 return 0; 3526 return 0;
3522 cfg = snd_hda_codec_get_pincfg(codec, nid); 3527 cfg = snd_hda_codec_get_pincfg(codec, nid);
3528 type = get_defcfg_device(cfg);
3523 switch (snd_hda_get_input_pin_attr(cfg)) { 3529 switch (snd_hda_get_input_pin_attr(cfg)) {
3524 case INPUT_PIN_ATTR_INT: 3530 case INPUT_PIN_ATTR_INT:
3525 if (*fixed) 3531 if (*fixed)
3526 return 1; /* already occupied */ 3532 return 1; /* already occupied */
3533 if (type != AC_JACK_MIC_IN)
3534 return 1; /* invalid type */
3527 *fixed = nid; 3535 *fixed = nid;
3528 break; 3536 break;
3529 case INPUT_PIN_ATTR_UNUSED: 3537 case INPUT_PIN_ATTR_UNUSED:
@@ -3531,11 +3539,15 @@ static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid,
3531 case INPUT_PIN_ATTR_DOCK: 3539 case INPUT_PIN_ATTR_DOCK:
3532 if (*dock) 3540 if (*dock)
3533 return 1; /* already occupied */ 3541 return 1; /* already occupied */
3542 if (type != AC_JACK_MIC_IN && type != AC_JACK_LINE_IN)
3543 return 1; /* invalid type */
3534 *dock = nid; 3544 *dock = nid;
3535 break; 3545 break;
3536 default: 3546 default:
3537 if (*ext) 3547 if (*ext)
3538 return 1; /* already occupied */ 3548 return 1; /* already occupied */
3549 if (type != AC_JACK_MIC_IN)
3550 return 1; /* invalid type */
3539 *ext = nid; 3551 *ext = nid;
3540 break; 3552 break;
3541 } 3553 }
@@ -3591,10 +3603,6 @@ static int stac_check_auto_mic(struct hda_codec *codec)
3591 hda_nid_t fixed, ext, dock; 3603 hda_nid_t fixed, ext, dock;
3592 int i; 3604 int i;
3593 3605
3594 for (i = 0; i < cfg->num_inputs; i++) {
3595 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
3596 return 0; /* must be exclusively mics */
3597 }
3598 fixed = ext = dock = 0; 3606 fixed = ext = dock = 0;
3599 for (i = 0; i < cfg->num_inputs; i++) 3607 for (i = 0; i < cfg->num_inputs; i++)
3600 if (check_mic_pin(codec, cfg->inputs[i].pin, 3608 if (check_mic_pin(codec, cfg->inputs[i].pin,
@@ -3606,7 +3614,7 @@ static int stac_check_auto_mic(struct hda_codec *codec)
3606 return 0; 3614 return 0;
3607 if (!fixed || (!ext && !dock)) 3615 if (!fixed || (!ext && !dock))
3608 return 0; /* no input to switch */ 3616 return 0; /* no input to switch */
3609 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) 3617 if (!is_jack_detectable(codec, ext))
3610 return 0; /* no unsol support */ 3618 return 0; /* no unsol support */
3611 if (set_mic_route(codec, &spec->ext_mic, ext) || 3619 if (set_mic_route(codec, &spec->ext_mic, ext) ||
3612 set_mic_route(codec, &spec->int_mic, fixed) || 3620 set_mic_route(codec, &spec->int_mic, fixed) ||
@@ -3921,13 +3929,11 @@ static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
3921{ 3929{
3922 struct sigmatel_spec *spec = codec->spec; 3930 struct sigmatel_spec *spec = codec->spec;
3923 hda_nid_t pin = cfg->hp_pins[0]; 3931 hda_nid_t pin = cfg->hp_pins[0];
3924 unsigned int wid_caps;
3925 3932
3926 if (! pin) 3933 if (! pin)
3927 return 0; 3934 return 0;
3928 3935
3929 wid_caps = get_wcaps(codec, pin); 3936 if (is_jack_detectable(codec, pin))
3930 if (wid_caps & AC_WCAP_UNSOL_CAP)
3931 spec->hp_detect = 1; 3937 spec->hp_detect = 1;
3932 3938
3933 return 0; 3939 return 0;
@@ -4138,7 +4144,7 @@ static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
4138 struct sigmatel_event *event; 4144 struct sigmatel_event *event;
4139 int tag; 4145 int tag;
4140 4146
4141 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) 4147 if (!is_jack_detectable(codec, nid))
4142 return 0; 4148 return 0;
4143 event = stac_get_event(codec, nid); 4149 event = stac_get_event(codec, nid);
4144 if (event) { 4150 if (event) {
@@ -4171,7 +4177,7 @@ static void stac92xx_power_down(struct hda_codec *codec)
4171 struct sigmatel_spec *spec = codec->spec; 4177 struct sigmatel_spec *spec = codec->spec;
4172 4178
4173 /* power down inactive DACs */ 4179 /* power down inactive DACs */
4174 hda_nid_t *dac; 4180 const hda_nid_t *dac;
4175 for (dac = spec->dac_list; *dac; dac++) 4181 for (dac = spec->dac_list; *dac; dac++)
4176 if (!check_all_dac_nids(spec, *dac)) 4182 if (!check_all_dac_nids(spec, *dac))
4177 snd_hda_codec_write(codec, *dac, 0, 4183 snd_hda_codec_write(codec, *dac, 0,
@@ -4644,7 +4650,7 @@ static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx)
4644} 4650}
4645 4651
4646static int stac92xx_connected_ports(struct hda_codec *codec, 4652static int stac92xx_connected_ports(struct hda_codec *codec,
4647 hda_nid_t *nids, int num_nids) 4653 const hda_nid_t *nids, int num_nids)
4648{ 4654{
4649 struct sigmatel_spec *spec = codec->spec; 4655 struct sigmatel_spec *spec = codec->spec;
4650 int idx, num; 4656 int idx, num;
@@ -4968,7 +4974,7 @@ static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
4968} 4974}
4969#endif 4975#endif
4970 4976
4971static struct hda_codec_ops stac92xx_patch_ops = { 4977static const struct hda_codec_ops stac92xx_patch_ops = {
4972 .build_controls = stac92xx_build_controls, 4978 .build_controls = stac92xx_build_controls,
4973 .build_pcms = stac92xx_build_pcms, 4979 .build_pcms = stac92xx_build_pcms,
4974 .init = stac92xx_init, 4980 .init = stac92xx_init,
@@ -5588,7 +5594,7 @@ static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
5588 return 1; 5594 return 1;
5589} 5595}
5590 5596
5591static struct snd_kcontrol_new stac_hp_bass_sw_ctrl = { 5597static const struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
5592 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5598 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5593 .info = stac_hp_bass_gpio_info, 5599 .info = stac_hp_bass_gpio_info,
5594 .get = stac_hp_bass_gpio_get, 5600 .get = stac_hp_bass_gpio_get,
@@ -5612,7 +5618,7 @@ static int stac_add_hp_bass_switch(struct hda_codec *codec)
5612static int patch_stac92hd71bxx(struct hda_codec *codec) 5618static int patch_stac92hd71bxx(struct hda_codec *codec)
5613{ 5619{
5614 struct sigmatel_spec *spec; 5620 struct sigmatel_spec *spec;
5615 struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; 5621 const struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init;
5616 unsigned int pin_cfg; 5622 unsigned int pin_cfg;
5617 int err = 0; 5623 int err = 0;
5618 5624
@@ -5705,9 +5711,9 @@ again:
5705 unmute_init++; 5711 unmute_init++;
5706 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); 5712 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
5707 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); 5713 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
5708 stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS - 1] = 0; 5714 spec->dmic_nids = stac92hd71bxx_dmic_5port_nids;
5709 spec->num_dmics = stac92xx_connected_ports(codec, 5715 spec->num_dmics = stac92xx_connected_ports(codec,
5710 stac92hd71bxx_dmic_nids, 5716 stac92hd71bxx_dmic_5port_nids,
5711 STAC92HD71BXX_NUM_DMICS - 1); 5717 STAC92HD71BXX_NUM_DMICS - 1);
5712 break; 5718 break;
5713 case 0x111d7603: /* 6 Port with Analog Mixer */ 5719 case 0x111d7603: /* 6 Port with Analog Mixer */
@@ -5729,15 +5735,6 @@ again:
5729 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) 5735 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
5730 snd_hda_sequence_write_cache(codec, unmute_init); 5736 snd_hda_sequence_write_cache(codec, unmute_init);
5731 5737
5732 /* Some HP machines seem to have unstable codec communications
5733 * especially with ATI fglrx driver. For recovering from the
5734 * CORB/RIRB stall, allow the BUS reset and keep always sync
5735 */
5736 if (spec->board_config == STAC_HP_DV5) {
5737 codec->bus->sync_write = 1;
5738 codec->bus->allow_bus_reset = 1;
5739 }
5740
5741 spec->aloopback_ctl = stac92hd71bxx_loopback; 5738 spec->aloopback_ctl = stac92hd71bxx_loopback;
5742 spec->aloopback_mask = 0x50; 5739 spec->aloopback_mask = 0x50;
5743 spec->aloopback_shift = 0; 5740 spec->aloopback_shift = 0;
@@ -6223,31 +6220,31 @@ static int patch_stac9205(struct hda_codec *codec)
6223 * STAC9872 hack 6220 * STAC9872 hack
6224 */ 6221 */
6225 6222
6226static struct hda_verb stac9872_core_init[] = { 6223static const struct hda_verb stac9872_core_init[] = {
6227 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ 6224 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
6228 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ 6225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
6229 {} 6226 {}
6230}; 6227};
6231 6228
6232static hda_nid_t stac9872_pin_nids[] = { 6229static const hda_nid_t stac9872_pin_nids[] = {
6233 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 6230 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
6234 0x11, 0x13, 0x14, 6231 0x11, 0x13, 0x14,
6235}; 6232};
6236 6233
6237static hda_nid_t stac9872_adc_nids[] = { 6234static const hda_nid_t stac9872_adc_nids[] = {
6238 0x8 /*,0x6*/ 6235 0x8 /*,0x6*/
6239}; 6236};
6240 6237
6241static hda_nid_t stac9872_mux_nids[] = { 6238static const hda_nid_t stac9872_mux_nids[] = {
6242 0x15 6239 0x15
6243}; 6240};
6244 6241
6245static unsigned long stac9872_capvols[] = { 6242static const unsigned long stac9872_capvols[] = {
6246 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 6243 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
6247}; 6244};
6248#define stac9872_capsws stac9872_capvols 6245#define stac9872_capsws stac9872_capvols
6249 6246
6250static unsigned int stac9872_vaio_pin_configs[9] = { 6247static const unsigned int stac9872_vaio_pin_configs[9] = {
6251 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030, 6248 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030,
6252 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0, 6249 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0,
6253 0x90a7013e 6250 0x90a7013e
@@ -6258,11 +6255,11 @@ static const char * const stac9872_models[STAC_9872_MODELS] = {
6258 [STAC_9872_VAIO] = "vaio", 6255 [STAC_9872_VAIO] = "vaio",
6259}; 6256};
6260 6257
6261static unsigned int *stac9872_brd_tbl[STAC_9872_MODELS] = { 6258static const unsigned int *stac9872_brd_tbl[STAC_9872_MODELS] = {
6262 [STAC_9872_VAIO] = stac9872_vaio_pin_configs, 6259 [STAC_9872_VAIO] = stac9872_vaio_pin_configs,
6263}; 6260};
6264 6261
6265static struct snd_pci_quirk stac9872_cfg_tbl[] = { 6262static const struct snd_pci_quirk stac9872_cfg_tbl[] = {
6266 SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0, 6263 SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0,
6267 "Sony VAIO F/S", STAC_9872_VAIO), 6264 "Sony VAIO F/S", STAC_9872_VAIO),
6268 {} /* terminator */ 6265 {} /* terminator */
@@ -6316,7 +6313,7 @@ static int patch_stac9872(struct hda_codec *codec)
6316/* 6313/*
6317 * patch entries 6314 * patch entries
6318 */ 6315 */
6319static struct hda_codec_preset snd_hda_preset_sigmatel[] = { 6316static const struct hda_codec_preset snd_hda_preset_sigmatel[] = {
6320 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 }, 6317 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
6321 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x }, 6318 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
6322 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x }, 6319 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 0997031c48d2..605c99e1e520 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -98,24 +98,30 @@ enum VIA_HDA_CODEC {
98 VT1716S, 98 VT1716S,
99 VT2002P, 99 VT2002P,
100 VT1812, 100 VT1812,
101 VT1802,
101 CODEC_TYPES, 102 CODEC_TYPES,
102}; 103};
103 104
105#define VT2002P_COMPATIBLE(spec) \
106 ((spec)->codec_type == VT2002P ||\
107 (spec)->codec_type == VT1812 ||\
108 (spec)->codec_type == VT1802)
109
104struct via_spec { 110struct via_spec {
105 /* codec parameterization */ 111 /* codec parameterization */
106 struct snd_kcontrol_new *mixers[6]; 112 const struct snd_kcontrol_new *mixers[6];
107 unsigned int num_mixers; 113 unsigned int num_mixers;
108 114
109 struct hda_verb *init_verbs[5]; 115 const struct hda_verb *init_verbs[5];
110 unsigned int num_iverbs; 116 unsigned int num_iverbs;
111 117
112 char *stream_name_analog; 118 char *stream_name_analog;
113 struct hda_pcm_stream *stream_analog_playback; 119 const struct hda_pcm_stream *stream_analog_playback;
114 struct hda_pcm_stream *stream_analog_capture; 120 const struct hda_pcm_stream *stream_analog_capture;
115 121
116 char *stream_name_digital; 122 char *stream_name_digital;
117 struct hda_pcm_stream *stream_digital_playback; 123 const struct hda_pcm_stream *stream_digital_playback;
118 struct hda_pcm_stream *stream_digital_capture; 124 const struct hda_pcm_stream *stream_digital_capture;
119 125
120 /* playback */ 126 /* playback */
121 struct hda_multi_out multiout; 127 struct hda_multi_out multiout;
@@ -123,7 +129,7 @@ struct via_spec {
123 129
124 /* capture */ 130 /* capture */
125 unsigned int num_adc_nids; 131 unsigned int num_adc_nids;
126 hda_nid_t *adc_nids; 132 const hda_nid_t *adc_nids;
127 hda_nid_t mux_nids[3]; 133 hda_nid_t mux_nids[3];
128 hda_nid_t dig_in_nid; 134 hda_nid_t dig_in_nid;
129 hda_nid_t dig_in_pin; 135 hda_nid_t dig_in_pin;
@@ -154,6 +160,9 @@ struct via_spec {
154 struct delayed_work vt1708_hp_work; 160 struct delayed_work vt1708_hp_work;
155 int vt1708_jack_detectect; 161 int vt1708_jack_detectect;
156 int vt1708_hp_present; 162 int vt1708_hp_present;
163
164 void (*set_widgets_power_state)(struct hda_codec *codec);
165
157#ifdef CONFIG_SND_HDA_POWER_SAVE 166#ifdef CONFIG_SND_HDA_POWER_SAVE
158 struct hda_loopback_check loopback; 167 struct hda_loopback_check loopback;
159#endif 168#endif
@@ -218,17 +227,19 @@ static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
218 codec_type = VT1812; 227 codec_type = VT1812;
219 else if (dev_id == 0x0440) 228 else if (dev_id == 0x0440)
220 codec_type = VT1708S; 229 codec_type = VT1708S;
230 else if ((dev_id & 0xfff) == 0x446)
231 codec_type = VT1802;
221 else 232 else
222 codec_type = UNKNOWN; 233 codec_type = UNKNOWN;
223 return codec_type; 234 return codec_type;
224}; 235};
225 236
237#define VIA_JACK_EVENT 0x20
226#define VIA_HP_EVENT 0x01 238#define VIA_HP_EVENT 0x01
227#define VIA_GPIO_EVENT 0x02 239#define VIA_GPIO_EVENT 0x02
228#define VIA_JACK_EVENT 0x04 240#define VIA_MONO_EVENT 0x03
229#define VIA_MONO_EVENT 0x08 241#define VIA_SPEAKER_EVENT 0x04
230#define VIA_SPEAKER_EVENT 0x10 242#define VIA_BIND_HP_EVENT 0x05
231#define VIA_BIND_HP_EVENT 0x20
232 243
233enum { 244enum {
234 VIA_CTL_WIDGET_VOL, 245 VIA_CTL_WIDGET_VOL,
@@ -245,7 +256,6 @@ enum {
245}; 256};
246 257
247static void analog_low_current_mode(struct hda_codec *codec, int stream_idle); 258static void analog_low_current_mode(struct hda_codec *codec, int stream_idle);
248static void set_jack_power_state(struct hda_codec *codec);
249static int is_aa_path_mute(struct hda_codec *codec); 259static int is_aa_path_mute(struct hda_codec *codec);
250 260
251static void vt1708_start_hp_work(struct via_spec *spec) 261static void vt1708_start_hp_work(struct via_spec *spec)
@@ -271,6 +281,12 @@ static void vt1708_stop_hp_work(struct via_spec *spec)
271 cancel_delayed_work_sync(&spec->vt1708_hp_work); 281 cancel_delayed_work_sync(&spec->vt1708_hp_work);
272} 282}
273 283
284static void set_widgets_power_state(struct hda_codec *codec)
285{
286 struct via_spec *spec = codec->spec;
287 if (spec->set_widgets_power_state)
288 spec->set_widgets_power_state(codec);
289}
274 290
275static int analog_input_switch_put(struct snd_kcontrol *kcontrol, 291static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
276 struct snd_ctl_elem_value *ucontrol) 292 struct snd_ctl_elem_value *ucontrol)
@@ -278,7 +294,7 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
278 int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 294 int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
279 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 295 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
280 296
281 set_jack_power_state(codec); 297 set_widgets_power_state(codec);
282 analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1); 298 analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1);
283 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) { 299 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
284 if (is_aa_path_mute(codec)) 300 if (is_aa_path_mute(codec))
@@ -394,54 +410,54 @@ static int bind_pin_switch_put(struct snd_kcontrol *kcontrol,
394 .put = bind_pin_switch_put, \ 410 .put = bind_pin_switch_put, \
395 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) } 411 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
396 412
397static struct snd_kcontrol_new via_control_templates[] = { 413static const struct snd_kcontrol_new via_control_templates[] = {
398 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 414 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
399 HDA_CODEC_MUTE(NULL, 0, 0, 0), 415 HDA_CODEC_MUTE(NULL, 0, 0, 0),
400 ANALOG_INPUT_MUTE, 416 ANALOG_INPUT_MUTE,
401 BIND_PIN_MUTE, 417 BIND_PIN_MUTE,
402}; 418};
403 419
404static hda_nid_t vt1708_adc_nids[2] = { 420static const hda_nid_t vt1708_adc_nids[2] = {
405 /* ADC1-2 */ 421 /* ADC1-2 */
406 0x15, 0x27 422 0x15, 0x27
407}; 423};
408 424
409static hda_nid_t vt1709_adc_nids[3] = { 425static const hda_nid_t vt1709_adc_nids[3] = {
410 /* ADC1-2 */ 426 /* ADC1-2 */
411 0x14, 0x15, 0x16 427 0x14, 0x15, 0x16
412}; 428};
413 429
414static hda_nid_t vt1708B_adc_nids[2] = { 430static const hda_nid_t vt1708B_adc_nids[2] = {
415 /* ADC1-2 */ 431 /* ADC1-2 */
416 0x13, 0x14 432 0x13, 0x14
417}; 433};
418 434
419static hda_nid_t vt1708S_adc_nids[2] = { 435static const hda_nid_t vt1708S_adc_nids[2] = {
420 /* ADC1-2 */ 436 /* ADC1-2 */
421 0x13, 0x14 437 0x13, 0x14
422}; 438};
423 439
424static hda_nid_t vt1702_adc_nids[3] = { 440static const hda_nid_t vt1702_adc_nids[3] = {
425 /* ADC1-2 */ 441 /* ADC1-2 */
426 0x12, 0x20, 0x1F 442 0x12, 0x20, 0x1F
427}; 443};
428 444
429static hda_nid_t vt1718S_adc_nids[2] = { 445static const hda_nid_t vt1718S_adc_nids[2] = {
430 /* ADC1-2 */ 446 /* ADC1-2 */
431 0x10, 0x11 447 0x10, 0x11
432}; 448};
433 449
434static hda_nid_t vt1716S_adc_nids[2] = { 450static const hda_nid_t vt1716S_adc_nids[2] = {
435 /* ADC1-2 */ 451 /* ADC1-2 */
436 0x13, 0x14 452 0x13, 0x14
437}; 453};
438 454
439static hda_nid_t vt2002P_adc_nids[2] = { 455static const hda_nid_t vt2002P_adc_nids[2] = {
440 /* ADC1-2 */ 456 /* ADC1-2 */
441 0x10, 0x11 457 0x10, 0x11
442}; 458};
443 459
444static hda_nid_t vt1812_adc_nids[2] = { 460static const hda_nid_t vt1812_adc_nids[2] = {
445 /* ADC1-2 */ 461 /* ADC1-2 */
446 0x10, 0x11 462 0x10, 0x11
447}; 463};
@@ -471,7 +487,7 @@ static int __via_add_control(struct via_spec *spec, int type, const char *name,
471 __via_add_control(spec, type, name, 0, val) 487 __via_add_control(spec, type, name, 0, val)
472 488
473static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, 489static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
474 struct snd_kcontrol_new *tmpl) 490 const struct snd_kcontrol_new *tmpl)
475{ 491{
476 struct snd_kcontrol_new *knew; 492 struct snd_kcontrol_new *knew;
477 493
@@ -602,482 +618,6 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
602 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); 618 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
603} 619}
604 620
605static void set_jack_power_state(struct hda_codec *codec)
606{
607 struct via_spec *spec = codec->spec;
608 int imux_is_smixer;
609 unsigned int parm;
610
611 if (spec->codec_type == VT1702) {
612 imux_is_smixer = snd_hda_codec_read(
613 codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
614 /* inputs */
615 /* PW 1/2/5 (14h/15h/18h) */
616 parm = AC_PWRST_D3;
617 set_pin_power_state(codec, 0x14, &parm);
618 set_pin_power_state(codec, 0x15, &parm);
619 set_pin_power_state(codec, 0x18, &parm);
620 if (imux_is_smixer)
621 parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */
622 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
623 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
624 parm);
625 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE,
626 parm);
627 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
628 parm);
629 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE,
630 parm);
631
632 /* outputs */
633 /* PW 3/4 (16h/17h) */
634 parm = AC_PWRST_D3;
635 set_pin_power_state(codec, 0x16, &parm);
636 set_pin_power_state(codec, 0x17, &parm);
637 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
638 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
639 imux_is_smixer ? AC_PWRST_D0 : parm);
640 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
641 parm);
642 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE,
643 parm);
644 } else if (spec->codec_type == VT1708B_8CH
645 || spec->codec_type == VT1708B_4CH
646 || spec->codec_type == VT1708S) {
647 /* SW0 (17h) = stereo mixer */
648 int is_8ch = spec->codec_type != VT1708B_4CH;
649 imux_is_smixer = snd_hda_codec_read(
650 codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
651 == ((spec->codec_type == VT1708S) ? 5 : 0);
652 /* inputs */
653 /* PW 1/2/5 (1ah/1bh/1eh) */
654 parm = AC_PWRST_D3;
655 set_pin_power_state(codec, 0x1a, &parm);
656 set_pin_power_state(codec, 0x1b, &parm);
657 set_pin_power_state(codec, 0x1e, &parm);
658 if (imux_is_smixer)
659 parm = AC_PWRST_D0;
660 /* SW0 (17h), AIW 0/1 (13h/14h) */
661 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
662 parm);
663 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
664 parm);
665 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
666 parm);
667
668 /* outputs */
669 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
670 parm = AC_PWRST_D3;
671 set_pin_power_state(codec, 0x19, &parm);
672 if (spec->smart51_enabled)
673 parm = AC_PWRST_D0;
674 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
675 parm);
676 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
677 parm);
678
679 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
680 if (is_8ch) {
681 parm = AC_PWRST_D3;
682 set_pin_power_state(codec, 0x22, &parm);
683 if (spec->smart51_enabled)
684 parm = AC_PWRST_D0;
685 snd_hda_codec_write(codec, 0x26, 0,
686 AC_VERB_SET_POWER_STATE, parm);
687 snd_hda_codec_write(codec, 0x24, 0,
688 AC_VERB_SET_POWER_STATE, parm);
689 }
690
691 /* PW 3/4/7 (1ch/1dh/23h) */
692 parm = AC_PWRST_D3;
693 /* force to D0 for internal Speaker */
694 set_pin_power_state(codec, 0x1c, &parm);
695 set_pin_power_state(codec, 0x1d, &parm);
696 if (is_8ch)
697 set_pin_power_state(codec, 0x23, &parm);
698 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
699 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
700 imux_is_smixer ? AC_PWRST_D0 : parm);
701 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
702 parm);
703 if (is_8ch) {
704 snd_hda_codec_write(codec, 0x25, 0,
705 AC_VERB_SET_POWER_STATE, parm);
706 snd_hda_codec_write(codec, 0x27, 0,
707 AC_VERB_SET_POWER_STATE, parm);
708 }
709 } else if (spec->codec_type == VT1718S) {
710 /* MUX6 (1eh) = stereo mixer */
711 imux_is_smixer = snd_hda_codec_read(
712 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
713 /* inputs */
714 /* PW 5/6/7 (29h/2ah/2bh) */
715 parm = AC_PWRST_D3;
716 set_pin_power_state(codec, 0x29, &parm);
717 set_pin_power_state(codec, 0x2a, &parm);
718 set_pin_power_state(codec, 0x2b, &parm);
719 if (imux_is_smixer)
720 parm = AC_PWRST_D0;
721 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
722 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE,
723 parm);
724 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
725 parm);
726 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
727 parm);
728 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
729 parm);
730
731 /* outputs */
732 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
733 parm = AC_PWRST_D3;
734 set_pin_power_state(codec, 0x27, &parm);
735 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
736 parm);
737 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE,
738 parm);
739
740 /* PW2 (26h), AOW2 (ah) */
741 parm = AC_PWRST_D3;
742 set_pin_power_state(codec, 0x26, &parm);
743 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE,
744 parm);
745
746 /* PW0/1 (24h/25h) */
747 parm = AC_PWRST_D3;
748 set_pin_power_state(codec, 0x24, &parm);
749 set_pin_power_state(codec, 0x25, &parm);
750 if (!spec->hp_independent_mode) /* check for redirected HP */
751 set_pin_power_state(codec, 0x28, &parm);
752 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE,
753 parm);
754 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE,
755 parm);
756 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
757 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
758 imux_is_smixer ? AC_PWRST_D0 : parm);
759 if (spec->hp_independent_mode) {
760 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
761 parm = AC_PWRST_D3;
762 set_pin_power_state(codec, 0x28, &parm);
763 snd_hda_codec_write(codec, 0x1b, 0,
764 AC_VERB_SET_POWER_STATE, parm);
765 snd_hda_codec_write(codec, 0x34, 0,
766 AC_VERB_SET_POWER_STATE, parm);
767 snd_hda_codec_write(codec, 0xc, 0,
768 AC_VERB_SET_POWER_STATE, parm);
769 }
770 } else if (spec->codec_type == VT1716S) {
771 unsigned int mono_out, present;
772 /* SW0 (17h) = stereo mixer */
773 imux_is_smixer = snd_hda_codec_read(
774 codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
775 /* inputs */
776 /* PW 1/2/5 (1ah/1bh/1eh) */
777 parm = AC_PWRST_D3;
778 set_pin_power_state(codec, 0x1a, &parm);
779 set_pin_power_state(codec, 0x1b, &parm);
780 set_pin_power_state(codec, 0x1e, &parm);
781 if (imux_is_smixer)
782 parm = AC_PWRST_D0;
783 /* SW0 (17h), AIW0(13h) */
784 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
785 parm);
786 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
787 parm);
788
789 parm = AC_PWRST_D3;
790 set_pin_power_state(codec, 0x1e, &parm);
791 /* PW11 (22h) */
792 if (spec->dmic_enabled)
793 set_pin_power_state(codec, 0x22, &parm);
794 else
795 snd_hda_codec_write(
796 codec, 0x22, 0,
797 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
798
799 /* SW2(26h), AIW1(14h) */
800 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE,
801 parm);
802 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
803 parm);
804
805 /* outputs */
806 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
807 parm = AC_PWRST_D3;
808 set_pin_power_state(codec, 0x19, &parm);
809 /* Smart 5.1 PW2(1bh) */
810 if (spec->smart51_enabled)
811 set_pin_power_state(codec, 0x1b, &parm);
812 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
813 parm);
814 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
815 parm);
816
817 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
818 parm = AC_PWRST_D3;
819 set_pin_power_state(codec, 0x23, &parm);
820 /* Smart 5.1 PW1(1ah) */
821 if (spec->smart51_enabled)
822 set_pin_power_state(codec, 0x1a, &parm);
823 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE,
824 parm);
825
826 /* Smart 5.1 PW5(1eh) */
827 if (spec->smart51_enabled)
828 set_pin_power_state(codec, 0x1e, &parm);
829 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE,
830 parm);
831
832 /* Mono out */
833 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
834 present = snd_hda_jack_detect(codec, 0x1c);
835 if (present)
836 mono_out = 0;
837 else {
838 present = snd_hda_jack_detect(codec, 0x1d);
839 if (!spec->hp_independent_mode && present)
840 mono_out = 0;
841 else
842 mono_out = 1;
843 }
844 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
845 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE,
846 parm);
847 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE,
848 parm);
849 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE,
850 parm);
851
852 /* PW 3/4 (1ch/1dh) */
853 parm = AC_PWRST_D3;
854 set_pin_power_state(codec, 0x1c, &parm);
855 set_pin_power_state(codec, 0x1d, &parm);
856 /* HP Independent Mode, power on AOW3 */
857 if (spec->hp_independent_mode)
858 snd_hda_codec_write(codec, 0x25, 0,
859 AC_VERB_SET_POWER_STATE, parm);
860
861 /* force to D0 for internal Speaker */
862 /* MW0 (16h), AOW0 (10h) */
863 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
864 imux_is_smixer ? AC_PWRST_D0 : parm);
865 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
866 mono_out ? AC_PWRST_D0 : parm);
867 } else if (spec->codec_type == VT2002P) {
868 unsigned int present;
869 /* MUX9 (1eh) = stereo mixer */
870 imux_is_smixer = snd_hda_codec_read(
871 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
872 /* inputs */
873 /* PW 5/6/7 (29h/2ah/2bh) */
874 parm = AC_PWRST_D3;
875 set_pin_power_state(codec, 0x29, &parm);
876 set_pin_power_state(codec, 0x2a, &parm);
877 set_pin_power_state(codec, 0x2b, &parm);
878 if (imux_is_smixer)
879 parm = AC_PWRST_D0;
880 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
881 snd_hda_codec_write(codec, 0x1e, 0,
882 AC_VERB_SET_POWER_STATE, parm);
883 snd_hda_codec_write(codec, 0x1f, 0,
884 AC_VERB_SET_POWER_STATE, parm);
885 snd_hda_codec_write(codec, 0x10, 0,
886 AC_VERB_SET_POWER_STATE, parm);
887 snd_hda_codec_write(codec, 0x11, 0,
888 AC_VERB_SET_POWER_STATE, parm);
889
890 /* outputs */
891 /* AOW0 (8h)*/
892 snd_hda_codec_write(codec, 0x8, 0,
893 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
894
895 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
896 parm = AC_PWRST_D3;
897 set_pin_power_state(codec, 0x26, &parm);
898 snd_hda_codec_write(codec, 0x1c, 0,
899 AC_VERB_SET_POWER_STATE, parm);
900 snd_hda_codec_write(codec, 0x37,
901 0, AC_VERB_SET_POWER_STATE, parm);
902
903 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
904 parm = AC_PWRST_D3;
905 set_pin_power_state(codec, 0x25, &parm);
906 snd_hda_codec_write(codec, 0x19, 0,
907 AC_VERB_SET_POWER_STATE, parm);
908 snd_hda_codec_write(codec, 0x35, 0,
909 AC_VERB_SET_POWER_STATE, parm);
910 if (spec->hp_independent_mode) {
911 snd_hda_codec_write(codec, 0x9, 0,
912 AC_VERB_SET_POWER_STATE, parm);
913 }
914
915 /* Class-D */
916 /* PW0 (24h), MW0(18h), MUX0(34h) */
917 present = snd_hda_jack_detect(codec, 0x25);
918 parm = AC_PWRST_D3;
919 set_pin_power_state(codec, 0x24, &parm);
920 if (present) {
921 snd_hda_codec_write(
922 codec, 0x18, 0,
923 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
924 snd_hda_codec_write(
925 codec, 0x34, 0,
926 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
927 } else {
928 snd_hda_codec_write(
929 codec, 0x18, 0,
930 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
931 snd_hda_codec_write(
932 codec, 0x34, 0,
933 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
934 }
935
936 /* Mono Out */
937 /* PW15 (31h), MW8(17h), MUX8(3bh) */
938 present = snd_hda_jack_detect(codec, 0x26);
939 parm = AC_PWRST_D3;
940 set_pin_power_state(codec, 0x31, &parm);
941 if (present) {
942 snd_hda_codec_write(
943 codec, 0x17, 0,
944 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
945 snd_hda_codec_write(
946 codec, 0x3b, 0,
947 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
948 } else {
949 snd_hda_codec_write(
950 codec, 0x17, 0,
951 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
952 snd_hda_codec_write(
953 codec, 0x3b, 0,
954 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
955 }
956
957 /* MW9 (21h) */
958 if (imux_is_smixer || !is_aa_path_mute(codec))
959 snd_hda_codec_write(
960 codec, 0x21, 0,
961 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
962 else
963 snd_hda_codec_write(
964 codec, 0x21, 0,
965 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
966 } else if (spec->codec_type == VT1812) {
967 unsigned int present;
968 /* MUX10 (1eh) = stereo mixer */
969 imux_is_smixer = snd_hda_codec_read(
970 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
971 /* inputs */
972 /* PW 5/6/7 (29h/2ah/2bh) */
973 parm = AC_PWRST_D3;
974 set_pin_power_state(codec, 0x29, &parm);
975 set_pin_power_state(codec, 0x2a, &parm);
976 set_pin_power_state(codec, 0x2b, &parm);
977 if (imux_is_smixer)
978 parm = AC_PWRST_D0;
979 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
980 snd_hda_codec_write(codec, 0x1e, 0,
981 AC_VERB_SET_POWER_STATE, parm);
982 snd_hda_codec_write(codec, 0x1f, 0,
983 AC_VERB_SET_POWER_STATE, parm);
984 snd_hda_codec_write(codec, 0x10, 0,
985 AC_VERB_SET_POWER_STATE, parm);
986 snd_hda_codec_write(codec, 0x11, 0,
987 AC_VERB_SET_POWER_STATE, parm);
988
989 /* outputs */
990 /* AOW0 (8h)*/
991 snd_hda_codec_write(codec, 0x8, 0,
992 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
993
994 /* PW4 (28h), MW4 (18h), MUX4(38h) */
995 parm = AC_PWRST_D3;
996 set_pin_power_state(codec, 0x28, &parm);
997 snd_hda_codec_write(codec, 0x18, 0,
998 AC_VERB_SET_POWER_STATE, parm);
999 snd_hda_codec_write(codec, 0x38, 0,
1000 AC_VERB_SET_POWER_STATE, parm);
1001
1002 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
1003 parm = AC_PWRST_D3;
1004 set_pin_power_state(codec, 0x25, &parm);
1005 snd_hda_codec_write(codec, 0x15, 0,
1006 AC_VERB_SET_POWER_STATE, parm);
1007 snd_hda_codec_write(codec, 0x35, 0,
1008 AC_VERB_SET_POWER_STATE, parm);
1009 if (spec->hp_independent_mode) {
1010 snd_hda_codec_write(codec, 0x9, 0,
1011 AC_VERB_SET_POWER_STATE, parm);
1012 }
1013
1014 /* Internal Speaker */
1015 /* PW0 (24h), MW0(14h), MUX0(34h) */
1016 present = snd_hda_jack_detect(codec, 0x25);
1017 parm = AC_PWRST_D3;
1018 set_pin_power_state(codec, 0x24, &parm);
1019 if (present) {
1020 snd_hda_codec_write(codec, 0x14, 0,
1021 AC_VERB_SET_POWER_STATE,
1022 AC_PWRST_D3);
1023 snd_hda_codec_write(codec, 0x34, 0,
1024 AC_VERB_SET_POWER_STATE,
1025 AC_PWRST_D3);
1026 } else {
1027 snd_hda_codec_write(codec, 0x14, 0,
1028 AC_VERB_SET_POWER_STATE,
1029 AC_PWRST_D0);
1030 snd_hda_codec_write(codec, 0x34, 0,
1031 AC_VERB_SET_POWER_STATE,
1032 AC_PWRST_D0);
1033 }
1034 /* Mono Out */
1035 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
1036 present = snd_hda_jack_detect(codec, 0x28);
1037 parm = AC_PWRST_D3;
1038 set_pin_power_state(codec, 0x31, &parm);
1039 if (present) {
1040 snd_hda_codec_write(codec, 0x1c, 0,
1041 AC_VERB_SET_POWER_STATE,
1042 AC_PWRST_D3);
1043 snd_hda_codec_write(codec, 0x3c, 0,
1044 AC_VERB_SET_POWER_STATE,
1045 AC_PWRST_D3);
1046 snd_hda_codec_write(codec, 0x3e, 0,
1047 AC_VERB_SET_POWER_STATE,
1048 AC_PWRST_D3);
1049 } else {
1050 snd_hda_codec_write(codec, 0x1c, 0,
1051 AC_VERB_SET_POWER_STATE,
1052 AC_PWRST_D0);
1053 snd_hda_codec_write(codec, 0x3c, 0,
1054 AC_VERB_SET_POWER_STATE,
1055 AC_PWRST_D0);
1056 snd_hda_codec_write(codec, 0x3e, 0,
1057 AC_VERB_SET_POWER_STATE,
1058 AC_PWRST_D0);
1059 }
1060
1061 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
1062 parm = AC_PWRST_D3;
1063 set_pin_power_state(codec, 0x33, &parm);
1064 snd_hda_codec_write(codec, 0x1d, 0,
1065 AC_VERB_SET_POWER_STATE, parm);
1066 snd_hda_codec_write(codec, 0x3d, 0,
1067 AC_VERB_SET_POWER_STATE, parm);
1068
1069 /* MW9 (21h) */
1070 if (imux_is_smixer || !is_aa_path_mute(codec))
1071 snd_hda_codec_write(
1072 codec, 0x21, 0,
1073 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1074 else
1075 snd_hda_codec_write(
1076 codec, 0x21, 0,
1077 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1078 }
1079}
1080
1081/* 621/*
1082 * input MUX handling 622 * input MUX handling
1083 */ 623 */
@@ -1120,7 +660,7 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
1120 spec->mux_nids[adc_idx], 660 spec->mux_nids[adc_idx],
1121 &spec->cur_mux[adc_idx]); 661 &spec->cur_mux[adc_idx]);
1122 /* update jack power state */ 662 /* update jack power state */
1123 set_jack_power_state(codec); 663 set_widgets_power_state(codec);
1124 664
1125 return ret; 665 return ret;
1126} 666}
@@ -1168,6 +708,9 @@ static hda_nid_t side_mute_channel(struct via_spec *spec)
1168 case VT1709_10CH: return 0x29; 708 case VT1709_10CH: return 0x29;
1169 case VT1708B_8CH: /* fall thru */ 709 case VT1708B_8CH: /* fall thru */
1170 case VT1708S: return 0x27; 710 case VT1708S: return 0x27;
711 case VT2002P: return 0x19;
712 case VT1802: return 0x15;
713 case VT1812: return 0x15;
1171 default: return 0; 714 default: return 0;
1172 } 715 }
1173} 716}
@@ -1176,13 +719,22 @@ static int update_side_mute_status(struct hda_codec *codec)
1176{ 719{
1177 /* mute side channel */ 720 /* mute side channel */
1178 struct via_spec *spec = codec->spec; 721 struct via_spec *spec = codec->spec;
1179 unsigned int parm = spec->hp_independent_mode 722 unsigned int parm;
1180 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
1181 hda_nid_t sw3 = side_mute_channel(spec); 723 hda_nid_t sw3 = side_mute_channel(spec);
1182 724
1183 if (sw3) 725 if (sw3) {
1184 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE, 726 if (VT2002P_COMPATIBLE(spec))
1185 parm); 727 parm = spec->hp_independent_mode ?
728 AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1);
729 else
730 parm = spec->hp_independent_mode ?
731 AMP_OUT_MUTE : AMP_OUT_UNMUTE;
732 snd_hda_codec_write(codec, sw3, 0,
733 AC_VERB_SET_AMP_GAIN_MUTE, parm);
734 if (spec->codec_type == VT1812)
735 snd_hda_codec_write(codec, 0x1d, 0,
736 AC_VERB_SET_AMP_GAIN_MUTE, parm);
737 }
1186 return 0; 738 return 0;
1187} 739}
1188 740
@@ -1217,19 +769,18 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1217 || spec->codec_type == VT1702 769 || spec->codec_type == VT1702
1218 || spec->codec_type == VT1718S 770 || spec->codec_type == VT1718S
1219 || spec->codec_type == VT1716S 771 || spec->codec_type == VT1716S
1220 || spec->codec_type == VT2002P 772 || VT2002P_COMPATIBLE(spec)) {
1221 || spec->codec_type == VT1812) {
1222 activate_ctl(codec, "Headphone Playback Volume", 773 activate_ctl(codec, "Headphone Playback Volume",
1223 spec->hp_independent_mode); 774 spec->hp_independent_mode);
1224 activate_ctl(codec, "Headphone Playback Switch", 775 activate_ctl(codec, "Headphone Playback Switch",
1225 spec->hp_independent_mode); 776 spec->hp_independent_mode);
1226 } 777 }
1227 /* update jack power state */ 778 /* update jack power state */
1228 set_jack_power_state(codec); 779 set_widgets_power_state(codec);
1229 return 0; 780 return 0;
1230} 781}
1231 782
1232static struct snd_kcontrol_new via_hp_mixer[2] = { 783static const struct snd_kcontrol_new via_hp_mixer[2] = {
1233 { 784 {
1234 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1235 .name = "Independent HP", 786 .name = "Independent HP",
@@ -1256,6 +807,7 @@ static int via_hp_build(struct hda_codec *codec)
1256 nid = 0x34; 807 nid = 0x34;
1257 break; 808 break;
1258 case VT2002P: 809 case VT2002P:
810 case VT1802:
1259 nid = 0x35; 811 nid = 0x35;
1260 break; 812 break;
1261 case VT1812: 813 case VT1812:
@@ -1447,11 +999,11 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
1447 } 999 }
1448 } 1000 }
1449 spec->smart51_enabled = *ucontrol->value.integer.value; 1001 spec->smart51_enabled = *ucontrol->value.integer.value;
1450 set_jack_power_state(codec); 1002 set_widgets_power_state(codec);
1451 return 1; 1003 return 1;
1452} 1004}
1453 1005
1454static struct snd_kcontrol_new via_smart51_mixer[2] = { 1006static const struct snd_kcontrol_new via_smart51_mixer[2] = {
1455 { 1007 {
1456 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1008 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1457 .name = "Smart 5.1", 1009 .name = "Smart 5.1",
@@ -1473,6 +1025,11 @@ static int via_smart51_build(struct via_spec *spec)
1473 hda_nid_t nid; 1025 hda_nid_t nid;
1474 int i; 1026 int i;
1475 1027
1028 if (!cfg)
1029 return 0;
1030 if (cfg->line_outs > 2)
1031 return 0;
1032
1476 knew = via_clone_control(spec, &via_smart51_mixer[0]); 1033 knew = via_clone_control(spec, &via_smart51_mixer[0]);
1477 if (knew == NULL) 1034 if (knew == NULL)
1478 return -ENOMEM; 1035 return -ENOMEM;
@@ -1492,7 +1049,7 @@ static int via_smart51_build(struct via_spec *spec)
1492} 1049}
1493 1050
1494/* capture mixer elements */ 1051/* capture mixer elements */
1495static struct snd_kcontrol_new vt1708_capture_mixer[] = { 1052static const struct snd_kcontrol_new vt1708_capture_mixer[] = {
1496 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), 1053 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
1497 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT), 1054 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
1498 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT), 1055 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
@@ -1543,6 +1100,7 @@ static int is_aa_path_mute(struct hda_codec *codec)
1543 break; 1100 break;
1544 case VT2002P: 1101 case VT2002P:
1545 case VT1812: 1102 case VT1812:
1103 case VT1802:
1546 nid_mixer = 0x21; 1104 nid_mixer = 0x21;
1547 start_idx = 0; 1105 start_idx = 0;
1548 end_idx = 2; 1106 end_idx = 2;
@@ -1607,6 +1165,7 @@ static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1607 break; 1165 break;
1608 case VT2002P: 1166 case VT2002P:
1609 case VT1812: 1167 case VT1812:
1168 case VT1802:
1610 verb = 0xf93; 1169 verb = 0xf93;
1611 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */ 1170 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
1612 break; 1171 break;
@@ -1620,7 +1179,7 @@ static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1620/* 1179/*
1621 * generic initialization of ADC, input mixers and output mixers 1180 * generic initialization of ADC, input mixers and output mixers
1622 */ 1181 */
1623static struct hda_verb vt1708_volume_init_verbs[] = { 1182static const struct hda_verb vt1708_volume_init_verbs[] = {
1624 /* 1183 /*
1625 * Unmute ADC0-1 and set the default input to mic-in 1184 * Unmute ADC0-1 and set the default input to mic-in
1626 */ 1185 */
@@ -1650,6 +1209,8 @@ static struct hda_verb vt1708_volume_init_verbs[] = {
1650 {0x20, AC_VERB_SET_CONNECT_SEL, 0}, 1209 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
1651 /* PW9 Output enable */ 1210 /* PW9 Output enable */
1652 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 1211 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1212 /* power down jack detect function */
1213 {0x1, 0xf81, 0x1},
1653 { } 1214 { }
1654}; 1215};
1655 1216
@@ -1672,7 +1233,7 @@ static void playback_multi_pcm_prep_0(struct hda_codec *codec,
1672{ 1233{
1673 struct via_spec *spec = codec->spec; 1234 struct via_spec *spec = codec->spec;
1674 struct hda_multi_out *mout = &spec->multiout; 1235 struct hda_multi_out *mout = &spec->multiout;
1675 hda_nid_t *nids = mout->dac_nids; 1236 const hda_nid_t *nids = mout->dac_nids;
1676 int chs = substream->runtime->channels; 1237 int chs = substream->runtime->channels;
1677 int i; 1238 int i;
1678 1239
@@ -1741,7 +1302,7 @@ static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
1741{ 1302{
1742 struct via_spec *spec = codec->spec; 1303 struct via_spec *spec = codec->spec;
1743 struct hda_multi_out *mout = &spec->multiout; 1304 struct hda_multi_out *mout = &spec->multiout;
1744 hda_nid_t *nids = mout->dac_nids; 1305 const hda_nid_t *nids = mout->dac_nids;
1745 1306
1746 if (substream->number == 0) 1307 if (substream->number == 0)
1747 playback_multi_pcm_prep_0(codec, stream_tag, format, 1308 playback_multi_pcm_prep_0(codec, stream_tag, format,
@@ -1762,7 +1323,7 @@ static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
1762{ 1323{
1763 struct via_spec *spec = codec->spec; 1324 struct via_spec *spec = codec->spec;
1764 struct hda_multi_out *mout = &spec->multiout; 1325 struct hda_multi_out *mout = &spec->multiout;
1765 hda_nid_t *nids = mout->dac_nids; 1326 const hda_nid_t *nids = mout->dac_nids;
1766 int i; 1327 int i;
1767 1328
1768 if (substream->number == 0) { 1329 if (substream->number == 0) {
@@ -1860,7 +1421,7 @@ static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1860 return 0; 1421 return 0;
1861} 1422}
1862 1423
1863static struct hda_pcm_stream vt1708_pcm_analog_playback = { 1424static const struct hda_pcm_stream vt1708_pcm_analog_playback = {
1864 .substreams = 2, 1425 .substreams = 2,
1865 .channels_min = 2, 1426 .channels_min = 2,
1866 .channels_max = 8, 1427 .channels_max = 8,
@@ -1872,7 +1433,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_playback = {
1872 }, 1433 },
1873}; 1434};
1874 1435
1875static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = { 1436static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1876 .substreams = 2, 1437 .substreams = 2,
1877 .channels_min = 2, 1438 .channels_min = 2,
1878 .channels_max = 8, 1439 .channels_max = 8,
@@ -1889,7 +1450,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1889 }, 1450 },
1890}; 1451};
1891 1452
1892static struct hda_pcm_stream vt1708_pcm_analog_capture = { 1453static const struct hda_pcm_stream vt1708_pcm_analog_capture = {
1893 .substreams = 2, 1454 .substreams = 2,
1894 .channels_min = 2, 1455 .channels_min = 2,
1895 .channels_max = 2, 1456 .channels_max = 2,
@@ -1900,7 +1461,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_capture = {
1900 }, 1461 },
1901}; 1462};
1902 1463
1903static struct hda_pcm_stream vt1708_pcm_digital_playback = { 1464static const struct hda_pcm_stream vt1708_pcm_digital_playback = {
1904 .substreams = 1, 1465 .substreams = 1,
1905 .channels_min = 2, 1466 .channels_min = 2,
1906 .channels_max = 2, 1467 .channels_max = 2,
@@ -1913,7 +1474,7 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = {
1913 }, 1474 },
1914}; 1475};
1915 1476
1916static struct hda_pcm_stream vt1708_pcm_digital_capture = { 1477static const struct hda_pcm_stream vt1708_pcm_digital_capture = {
1917 .substreams = 1, 1478 .substreams = 1,
1918 .channels_min = 2, 1479 .channels_min = 2,
1919 .channels_max = 2, 1480 .channels_max = 2,
@@ -1923,7 +1484,7 @@ static int via_build_controls(struct hda_codec *codec)
1923{ 1484{
1924 struct via_spec *spec = codec->spec; 1485 struct via_spec *spec = codec->spec;
1925 struct snd_kcontrol *kctl; 1486 struct snd_kcontrol *kctl;
1926 struct snd_kcontrol_new *knew; 1487 const struct snd_kcontrol_new *knew;
1927 int err, i; 1488 int err, i;
1928 1489
1929 for (i = 0; i < spec->num_mixers; i++) { 1490 for (i = 0; i < spec->num_mixers; i++) {
@@ -1971,7 +1532,7 @@ static int via_build_controls(struct hda_codec *codec)
1971 } 1532 }
1972 1533
1973 /* init power states */ 1534 /* init power states */
1974 set_jack_power_state(codec); 1535 set_widgets_power_state(codec);
1975 analog_low_current_mode(codec, 1); 1536 analog_low_current_mode(codec, 1);
1976 1537
1977 via_free_kctls(codec); /* no longer needed */ 1538 via_free_kctls(codec); /* no longer needed */
@@ -2135,7 +1696,7 @@ static void via_speaker_automute(struct hda_codec *codec)
2135 unsigned int hp_present; 1696 unsigned int hp_present;
2136 struct via_spec *spec = codec->spec; 1697 struct via_spec *spec = codec->spec;
2137 1698
2138 if (spec->codec_type != VT2002P && spec->codec_type != VT1812) 1699 if (!VT2002P_COMPATIBLE(spec))
2139 return; 1700 return;
2140 1701
2141 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); 1702 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
@@ -2194,17 +1755,21 @@ static void via_unsol_event(struct hda_codec *codec,
2194 unsigned int res) 1755 unsigned int res)
2195{ 1756{
2196 res >>= 26; 1757 res >>= 26;
2197 if (res & VIA_HP_EVENT) 1758
1759 if (res & VIA_JACK_EVENT)
1760 set_widgets_power_state(codec);
1761
1762 res &= ~VIA_JACK_EVENT;
1763
1764 if (res == VIA_HP_EVENT)
2198 via_hp_automute(codec); 1765 via_hp_automute(codec);
2199 if (res & VIA_GPIO_EVENT) 1766 else if (res == VIA_GPIO_EVENT)
2200 via_gpio_control(codec); 1767 via_gpio_control(codec);
2201 if (res & VIA_JACK_EVENT) 1768 else if (res == VIA_MONO_EVENT)
2202 set_jack_power_state(codec);
2203 if (res & VIA_MONO_EVENT)
2204 via_mono_automute(codec); 1769 via_mono_automute(codec);
2205 if (res & VIA_SPEAKER_EVENT) 1770 else if (res == VIA_SPEAKER_EVENT)
2206 via_speaker_automute(codec); 1771 via_speaker_automute(codec);
2207 if (res & VIA_BIND_HP_EVENT) 1772 else if (res == VIA_BIND_HP_EVENT)
2208 via_hp_bind_automute(codec); 1773 via_hp_bind_automute(codec);
2209} 1774}
2210 1775
@@ -2254,7 +1819,7 @@ static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2254 1819
2255/* 1820/*
2256 */ 1821 */
2257static struct hda_codec_ops via_patch_ops = { 1822static const struct hda_codec_ops via_patch_ops = {
2258 .build_controls = via_build_controls, 1823 .build_controls = via_build_controls,
2259 .build_pcms = via_build_pcms, 1824 .build_pcms = via_build_pcms,
2260 .init = via_init, 1825 .init = via_init,
@@ -2284,16 +1849,16 @@ static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
2284 /* config dac list */ 1849 /* config dac list */
2285 switch (i) { 1850 switch (i) {
2286 case AUTO_SEQ_FRONT: 1851 case AUTO_SEQ_FRONT:
2287 spec->multiout.dac_nids[i] = 0x10; 1852 spec->private_dac_nids[i] = 0x10;
2288 break; 1853 break;
2289 case AUTO_SEQ_CENLFE: 1854 case AUTO_SEQ_CENLFE:
2290 spec->multiout.dac_nids[i] = 0x12; 1855 spec->private_dac_nids[i] = 0x12;
2291 break; 1856 break;
2292 case AUTO_SEQ_SURROUND: 1857 case AUTO_SEQ_SURROUND:
2293 spec->multiout.dac_nids[i] = 0x11; 1858 spec->private_dac_nids[i] = 0x11;
2294 break; 1859 break;
2295 case AUTO_SEQ_SIDE: 1860 case AUTO_SEQ_SIDE:
2296 spec->multiout.dac_nids[i] = 0x13; 1861 spec->private_dac_nids[i] = 0x13;
2297 break; 1862 break;
2298 } 1863 }
2299 } 1864 }
@@ -2437,7 +2002,8 @@ static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2437static int vt_auto_create_analog_input_ctls(struct hda_codec *codec, 2002static int vt_auto_create_analog_input_ctls(struct hda_codec *codec,
2438 const struct auto_pin_cfg *cfg, 2003 const struct auto_pin_cfg *cfg,
2439 hda_nid_t cap_nid, 2004 hda_nid_t cap_nid,
2440 hda_nid_t pin_idxs[], int num_idxs) 2005 const hda_nid_t pin_idxs[],
2006 int num_idxs)
2441{ 2007{
2442 struct via_spec *spec = codec->spec; 2008 struct via_spec *spec = codec->spec;
2443 struct hda_input_mux *imux = &spec->private_imux[0]; 2009 struct hda_input_mux *imux = &spec->private_imux[0];
@@ -2483,13 +2049,13 @@ static int vt_auto_create_analog_input_ctls(struct hda_codec *codec,
2483static int vt1708_auto_create_analog_input_ctls(struct hda_codec *codec, 2049static int vt1708_auto_create_analog_input_ctls(struct hda_codec *codec,
2484 const struct auto_pin_cfg *cfg) 2050 const struct auto_pin_cfg *cfg)
2485{ 2051{
2486 static hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 }; 2052 static const hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 };
2487 return vt_auto_create_analog_input_ctls(codec, cfg, 0x17, pin_idxs, 2053 return vt_auto_create_analog_input_ctls(codec, cfg, 0x17, pin_idxs,
2488 ARRAY_SIZE(pin_idxs)); 2054 ARRAY_SIZE(pin_idxs));
2489} 2055}
2490 2056
2491#ifdef CONFIG_SND_HDA_POWER_SAVE 2057#ifdef CONFIG_SND_HDA_POWER_SAVE
2492static struct hda_amp_list vt1708_loopbacks[] = { 2058static const struct hda_amp_list vt1708_loopbacks[] = {
2493 { 0x17, HDA_INPUT, 1 }, 2059 { 0x17, HDA_INPUT, 1 },
2494 { 0x17, HDA_INPUT, 2 }, 2060 { 0x17, HDA_INPUT, 2 },
2495 { 0x17, HDA_INPUT, 3 }, 2061 { 0x17, HDA_INPUT, 3 },
@@ -2548,7 +2114,7 @@ static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol,
2548 return change; 2114 return change;
2549} 2115}
2550 2116
2551static struct snd_kcontrol_new vt1708_jack_detectect[] = { 2117static const struct snd_kcontrol_new vt1708_jack_detectect[] = {
2552 { 2118 {
2553 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2119 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2554 .name = "Jack Detect", 2120 .name = "Jack Detect",
@@ -2623,7 +2189,8 @@ static int via_auto_init(struct hda_codec *codec)
2623 via_auto_init_multi_out(codec); 2189 via_auto_init_multi_out(codec);
2624 via_auto_init_hp_out(codec); 2190 via_auto_init_hp_out(codec);
2625 via_auto_init_analog_input(codec); 2191 via_auto_init_analog_input(codec);
2626 if (spec->codec_type == VT2002P || spec->codec_type == VT1812) { 2192
2193 if (VT2002P_COMPATIBLE(spec)) {
2627 via_hp_bind_automute(codec); 2194 via_hp_bind_automute(codec);
2628 } else { 2195 } else {
2629 via_hp_automute(codec); 2196 via_hp_automute(codec);
@@ -2727,7 +2294,7 @@ static int patch_vt1708(struct hda_codec *codec)
2727} 2294}
2728 2295
2729/* capture mixer elements */ 2296/* capture mixer elements */
2730static struct snd_kcontrol_new vt1709_capture_mixer[] = { 2297static const struct snd_kcontrol_new vt1709_capture_mixer[] = {
2731 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT), 2298 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
2732 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT), 2299 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
2733 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT), 2300 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
@@ -2749,7 +2316,7 @@ static struct snd_kcontrol_new vt1709_capture_mixer[] = {
2749 { } /* end */ 2316 { } /* end */
2750}; 2317};
2751 2318
2752static struct hda_verb vt1709_uniwill_init_verbs[] = { 2319static const struct hda_verb vt1709_uniwill_init_verbs[] = {
2753 {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 2320 {0x20, AC_VERB_SET_UNSOLICITED_ENABLE,
2754 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 2321 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
2755 { } 2322 { }
@@ -2758,7 +2325,7 @@ static struct hda_verb vt1709_uniwill_init_verbs[] = {
2758/* 2325/*
2759 * generic initialization of ADC, input mixers and output mixers 2326 * generic initialization of ADC, input mixers and output mixers
2760 */ 2327 */
2761static struct hda_verb vt1709_10ch_volume_init_verbs[] = { 2328static const struct hda_verb vt1709_10ch_volume_init_verbs[] = {
2762 /* 2329 /*
2763 * Unmute ADC0-2 and set the default input to mic-in 2330 * Unmute ADC0-2 and set the default input to mic-in
2764 */ 2331 */
@@ -2798,7 +2365,7 @@ static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
2798 { } 2365 { }
2799}; 2366};
2800 2367
2801static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = { 2368static const struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
2802 .substreams = 1, 2369 .substreams = 1,
2803 .channels_min = 2, 2370 .channels_min = 2,
2804 .channels_max = 10, 2371 .channels_max = 10,
@@ -2810,7 +2377,7 @@ static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
2810 }, 2377 },
2811}; 2378};
2812 2379
2813static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = { 2380static const struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
2814 .substreams = 1, 2381 .substreams = 1,
2815 .channels_min = 2, 2382 .channels_min = 2,
2816 .channels_max = 6, 2383 .channels_max = 6,
@@ -2822,7 +2389,7 @@ static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
2822 }, 2389 },
2823}; 2390};
2824 2391
2825static struct hda_pcm_stream vt1709_pcm_analog_capture = { 2392static const struct hda_pcm_stream vt1709_pcm_analog_capture = {
2826 .substreams = 2, 2393 .substreams = 2,
2827 .channels_min = 2, 2394 .channels_min = 2,
2828 .channels_max = 2, 2395 .channels_max = 2,
@@ -2833,7 +2400,7 @@ static struct hda_pcm_stream vt1709_pcm_analog_capture = {
2833 }, 2400 },
2834}; 2401};
2835 2402
2836static struct hda_pcm_stream vt1709_pcm_digital_playback = { 2403static const struct hda_pcm_stream vt1709_pcm_digital_playback = {
2837 .substreams = 1, 2404 .substreams = 1,
2838 .channels_min = 2, 2405 .channels_min = 2,
2839 .channels_max = 2, 2406 .channels_max = 2,
@@ -2844,7 +2411,7 @@ static struct hda_pcm_stream vt1709_pcm_digital_playback = {
2844 }, 2411 },
2845}; 2412};
2846 2413
2847static struct hda_pcm_stream vt1709_pcm_digital_capture = { 2414static const struct hda_pcm_stream vt1709_pcm_digital_capture = {
2848 .substreams = 1, 2415 .substreams = 1,
2849 .channels_min = 2, 2416 .channels_min = 2,
2850 .channels_max = 2, 2417 .channels_max = 2,
@@ -2871,26 +2438,26 @@ static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
2871 switch (i) { 2438 switch (i) {
2872 case AUTO_SEQ_FRONT: 2439 case AUTO_SEQ_FRONT:
2873 /* AOW0 */ 2440 /* AOW0 */
2874 spec->multiout.dac_nids[i] = 0x10; 2441 spec->private_dac_nids[i] = 0x10;
2875 break; 2442 break;
2876 case AUTO_SEQ_CENLFE: 2443 case AUTO_SEQ_CENLFE:
2877 /* AOW2 */ 2444 /* AOW2 */
2878 spec->multiout.dac_nids[i] = 0x12; 2445 spec->private_dac_nids[i] = 0x12;
2879 break; 2446 break;
2880 case AUTO_SEQ_SURROUND: 2447 case AUTO_SEQ_SURROUND:
2881 /* AOW3 */ 2448 /* AOW3 */
2882 spec->multiout.dac_nids[i] = 0x11; 2449 spec->private_dac_nids[i] = 0x11;
2883 break; 2450 break;
2884 case AUTO_SEQ_SIDE: 2451 case AUTO_SEQ_SIDE:
2885 /* AOW1 */ 2452 /* AOW1 */
2886 spec->multiout.dac_nids[i] = 0x27; 2453 spec->private_dac_nids[i] = 0x27;
2887 break; 2454 break;
2888 default: 2455 default:
2889 break; 2456 break;
2890 } 2457 }
2891 } 2458 }
2892 } 2459 }
2893 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */ 2460 spec->private_dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
2894 2461
2895 } else if (cfg->line_outs == 3) { /* 6 channels */ 2462 } else if (cfg->line_outs == 3) { /* 6 channels */
2896 for (i = 0; i < cfg->line_outs; i++) { 2463 for (i = 0; i < cfg->line_outs; i++) {
@@ -2900,15 +2467,15 @@ static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
2900 switch (i) { 2467 switch (i) {
2901 case AUTO_SEQ_FRONT: 2468 case AUTO_SEQ_FRONT:
2902 /* AOW0 */ 2469 /* AOW0 */
2903 spec->multiout.dac_nids[i] = 0x10; 2470 spec->private_dac_nids[i] = 0x10;
2904 break; 2471 break;
2905 case AUTO_SEQ_CENLFE: 2472 case AUTO_SEQ_CENLFE:
2906 /* AOW2 */ 2473 /* AOW2 */
2907 spec->multiout.dac_nids[i] = 0x12; 2474 spec->private_dac_nids[i] = 0x12;
2908 break; 2475 break;
2909 case AUTO_SEQ_SURROUND: 2476 case AUTO_SEQ_SURROUND:
2910 /* AOW1 */ 2477 /* AOW1 */
2911 spec->multiout.dac_nids[i] = 0x11; 2478 spec->private_dac_nids[i] = 0x11;
2912 break; 2479 break;
2913 default: 2480 default:
2914 break; 2481 break;
@@ -3056,7 +2623,7 @@ static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3056static int vt1709_auto_create_analog_input_ctls(struct hda_codec *codec, 2623static int vt1709_auto_create_analog_input_ctls(struct hda_codec *codec,
3057 const struct auto_pin_cfg *cfg) 2624 const struct auto_pin_cfg *cfg)
3058{ 2625{
3059 static hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 }; 2626 static const hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 };
3060 return vt_auto_create_analog_input_ctls(codec, cfg, 0x18, pin_idxs, 2627 return vt_auto_create_analog_input_ctls(codec, cfg, 0x18, pin_idxs,
3061 ARRAY_SIZE(pin_idxs)); 2628 ARRAY_SIZE(pin_idxs));
3062} 2629}
@@ -3106,7 +2673,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
3106} 2673}
3107 2674
3108#ifdef CONFIG_SND_HDA_POWER_SAVE 2675#ifdef CONFIG_SND_HDA_POWER_SAVE
3109static struct hda_amp_list vt1709_loopbacks[] = { 2676static const struct hda_amp_list vt1709_loopbacks[] = {
3110 { 0x18, HDA_INPUT, 1 }, 2677 { 0x18, HDA_INPUT, 1 },
3111 { 0x18, HDA_INPUT, 2 }, 2678 { 0x18, HDA_INPUT, 2 },
3112 { 0x18, HDA_INPUT, 3 }, 2679 { 0x18, HDA_INPUT, 3 },
@@ -3167,7 +2734,7 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
3167/* 2734/*
3168 * generic initialization of ADC, input mixers and output mixers 2735 * generic initialization of ADC, input mixers and output mixers
3169 */ 2736 */
3170static struct hda_verb vt1709_6ch_volume_init_verbs[] = { 2737static const struct hda_verb vt1709_6ch_volume_init_verbs[] = {
3171 /* 2738 /*
3172 * Unmute ADC0-2 and set the default input to mic-in 2739 * Unmute ADC0-2 and set the default input to mic-in
3173 */ 2740 */
@@ -3257,7 +2824,7 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
3257} 2824}
3258 2825
3259/* capture mixer elements */ 2826/* capture mixer elements */
3260static struct snd_kcontrol_new vt1708B_capture_mixer[] = { 2827static const struct snd_kcontrol_new vt1708B_capture_mixer[] = {
3261 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), 2828 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3262 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), 2829 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3263 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), 2830 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
@@ -3279,7 +2846,7 @@ static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
3279/* 2846/*
3280 * generic initialization of ADC, input mixers and output mixers 2847 * generic initialization of ADC, input mixers and output mixers
3281 */ 2848 */
3282static struct hda_verb vt1708B_8ch_volume_init_verbs[] = { 2849static const struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
3283 /* 2850 /*
3284 * Unmute ADC0-1 and set the default input to mic-in 2851 * Unmute ADC0-1 and set the default input to mic-in
3285 */ 2852 */
@@ -3314,7 +2881,7 @@ static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
3314 { } 2881 { }
3315}; 2882};
3316 2883
3317static struct hda_verb vt1708B_4ch_volume_init_verbs[] = { 2884static const struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
3318 /* 2885 /*
3319 * Unmute ADC0-1 and set the default input to mic-in 2886 * Unmute ADC0-1 and set the default input to mic-in
3320 */ 2887 */
@@ -3349,7 +2916,7 @@ static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
3349 { } 2916 { }
3350}; 2917};
3351 2918
3352static struct hda_verb vt1708B_uniwill_init_verbs[] = { 2919static const struct hda_verb vt1708B_uniwill_init_verbs[] = {
3353 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 2920 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3354 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 2921 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3355 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 2922 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
@@ -3373,7 +2940,7 @@ static int via_pcm_open_close(struct hda_pcm_stream *hinfo,
3373 return 0; 2940 return 0;
3374} 2941}
3375 2942
3376static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { 2943static const struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
3377 .substreams = 2, 2944 .substreams = 2,
3378 .channels_min = 2, 2945 .channels_min = 2,
3379 .channels_max = 8, 2946 .channels_max = 8,
@@ -3386,7 +2953,7 @@ static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
3386 }, 2953 },
3387}; 2954};
3388 2955
3389static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = { 2956static const struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
3390 .substreams = 2, 2957 .substreams = 2,
3391 .channels_min = 2, 2958 .channels_min = 2,
3392 .channels_max = 4, 2959 .channels_max = 4,
@@ -3398,7 +2965,7 @@ static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
3398 }, 2965 },
3399}; 2966};
3400 2967
3401static struct hda_pcm_stream vt1708B_pcm_analog_capture = { 2968static const struct hda_pcm_stream vt1708B_pcm_analog_capture = {
3402 .substreams = 2, 2969 .substreams = 2,
3403 .channels_min = 2, 2970 .channels_min = 2,
3404 .channels_max = 2, 2971 .channels_max = 2,
@@ -3411,7 +2978,7 @@ static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
3411 }, 2978 },
3412}; 2979};
3413 2980
3414static struct hda_pcm_stream vt1708B_pcm_digital_playback = { 2981static const struct hda_pcm_stream vt1708B_pcm_digital_playback = {
3415 .substreams = 1, 2982 .substreams = 1,
3416 .channels_min = 2, 2983 .channels_min = 2,
3417 .channels_max = 2, 2984 .channels_max = 2,
@@ -3424,7 +2991,7 @@ static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
3424 }, 2991 },
3425}; 2992};
3426 2993
3427static struct hda_pcm_stream vt1708B_pcm_digital_capture = { 2994static const struct hda_pcm_stream vt1708B_pcm_digital_capture = {
3428 .substreams = 1, 2995 .substreams = 1,
3429 .channels_min = 2, 2996 .channels_min = 2,
3430 .channels_max = 2, 2997 .channels_max = 2,
@@ -3447,16 +3014,16 @@ static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
3447 /* config dac list */ 3014 /* config dac list */
3448 switch (i) { 3015 switch (i) {
3449 case AUTO_SEQ_FRONT: 3016 case AUTO_SEQ_FRONT:
3450 spec->multiout.dac_nids[i] = 0x10; 3017 spec->private_dac_nids[i] = 0x10;
3451 break; 3018 break;
3452 case AUTO_SEQ_CENLFE: 3019 case AUTO_SEQ_CENLFE:
3453 spec->multiout.dac_nids[i] = 0x24; 3020 spec->private_dac_nids[i] = 0x24;
3454 break; 3021 break;
3455 case AUTO_SEQ_SURROUND: 3022 case AUTO_SEQ_SURROUND:
3456 spec->multiout.dac_nids[i] = 0x11; 3023 spec->private_dac_nids[i] = 0x11;
3457 break; 3024 break;
3458 case AUTO_SEQ_SIDE: 3025 case AUTO_SEQ_SIDE:
3459 spec->multiout.dac_nids[i] = 0x25; 3026 spec->private_dac_nids[i] = 0x25;
3460 break; 3027 break;
3461 } 3028 }
3462 } 3029 }
@@ -3588,7 +3155,7 @@ static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3588static int vt1708B_auto_create_analog_input_ctls(struct hda_codec *codec, 3155static int vt1708B_auto_create_analog_input_ctls(struct hda_codec *codec,
3589 const struct auto_pin_cfg *cfg) 3156 const struct auto_pin_cfg *cfg)
3590{ 3157{
3591 static hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e }; 3158 static const hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e };
3592 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs, 3159 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
3593 ARRAY_SIZE(pin_idxs)); 3160 ARRAY_SIZE(pin_idxs));
3594} 3161}
@@ -3638,7 +3205,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
3638} 3205}
3639 3206
3640#ifdef CONFIG_SND_HDA_POWER_SAVE 3207#ifdef CONFIG_SND_HDA_POWER_SAVE
3641static struct hda_amp_list vt1708B_loopbacks[] = { 3208static const struct hda_amp_list vt1708B_loopbacks[] = {
3642 { 0x16, HDA_INPUT, 1 }, 3209 { 0x16, HDA_INPUT, 1 },
3643 { 0x16, HDA_INPUT, 2 }, 3210 { 0x16, HDA_INPUT, 2 },
3644 { 0x16, HDA_INPUT, 3 }, 3211 { 0x16, HDA_INPUT, 3 },
@@ -3646,6 +3213,87 @@ static struct hda_amp_list vt1708B_loopbacks[] = {
3646 { } /* end */ 3213 { } /* end */
3647}; 3214};
3648#endif 3215#endif
3216
3217static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
3218{
3219 struct via_spec *spec = codec->spec;
3220 int imux_is_smixer;
3221 unsigned int parm;
3222 int is_8ch = 0;
3223 if ((spec->codec_type != VT1708B_4CH) &&
3224 (codec->vendor_id != 0x11064397))
3225 is_8ch = 1;
3226
3227 /* SW0 (17h) = stereo mixer */
3228 imux_is_smixer =
3229 (snd_hda_codec_read(codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
3230 == ((spec->codec_type == VT1708S) ? 5 : 0));
3231 /* inputs */
3232 /* PW 1/2/5 (1ah/1bh/1eh) */
3233 parm = AC_PWRST_D3;
3234 set_pin_power_state(codec, 0x1a, &parm);
3235 set_pin_power_state(codec, 0x1b, &parm);
3236 set_pin_power_state(codec, 0x1e, &parm);
3237 if (imux_is_smixer)
3238 parm = AC_PWRST_D0;
3239 /* SW0 (17h), AIW 0/1 (13h/14h) */
3240 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
3241 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
3242 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
3243
3244 /* outputs */
3245 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
3246 parm = AC_PWRST_D3;
3247 set_pin_power_state(codec, 0x19, &parm);
3248 if (spec->smart51_enabled)
3249 set_pin_power_state(codec, 0x1b, &parm);
3250 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
3251 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
3252
3253 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
3254 if (is_8ch) {
3255 parm = AC_PWRST_D3;
3256 set_pin_power_state(codec, 0x22, &parm);
3257 if (spec->smart51_enabled)
3258 set_pin_power_state(codec, 0x1a, &parm);
3259 snd_hda_codec_write(codec, 0x26, 0,
3260 AC_VERB_SET_POWER_STATE, parm);
3261 snd_hda_codec_write(codec, 0x24, 0,
3262 AC_VERB_SET_POWER_STATE, parm);
3263 } else if (codec->vendor_id == 0x11064397) {
3264 /* PW7(23h), SW2(27h), AOW2(25h) */
3265 parm = AC_PWRST_D3;
3266 set_pin_power_state(codec, 0x23, &parm);
3267 if (spec->smart51_enabled)
3268 set_pin_power_state(codec, 0x1a, &parm);
3269 snd_hda_codec_write(codec, 0x27, 0,
3270 AC_VERB_SET_POWER_STATE, parm);
3271 snd_hda_codec_write(codec, 0x25, 0,
3272 AC_VERB_SET_POWER_STATE, parm);
3273 }
3274
3275 /* PW 3/4/7 (1ch/1dh/23h) */
3276 parm = AC_PWRST_D3;
3277 /* force to D0 for internal Speaker */
3278 set_pin_power_state(codec, 0x1c, &parm);
3279 set_pin_power_state(codec, 0x1d, &parm);
3280 if (is_8ch)
3281 set_pin_power_state(codec, 0x23, &parm);
3282
3283 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
3284 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
3285 imux_is_smixer ? AC_PWRST_D0 : parm);
3286 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
3287 if (is_8ch) {
3288 snd_hda_codec_write(codec, 0x25, 0,
3289 AC_VERB_SET_POWER_STATE, parm);
3290 snd_hda_codec_write(codec, 0x27, 0,
3291 AC_VERB_SET_POWER_STATE, parm);
3292 } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode)
3293 snd_hda_codec_write(codec, 0x25, 0,
3294 AC_VERB_SET_POWER_STATE, parm);
3295}
3296
3649static int patch_vt1708S(struct hda_codec *codec); 3297static int patch_vt1708S(struct hda_codec *codec);
3650static int patch_vt1708B_8ch(struct hda_codec *codec) 3298static int patch_vt1708B_8ch(struct hda_codec *codec)
3651{ 3299{
@@ -3696,6 +3344,8 @@ static int patch_vt1708B_8ch(struct hda_codec *codec)
3696 spec->loopback.amplist = vt1708B_loopbacks; 3344 spec->loopback.amplist = vt1708B_loopbacks;
3697#endif 3345#endif
3698 3346
3347 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
3348
3699 return 0; 3349 return 0;
3700} 3350}
3701 3351
@@ -3746,13 +3396,15 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
3746 spec->loopback.amplist = vt1708B_loopbacks; 3396 spec->loopback.amplist = vt1708B_loopbacks;
3747#endif 3397#endif
3748 3398
3399 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
3400
3749 return 0; 3401 return 0;
3750} 3402}
3751 3403
3752/* Patch for VT1708S */ 3404/* Patch for VT1708S */
3753 3405
3754/* capture mixer elements */ 3406/* capture mixer elements */
3755static struct snd_kcontrol_new vt1708S_capture_mixer[] = { 3407static const struct snd_kcontrol_new vt1708S_capture_mixer[] = {
3756 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), 3408 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3757 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), 3409 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3758 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), 3410 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
@@ -3775,7 +3427,7 @@ static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
3775 { } /* end */ 3427 { } /* end */
3776}; 3428};
3777 3429
3778static struct hda_verb vt1708S_volume_init_verbs[] = { 3430static const struct hda_verb vt1708S_volume_init_verbs[] = {
3779 /* Unmute ADC0-1 and set the default input to mic-in */ 3431 /* Unmute ADC0-1 and set the default input to mic-in */
3780 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3432 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3781 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3433 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -3801,7 +3453,7 @@ static struct hda_verb vt1708S_volume_init_verbs[] = {
3801 { } 3453 { }
3802}; 3454};
3803 3455
3804static struct hda_verb vt1708S_uniwill_init_verbs[] = { 3456static const struct hda_verb vt1708S_uniwill_init_verbs[] = {
3805 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 3457 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3806 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 3458 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3807 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3459 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
@@ -3814,7 +3466,19 @@ static struct hda_verb vt1708S_uniwill_init_verbs[] = {
3814 { } 3466 { }
3815}; 3467};
3816 3468
3817static struct hda_pcm_stream vt1708S_pcm_analog_playback = { 3469static const struct hda_verb vt1705_uniwill_init_verbs[] = {
3470 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3471 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3472 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3473 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3474 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3475 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3476 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3477 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3478 { }
3479};
3480
3481static const struct hda_pcm_stream vt1708S_pcm_analog_playback = {
3818 .substreams = 2, 3482 .substreams = 2,
3819 .channels_min = 2, 3483 .channels_min = 2,
3820 .channels_max = 8, 3484 .channels_max = 8,
@@ -3827,7 +3491,20 @@ static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
3827 }, 3491 },
3828}; 3492};
3829 3493
3830static struct hda_pcm_stream vt1708S_pcm_analog_capture = { 3494static const struct hda_pcm_stream vt1705_pcm_analog_playback = {
3495 .substreams = 2,
3496 .channels_min = 2,
3497 .channels_max = 6,
3498 .nid = 0x10, /* NID to query formats and rates */
3499 .ops = {
3500 .open = via_playback_pcm_open,
3501 .prepare = via_playback_multi_pcm_prepare,
3502 .cleanup = via_playback_multi_pcm_cleanup,
3503 .close = via_pcm_open_close
3504 },
3505};
3506
3507static const struct hda_pcm_stream vt1708S_pcm_analog_capture = {
3831 .substreams = 2, 3508 .substreams = 2,
3832 .channels_min = 2, 3509 .channels_min = 2,
3833 .channels_max = 2, 3510 .channels_max = 2,
@@ -3840,7 +3517,7 @@ static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
3840 }, 3517 },
3841}; 3518};
3842 3519
3843static struct hda_pcm_stream vt1708S_pcm_digital_playback = { 3520static const struct hda_pcm_stream vt1708S_pcm_digital_playback = {
3844 .substreams = 1, 3521 .substreams = 1,
3845 .channels_min = 2, 3522 .channels_min = 2,
3846 .channels_max = 2, 3523 .channels_max = 2,
@@ -3870,16 +3547,19 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
3870 /* config dac list */ 3547 /* config dac list */
3871 switch (i) { 3548 switch (i) {
3872 case AUTO_SEQ_FRONT: 3549 case AUTO_SEQ_FRONT:
3873 spec->multiout.dac_nids[i] = 0x10; 3550 spec->private_dac_nids[i] = 0x10;
3874 break; 3551 break;
3875 case AUTO_SEQ_CENLFE: 3552 case AUTO_SEQ_CENLFE:
3876 spec->multiout.dac_nids[i] = 0x24; 3553 if (spec->codec->vendor_id == 0x11064397)
3554 spec->private_dac_nids[i] = 0x25;
3555 else
3556 spec->private_dac_nids[i] = 0x24;
3877 break; 3557 break;
3878 case AUTO_SEQ_SURROUND: 3558 case AUTO_SEQ_SURROUND:
3879 spec->multiout.dac_nids[i] = 0x11; 3559 spec->private_dac_nids[i] = 0x11;
3880 break; 3560 break;
3881 case AUTO_SEQ_SIDE: 3561 case AUTO_SEQ_SIDE:
3882 spec->multiout.dac_nids[i] = 0x25; 3562 spec->private_dac_nids[i] = 0x25;
3883 break; 3563 break;
3884 } 3564 }
3885 } 3565 }
@@ -3888,23 +3568,29 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
3888 /* for Smart 5.1, line/mic inputs double as output pins */ 3568 /* for Smart 5.1, line/mic inputs double as output pins */
3889 if (cfg->line_outs == 1) { 3569 if (cfg->line_outs == 1) {
3890 spec->multiout.num_dacs = 3; 3570 spec->multiout.num_dacs = 3;
3891 spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11; 3571 spec->private_dac_nids[AUTO_SEQ_SURROUND] = 0x11;
3892 spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24; 3572 if (spec->codec->vendor_id == 0x11064397)
3573 spec->private_dac_nids[AUTO_SEQ_CENLFE] = 0x25;
3574 else
3575 spec->private_dac_nids[AUTO_SEQ_CENLFE] = 0x24;
3893 } 3576 }
3894 3577
3895 return 0; 3578 return 0;
3896} 3579}
3897 3580
3898/* add playback controls from the parsed DAC table */ 3581/* add playback controls from the parsed DAC table */
3899static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, 3582static int vt1708S_auto_create_multi_out_ctls(struct hda_codec *codec,
3900 const struct auto_pin_cfg *cfg) 3583 const struct auto_pin_cfg *cfg)
3901{ 3584{
3585 struct via_spec *spec = codec->spec;
3902 char name[32]; 3586 char name[32];
3903 static const char * const chname[4] = { 3587 static const char * const chname[4] = {
3904 "Front", "Surround", "C/LFE", "Side" 3588 "Front", "Surround", "C/LFE", "Side"
3905 }; 3589 };
3906 hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25}; 3590 hda_nid_t nid_vols[2][4] = { {0x10, 0x11, 0x24, 0x25},
3907 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27}; 3591 {0x10, 0x11, 0x25, 0} };
3592 hda_nid_t nid_mutes[2][4] = { {0x1C, 0x18, 0x26, 0x27},
3593 {0x1C, 0x18, 0x27, 0} };
3908 hda_nid_t nid, nid_vol, nid_mute; 3594 hda_nid_t nid, nid_vol, nid_mute;
3909 int i, err; 3595 int i, err;
3910 3596
@@ -3915,8 +3601,15 @@ static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
3915 if (!nid && i > AUTO_SEQ_CENLFE) 3601 if (!nid && i > AUTO_SEQ_CENLFE)
3916 continue; 3602 continue;
3917 3603
3918 nid_vol = nid_vols[i]; 3604 if (codec->vendor_id == 0x11064397) {
3919 nid_mute = nid_mutes[i]; 3605 nid_vol = nid_vols[1][i];
3606 nid_mute = nid_mutes[1][i];
3607 } else {
3608 nid_vol = nid_vols[0][i];
3609 nid_mute = nid_mutes[0][i];
3610 }
3611 if (!nid_vol && !nid_mute)
3612 continue;
3920 3613
3921 if (i == AUTO_SEQ_CENLFE) { 3614 if (i == AUTO_SEQ_CENLFE) {
3922 /* Center/LFE */ 3615 /* Center/LFE */
@@ -4026,7 +3719,7 @@ static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4026static int vt1708S_auto_create_analog_input_ctls(struct hda_codec *codec, 3719static int vt1708S_auto_create_analog_input_ctls(struct hda_codec *codec,
4027 const struct auto_pin_cfg *cfg) 3720 const struct auto_pin_cfg *cfg)
4028{ 3721{
4029 static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff }; 3722 static const hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
4030 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs, 3723 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
4031 ARRAY_SIZE(pin_idxs)); 3724 ARRAY_SIZE(pin_idxs));
4032} 3725}
@@ -4070,7 +3763,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
4070 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 3763 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4071 return 0; /* can't find valid BIOS pin config */ 3764 return 0; /* can't find valid BIOS pin config */
4072 3765
4073 err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg); 3766 err = vt1708S_auto_create_multi_out_ctls(codec, &spec->autocfg);
4074 if (err < 0) 3767 if (err < 0)
4075 return err; 3768 return err;
4076 err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 3769 err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
@@ -4097,7 +3790,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
4097} 3790}
4098 3791
4099#ifdef CONFIG_SND_HDA_POWER_SAVE 3792#ifdef CONFIG_SND_HDA_POWER_SAVE
4100static struct hda_amp_list vt1708S_loopbacks[] = { 3793static const struct hda_amp_list vt1708S_loopbacks[] = {
4101 { 0x16, HDA_INPUT, 1 }, 3794 { 0x16, HDA_INPUT, 1 },
4102 { 0x16, HDA_INPUT, 2 }, 3795 { 0x16, HDA_INPUT, 2 },
4103 { 0x16, HDA_INPUT, 3 }, 3796 { 0x16, HDA_INPUT, 3 },
@@ -4137,17 +3830,29 @@ static int patch_vt1708S(struct hda_codec *codec)
4137 } 3830 }
4138 3831
4139 spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs; 3832 spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
4140 spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs; 3833 if (codec->vendor_id == 0x11064397)
3834 spec->init_verbs[spec->num_iverbs++] =
3835 vt1705_uniwill_init_verbs;
3836 else
3837 spec->init_verbs[spec->num_iverbs++] =
3838 vt1708S_uniwill_init_verbs;
4141 3839
4142 if (codec->vendor_id == 0x11060440) 3840 if (codec->vendor_id == 0x11060440)
4143 spec->stream_name_analog = "VT1818S Analog"; 3841 spec->stream_name_analog = "VT1818S Analog";
3842 else if (codec->vendor_id == 0x11064397)
3843 spec->stream_name_analog = "VT1705 Analog";
4144 else 3844 else
4145 spec->stream_name_analog = "VT1708S Analog"; 3845 spec->stream_name_analog = "VT1708S Analog";
4146 spec->stream_analog_playback = &vt1708S_pcm_analog_playback; 3846 if (codec->vendor_id == 0x11064397)
3847 spec->stream_analog_playback = &vt1705_pcm_analog_playback;
3848 else
3849 spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
4147 spec->stream_analog_capture = &vt1708S_pcm_analog_capture; 3850 spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
4148 3851
4149 if (codec->vendor_id == 0x11060440) 3852 if (codec->vendor_id == 0x11060440)
4150 spec->stream_name_digital = "VT1818S Digital"; 3853 spec->stream_name_digital = "VT1818S Digital";
3854 else if (codec->vendor_id == 0x11064397)
3855 spec->stream_name_digital = "VT1705 Digital";
4151 else 3856 else
4152 spec->stream_name_digital = "VT1708S Digital"; 3857 spec->stream_name_digital = "VT1708S Digital";
4153 spec->stream_digital_playback = &vt1708S_pcm_digital_playback; 3858 spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
@@ -4185,13 +3890,22 @@ static int patch_vt1708S(struct hda_codec *codec)
4185 spec->stream_name_analog = "VT1818S Analog"; 3890 spec->stream_name_analog = "VT1818S Analog";
4186 spec->stream_name_digital = "VT1818S Digital"; 3891 spec->stream_name_digital = "VT1818S Digital";
4187 } 3892 }
3893 /* correct names for VT1705 */
3894 if (codec->vendor_id == 0x11064397) {
3895 kfree(codec->chip_name);
3896 codec->chip_name = kstrdup("VT1705", GFP_KERNEL);
3897 snprintf(codec->bus->card->mixername,
3898 sizeof(codec->bus->card->mixername),
3899 "%s %s", codec->vendor_name, codec->chip_name);
3900 }
3901 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
4188 return 0; 3902 return 0;
4189} 3903}
4190 3904
4191/* Patch for VT1702 */ 3905/* Patch for VT1702 */
4192 3906
4193/* capture mixer elements */ 3907/* capture mixer elements */
4194static struct snd_kcontrol_new vt1702_capture_mixer[] = { 3908static const struct snd_kcontrol_new vt1702_capture_mixer[] = {
4195 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT), 3909 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
4196 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT), 3910 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
4197 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT), 3911 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
@@ -4215,7 +3929,7 @@ static struct snd_kcontrol_new vt1702_capture_mixer[] = {
4215 { } /* end */ 3929 { } /* end */
4216}; 3930};
4217 3931
4218static struct hda_verb vt1702_volume_init_verbs[] = { 3932static const struct hda_verb vt1702_volume_init_verbs[] = {
4219 /* 3933 /*
4220 * Unmute ADC0-1 and set the default input to mic-in 3934 * Unmute ADC0-1 and set the default input to mic-in
4221 */ 3935 */
@@ -4246,7 +3960,7 @@ static struct hda_verb vt1702_volume_init_verbs[] = {
4246 { } 3960 { }
4247}; 3961};
4248 3962
4249static struct hda_verb vt1702_uniwill_init_verbs[] = { 3963static const struct hda_verb vt1702_uniwill_init_verbs[] = {
4250 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, 3964 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE,
4251 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 3965 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4252 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3966 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
@@ -4256,7 +3970,7 @@ static struct hda_verb vt1702_uniwill_init_verbs[] = {
4256 { } 3970 { }
4257}; 3971};
4258 3972
4259static struct hda_pcm_stream vt1702_pcm_analog_playback = { 3973static const struct hda_pcm_stream vt1702_pcm_analog_playback = {
4260 .substreams = 2, 3974 .substreams = 2,
4261 .channels_min = 2, 3975 .channels_min = 2,
4262 .channels_max = 2, 3976 .channels_max = 2,
@@ -4269,7 +3983,7 @@ static struct hda_pcm_stream vt1702_pcm_analog_playback = {
4269 }, 3983 },
4270}; 3984};
4271 3985
4272static struct hda_pcm_stream vt1702_pcm_analog_capture = { 3986static const struct hda_pcm_stream vt1702_pcm_analog_capture = {
4273 .substreams = 3, 3987 .substreams = 3,
4274 .channels_min = 2, 3988 .channels_min = 2,
4275 .channels_max = 2, 3989 .channels_max = 2,
@@ -4282,7 +3996,7 @@ static struct hda_pcm_stream vt1702_pcm_analog_capture = {
4282 }, 3996 },
4283}; 3997};
4284 3998
4285static struct hda_pcm_stream vt1702_pcm_digital_playback = { 3999static const struct hda_pcm_stream vt1702_pcm_digital_playback = {
4286 .substreams = 2, 4000 .substreams = 2,
4287 .channels_min = 2, 4001 .channels_min = 2,
4288 .channels_max = 2, 4002 .channels_max = 2,
@@ -4304,7 +4018,7 @@ static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
4304 4018
4305 if (cfg->line_out_pins[0]) { 4019 if (cfg->line_out_pins[0]) {
4306 /* config dac list */ 4020 /* config dac list */
4307 spec->multiout.dac_nids[0] = 0x10; 4021 spec->private_dac_nids[0] = 0x10;
4308 } 4022 }
4309 4023
4310 return 0; 4024 return 0;
@@ -4382,7 +4096,7 @@ static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4382static int vt1702_auto_create_analog_input_ctls(struct hda_codec *codec, 4096static int vt1702_auto_create_analog_input_ctls(struct hda_codec *codec,
4383 const struct auto_pin_cfg *cfg) 4097 const struct auto_pin_cfg *cfg)
4384{ 4098{
4385 static hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff }; 4099 static const hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff };
4386 return vt_auto_create_analog_input_ctls(codec, cfg, 0x1a, pin_idxs, 4100 return vt_auto_create_analog_input_ctls(codec, cfg, 0x1a, pin_idxs,
4387 ARRAY_SIZE(pin_idxs)); 4101 ARRAY_SIZE(pin_idxs));
4388} 4102}
@@ -4433,7 +4147,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
4433} 4147}
4434 4148
4435#ifdef CONFIG_SND_HDA_POWER_SAVE 4149#ifdef CONFIG_SND_HDA_POWER_SAVE
4436static struct hda_amp_list vt1702_loopbacks[] = { 4150static const struct hda_amp_list vt1702_loopbacks[] = {
4437 { 0x1A, HDA_INPUT, 1 }, 4151 { 0x1A, HDA_INPUT, 1 },
4438 { 0x1A, HDA_INPUT, 2 }, 4152 { 0x1A, HDA_INPUT, 2 },
4439 { 0x1A, HDA_INPUT, 3 }, 4153 { 0x1A, HDA_INPUT, 3 },
@@ -4442,6 +4156,37 @@ static struct hda_amp_list vt1702_loopbacks[] = {
4442}; 4156};
4443#endif 4157#endif
4444 4158
4159static void set_widgets_power_state_vt1702(struct hda_codec *codec)
4160{
4161 int imux_is_smixer =
4162 snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
4163 unsigned int parm;
4164 /* inputs */
4165 /* PW 1/2/5 (14h/15h/18h) */
4166 parm = AC_PWRST_D3;
4167 set_pin_power_state(codec, 0x14, &parm);
4168 set_pin_power_state(codec, 0x15, &parm);
4169 set_pin_power_state(codec, 0x18, &parm);
4170 if (imux_is_smixer)
4171 parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */
4172 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
4173 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
4174 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, parm);
4175 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
4176 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, parm);
4177
4178 /* outputs */
4179 /* PW 3/4 (16h/17h) */
4180 parm = AC_PWRST_D3;
4181 set_pin_power_state(codec, 0x17, &parm);
4182 set_pin_power_state(codec, 0x16, &parm);
4183 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
4184 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
4185 imux_is_smixer ? AC_PWRST_D0 : parm);
4186 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
4187 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
4188}
4189
4445static int patch_vt1702(struct hda_codec *codec) 4190static int patch_vt1702(struct hda_codec *codec)
4446{ 4191{
4447 struct via_spec *spec; 4192 struct via_spec *spec;
@@ -4488,13 +4233,14 @@ static int patch_vt1702(struct hda_codec *codec)
4488 spec->loopback.amplist = vt1702_loopbacks; 4233 spec->loopback.amplist = vt1702_loopbacks;
4489#endif 4234#endif
4490 4235
4236 spec->set_widgets_power_state = set_widgets_power_state_vt1702;
4491 return 0; 4237 return 0;
4492} 4238}
4493 4239
4494/* Patch for VT1718S */ 4240/* Patch for VT1718S */
4495 4241
4496/* capture mixer elements */ 4242/* capture mixer elements */
4497static struct snd_kcontrol_new vt1718S_capture_mixer[] = { 4243static const struct snd_kcontrol_new vt1718S_capture_mixer[] = {
4498 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), 4244 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
4499 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), 4245 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
4500 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), 4246 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
@@ -4516,14 +4262,15 @@ static struct snd_kcontrol_new vt1718S_capture_mixer[] = {
4516 { } /* end */ 4262 { } /* end */
4517}; 4263};
4518 4264
4519static struct hda_verb vt1718S_volume_init_verbs[] = { 4265static const struct hda_verb vt1718S_volume_init_verbs[] = {
4520 /* 4266 /*
4521 * Unmute ADC0-1 and set the default input to mic-in 4267 * Unmute ADC0-1 and set the default input to mic-in
4522 */ 4268 */
4523 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4269 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4524 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4270 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4525 4271
4526 4272 /* Enable MW0 adjust Gain 5 */
4273 {0x1, 0xfb2, 0x10},
4527 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 4274 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4528 * mixer widget 4275 * mixer widget
4529 */ 4276 */
@@ -4532,7 +4279,7 @@ static struct hda_verb vt1718S_volume_init_verbs[] = {
4532 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4279 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4533 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4280 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4534 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4281 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4535 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 4282 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
4536 4283
4537 /* Setup default input of Front HP to MW9 */ 4284 /* Setup default input of Front HP to MW9 */
4538 {0x28, AC_VERB_SET_CONNECT_SEL, 0x1}, 4285 {0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
@@ -4563,7 +4310,7 @@ static struct hda_verb vt1718S_volume_init_verbs[] = {
4563}; 4310};
4564 4311
4565 4312
4566static struct hda_verb vt1718S_uniwill_init_verbs[] = { 4313static const struct hda_verb vt1718S_uniwill_init_verbs[] = {
4567 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE, 4314 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
4568 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 4315 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4569 {0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 4316 {0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
@@ -4576,7 +4323,7 @@ static struct hda_verb vt1718S_uniwill_init_verbs[] = {
4576 { } 4323 { }
4577}; 4324};
4578 4325
4579static struct hda_pcm_stream vt1718S_pcm_analog_playback = { 4326static const struct hda_pcm_stream vt1718S_pcm_analog_playback = {
4580 .substreams = 2, 4327 .substreams = 2,
4581 .channels_min = 2, 4328 .channels_min = 2,
4582 .channels_max = 10, 4329 .channels_max = 10,
@@ -4589,7 +4336,7 @@ static struct hda_pcm_stream vt1718S_pcm_analog_playback = {
4589 }, 4336 },
4590}; 4337};
4591 4338
4592static struct hda_pcm_stream vt1718S_pcm_analog_capture = { 4339static const struct hda_pcm_stream vt1718S_pcm_analog_capture = {
4593 .substreams = 2, 4340 .substreams = 2,
4594 .channels_min = 2, 4341 .channels_min = 2,
4595 .channels_max = 2, 4342 .channels_max = 2,
@@ -4602,7 +4349,7 @@ static struct hda_pcm_stream vt1718S_pcm_analog_capture = {
4602 }, 4349 },
4603}; 4350};
4604 4351
4605static struct hda_pcm_stream vt1718S_pcm_digital_playback = { 4352static const struct hda_pcm_stream vt1718S_pcm_digital_playback = {
4606 .substreams = 2, 4353 .substreams = 2,
4607 .channels_min = 2, 4354 .channels_min = 2,
4608 .channels_max = 2, 4355 .channels_max = 2,
@@ -4615,7 +4362,7 @@ static struct hda_pcm_stream vt1718S_pcm_digital_playback = {
4615 }, 4362 },
4616}; 4363};
4617 4364
4618static struct hda_pcm_stream vt1718S_pcm_digital_capture = { 4365static const struct hda_pcm_stream vt1718S_pcm_digital_capture = {
4619 .substreams = 1, 4366 .substreams = 1,
4620 .channels_min = 2, 4367 .channels_min = 2,
4621 .channels_max = 2, 4368 .channels_max = 2,
@@ -4638,16 +4385,16 @@ static int vt1718S_auto_fill_dac_nids(struct via_spec *spec,
4638 /* config dac list */ 4385 /* config dac list */
4639 switch (i) { 4386 switch (i) {
4640 case AUTO_SEQ_FRONT: 4387 case AUTO_SEQ_FRONT:
4641 spec->multiout.dac_nids[i] = 0x8; 4388 spec->private_dac_nids[i] = 0x8;
4642 break; 4389 break;
4643 case AUTO_SEQ_CENLFE: 4390 case AUTO_SEQ_CENLFE:
4644 spec->multiout.dac_nids[i] = 0xa; 4391 spec->private_dac_nids[i] = 0xa;
4645 break; 4392 break;
4646 case AUTO_SEQ_SURROUND: 4393 case AUTO_SEQ_SURROUND:
4647 spec->multiout.dac_nids[i] = 0x9; 4394 spec->private_dac_nids[i] = 0x9;
4648 break; 4395 break;
4649 case AUTO_SEQ_SIDE: 4396 case AUTO_SEQ_SIDE:
4650 spec->multiout.dac_nids[i] = 0xb; 4397 spec->private_dac_nids[i] = 0xb;
4651 break; 4398 break;
4652 } 4399 }
4653 } 4400 }
@@ -4769,7 +4516,7 @@ static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4769static int vt1718S_auto_create_analog_input_ctls(struct hda_codec *codec, 4516static int vt1718S_auto_create_analog_input_ctls(struct hda_codec *codec,
4770 const struct auto_pin_cfg *cfg) 4517 const struct auto_pin_cfg *cfg)
4771{ 4518{
4772 static hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff }; 4519 static const hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff };
4773 return vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs, 4520 return vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
4774 ARRAY_SIZE(pin_idxs)); 4521 ARRAY_SIZE(pin_idxs));
4775} 4522}
@@ -4820,7 +4567,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec)
4820} 4567}
4821 4568
4822#ifdef CONFIG_SND_HDA_POWER_SAVE 4569#ifdef CONFIG_SND_HDA_POWER_SAVE
4823static struct hda_amp_list vt1718S_loopbacks[] = { 4570static const struct hda_amp_list vt1718S_loopbacks[] = {
4824 { 0x21, HDA_INPUT, 1 }, 4571 { 0x21, HDA_INPUT, 1 },
4825 { 0x21, HDA_INPUT, 2 }, 4572 { 0x21, HDA_INPUT, 2 },
4826 { 0x21, HDA_INPUT, 3 }, 4573 { 0x21, HDA_INPUT, 3 },
@@ -4829,6 +4576,72 @@ static struct hda_amp_list vt1718S_loopbacks[] = {
4829}; 4576};
4830#endif 4577#endif
4831 4578
4579static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
4580{
4581 struct via_spec *spec = codec->spec;
4582 int imux_is_smixer;
4583 unsigned int parm;
4584 /* MUX6 (1eh) = stereo mixer */
4585 imux_is_smixer =
4586 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
4587 /* inputs */
4588 /* PW 5/6/7 (29h/2ah/2bh) */
4589 parm = AC_PWRST_D3;
4590 set_pin_power_state(codec, 0x29, &parm);
4591 set_pin_power_state(codec, 0x2a, &parm);
4592 set_pin_power_state(codec, 0x2b, &parm);
4593 if (imux_is_smixer)
4594 parm = AC_PWRST_D0;
4595 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
4596 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
4597 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
4598 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
4599 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
4600
4601 /* outputs */
4602 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
4603 parm = AC_PWRST_D3;
4604 set_pin_power_state(codec, 0x27, &parm);
4605 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm);
4606 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm);
4607
4608 /* PW2 (26h), AOW2 (ah) */
4609 parm = AC_PWRST_D3;
4610 set_pin_power_state(codec, 0x26, &parm);
4611 if (spec->smart51_enabled)
4612 set_pin_power_state(codec, 0x2b, &parm);
4613 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, parm);
4614
4615 /* PW0 (24h), AOW0 (8h) */
4616 parm = AC_PWRST_D3;
4617 set_pin_power_state(codec, 0x24, &parm);
4618 if (!spec->hp_independent_mode) /* check for redirected HP */
4619 set_pin_power_state(codec, 0x28, &parm);
4620 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
4621 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
4622 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
4623 imux_is_smixer ? AC_PWRST_D0 : parm);
4624
4625 /* PW1 (25h), AOW1 (9h) */
4626 parm = AC_PWRST_D3;
4627 set_pin_power_state(codec, 0x25, &parm);
4628 if (spec->smart51_enabled)
4629 set_pin_power_state(codec, 0x2a, &parm);
4630 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm);
4631
4632 if (spec->hp_independent_mode) {
4633 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
4634 parm = AC_PWRST_D3;
4635 set_pin_power_state(codec, 0x28, &parm);
4636 snd_hda_codec_write(codec, 0x1b, 0,
4637 AC_VERB_SET_POWER_STATE, parm);
4638 snd_hda_codec_write(codec, 0x34, 0,
4639 AC_VERB_SET_POWER_STATE, parm);
4640 snd_hda_codec_write(codec, 0xc, 0,
4641 AC_VERB_SET_POWER_STATE, parm);
4642 }
4643}
4644
4832static int patch_vt1718S(struct hda_codec *codec) 4645static int patch_vt1718S(struct hda_codec *codec)
4833{ 4646{
4834 struct via_spec *spec; 4647 struct via_spec *spec;
@@ -4890,6 +4703,8 @@ static int patch_vt1718S(struct hda_codec *codec)
4890 spec->loopback.amplist = vt1718S_loopbacks; 4703 spec->loopback.amplist = vt1718S_loopbacks;
4891#endif 4704#endif
4892 4705
4706 spec->set_widgets_power_state = set_widgets_power_state_vt1718S;
4707
4893 return 0; 4708 return 0;
4894} 4709}
4895 4710
@@ -4929,13 +4744,12 @@ static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
4929 snd_hda_codec_write(codec, 0x26, 0, 4744 snd_hda_codec_write(codec, 0x26, 0,
4930 AC_VERB_SET_CONNECT_SEL, index); 4745 AC_VERB_SET_CONNECT_SEL, index);
4931 spec->dmic_enabled = index; 4746 spec->dmic_enabled = index;
4932 set_jack_power_state(codec); 4747 set_widgets_power_state(codec);
4933
4934 return 1; 4748 return 1;
4935} 4749}
4936 4750
4937/* capture mixer elements */ 4751/* capture mixer elements */
4938static struct snd_kcontrol_new vt1716S_capture_mixer[] = { 4752static const struct snd_kcontrol_new vt1716S_capture_mixer[] = {
4939 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), 4753 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
4940 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), 4754 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
4941 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), 4755 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
@@ -4954,7 +4768,7 @@ static struct snd_kcontrol_new vt1716S_capture_mixer[] = {
4954 { } /* end */ 4768 { } /* end */
4955}; 4769};
4956 4770
4957static struct snd_kcontrol_new vt1716s_dmic_mixer[] = { 4771static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
4958 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT), 4772 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
4959 { 4773 {
4960 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4774 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -4970,12 +4784,12 @@ static struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
4970 4784
4971 4785
4972/* mono-out mixer elements */ 4786/* mono-out mixer elements */
4973static struct snd_kcontrol_new vt1716S_mono_out_mixer[] = { 4787static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
4974 HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT), 4788 HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
4975 { } /* end */ 4789 { } /* end */
4976}; 4790};
4977 4791
4978static struct hda_verb vt1716S_volume_init_verbs[] = { 4792static const struct hda_verb vt1716S_volume_init_verbs[] = {
4979 /* 4793 /*
4980 * Unmute ADC0-1 and set the default input to mic-in 4794 * Unmute ADC0-1 and set the default input to mic-in
4981 */ 4795 */
@@ -5024,7 +4838,7 @@ static struct hda_verb vt1716S_volume_init_verbs[] = {
5024}; 4838};
5025 4839
5026 4840
5027static struct hda_verb vt1716S_uniwill_init_verbs[] = { 4841static const struct hda_verb vt1716S_uniwill_init_verbs[] = {
5028 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 4842 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
5029 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 4843 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
5030 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 4844 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
@@ -5037,7 +4851,7 @@ static struct hda_verb vt1716S_uniwill_init_verbs[] = {
5037 { } 4851 { }
5038}; 4852};
5039 4853
5040static struct hda_pcm_stream vt1716S_pcm_analog_playback = { 4854static const struct hda_pcm_stream vt1716S_pcm_analog_playback = {
5041 .substreams = 2, 4855 .substreams = 2,
5042 .channels_min = 2, 4856 .channels_min = 2,
5043 .channels_max = 6, 4857 .channels_max = 6,
@@ -5050,7 +4864,7 @@ static struct hda_pcm_stream vt1716S_pcm_analog_playback = {
5050 }, 4864 },
5051}; 4865};
5052 4866
5053static struct hda_pcm_stream vt1716S_pcm_analog_capture = { 4867static const struct hda_pcm_stream vt1716S_pcm_analog_capture = {
5054 .substreams = 2, 4868 .substreams = 2,
5055 .channels_min = 2, 4869 .channels_min = 2,
5056 .channels_max = 2, 4870 .channels_max = 2,
@@ -5063,7 +4877,7 @@ static struct hda_pcm_stream vt1716S_pcm_analog_capture = {
5063 }, 4877 },
5064}; 4878};
5065 4879
5066static struct hda_pcm_stream vt1716S_pcm_digital_playback = { 4880static const struct hda_pcm_stream vt1716S_pcm_digital_playback = {
5067 .substreams = 2, 4881 .substreams = 2,
5068 .channels_min = 2, 4882 .channels_min = 2,
5069 .channels_max = 2, 4883 .channels_max = 2,
@@ -5092,13 +4906,13 @@ static int vt1716S_auto_fill_dac_nids(struct via_spec *spec,
5092 /* config dac list */ 4906 /* config dac list */
5093 switch (i) { 4907 switch (i) {
5094 case AUTO_SEQ_FRONT: 4908 case AUTO_SEQ_FRONT:
5095 spec->multiout.dac_nids[i] = 0x10; 4909 spec->private_dac_nids[i] = 0x10;
5096 break; 4910 break;
5097 case AUTO_SEQ_CENLFE: 4911 case AUTO_SEQ_CENLFE:
5098 spec->multiout.dac_nids[i] = 0x25; 4912 spec->private_dac_nids[i] = 0x25;
5099 break; 4913 break;
5100 case AUTO_SEQ_SURROUND: 4914 case AUTO_SEQ_SURROUND:
5101 spec->multiout.dac_nids[i] = 0x11; 4915 spec->private_dac_nids[i] = 0x11;
5102 break; 4916 break;
5103 } 4917 }
5104 } 4918 }
@@ -5233,7 +5047,7 @@ static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5233static int vt1716S_auto_create_analog_input_ctls(struct hda_codec *codec, 5047static int vt1716S_auto_create_analog_input_ctls(struct hda_codec *codec,
5234 const struct auto_pin_cfg *cfg) 5048 const struct auto_pin_cfg *cfg)
5235{ 5049{
5236 static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff }; 5050 static const hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
5237 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs, 5051 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
5238 ARRAY_SIZE(pin_idxs)); 5052 ARRAY_SIZE(pin_idxs));
5239} 5053}
@@ -5280,7 +5094,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec)
5280} 5094}
5281 5095
5282#ifdef CONFIG_SND_HDA_POWER_SAVE 5096#ifdef CONFIG_SND_HDA_POWER_SAVE
5283static struct hda_amp_list vt1716S_loopbacks[] = { 5097static const struct hda_amp_list vt1716S_loopbacks[] = {
5284 { 0x16, HDA_INPUT, 1 }, 5098 { 0x16, HDA_INPUT, 1 },
5285 { 0x16, HDA_INPUT, 2 }, 5099 { 0x16, HDA_INPUT, 2 },
5286 { 0x16, HDA_INPUT, 3 }, 5100 { 0x16, HDA_INPUT, 3 },
@@ -5289,6 +5103,99 @@ static struct hda_amp_list vt1716S_loopbacks[] = {
5289}; 5103};
5290#endif 5104#endif
5291 5105
5106static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
5107{
5108 struct via_spec *spec = codec->spec;
5109 int imux_is_smixer;
5110 unsigned int parm;
5111 unsigned int mono_out, present;
5112 /* SW0 (17h) = stereo mixer */
5113 imux_is_smixer =
5114 (snd_hda_codec_read(codec, 0x17, 0,
5115 AC_VERB_GET_CONNECT_SEL, 0x00) == 5);
5116 /* inputs */
5117 /* PW 1/2/5 (1ah/1bh/1eh) */
5118 parm = AC_PWRST_D3;
5119 set_pin_power_state(codec, 0x1a, &parm);
5120 set_pin_power_state(codec, 0x1b, &parm);
5121 set_pin_power_state(codec, 0x1e, &parm);
5122 if (imux_is_smixer)
5123 parm = AC_PWRST_D0;
5124 /* SW0 (17h), AIW0(13h) */
5125 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
5126 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
5127
5128 parm = AC_PWRST_D3;
5129 set_pin_power_state(codec, 0x1e, &parm);
5130 /* PW11 (22h) */
5131 if (spec->dmic_enabled)
5132 set_pin_power_state(codec, 0x22, &parm);
5133 else
5134 snd_hda_codec_write(codec, 0x22, 0,
5135 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5136
5137 /* SW2(26h), AIW1(14h) */
5138 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, parm);
5139 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
5140
5141 /* outputs */
5142 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
5143 parm = AC_PWRST_D3;
5144 set_pin_power_state(codec, 0x19, &parm);
5145 /* Smart 5.1 PW2(1bh) */
5146 if (spec->smart51_enabled)
5147 set_pin_power_state(codec, 0x1b, &parm);
5148 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
5149 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
5150
5151 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
5152 parm = AC_PWRST_D3;
5153 set_pin_power_state(codec, 0x23, &parm);
5154 /* Smart 5.1 PW1(1ah) */
5155 if (spec->smart51_enabled)
5156 set_pin_power_state(codec, 0x1a, &parm);
5157 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm);
5158
5159 /* Smart 5.1 PW5(1eh) */
5160 if (spec->smart51_enabled)
5161 set_pin_power_state(codec, 0x1e, &parm);
5162 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, parm);
5163
5164 /* Mono out */
5165 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
5166 present = snd_hda_jack_detect(codec, 0x1c);
5167
5168 if (present)
5169 mono_out = 0;
5170 else {
5171 present = snd_hda_jack_detect(codec, 0x1d);
5172 if (!spec->hp_independent_mode && present)
5173 mono_out = 0;
5174 else
5175 mono_out = 1;
5176 }
5177 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
5178 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, parm);
5179 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, parm);
5180 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, parm);
5181
5182 /* PW 3/4 (1ch/1dh) */
5183 parm = AC_PWRST_D3;
5184 set_pin_power_state(codec, 0x1c, &parm);
5185 set_pin_power_state(codec, 0x1d, &parm);
5186 /* HP Independent Mode, power on AOW3 */
5187 if (spec->hp_independent_mode)
5188 snd_hda_codec_write(codec, 0x25, 0,
5189 AC_VERB_SET_POWER_STATE, parm);
5190
5191 /* force to D0 for internal Speaker */
5192 /* MW0 (16h), AOW0 (10h) */
5193 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
5194 imux_is_smixer ? AC_PWRST_D0 : parm);
5195 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
5196 mono_out ? AC_PWRST_D0 : parm);
5197}
5198
5292static int patch_vt1716S(struct hda_codec *codec) 5199static int patch_vt1716S(struct hda_codec *codec)
5293{ 5200{
5294 struct via_spec *spec; 5201 struct via_spec *spec;
@@ -5343,13 +5250,14 @@ static int patch_vt1716S(struct hda_codec *codec)
5343 spec->loopback.amplist = vt1716S_loopbacks; 5250 spec->loopback.amplist = vt1716S_loopbacks;
5344#endif 5251#endif
5345 5252
5253 spec->set_widgets_power_state = set_widgets_power_state_vt1716S;
5346 return 0; 5254 return 0;
5347} 5255}
5348 5256
5349/* for vt2002P */ 5257/* for vt2002P */
5350 5258
5351/* capture mixer elements */ 5259/* capture mixer elements */
5352static struct snd_kcontrol_new vt2002P_capture_mixer[] = { 5260static const struct snd_kcontrol_new vt2002P_capture_mixer[] = {
5353 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), 5261 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5354 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), 5262 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5355 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), 5263 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
@@ -5372,7 +5280,11 @@ static struct snd_kcontrol_new vt2002P_capture_mixer[] = {
5372 { } /* end */ 5280 { } /* end */
5373}; 5281};
5374 5282
5375static struct hda_verb vt2002P_volume_init_verbs[] = { 5283static const struct hda_verb vt2002P_volume_init_verbs[] = {
5284 /* Class-D speaker related verbs */
5285 {0x1, 0xfe0, 0x4},
5286 {0x1, 0xfe9, 0x80},
5287 {0x1, 0xfe2, 0x22},
5376 /* 5288 /*
5377 * Unmute ADC0-1 and set the default input to mic-in 5289 * Unmute ADC0-1 and set the default input to mic-in
5378 */ 5290 */
@@ -5423,9 +5335,60 @@ static struct hda_verb vt2002P_volume_init_verbs[] = {
5423 {0x1, 0xfb8, 0x88}, 5335 {0x1, 0xfb8, 0x88},
5424 { } 5336 { }
5425}; 5337};
5338static const struct hda_verb vt1802_volume_init_verbs[] = {
5339 /*
5340 * Unmute ADC0-1 and set the default input to mic-in
5341 */
5342 {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5343 {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5344
5345
5346 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5347 * mixer widget
5348 */
5349 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5350 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5351 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5352 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5353 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5354 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5355
5356 /* MUX Indices: Mic = 0 */
5357 {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5358 {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5359
5360 /* PW9 Output enable */
5361 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5362
5363 /* Enable Boost Volume backdoor */
5364 {0x1, 0xfb9, 0x24},
5365
5366 /* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5367 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5368 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5369 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5370 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5371 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5373 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5374 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5375
5376 /* set MUX0/1/4/8 = 0 (AOW0) */
5377 {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5378 {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5379 {0x38, AC_VERB_SET_CONNECT_SEL, 0},
5380 {0x3c, AC_VERB_SET_CONNECT_SEL, 0},
5381
5382 /* set PW0 index=0 (MW0) */
5383 {0x24, AC_VERB_SET_CONNECT_SEL, 0},
5384
5385 /* Enable AOW0 to MW9 */
5386 {0x1, 0xfb8, 0x88},
5387 { }
5388};
5426 5389
5427 5390
5428static struct hda_verb vt2002P_uniwill_init_verbs[] = { 5391static const struct hda_verb vt2002P_uniwill_init_verbs[] = {
5429 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, 5392 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE,
5430 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, 5393 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5431 {0x26, AC_VERB_SET_UNSOLICITED_ENABLE, 5394 {0x26, AC_VERB_SET_UNSOLICITED_ENABLE,
@@ -5435,8 +5398,18 @@ static struct hda_verb vt2002P_uniwill_init_verbs[] = {
5435 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 5398 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5436 { } 5399 { }
5437}; 5400};
5401static const struct hda_verb vt1802_uniwill_init_verbs[] = {
5402 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE,
5403 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5404 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
5405 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5406 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5407 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5408 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5409 { }
5410};
5438 5411
5439static struct hda_pcm_stream vt2002P_pcm_analog_playback = { 5412static const struct hda_pcm_stream vt2002P_pcm_analog_playback = {
5440 .substreams = 2, 5413 .substreams = 2,
5441 .channels_min = 2, 5414 .channels_min = 2,
5442 .channels_max = 2, 5415 .channels_max = 2,
@@ -5449,7 +5422,7 @@ static struct hda_pcm_stream vt2002P_pcm_analog_playback = {
5449 }, 5422 },
5450}; 5423};
5451 5424
5452static struct hda_pcm_stream vt2002P_pcm_analog_capture = { 5425static const struct hda_pcm_stream vt2002P_pcm_analog_capture = {
5453 .substreams = 2, 5426 .substreams = 2,
5454 .channels_min = 2, 5427 .channels_min = 2,
5455 .channels_max = 2, 5428 .channels_max = 2,
@@ -5462,7 +5435,7 @@ static struct hda_pcm_stream vt2002P_pcm_analog_capture = {
5462 }, 5435 },
5463}; 5436};
5464 5437
5465static struct hda_pcm_stream vt2002P_pcm_digital_playback = { 5438static const struct hda_pcm_stream vt2002P_pcm_digital_playback = {
5466 .substreams = 1, 5439 .substreams = 1,
5467 .channels_min = 2, 5440 .channels_min = 2,
5468 .channels_max = 2, 5441 .channels_max = 2,
@@ -5482,7 +5455,7 @@ static int vt2002P_auto_fill_dac_nids(struct via_spec *spec,
5482 spec->multiout.num_dacs = 1; 5455 spec->multiout.num_dacs = 1;
5483 spec->multiout.dac_nids = spec->private_dac_nids; 5456 spec->multiout.dac_nids = spec->private_dac_nids;
5484 if (cfg->line_out_pins[0]) 5457 if (cfg->line_out_pins[0])
5485 spec->multiout.dac_nids[0] = 0x8; 5458 spec->private_dac_nids[0] = 0x8;
5486 return 0; 5459 return 0;
5487} 5460}
5488 5461
@@ -5491,10 +5464,15 @@ static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec,
5491 const struct auto_pin_cfg *cfg) 5464 const struct auto_pin_cfg *cfg)
5492{ 5465{
5493 int err; 5466 int err;
5467 hda_nid_t sw_nid;
5494 5468
5495 if (!cfg->line_out_pins[0]) 5469 if (!cfg->line_out_pins[0])
5496 return -1; 5470 return -1;
5497 5471
5472 if (spec->codec_type == VT1802)
5473 sw_nid = 0x28;
5474 else
5475 sw_nid = 0x26;
5498 5476
5499 /* Line-Out: PortE */ 5477 /* Line-Out: PortE */
5500 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 5478 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
@@ -5504,7 +5482,7 @@ static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec,
5504 return err; 5482 return err;
5505 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE, 5483 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
5506 "Master Front Playback Switch", 5484 "Master Front Playback Switch",
5507 HDA_COMPOSE_AMP_VAL(0x26, 3, 0, HDA_OUTPUT)); 5485 HDA_COMPOSE_AMP_VAL(sw_nid, 3, 0, HDA_OUTPUT));
5508 if (err < 0) 5486 if (err < 0)
5509 return err; 5487 return err;
5510 5488
@@ -5544,7 +5522,7 @@ static int vt2002P_auto_create_analog_input_ctls(struct hda_codec *codec,
5544{ 5522{
5545 struct via_spec *spec = codec->spec; 5523 struct via_spec *spec = codec->spec;
5546 struct hda_input_mux *imux = &spec->private_imux[0]; 5524 struct hda_input_mux *imux = &spec->private_imux[0];
5547 static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff }; 5525 static const hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff };
5548 int err; 5526 int err;
5549 5527
5550 err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs, 5528 err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
@@ -5605,7 +5583,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec)
5605} 5583}
5606 5584
5607#ifdef CONFIG_SND_HDA_POWER_SAVE 5585#ifdef CONFIG_SND_HDA_POWER_SAVE
5608static struct hda_amp_list vt2002P_loopbacks[] = { 5586static const struct hda_amp_list vt2002P_loopbacks[] = {
5609 { 0x21, HDA_INPUT, 0 }, 5587 { 0x21, HDA_INPUT, 0 },
5610 { 0x21, HDA_INPUT, 1 }, 5588 { 0x21, HDA_INPUT, 1 },
5611 { 0x21, HDA_INPUT, 2 }, 5589 { 0x21, HDA_INPUT, 2 },
@@ -5613,6 +5591,116 @@ static struct hda_amp_list vt2002P_loopbacks[] = {
5613}; 5591};
5614#endif 5592#endif
5615 5593
5594static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
5595{
5596 struct via_spec *spec = codec->spec;
5597 int imux_is_smixer;
5598 unsigned int parm;
5599 unsigned int present;
5600 /* MUX9 (1eh) = stereo mixer */
5601 imux_is_smixer =
5602 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
5603 /* inputs */
5604 /* PW 5/6/7 (29h/2ah/2bh) */
5605 parm = AC_PWRST_D3;
5606 set_pin_power_state(codec, 0x29, &parm);
5607 set_pin_power_state(codec, 0x2a, &parm);
5608 set_pin_power_state(codec, 0x2b, &parm);
5609 parm = AC_PWRST_D0;
5610 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
5611 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
5612 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
5613 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
5614 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
5615
5616 /* outputs */
5617 /* AOW0 (8h)*/
5618 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
5619
5620 if (spec->codec_type == VT1802) {
5621 /* PW4 (28h), MW4 (18h), MUX4(38h) */
5622 parm = AC_PWRST_D3;
5623 set_pin_power_state(codec, 0x28, &parm);
5624 snd_hda_codec_write(codec, 0x18, 0,
5625 AC_VERB_SET_POWER_STATE, parm);
5626 snd_hda_codec_write(codec, 0x38, 0,
5627 AC_VERB_SET_POWER_STATE, parm);
5628 } else {
5629 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
5630 parm = AC_PWRST_D3;
5631 set_pin_power_state(codec, 0x26, &parm);
5632 snd_hda_codec_write(codec, 0x1c, 0,
5633 AC_VERB_SET_POWER_STATE, parm);
5634 snd_hda_codec_write(codec, 0x37, 0,
5635 AC_VERB_SET_POWER_STATE, parm);
5636 }
5637
5638 if (spec->codec_type == VT1802) {
5639 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
5640 parm = AC_PWRST_D3;
5641 set_pin_power_state(codec, 0x25, &parm);
5642 snd_hda_codec_write(codec, 0x15, 0,
5643 AC_VERB_SET_POWER_STATE, parm);
5644 snd_hda_codec_write(codec, 0x35, 0,
5645 AC_VERB_SET_POWER_STATE, parm);
5646 } else {
5647 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
5648 parm = AC_PWRST_D3;
5649 set_pin_power_state(codec, 0x25, &parm);
5650 snd_hda_codec_write(codec, 0x19, 0,
5651 AC_VERB_SET_POWER_STATE, parm);
5652 snd_hda_codec_write(codec, 0x35, 0,
5653 AC_VERB_SET_POWER_STATE, parm);
5654 }
5655
5656 if (spec->hp_independent_mode)
5657 snd_hda_codec_write(codec, 0x9, 0,
5658 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
5659
5660 /* Class-D */
5661 /* PW0 (24h), MW0(18h/14h), MUX0(34h) */
5662 present = snd_hda_jack_detect(codec, 0x25);
5663
5664 parm = AC_PWRST_D3;
5665 set_pin_power_state(codec, 0x24, &parm);
5666 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
5667 if (spec->codec_type == VT1802)
5668 snd_hda_codec_write(codec, 0x14, 0,
5669 AC_VERB_SET_POWER_STATE, parm);
5670 else
5671 snd_hda_codec_write(codec, 0x18, 0,
5672 AC_VERB_SET_POWER_STATE, parm);
5673 snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm);
5674
5675 /* Mono Out */
5676 present = snd_hda_jack_detect(codec, 0x26);
5677
5678 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
5679 if (spec->codec_type == VT1802) {
5680 /* PW15 (33h), MW8(1ch), MUX8(3ch) */
5681 snd_hda_codec_write(codec, 0x33, 0,
5682 AC_VERB_SET_POWER_STATE, parm);
5683 snd_hda_codec_write(codec, 0x1c, 0,
5684 AC_VERB_SET_POWER_STATE, parm);
5685 snd_hda_codec_write(codec, 0x3c, 0,
5686 AC_VERB_SET_POWER_STATE, parm);
5687 } else {
5688 /* PW15 (31h), MW8(17h), MUX8(3bh) */
5689 snd_hda_codec_write(codec, 0x31, 0,
5690 AC_VERB_SET_POWER_STATE, parm);
5691 snd_hda_codec_write(codec, 0x17, 0,
5692 AC_VERB_SET_POWER_STATE, parm);
5693 snd_hda_codec_write(codec, 0x3b, 0,
5694 AC_VERB_SET_POWER_STATE, parm);
5695 }
5696 /* MW9 (21h) */
5697 if (imux_is_smixer || !is_aa_path_mute(codec))
5698 snd_hda_codec_write(codec, 0x21, 0,
5699 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
5700 else
5701 snd_hda_codec_write(codec, 0x21, 0,
5702 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5703}
5616 5704
5617/* patch for vt2002P */ 5705/* patch for vt2002P */
5618static int patch_vt2002P(struct hda_codec *codec) 5706static int patch_vt2002P(struct hda_codec *codec)
@@ -5635,14 +5723,31 @@ static int patch_vt2002P(struct hda_codec *codec)
5635 "from BIOS. Using genenic mode...\n"); 5723 "from BIOS. Using genenic mode...\n");
5636 } 5724 }
5637 5725
5638 spec->init_verbs[spec->num_iverbs++] = vt2002P_volume_init_verbs; 5726 if (spec->codec_type == VT1802)
5639 spec->init_verbs[spec->num_iverbs++] = vt2002P_uniwill_init_verbs; 5727 spec->init_verbs[spec->num_iverbs++] =
5728 vt1802_volume_init_verbs;
5729 else
5730 spec->init_verbs[spec->num_iverbs++] =
5731 vt2002P_volume_init_verbs;
5732
5733 if (spec->codec_type == VT1802)
5734 spec->init_verbs[spec->num_iverbs++] =
5735 vt1802_uniwill_init_verbs;
5736 else
5737 spec->init_verbs[spec->num_iverbs++] =
5738 vt2002P_uniwill_init_verbs;
5640 5739
5641 spec->stream_name_analog = "VT2002P Analog"; 5740 if (spec->codec_type == VT1802)
5741 spec->stream_name_analog = "VT1802 Analog";
5742 else
5743 spec->stream_name_analog = "VT2002P Analog";
5642 spec->stream_analog_playback = &vt2002P_pcm_analog_playback; 5744 spec->stream_analog_playback = &vt2002P_pcm_analog_playback;
5643 spec->stream_analog_capture = &vt2002P_pcm_analog_capture; 5745 spec->stream_analog_capture = &vt2002P_pcm_analog_capture;
5644 5746
5645 spec->stream_name_digital = "VT2002P Digital"; 5747 if (spec->codec_type == VT1802)
5748 spec->stream_name_digital = "VT1802 Digital";
5749 else
5750 spec->stream_name_digital = "VT2002P Digital";
5646 spec->stream_digital_playback = &vt2002P_pcm_digital_playback; 5751 spec->stream_digital_playback = &vt2002P_pcm_digital_playback;
5647 5752
5648 if (!spec->adc_nids && spec->input_mux) { 5753 if (!spec->adc_nids && spec->input_mux) {
@@ -5664,13 +5769,14 @@ static int patch_vt2002P(struct hda_codec *codec)
5664 spec->loopback.amplist = vt2002P_loopbacks; 5769 spec->loopback.amplist = vt2002P_loopbacks;
5665#endif 5770#endif
5666 5771
5772 spec->set_widgets_power_state = set_widgets_power_state_vt2002P;
5667 return 0; 5773 return 0;
5668} 5774}
5669 5775
5670/* for vt1812 */ 5776/* for vt1812 */
5671 5777
5672/* capture mixer elements */ 5778/* capture mixer elements */
5673static struct snd_kcontrol_new vt1812_capture_mixer[] = { 5779static const struct snd_kcontrol_new vt1812_capture_mixer[] = {
5674 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), 5780 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5675 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), 5781 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5676 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), 5782 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
@@ -5692,7 +5798,7 @@ static struct snd_kcontrol_new vt1812_capture_mixer[] = {
5692 { } /* end */ 5798 { } /* end */
5693}; 5799};
5694 5800
5695static struct hda_verb vt1812_volume_init_verbs[] = { 5801static const struct hda_verb vt1812_volume_init_verbs[] = {
5696 /* 5802 /*
5697 * Unmute ADC0-1 and set the default input to mic-in 5803 * Unmute ADC0-1 and set the default input to mic-in
5698 */ 5804 */
@@ -5745,7 +5851,7 @@ static struct hda_verb vt1812_volume_init_verbs[] = {
5745}; 5851};
5746 5852
5747 5853
5748static struct hda_verb vt1812_uniwill_init_verbs[] = { 5854static const struct hda_verb vt1812_uniwill_init_verbs[] = {
5749 {0x33, AC_VERB_SET_UNSOLICITED_ENABLE, 5855 {0x33, AC_VERB_SET_UNSOLICITED_ENABLE,
5750 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, 5856 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5751 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT }, 5857 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT },
@@ -5757,7 +5863,7 @@ static struct hda_verb vt1812_uniwill_init_verbs[] = {
5757 { } 5863 { }
5758}; 5864};
5759 5865
5760static struct hda_pcm_stream vt1812_pcm_analog_playback = { 5866static const struct hda_pcm_stream vt1812_pcm_analog_playback = {
5761 .substreams = 2, 5867 .substreams = 2,
5762 .channels_min = 2, 5868 .channels_min = 2,
5763 .channels_max = 2, 5869 .channels_max = 2,
@@ -5770,7 +5876,7 @@ static struct hda_pcm_stream vt1812_pcm_analog_playback = {
5770 }, 5876 },
5771}; 5877};
5772 5878
5773static struct hda_pcm_stream vt1812_pcm_analog_capture = { 5879static const struct hda_pcm_stream vt1812_pcm_analog_capture = {
5774 .substreams = 2, 5880 .substreams = 2,
5775 .channels_min = 2, 5881 .channels_min = 2,
5776 .channels_max = 2, 5882 .channels_max = 2,
@@ -5783,7 +5889,7 @@ static struct hda_pcm_stream vt1812_pcm_analog_capture = {
5783 }, 5889 },
5784}; 5890};
5785 5891
5786static struct hda_pcm_stream vt1812_pcm_digital_playback = { 5892static const struct hda_pcm_stream vt1812_pcm_digital_playback = {
5787 .substreams = 1, 5893 .substreams = 1,
5788 .channels_min = 2, 5894 .channels_min = 2,
5789 .channels_max = 2, 5895 .channels_max = 2,
@@ -5802,7 +5908,7 @@ static int vt1812_auto_fill_dac_nids(struct via_spec *spec,
5802 spec->multiout.num_dacs = 1; 5908 spec->multiout.num_dacs = 1;
5803 spec->multiout.dac_nids = spec->private_dac_nids; 5909 spec->multiout.dac_nids = spec->private_dac_nids;
5804 if (cfg->line_out_pins[0]) 5910 if (cfg->line_out_pins[0])
5805 spec->multiout.dac_nids[0] = 0x8; 5911 spec->private_dac_nids[0] = 0x8;
5806 return 0; 5912 return 0;
5807} 5913}
5808 5914
@@ -5865,7 +5971,7 @@ static int vt1812_auto_create_analog_input_ctls(struct hda_codec *codec,
5865{ 5971{
5866 struct via_spec *spec = codec->spec; 5972 struct via_spec *spec = codec->spec;
5867 struct hda_input_mux *imux = &spec->private_imux[0]; 5973 struct hda_input_mux *imux = &spec->private_imux[0];
5868 static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff }; 5974 static const hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff };
5869 int err; 5975 int err;
5870 5976
5871 err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs, 5977 err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
@@ -5927,7 +6033,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec)
5927} 6033}
5928 6034
5929#ifdef CONFIG_SND_HDA_POWER_SAVE 6035#ifdef CONFIG_SND_HDA_POWER_SAVE
5930static struct hda_amp_list vt1812_loopbacks[] = { 6036static const struct hda_amp_list vt1812_loopbacks[] = {
5931 { 0x21, HDA_INPUT, 0 }, 6037 { 0x21, HDA_INPUT, 0 },
5932 { 0x21, HDA_INPUT, 1 }, 6038 { 0x21, HDA_INPUT, 1 },
5933 { 0x21, HDA_INPUT, 2 }, 6039 { 0x21, HDA_INPUT, 2 },
@@ -5935,6 +6041,97 @@ static struct hda_amp_list vt1812_loopbacks[] = {
5935}; 6041};
5936#endif 6042#endif
5937 6043
6044static void set_widgets_power_state_vt1812(struct hda_codec *codec)
6045{
6046 struct via_spec *spec = codec->spec;
6047 int imux_is_smixer =
6048 snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
6049 unsigned int parm;
6050 unsigned int present;
6051 /* MUX10 (1eh) = stereo mixer */
6052 imux_is_smixer =
6053 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
6054 /* inputs */
6055 /* PW 5/6/7 (29h/2ah/2bh) */
6056 parm = AC_PWRST_D3;
6057 set_pin_power_state(codec, 0x29, &parm);
6058 set_pin_power_state(codec, 0x2a, &parm);
6059 set_pin_power_state(codec, 0x2b, &parm);
6060 parm = AC_PWRST_D0;
6061 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
6062 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
6063 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
6064 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
6065 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
6066
6067 /* outputs */
6068 /* AOW0 (8h)*/
6069 snd_hda_codec_write(codec, 0x8, 0,
6070 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
6071
6072 /* PW4 (28h), MW4 (18h), MUX4(38h) */
6073 parm = AC_PWRST_D3;
6074 set_pin_power_state(codec, 0x28, &parm);
6075 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
6076 snd_hda_codec_write(codec, 0x38, 0, AC_VERB_SET_POWER_STATE, parm);
6077
6078 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
6079 parm = AC_PWRST_D3;
6080 set_pin_power_state(codec, 0x25, &parm);
6081 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_POWER_STATE, parm);
6082 snd_hda_codec_write(codec, 0x35, 0, AC_VERB_SET_POWER_STATE, parm);
6083 if (spec->hp_independent_mode)
6084 snd_hda_codec_write(codec, 0x9, 0,
6085 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
6086
6087 /* Internal Speaker */
6088 /* PW0 (24h), MW0(14h), MUX0(34h) */
6089 present = snd_hda_jack_detect(codec, 0x25);
6090
6091 parm = AC_PWRST_D3;
6092 set_pin_power_state(codec, 0x24, &parm);
6093 if (present) {
6094 snd_hda_codec_write(codec, 0x14, 0,
6095 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
6096 snd_hda_codec_write(codec, 0x34, 0,
6097 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
6098 } else {
6099 snd_hda_codec_write(codec, 0x14, 0,
6100 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
6101 snd_hda_codec_write(codec, 0x34, 0,
6102 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
6103 }
6104
6105
6106 /* Mono Out */
6107 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
6108 present = snd_hda_jack_detect(codec, 0x28);
6109
6110 parm = AC_PWRST_D3;
6111 set_pin_power_state(codec, 0x31, &parm);
6112 if (present) {
6113 snd_hda_codec_write(codec, 0x1c, 0,
6114 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
6115 snd_hda_codec_write(codec, 0x3c, 0,
6116 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
6117 snd_hda_codec_write(codec, 0x3e, 0,
6118 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
6119 } else {
6120 snd_hda_codec_write(codec, 0x1c, 0,
6121 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
6122 snd_hda_codec_write(codec, 0x3c, 0,
6123 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
6124 snd_hda_codec_write(codec, 0x3e, 0,
6125 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
6126 }
6127
6128 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
6129 parm = AC_PWRST_D3;
6130 set_pin_power_state(codec, 0x33, &parm);
6131 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
6132 snd_hda_codec_write(codec, 0x3d, 0, AC_VERB_SET_POWER_STATE, parm);
6133
6134}
5938 6135
5939/* patch for vt1812 */ 6136/* patch for vt1812 */
5940static int patch_vt1812(struct hda_codec *codec) 6137static int patch_vt1812(struct hda_codec *codec)
@@ -5988,13 +6185,14 @@ static int patch_vt1812(struct hda_codec *codec)
5988 spec->loopback.amplist = vt1812_loopbacks; 6185 spec->loopback.amplist = vt1812_loopbacks;
5989#endif 6186#endif
5990 6187
6188 spec->set_widgets_power_state = set_widgets_power_state_vt1812;
5991 return 0; 6189 return 0;
5992} 6190}
5993 6191
5994/* 6192/*
5995 * patch entries 6193 * patch entries
5996 */ 6194 */
5997static struct hda_codec_preset snd_hda_preset_via[] = { 6195static const struct hda_codec_preset snd_hda_preset_via[] = {
5998 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708}, 6196 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
5999 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708}, 6197 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
6000 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708}, 6198 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
@@ -6039,7 +6237,7 @@ static struct hda_codec_preset snd_hda_preset_via[] = {
6039 .patch = patch_vt1708S}, 6237 .patch = patch_vt1708S},
6040 { .id = 0x11063397, .name = "VT1708S", 6238 { .id = 0x11063397, .name = "VT1708S",
6041 .patch = patch_vt1708S}, 6239 .patch = patch_vt1708S},
6042 { .id = 0x11064397, .name = "VT1708S", 6240 { .id = 0x11064397, .name = "VT1705",
6043 .patch = patch_vt1708S}, 6241 .patch = patch_vt1708S},
6044 { .id = 0x11065397, .name = "VT1708S", 6242 { .id = 0x11065397, .name = "VT1708S",
6045 .patch = patch_vt1708S}, 6243 .patch = patch_vt1708S},
@@ -6080,6 +6278,10 @@ static struct hda_codec_preset snd_hda_preset_via[] = {
6080 { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812}, 6278 { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812},
6081 { .id = 0x11060440, .name = "VT1818S", 6279 { .id = 0x11060440, .name = "VT1818S",
6082 .patch = patch_vt1708S}, 6280 .patch = patch_vt1708S},
6281 { .id = 0x11060446, .name = "VT1802",
6282 .patch = patch_vt2002P},
6283 { .id = 0x11068446, .name = "VT1802",
6284 .patch = patch_vt2002P},
6083 {} /* terminator */ 6285 {} /* terminator */
6084}; 6286};
6085 6287
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 27709f0cd2a6..f3353b49c785 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -235,8 +235,8 @@ static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0m_ids) = {
235 { PCI_VDEVICE(NVIDIA, 0x0069), DEVICE_NFORCE }, /* NFORCE2 */ 235 { PCI_VDEVICE(NVIDIA, 0x0069), DEVICE_NFORCE }, /* NFORCE2 */
236 { PCI_VDEVICE(NVIDIA, 0x0089), DEVICE_NFORCE }, /* NFORCE2s */ 236 { PCI_VDEVICE(NVIDIA, 0x0089), DEVICE_NFORCE }, /* NFORCE2s */
237 { PCI_VDEVICE(NVIDIA, 0x00d9), DEVICE_NFORCE }, /* NFORCE3 */ 237 { PCI_VDEVICE(NVIDIA, 0x00d9), DEVICE_NFORCE }, /* NFORCE3 */
238 { PCI_VDEVICE(AMD, 0x746e), DEVICE_INTEL }, /* AMD8111 */
238#if 0 239#if 0
239 { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL }, /* AMD8111 */
240 { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */ 240 { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */
241#endif 241#endif
242 { 0, } 242 { 0, }
@@ -1261,9 +1261,9 @@ static struct shortname_table {
1261 { PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" }, 1261 { PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" },
1262 { PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" }, 1262 { PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" },
1263 { PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" }, 1263 { PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" },
1264 { 0x746e, "AMD AMD8111" },
1264#if 0 1265#if 0
1265 { 0x5455, "ALi M5455" }, 1266 { 0x5455, "ALi M5455" },
1266 { 0x746d, "AMD AMD8111" },
1267#endif 1267#endif
1268 { 0 }, 1268 { 0 },
1269}; 1269};
diff --git a/sound/pci/lola/Makefile b/sound/pci/lola/Makefile
new file mode 100644
index 000000000000..8178a2a59d00
--- /dev/null
+++ b/sound/pci/lola/Makefile
@@ -0,0 +1,4 @@
1snd-lola-y := lola.o lola_pcm.o lola_clock.o lola_mixer.o
2snd-lola-$(CONFIG_SND_DEBUG) += lola_proc.o
3
4obj-$(CONFIG_SND_LOLA) += snd-lola.o
diff --git a/sound/pci/lola/lola.c b/sound/pci/lola/lola.c
new file mode 100644
index 000000000000..34b24286d279
--- /dev/null
+++ b/sound/pci/lola/lola.c
@@ -0,0 +1,791 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/moduleparam.h>
24#include <linux/dma-mapping.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/slab.h>
28#include <linux/pci.h>
29#include <sound/core.h>
30#include <sound/control.h>
31#include <sound/pcm.h>
32#include <sound/initval.h>
33#include "lola.h"
34
35/* Standard options */
36static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
37static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
38static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
39
40module_param_array(index, int, NULL, 0444);
41MODULE_PARM_DESC(index, "Index value for Digigram Lola driver.");
42module_param_array(id, charp, NULL, 0444);
43MODULE_PARM_DESC(id, "ID string for Digigram Lola driver.");
44module_param_array(enable, bool, NULL, 0444);
45MODULE_PARM_DESC(enable, "Enable Digigram Lola driver.");
46
47/* Lola-specific options */
48
49/* for instance use always max granularity which is compatible
50 * with all sample rates
51 */
52static int granularity[SNDRV_CARDS] = {
53 [0 ... (SNDRV_CARDS - 1)] = LOLA_GRANULARITY_MAX
54};
55
56/* below a sample_rate of 16kHz the analogue audio quality is NOT excellent */
57static int sample_rate_min[SNDRV_CARDS] = {
58 [0 ... (SNDRV_CARDS - 1) ] = 16000
59};
60
61module_param_array(granularity, int, NULL, 0444);
62MODULE_PARM_DESC(granularity, "Granularity value");
63module_param_array(sample_rate_min, int, NULL, 0444);
64MODULE_PARM_DESC(sample_rate_min, "Minimal sample rate");
65
66/*
67 */
68
69MODULE_LICENSE("GPL");
70MODULE_SUPPORTED_DEVICE("{{Digigram, Lola}}");
71MODULE_DESCRIPTION("Digigram Lola driver");
72MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
73
74#ifdef CONFIG_SND_DEBUG_VERBOSE
75static int debug;
76module_param(debug, int, 0644);
77#define verbose_debug(fmt, args...) \
78 do { if (debug > 1) printk(KERN_DEBUG SFX fmt, ##args); } while (0)
79#else
80#define verbose_debug(fmt, args...)
81#endif
82
83/*
84 * pseudo-codec read/write via CORB/RIRB
85 */
86
87static int corb_send_verb(struct lola *chip, unsigned int nid,
88 unsigned int verb, unsigned int data,
89 unsigned int extdata)
90{
91 unsigned long flags;
92 int ret = -EIO;
93
94 chip->last_cmd_nid = nid;
95 chip->last_verb = verb;
96 chip->last_data = data;
97 chip->last_extdata = extdata;
98 data |= (nid << 20) | (verb << 8);
99
100 spin_lock_irqsave(&chip->reg_lock, flags);
101 if (chip->rirb.cmds < LOLA_CORB_ENTRIES - 1) {
102 unsigned int wp = chip->corb.wp + 1;
103 wp %= LOLA_CORB_ENTRIES;
104 chip->corb.wp = wp;
105 chip->corb.buf[wp * 2] = cpu_to_le32(data);
106 chip->corb.buf[wp * 2 + 1] = cpu_to_le32(extdata);
107 lola_writew(chip, BAR0, CORBWP, wp);
108 chip->rirb.cmds++;
109 smp_wmb();
110 ret = 0;
111 }
112 spin_unlock_irqrestore(&chip->reg_lock, flags);
113 return ret;
114}
115
116static void lola_queue_unsol_event(struct lola *chip, unsigned int res,
117 unsigned int res_ex)
118{
119 lola_update_ext_clock_freq(chip, res);
120}
121
122/* retrieve RIRB entry - called from interrupt handler */
123static void lola_update_rirb(struct lola *chip)
124{
125 unsigned int rp, wp;
126 u32 res, res_ex;
127
128 wp = lola_readw(chip, BAR0, RIRBWP);
129 if (wp == chip->rirb.wp)
130 return;
131 chip->rirb.wp = wp;
132
133 while (chip->rirb.rp != wp) {
134 chip->rirb.rp++;
135 chip->rirb.rp %= LOLA_CORB_ENTRIES;
136
137 rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */
138 res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]);
139 res = le32_to_cpu(chip->rirb.buf[rp]);
140 if (res_ex & LOLA_RIRB_EX_UNSOL_EV)
141 lola_queue_unsol_event(chip, res, res_ex);
142 else if (chip->rirb.cmds) {
143 chip->res = res;
144 chip->res_ex = res_ex;
145 smp_wmb();
146 chip->rirb.cmds--;
147 }
148 }
149}
150
151static int rirb_get_response(struct lola *chip, unsigned int *val,
152 unsigned int *extval)
153{
154 unsigned long timeout;
155
156 again:
157 timeout = jiffies + msecs_to_jiffies(1000);
158 for (;;) {
159 if (chip->polling_mode) {
160 spin_lock_irq(&chip->reg_lock);
161 lola_update_rirb(chip);
162 spin_unlock_irq(&chip->reg_lock);
163 }
164 if (!chip->rirb.cmds) {
165 *val = chip->res;
166 if (extval)
167 *extval = chip->res_ex;
168 verbose_debug("get_response: %x, %x\n",
169 chip->res, chip->res_ex);
170 if (chip->res_ex & LOLA_RIRB_EX_ERROR) {
171 printk(KERN_WARNING SFX "RIRB ERROR: "
172 "NID=%x, verb=%x, data=%x, ext=%x\n",
173 chip->last_cmd_nid,
174 chip->last_verb, chip->last_data,
175 chip->last_extdata);
176 return -EIO;
177 }
178 return 0;
179 }
180 if (time_after(jiffies, timeout))
181 break;
182 udelay(20);
183 cond_resched();
184 }
185 printk(KERN_WARNING SFX "RIRB response error\n");
186 if (!chip->polling_mode) {
187 printk(KERN_WARNING SFX "switching to polling mode\n");
188 chip->polling_mode = 1;
189 goto again;
190 }
191 return -EIO;
192}
193
194/* aynchronous write of a codec verb with data */
195int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
196 unsigned int data, unsigned int extdata)
197{
198 verbose_debug("codec_write NID=%x, verb=%x, data=%x, ext=%x\n",
199 nid, verb, data, extdata);
200 return corb_send_verb(chip, nid, verb, data, extdata);
201}
202
203/* write a codec verb with data and read the returned status */
204int lola_codec_read(struct lola *chip, unsigned int nid, unsigned int verb,
205 unsigned int data, unsigned int extdata,
206 unsigned int *val, unsigned int *extval)
207{
208 int err;
209
210 verbose_debug("codec_read NID=%x, verb=%x, data=%x, ext=%x\n",
211 nid, verb, data, extdata);
212 err = corb_send_verb(chip, nid, verb, data, extdata);
213 if (err < 0)
214 return err;
215 err = rirb_get_response(chip, val, extval);
216 return err;
217}
218
219/* flush all pending codec writes */
220int lola_codec_flush(struct lola *chip)
221{
222 unsigned int tmp;
223 return rirb_get_response(chip, &tmp, NULL);
224}
225
226/*
227 * interrupt handler
228 */
229static irqreturn_t lola_interrupt(int irq, void *dev_id)
230{
231 struct lola *chip = dev_id;
232 unsigned int notify_ins, notify_outs, error_ins, error_outs;
233 int handled = 0;
234 int i;
235
236 notify_ins = notify_outs = error_ins = error_outs = 0;
237 spin_lock(&chip->reg_lock);
238 for (;;) {
239 unsigned int status, in_sts, out_sts;
240 unsigned int reg;
241
242 status = lola_readl(chip, BAR1, DINTSTS);
243 if (!status || status == -1)
244 break;
245
246 in_sts = lola_readl(chip, BAR1, DIINTSTS);
247 out_sts = lola_readl(chip, BAR1, DOINTSTS);
248
249 /* clear Input Interrupts */
250 for (i = 0; in_sts && i < chip->pcm[CAPT].num_streams; i++) {
251 if (!(in_sts & (1 << i)))
252 continue;
253 in_sts &= ~(1 << i);
254 reg = lola_dsd_read(chip, i, STS);
255 if (reg & LOLA_DSD_STS_DESE) /* error */
256 error_ins |= (1 << i);
257 if (reg & LOLA_DSD_STS_BCIS) /* notify */
258 notify_ins |= (1 << i);
259 /* clear */
260 lola_dsd_write(chip, i, STS, reg);
261 }
262
263 /* clear Output Interrupts */
264 for (i = 0; out_sts && i < chip->pcm[PLAY].num_streams; i++) {
265 if (!(out_sts & (1 << i)))
266 continue;
267 out_sts &= ~(1 << i);
268 reg = lola_dsd_read(chip, i + MAX_STREAM_IN_COUNT, STS);
269 if (reg & LOLA_DSD_STS_DESE) /* error */
270 error_outs |= (1 << i);
271 if (reg & LOLA_DSD_STS_BCIS) /* notify */
272 notify_outs |= (1 << i);
273 lola_dsd_write(chip, i + MAX_STREAM_IN_COUNT, STS, reg);
274 }
275
276 if (status & LOLA_DINT_CTRL) {
277 unsigned char rbsts; /* ring status is byte access */
278 rbsts = lola_readb(chip, BAR0, RIRBSTS);
279 rbsts &= LOLA_RIRB_INT_MASK;
280 if (rbsts)
281 lola_writeb(chip, BAR0, RIRBSTS, rbsts);
282 rbsts = lola_readb(chip, BAR0, CORBSTS);
283 rbsts &= LOLA_CORB_INT_MASK;
284 if (rbsts)
285 lola_writeb(chip, BAR0, CORBSTS, rbsts);
286
287 lola_update_rirb(chip);
288 }
289
290 if (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR)) {
291 /* clear global fifo error interrupt */
292 lola_writel(chip, BAR1, DINTSTS,
293 (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR)));
294 }
295 handled = 1;
296 }
297 spin_unlock(&chip->reg_lock);
298
299 lola_pcm_update(chip, &chip->pcm[CAPT], notify_ins);
300 lola_pcm_update(chip, &chip->pcm[PLAY], notify_outs);
301
302 return IRQ_RETVAL(handled);
303}
304
305
306/*
307 * controller
308 */
309static int reset_controller(struct lola *chip)
310{
311 unsigned int gctl = lola_readl(chip, BAR0, GCTL);
312 unsigned long end_time;
313
314 if (gctl) {
315 /* to be sure */
316 lola_writel(chip, BAR1, BOARD_MODE, 0);
317 return 0;
318 }
319
320 chip->cold_reset = 1;
321 lola_writel(chip, BAR0, GCTL, LOLA_GCTL_RESET);
322 end_time = jiffies + msecs_to_jiffies(200);
323 do {
324 msleep(1);
325 gctl = lola_readl(chip, BAR0, GCTL);
326 if (gctl)
327 break;
328 } while (time_before(jiffies, end_time));
329 if (!gctl) {
330 printk(KERN_ERR SFX "cannot reset controller\n");
331 return -EIO;
332 }
333 return 0;
334}
335
336static void lola_irq_enable(struct lola *chip)
337{
338 unsigned int val;
339
340 /* enalbe all I/O streams */
341 val = (1 << chip->pcm[PLAY].num_streams) - 1;
342 lola_writel(chip, BAR1, DOINTCTL, val);
343 val = (1 << chip->pcm[CAPT].num_streams) - 1;
344 lola_writel(chip, BAR1, DIINTCTL, val);
345
346 /* enable global irqs */
347 val = LOLA_DINT_GLOBAL | LOLA_DINT_CTRL | LOLA_DINT_FIFOERR |
348 LOLA_DINT_MUERR;
349 lola_writel(chip, BAR1, DINTCTL, val);
350}
351
352static void lola_irq_disable(struct lola *chip)
353{
354 lola_writel(chip, BAR1, DINTCTL, 0);
355 lola_writel(chip, BAR1, DIINTCTL, 0);
356 lola_writel(chip, BAR1, DOINTCTL, 0);
357}
358
359static int setup_corb_rirb(struct lola *chip)
360{
361 int err;
362 unsigned char tmp;
363 unsigned long end_time;
364
365 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
366 snd_dma_pci_data(chip->pci),
367 PAGE_SIZE, &chip->rb);
368 if (err < 0)
369 return err;
370
371 chip->corb.addr = chip->rb.addr;
372 chip->corb.buf = (u32 *)chip->rb.area;
373 chip->rirb.addr = chip->rb.addr + 2048;
374 chip->rirb.buf = (u32 *)(chip->rb.area + 2048);
375
376 /* disable ringbuffer DMAs */
377 lola_writeb(chip, BAR0, RIRBCTL, 0);
378 lola_writeb(chip, BAR0, CORBCTL, 0);
379
380 end_time = jiffies + msecs_to_jiffies(200);
381 do {
382 if (!lola_readb(chip, BAR0, RIRBCTL) &&
383 !lola_readb(chip, BAR0, CORBCTL))
384 break;
385 msleep(1);
386 } while (time_before(jiffies, end_time));
387
388 /* CORB set up */
389 lola_writel(chip, BAR0, CORBLBASE, (u32)chip->corb.addr);
390 lola_writel(chip, BAR0, CORBUBASE, upper_32_bits(chip->corb.addr));
391 /* set the corb size to 256 entries */
392 lola_writeb(chip, BAR0, CORBSIZE, 0x02);
393 /* set the corb write pointer to 0 */
394 lola_writew(chip, BAR0, CORBWP, 0);
395 /* reset the corb hw read pointer */
396 lola_writew(chip, BAR0, CORBRP, LOLA_RBRWP_CLR);
397 /* enable corb dma */
398 lola_writeb(chip, BAR0, CORBCTL, LOLA_RBCTL_DMA_EN);
399 /* clear flags if set */
400 tmp = lola_readb(chip, BAR0, CORBSTS) & LOLA_CORB_INT_MASK;
401 if (tmp)
402 lola_writeb(chip, BAR0, CORBSTS, tmp);
403 chip->corb.wp = 0;
404
405 /* RIRB set up */
406 lola_writel(chip, BAR0, RIRBLBASE, (u32)chip->rirb.addr);
407 lola_writel(chip, BAR0, RIRBUBASE, upper_32_bits(chip->rirb.addr));
408 /* set the rirb size to 256 entries */
409 lola_writeb(chip, BAR0, RIRBSIZE, 0x02);
410 /* reset the rirb hw write pointer */
411 lola_writew(chip, BAR0, RIRBWP, LOLA_RBRWP_CLR);
412 /* set N=1, get RIRB response interrupt for new entry */
413 lola_writew(chip, BAR0, RINTCNT, 1);
414 /* enable rirb dma and response irq */
415 lola_writeb(chip, BAR0, RIRBCTL, LOLA_RBCTL_DMA_EN | LOLA_RBCTL_IRQ_EN);
416 /* clear flags if set */
417 tmp = lola_readb(chip, BAR0, RIRBSTS) & LOLA_RIRB_INT_MASK;
418 if (tmp)
419 lola_writeb(chip, BAR0, RIRBSTS, tmp);
420 chip->rirb.rp = chip->rirb.cmds = 0;
421
422 return 0;
423}
424
425static void stop_corb_rirb(struct lola *chip)
426{
427 /* disable ringbuffer DMAs */
428 lola_writeb(chip, BAR0, RIRBCTL, 0);
429 lola_writeb(chip, BAR0, CORBCTL, 0);
430}
431
432static void lola_reset_setups(struct lola *chip)
433{
434 /* update the granularity */
435 lola_set_granularity(chip, chip->granularity, true);
436 /* update the sample clock */
437 lola_set_clock_index(chip, chip->clock.cur_index);
438 /* enable unsolicited events of the clock widget */
439 lola_enable_clock_events(chip);
440 /* update the analog gains */
441 lola_setup_all_analog_gains(chip, CAPT, false); /* input, update */
442 /* update SRC configuration if applicable */
443 lola_set_src_config(chip, chip->input_src_mask, false);
444 /* update the analog outputs */
445 lola_setup_all_analog_gains(chip, PLAY, false); /* output, update */
446}
447
448static int lola_parse_tree(struct lola *chip)
449{
450 unsigned int val;
451 int nid, err;
452
453 err = lola_read_param(chip, 0, LOLA_PAR_VENDOR_ID, &val);
454 if (err < 0) {
455 printk(KERN_ERR SFX "Can't read VENDOR_ID\n");
456 return err;
457 }
458 val >>= 16;
459 if (val != 0x1369) {
460 printk(KERN_ERR SFX "Unknown codec vendor 0x%x\n", val);
461 return -EINVAL;
462 }
463
464 err = lola_read_param(chip, 1, LOLA_PAR_FUNCTION_TYPE, &val);
465 if (err < 0) {
466 printk(KERN_ERR SFX "Can't read FUNCTION_TYPE for 0x%x\n", nid);
467 return err;
468 }
469 if (val != 1) {
470 printk(KERN_ERR SFX "Unknown function type %d\n", val);
471 return -EINVAL;
472 }
473
474 err = lola_read_param(chip, 1, LOLA_PAR_SPECIFIC_CAPS, &val);
475 if (err < 0) {
476 printk(KERN_ERR SFX "Can't read SPECCAPS\n");
477 return err;
478 }
479 chip->lola_caps = val;
480 chip->pin[CAPT].num_pins = LOLA_AFG_INPUT_PIN_COUNT(chip->lola_caps);
481 chip->pin[PLAY].num_pins = LOLA_AFG_OUTPUT_PIN_COUNT(chip->lola_caps);
482 snd_printdd(SFX "speccaps=0x%x, pins in=%d, out=%d\n",
483 chip->lola_caps,
484 chip->pin[CAPT].num_pins, chip->pin[PLAY].num_pins);
485
486 if (chip->pin[CAPT].num_pins > MAX_AUDIO_INOUT_COUNT ||
487 chip->pin[PLAY].num_pins > MAX_AUDIO_INOUT_COUNT) {
488 printk(KERN_ERR SFX "Invalid Lola-spec caps 0x%x\n", val);
489 return -EINVAL;
490 }
491
492 nid = 0x02;
493 err = lola_init_pcm(chip, CAPT, &nid);
494 if (err < 0)
495 return err;
496 err = lola_init_pcm(chip, PLAY, &nid);
497 if (err < 0)
498 return err;
499
500 err = lola_init_pins(chip, CAPT, &nid);
501 if (err < 0)
502 return err;
503 err = lola_init_pins(chip, PLAY, &nid);
504 if (err < 0)
505 return err;
506
507 if (LOLA_AFG_CLOCK_WIDGET_PRESENT(chip->lola_caps)) {
508 err = lola_init_clock_widget(chip, nid);
509 if (err < 0)
510 return err;
511 nid++;
512 }
513 if (LOLA_AFG_MIXER_WIDGET_PRESENT(chip->lola_caps)) {
514 err = lola_init_mixer_widget(chip, nid);
515 if (err < 0)
516 return err;
517 nid++;
518 }
519
520 /* enable unsolicited events of the clock widget */
521 err = lola_enable_clock_events(chip);
522 if (err < 0)
523 return err;
524
525 /* if last ResetController was not a ColdReset, we don't know
526 * the state of the card; initialize here again
527 */
528 if (!chip->cold_reset) {
529 lola_reset_setups(chip);
530 chip->cold_reset = 1;
531 } else {
532 /* set the granularity if it is not the default */
533 if (chip->granularity != LOLA_GRANULARITY_MIN)
534 lola_set_granularity(chip, chip->granularity, true);
535 }
536
537 return 0;
538}
539
540static void lola_stop_hw(struct lola *chip)
541{
542 stop_corb_rirb(chip);
543 lola_irq_disable(chip);
544}
545
546static void lola_free(struct lola *chip)
547{
548 if (chip->initialized)
549 lola_stop_hw(chip);
550 lola_free_pcm(chip);
551 lola_free_mixer(chip);
552 if (chip->irq >= 0)
553 free_irq(chip->irq, (void *)chip);
554 if (chip->bar[0].remap_addr)
555 iounmap(chip->bar[0].remap_addr);
556 if (chip->bar[1].remap_addr)
557 iounmap(chip->bar[1].remap_addr);
558 if (chip->rb.area)
559 snd_dma_free_pages(&chip->rb);
560 pci_release_regions(chip->pci);
561 pci_disable_device(chip->pci);
562 kfree(chip);
563}
564
565static int lola_dev_free(struct snd_device *device)
566{
567 lola_free(device->device_data);
568 return 0;
569}
570
571static int __devinit lola_create(struct snd_card *card, struct pci_dev *pci,
572 int dev, struct lola **rchip)
573{
574 struct lola *chip;
575 int err;
576 unsigned int dever;
577 static struct snd_device_ops ops = {
578 .dev_free = lola_dev_free,
579 };
580
581 *rchip = NULL;
582
583 err = pci_enable_device(pci);
584 if (err < 0)
585 return err;
586
587 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
588 if (!chip) {
589 snd_printk(KERN_ERR SFX "cannot allocate chip\n");
590 pci_disable_device(pci);
591 return -ENOMEM;
592 }
593
594 spin_lock_init(&chip->reg_lock);
595 mutex_init(&chip->open_mutex);
596 chip->card = card;
597 chip->pci = pci;
598 chip->irq = -1;
599
600 chip->granularity = granularity[dev];
601 switch (chip->granularity) {
602 case 8:
603 chip->sample_rate_max = 48000;
604 break;
605 case 16:
606 chip->sample_rate_max = 96000;
607 break;
608 case 32:
609 chip->sample_rate_max = 192000;
610 break;
611 default:
612 snd_printk(KERN_WARNING SFX
613 "Invalid granularity %d, reset to %d\n",
614 chip->granularity, LOLA_GRANULARITY_MAX);
615 chip->granularity = LOLA_GRANULARITY_MAX;
616 chip->sample_rate_max = 192000;
617 break;
618 }
619 chip->sample_rate_min = sample_rate_min[dev];
620 if (chip->sample_rate_min > chip->sample_rate_max) {
621 snd_printk(KERN_WARNING SFX
622 "Invalid sample_rate_min %d, reset to 16000\n",
623 chip->sample_rate_min);
624 chip->sample_rate_min = 16000;
625 }
626
627 err = pci_request_regions(pci, DRVNAME);
628 if (err < 0) {
629 kfree(chip);
630 pci_disable_device(pci);
631 return err;
632 }
633
634 chip->bar[0].addr = pci_resource_start(pci, 0);
635 chip->bar[0].remap_addr = pci_ioremap_bar(pci, 0);
636 chip->bar[1].addr = pci_resource_start(pci, 2);
637 chip->bar[1].remap_addr = pci_ioremap_bar(pci, 2);
638 if (!chip->bar[0].remap_addr || !chip->bar[1].remap_addr) {
639 snd_printk(KERN_ERR SFX "ioremap error\n");
640 err = -ENXIO;
641 goto errout;
642 }
643
644 pci_set_master(pci);
645
646 err = reset_controller(chip);
647 if (err < 0)
648 goto errout;
649
650 if (request_irq(pci->irq, lola_interrupt, IRQF_SHARED,
651 DRVNAME, chip)) {
652 printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq);
653 err = -EBUSY;
654 goto errout;
655 }
656 chip->irq = pci->irq;
657 synchronize_irq(chip->irq);
658
659 dever = lola_readl(chip, BAR1, DEVER);
660 chip->pcm[CAPT].num_streams = (dever >> 0) & 0x3ff;
661 chip->pcm[PLAY].num_streams = (dever >> 10) & 0x3ff;
662 chip->version = (dever >> 24) & 0xff;
663 snd_printdd(SFX "streams in=%d, out=%d, version=0x%x\n",
664 chip->pcm[CAPT].num_streams, chip->pcm[PLAY].num_streams,
665 chip->version);
666
667 /* Test LOLA_BAR1_DEVER */
668 if (chip->pcm[CAPT].num_streams > MAX_STREAM_IN_COUNT ||
669 chip->pcm[PLAY].num_streams > MAX_STREAM_OUT_COUNT ||
670 (!chip->pcm[CAPT].num_streams &&
671 !chip->pcm[PLAY].num_streams)) {
672 printk(KERN_ERR SFX "invalid DEVER = %x\n", dever);
673 err = -EINVAL;
674 goto errout;
675 }
676
677 err = setup_corb_rirb(chip);
678 if (err < 0)
679 goto errout;
680
681 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
682 if (err < 0) {
683 snd_printk(KERN_ERR SFX "Error creating device [card]!\n");
684 goto errout;
685 }
686
687 strcpy(card->driver, "Lola");
688 strlcpy(card->shortname, "Digigram Lola", sizeof(card->shortname));
689 snprintf(card->longname, sizeof(card->longname),
690 "%s at 0x%lx irq %i",
691 card->shortname, chip->bar[0].addr, chip->irq);
692 strcpy(card->mixername, card->shortname);
693
694 lola_irq_enable(chip);
695
696 chip->initialized = 1;
697 *rchip = chip;
698 return 0;
699
700 errout:
701 lola_free(chip);
702 return err;
703}
704
705static int __devinit lola_probe(struct pci_dev *pci,
706 const struct pci_device_id *pci_id)
707{
708 static int dev;
709 struct snd_card *card;
710 struct lola *chip;
711 int err;
712
713 if (dev >= SNDRV_CARDS)
714 return -ENODEV;
715 if (!enable[dev]) {
716 dev++;
717 return -ENOENT;
718 }
719
720 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
721 if (err < 0) {
722 snd_printk(KERN_ERR SFX "Error creating card!\n");
723 return err;
724 }
725
726 snd_card_set_dev(card, &pci->dev);
727
728 err = lola_create(card, pci, dev, &chip);
729 if (err < 0)
730 goto out_free;
731 card->private_data = chip;
732
733 err = lola_parse_tree(chip);
734 if (err < 0)
735 goto out_free;
736
737 err = lola_create_pcm(chip);
738 if (err < 0)
739 goto out_free;
740
741 err = lola_create_mixer(chip);
742 if (err < 0)
743 goto out_free;
744
745 lola_proc_debug_new(chip);
746
747 err = snd_card_register(card);
748 if (err < 0)
749 goto out_free;
750
751 pci_set_drvdata(pci, card);
752 dev++;
753 return err;
754out_free:
755 snd_card_free(card);
756 return err;
757}
758
759static void __devexit lola_remove(struct pci_dev *pci)
760{
761 snd_card_free(pci_get_drvdata(pci));
762 pci_set_drvdata(pci, NULL);
763}
764
765/* PCI IDs */
766static DEFINE_PCI_DEVICE_TABLE(lola_ids) = {
767 { PCI_VDEVICE(DIGIGRAM, 0x0001) },
768 { 0, }
769};
770MODULE_DEVICE_TABLE(pci, lola_ids);
771
772/* pci_driver definition */
773static struct pci_driver driver = {
774 .name = DRVNAME,
775 .id_table = lola_ids,
776 .probe = lola_probe,
777 .remove = __devexit_p(lola_remove),
778};
779
780static int __init alsa_card_lola_init(void)
781{
782 return pci_register_driver(&driver);
783}
784
785static void __exit alsa_card_lola_exit(void)
786{
787 pci_unregister_driver(&driver);
788}
789
790module_init(alsa_card_lola_init)
791module_exit(alsa_card_lola_exit)
diff --git a/sound/pci/lola/lola.h b/sound/pci/lola/lola.h
new file mode 100644
index 000000000000..d5708e29b16d
--- /dev/null
+++ b/sound/pci/lola/lola.h
@@ -0,0 +1,527 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#ifndef _LOLA_H
22#define _LOLA_H
23
24#define DRVNAME "snd-lola"
25#define SFX DRVNAME ": "
26
27/*
28 * Lola HD Audio Registers BAR0
29 */
30#define LOLA_BAR0_GCAP 0x00
31#define LOLA_BAR0_VMIN 0x02
32#define LOLA_BAR0_VMAJ 0x03
33#define LOLA_BAR0_OUTPAY 0x04
34#define LOLA_BAR0_INPAY 0x06
35#define LOLA_BAR0_GCTL 0x08
36#define LOLA_BAR0_WAKEEN 0x0c
37#define LOLA_BAR0_STATESTS 0x0e
38#define LOLA_BAR0_GSTS 0x10
39#define LOLA_BAR0_OUTSTRMPAY 0x18
40#define LOLA_BAR0_INSTRMPAY 0x1a
41#define LOLA_BAR0_INTCTL 0x20
42#define LOLA_BAR0_INTSTS 0x24
43#define LOLA_BAR0_WALCLK 0x30
44#define LOLA_BAR0_SSYNC 0x38
45
46#define LOLA_BAR0_CORBLBASE 0x40
47#define LOLA_BAR0_CORBUBASE 0x44
48#define LOLA_BAR0_CORBWP 0x48 /* no ULONG access */
49#define LOLA_BAR0_CORBRP 0x4a /* no ULONG access */
50#define LOLA_BAR0_CORBCTL 0x4c /* no ULONG access */
51#define LOLA_BAR0_CORBSTS 0x4d /* UCHAR access only */
52#define LOLA_BAR0_CORBSIZE 0x4e /* no ULONG access */
53
54#define LOLA_BAR0_RIRBLBASE 0x50
55#define LOLA_BAR0_RIRBUBASE 0x54
56#define LOLA_BAR0_RIRBWP 0x58
57#define LOLA_BAR0_RINTCNT 0x5a /* no ULONG access */
58#define LOLA_BAR0_RIRBCTL 0x5c
59#define LOLA_BAR0_RIRBSTS 0x5d /* UCHAR access only */
60#define LOLA_BAR0_RIRBSIZE 0x5e /* no ULONG access */
61
62#define LOLA_BAR0_ICW 0x60
63#define LOLA_BAR0_IRR 0x64
64#define LOLA_BAR0_ICS 0x68
65#define LOLA_BAR0_DPLBASE 0x70
66#define LOLA_BAR0_DPUBASE 0x74
67
68/* stream register offsets from stream base 0x80 */
69#define LOLA_BAR0_SD0_OFFSET 0x80
70#define LOLA_REG0_SD_CTL 0x00
71#define LOLA_REG0_SD_STS 0x03
72#define LOLA_REG0_SD_LPIB 0x04
73#define LOLA_REG0_SD_CBL 0x08
74#define LOLA_REG0_SD_LVI 0x0c
75#define LOLA_REG0_SD_FIFOW 0x0e
76#define LOLA_REG0_SD_FIFOSIZE 0x10
77#define LOLA_REG0_SD_FORMAT 0x12
78#define LOLA_REG0_SD_BDLPL 0x18
79#define LOLA_REG0_SD_BDLPU 0x1c
80
81/*
82 * Lola Digigram Registers BAR1
83 */
84#define LOLA_BAR1_FPGAVER 0x00
85#define LOLA_BAR1_DEVER 0x04
86#define LOLA_BAR1_UCBMV 0x08
87#define LOLA_BAR1_JTAG 0x0c
88#define LOLA_BAR1_UARTRX 0x10
89#define LOLA_BAR1_UARTTX 0x14
90#define LOLA_BAR1_UARTCR 0x18
91#define LOLA_BAR1_NVRAMVER 0x1c
92#define LOLA_BAR1_CTRLSPI 0x20
93#define LOLA_BAR1_DSPI 0x24
94#define LOLA_BAR1_AISPI 0x28
95#define LOLA_BAR1_GRAN 0x2c
96
97#define LOLA_BAR1_DINTCTL 0x80
98#define LOLA_BAR1_DIINTCTL 0x84
99#define LOLA_BAR1_DOINTCTL 0x88
100#define LOLA_BAR1_LRC 0x90
101#define LOLA_BAR1_DINTSTS 0x94
102#define LOLA_BAR1_DIINTSTS 0x98
103#define LOLA_BAR1_DOINTSTS 0x9c
104
105#define LOLA_BAR1_DSD0_OFFSET 0xa0
106#define LOLA_BAR1_DSD_SIZE 0x18
107
108#define LOLA_BAR1_DSDnSTS 0x00
109#define LOLA_BAR1_DSDnLPIB 0x04
110#define LOLA_BAR1_DSDnCTL 0x08
111#define LOLA_BAR1_DSDnLVI 0x0c
112#define LOLA_BAR1_DSDnBDPL 0x10
113#define LOLA_BAR1_DSDnBDPU 0x14
114
115#define LOLA_BAR1_SSYNC 0x03e8
116
117#define LOLA_BAR1_BOARD_CTRL 0x0f00
118#define LOLA_BAR1_BOARD_MODE 0x0f02
119
120#define LOLA_BAR1_SOURCE_GAIN_ENABLE 0x1000
121#define LOLA_BAR1_DEST00_MIX_GAIN_ENABLE 0x1004
122#define LOLA_BAR1_DEST31_MIX_GAIN_ENABLE 0x1080
123#define LOLA_BAR1_SOURCE00_01_GAIN 0x1084
124#define LOLA_BAR1_SOURCE30_31_GAIN 0x10c0
125#define LOLA_BAR1_SOURCE_GAIN(src) \
126 (LOLA_BAR1_SOURCE00_01_GAIN + (src) * 2)
127#define LOLA_BAR1_DEST00_MIX00_01_GAIN 0x10c4
128#define LOLA_BAR1_DEST00_MIX30_31_GAIN 0x1100
129#define LOLA_BAR1_DEST01_MIX00_01_GAIN 0x1104
130#define LOLA_BAR1_DEST01_MIX30_31_GAIN 0x1140
131#define LOLA_BAR1_DEST31_MIX00_01_GAIN 0x1884
132#define LOLA_BAR1_DEST31_MIX30_31_GAIN 0x18c0
133#define LOLA_BAR1_MIX_GAIN(dest, mix) \
134 (LOLA_BAR1_DEST00_MIX00_01_GAIN + (dest) * 0x40 + (mix) * 2)
135#define LOLA_BAR1_ANALOG_CLIP_IN 0x18c4
136#define LOLA_BAR1_PEAKMETERS_SOURCE00_01 0x18c8
137#define LOLA_BAR1_PEAKMETERS_SOURCE30_31 0x1904
138#define LOLA_BAR1_PEAKMETERS_SOURCE(src) \
139 (LOLA_BAR1_PEAKMETERS_SOURCE00_01 + (src) * 2)
140#define LOLA_BAR1_PEAKMETERS_DEST00_01 0x1908
141#define LOLA_BAR1_PEAKMETERS_DEST30_31 0x1944
142#define LOLA_BAR1_PEAKMETERS_DEST(dest) \
143 (LOLA_BAR1_PEAKMETERS_DEST00_01 + (dest) * 2)
144#define LOLA_BAR1_PEAKMETERS_AGC00_01 0x1948
145#define LOLA_BAR1_PEAKMETERS_AGC14_15 0x1964
146#define LOLA_BAR1_PEAKMETERS_AGC(x) \
147 (LOLA_BAR1_PEAKMETERS_AGC00_01 + (x) * 2)
148
149/* GCTL reset bit */
150#define LOLA_GCTL_RESET (1 << 0)
151/* GCTL unsolicited response enable bit */
152#define LOLA_GCTL_UREN (1 << 8)
153
154/* CORB/RIRB control, read/write pointer */
155#define LOLA_RBCTL_DMA_EN 0x02 /* enable DMA */
156#define LOLA_RBCTL_IRQ_EN 0x01 /* enable IRQ */
157#define LOLA_RBRWP_CLR 0x8000 /* read/write pointer clear */
158
159#define LOLA_RIRB_EX_UNSOL_EV 0x40000000
160#define LOLA_RIRB_EX_ERROR 0x80000000
161
162/* CORB int mask: CMEI[0] */
163#define LOLA_CORB_INT_CMEI 0x01
164#define LOLA_CORB_INT_MASK LOLA_CORB_INT_CMEI
165
166/* RIRB int mask: overrun[2], response[0] */
167#define LOLA_RIRB_INT_RESPONSE 0x01
168#define LOLA_RIRB_INT_OVERRUN 0x04
169#define LOLA_RIRB_INT_MASK (LOLA_RIRB_INT_RESPONSE | LOLA_RIRB_INT_OVERRUN)
170
171/* DINTCTL and DINTSTS */
172#define LOLA_DINT_GLOBAL 0x80000000 /* global interrupt enable bit */
173#define LOLA_DINT_CTRL 0x40000000 /* controller interrupt enable bit */
174#define LOLA_DINT_FIFOERR 0x20000000 /* global fifo error enable bit */
175#define LOLA_DINT_MUERR 0x10000000 /* global microcontroller underrun error */
176
177/* DSDnCTL bits */
178#define LOLA_DSD_CTL_SRST 0x01 /* stream reset bit */
179#define LOLA_DSD_CTL_SRUN 0x02 /* stream DMA start bit */
180#define LOLA_DSD_CTL_IOCE 0x04 /* interrupt on completion enable */
181#define LOLA_DSD_CTL_DEIE 0x10 /* descriptor error interrupt enable */
182#define LOLA_DSD_CTL_VLRCV 0x20 /* valid LRCountValue information in bits 8..31 */
183#define LOLA_LRC_MASK 0xffffff00
184
185/* DSDnSTS */
186#define LOLA_DSD_STS_BCIS 0x04 /* buffer completion interrupt status */
187#define LOLA_DSD_STS_DESE 0x10 /* descriptor error interrupt */
188#define LOLA_DSD_STS_FIFORDY 0x20 /* fifo ready */
189
190#define LOLA_CORB_ENTRIES 256
191
192#define MAX_STREAM_IN_COUNT 16
193#define MAX_STREAM_OUT_COUNT 16
194#define MAX_STREAM_COUNT 16
195#define MAX_PINS MAX_STREAM_COUNT
196#define MAX_STREAM_BUFFER_COUNT 16
197#define MAX_AUDIO_INOUT_COUNT 16
198
199#define LOLA_CLOCK_TYPE_INTERNAL 0
200#define LOLA_CLOCK_TYPE_AES 1
201#define LOLA_CLOCK_TYPE_AES_SYNC 2
202#define LOLA_CLOCK_TYPE_WORDCLOCK 3
203#define LOLA_CLOCK_TYPE_ETHERSOUND 4
204#define LOLA_CLOCK_TYPE_VIDEO 5
205
206#define LOLA_CLOCK_FORMAT_NONE 0
207#define LOLA_CLOCK_FORMAT_NTSC 1
208#define LOLA_CLOCK_FORMAT_PAL 2
209
210#define MAX_SAMPLE_CLOCK_COUNT 48
211
212/* parameters used with mixer widget's mixer capabilities */
213#define LOLA_PEAK_METER_CAN_AGC_MASK 1
214#define LOLA_PEAK_METER_CAN_ANALOG_CLIP_MASK 2
215
216struct lola_bar {
217 unsigned long addr;
218 void __iomem *remap_addr;
219};
220
221/* CORB/RIRB */
222struct lola_rb {
223 u32 *buf; /* CORB/RIRB buffer, 8 byte per each entry */
224 dma_addr_t addr; /* physical address of CORB/RIRB buffer */
225 unsigned short rp, wp; /* read/write pointers */
226 int cmds; /* number of pending requests */
227};
228
229/* Pin widget setup */
230struct lola_pin {
231 unsigned int nid;
232 bool is_analog;
233 unsigned int amp_mute;
234 unsigned int amp_step_size;
235 unsigned int amp_num_steps;
236 unsigned int amp_offset;
237 unsigned int max_level;
238 unsigned int config_default_reg;
239 unsigned int fixed_gain_list_len;
240 unsigned int cur_gain_step;
241};
242
243struct lola_pin_array {
244 unsigned int num_pins;
245 unsigned int num_analog_pins;
246 struct lola_pin pins[MAX_PINS];
247};
248
249/* Clock widget setup */
250struct lola_sample_clock {
251 unsigned int type;
252 unsigned int format;
253 unsigned int freq;
254};
255
256struct lola_clock_widget {
257 unsigned int nid;
258 unsigned int items;
259 unsigned int cur_index;
260 unsigned int cur_freq;
261 bool cur_valid;
262 struct lola_sample_clock sample_clock[MAX_SAMPLE_CLOCK_COUNT];
263 unsigned int idx_lookup[MAX_SAMPLE_CLOCK_COUNT];
264};
265
266#define LOLA_MIXER_DIM 32
267struct lola_mixer_array {
268 u32 src_gain_enable;
269 u32 dest_mix_gain_enable[LOLA_MIXER_DIM];
270 u16 src_gain[LOLA_MIXER_DIM];
271 u16 dest_mix_gain[LOLA_MIXER_DIM][LOLA_MIXER_DIM];
272};
273
274/* Mixer widget setup */
275struct lola_mixer_widget {
276 unsigned int nid;
277 unsigned int caps;
278 struct lola_mixer_array __user *array;
279 struct lola_mixer_array *array_saved;
280 unsigned int src_stream_outs;
281 unsigned int src_phys_ins;
282 unsigned int dest_stream_ins;
283 unsigned int dest_phys_outs;
284 unsigned int src_stream_out_ofs;
285 unsigned int dest_phys_out_ofs;
286 unsigned int src_mask;
287 unsigned int dest_mask;
288};
289
290/* Audio stream */
291struct lola_stream {
292 unsigned int nid; /* audio widget NID */
293 unsigned int index; /* array index */
294 unsigned int dsd; /* DSD index */
295 bool can_float;
296 struct snd_pcm_substream *substream; /* assigned PCM substream */
297 struct lola_stream *master; /* master stream (for multi-channel) */
298
299 /* buffer setup */
300 unsigned int bufsize;
301 unsigned int period_bytes;
302 unsigned int frags;
303
304 /* format + channel setup */
305 unsigned int format_verb;
306
307 /* flags */
308 unsigned int opened:1;
309 unsigned int prepared:1;
310 unsigned int paused:1;
311 unsigned int running:1;
312};
313
314#define PLAY SNDRV_PCM_STREAM_PLAYBACK
315#define CAPT SNDRV_PCM_STREAM_CAPTURE
316
317struct lola_pcm {
318 unsigned int num_streams;
319 struct snd_dma_buffer bdl; /* BDL buffer */
320 struct lola_stream streams[MAX_STREAM_COUNT];
321};
322
323/* card instance */
324struct lola {
325 struct snd_card *card;
326 struct pci_dev *pci;
327
328 /* pci resources */
329 struct lola_bar bar[2];
330 int irq;
331
332 /* locks */
333 spinlock_t reg_lock;
334 struct mutex open_mutex;
335
336 /* CORB/RIRB */
337 struct lola_rb corb;
338 struct lola_rb rirb;
339 unsigned int res, res_ex; /* last read values */
340 /* last command (for debugging) */
341 unsigned int last_cmd_nid, last_verb, last_data, last_extdata;
342
343 /* CORB/RIRB buffers */
344 struct snd_dma_buffer rb;
345
346 /* unsolicited events */
347 unsigned int last_unsol_res;
348
349 /* streams */
350 struct lola_pcm pcm[2];
351
352 /* input src */
353 unsigned int input_src_caps_mask;
354 unsigned int input_src_mask;
355
356 /* pins */
357 struct lola_pin_array pin[2];
358
359 /* clock */
360 struct lola_clock_widget clock;
361 int ref_count_rate;
362 unsigned int sample_rate;
363
364 /* mixer */
365 struct lola_mixer_widget mixer;
366
367 /* hw info */
368 unsigned int version;
369 unsigned int lola_caps;
370
371 /* parameters */
372 unsigned int granularity;
373 unsigned int sample_rate_min;
374 unsigned int sample_rate_max;
375
376 /* flags */
377 unsigned int initialized:1;
378 unsigned int cold_reset:1;
379 unsigned int polling_mode:1;
380
381 /* for debugging */
382 unsigned int debug_res;
383 unsigned int debug_res_ex;
384};
385
386#define BAR0 0
387#define BAR1 1
388
389/* Helper macros */
390#define lola_readl(chip, idx, name) \
391 readl((chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
392#define lola_readw(chip, idx, name) \
393 readw((chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
394#define lola_readb(chip, idx, name) \
395 readb((chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
396#define lola_writel(chip, idx, name, val) \
397 writel((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
398#define lola_writew(chip, idx, name, val) \
399 writew((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
400#define lola_writeb(chip, idx, name, val) \
401 writeb((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
402
403#define lola_dsd_read(chip, dsd, name) \
404 readl((chip)->bar[BAR1].remap_addr + LOLA_BAR1_DSD0_OFFSET + \
405 (LOLA_BAR1_DSD_SIZE * (dsd)) + LOLA_BAR1_DSDn##name)
406#define lola_dsd_write(chip, dsd, name, val) \
407 writel((val), (chip)->bar[BAR1].remap_addr + LOLA_BAR1_DSD0_OFFSET + \
408 (LOLA_BAR1_DSD_SIZE * (dsd)) + LOLA_BAR1_DSDn##name)
409
410/* GET verbs HDAudio */
411#define LOLA_VERB_GET_STREAM_FORMAT 0xa00
412#define LOLA_VERB_GET_AMP_GAIN_MUTE 0xb00
413#define LOLA_VERB_PARAMETERS 0xf00
414#define LOLA_VERB_GET_POWER_STATE 0xf05
415#define LOLA_VERB_GET_CONV 0xf06
416#define LOLA_VERB_GET_UNSOLICITED_RESPONSE 0xf08
417#define LOLA_VERB_GET_DIGI_CONVERT_1 0xf0d
418#define LOLA_VERB_GET_CONFIG_DEFAULT 0xf1c
419#define LOLA_VERB_GET_SUBSYSTEM_ID 0xf20
420/* GET verbs Digigram */
421#define LOLA_VERB_GET_FIXED_GAIN 0xfc0
422#define LOLA_VERB_GET_GAIN_SELECT 0xfc1
423#define LOLA_VERB_GET_MAX_LEVEL 0xfc2
424#define LOLA_VERB_GET_CLOCK_LIST 0xfc3
425#define LOLA_VERB_GET_CLOCK_SELECT 0xfc4
426#define LOLA_VERB_GET_CLOCK_STATUS 0xfc5
427
428/* SET verbs HDAudio */
429#define LOLA_VERB_SET_STREAM_FORMAT 0x200
430#define LOLA_VERB_SET_AMP_GAIN_MUTE 0x300
431#define LOLA_VERB_SET_POWER_STATE 0x705
432#define LOLA_VERB_SET_CHANNEL_STREAMID 0x706
433#define LOLA_VERB_SET_UNSOLICITED_ENABLE 0x708
434#define LOLA_VERB_SET_DIGI_CONVERT_1 0x70d
435/* SET verbs Digigram */
436#define LOLA_VERB_SET_GAIN_SELECT 0xf81
437#define LOLA_VERB_SET_CLOCK_SELECT 0xf84
438#define LOLA_VERB_SET_GRANULARITY_STEPS 0xf86
439#define LOLA_VERB_SET_SOURCE_GAIN 0xf87
440#define LOLA_VERB_SET_MIX_GAIN 0xf88
441#define LOLA_VERB_SET_DESTINATION_GAIN 0xf89
442#define LOLA_VERB_SET_SRC 0xf8a
443
444/* Parameter IDs used with LOLA_VERB_PARAMETERS */
445#define LOLA_PAR_VENDOR_ID 0x00
446#define LOLA_PAR_FUNCTION_TYPE 0x05
447#define LOLA_PAR_AUDIO_WIDGET_CAP 0x09
448#define LOLA_PAR_PCM 0x0a
449#define LOLA_PAR_STREAM_FORMATS 0x0b
450#define LOLA_PAR_PIN_CAP 0x0c
451#define LOLA_PAR_AMP_IN_CAP 0x0d
452#define LOLA_PAR_CONNLIST_LEN 0x0e
453#define LOLA_PAR_POWER_STATE 0x0f
454#define LOLA_PAR_GPIO_CAP 0x11
455#define LOLA_PAR_AMP_OUT_CAP 0x12
456#define LOLA_PAR_SPECIFIC_CAPS 0x80
457#define LOLA_PAR_FIXED_GAIN_LIST 0x81
458
459/* extract results of LOLA_PAR_SPECIFIC_CAPS */
460#define LOLA_AFG_MIXER_WIDGET_PRESENT(res) ((res & (1 << 21)) != 0)
461#define LOLA_AFG_CLOCK_WIDGET_PRESENT(res) ((res & (1 << 20)) != 0)
462#define LOLA_AFG_INPUT_PIN_COUNT(res) ((res >> 10) & 0x2ff)
463#define LOLA_AFG_OUTPUT_PIN_COUNT(res) ((res) & 0x2ff)
464
465/* extract results of LOLA_PAR_AMP_IN_CAP / LOLA_PAR_AMP_OUT_CAP */
466#define LOLA_AMP_MUTE_CAPABLE(res) ((res & (1 << 31)) != 0)
467#define LOLA_AMP_STEP_SIZE(res) ((res >> 24) & 0x7f)
468#define LOLA_AMP_NUM_STEPS(res) ((res >> 12) & 0x3ff)
469#define LOLA_AMP_OFFSET(res) ((res) & 0x3ff)
470
471#define LOLA_GRANULARITY_MIN 8
472#define LOLA_GRANULARITY_MAX 32
473#define LOLA_GRANULARITY_STEP 8
474
475/* parameters used with unsolicited command/response */
476#define LOLA_UNSOLICITED_TAG_MASK 0x3f
477#define LOLA_UNSOLICITED_TAG 0x1a
478#define LOLA_UNSOLICITED_ENABLE 0x80
479#define LOLA_UNSOL_RESP_TAG_OFFSET 26
480
481/* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */
482#define LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(res) ((res >> 2) & 0x1f)
483#define LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(res) ((res >> 7) & 0x1f)
484
485int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
486 unsigned int data, unsigned int extdata);
487int lola_codec_read(struct lola *chip, unsigned int nid, unsigned int verb,
488 unsigned int data, unsigned int extdata,
489 unsigned int *val, unsigned int *extval);
490int lola_codec_flush(struct lola *chip);
491#define lola_read_param(chip, nid, param, val) \
492 lola_codec_read(chip, nid, LOLA_VERB_PARAMETERS, param, 0, val, NULL)
493
494/* PCM */
495int lola_create_pcm(struct lola *chip);
496void lola_free_pcm(struct lola *chip);
497int lola_init_pcm(struct lola *chip, int dir, int *nidp);
498void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits);
499
500/* clock */
501int lola_init_clock_widget(struct lola *chip, int nid);
502int lola_set_granularity(struct lola *chip, unsigned int val, bool force);
503int lola_enable_clock_events(struct lola *chip);
504int lola_set_clock_index(struct lola *chip, unsigned int idx);
505int lola_set_clock(struct lola *chip, int idx);
506int lola_set_sample_rate(struct lola *chip, int rate);
507bool lola_update_ext_clock_freq(struct lola *chip, unsigned int val);
508unsigned int lola_sample_rate_convert(unsigned int coded);
509
510/* mixer */
511int lola_init_pins(struct lola *chip, int dir, int *nidp);
512int lola_init_mixer_widget(struct lola *chip, int nid);
513void lola_free_mixer(struct lola *chip);
514int lola_create_mixer(struct lola *chip);
515int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute);
516void lola_save_mixer(struct lola *chip);
517void lola_restore_mixer(struct lola *chip);
518int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update);
519
520/* proc */
521#ifdef CONFIG_SND_DEBUG
522void lola_proc_debug_new(struct lola *chip);
523#else
524#define lola_proc_debug_new(chip)
525#endif
526
527#endif /* _LOLA_H */
diff --git a/sound/pci/lola/lola_clock.c b/sound/pci/lola/lola_clock.c
new file mode 100644
index 000000000000..72f8ef0ac865
--- /dev/null
+++ b/sound/pci/lola/lola_clock.c
@@ -0,0 +1,323 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include "lola.h"
27
28unsigned int lola_sample_rate_convert(unsigned int coded)
29{
30 unsigned int freq;
31
32 /* base frequency */
33 switch (coded & 0x3) {
34 case 0: freq = 48000; break;
35 case 1: freq = 44100; break;
36 case 2: freq = 32000; break;
37 default: return 0; /* error */
38 }
39
40 /* multiplier / devisor */
41 switch (coded & 0x1c) {
42 case (0 << 2): break;
43 case (4 << 2): break;
44 case (1 << 2): freq *= 2; break;
45 case (2 << 2): freq *= 4; break;
46 case (5 << 2): freq /= 2; break;
47 case (6 << 2): freq /= 4; break;
48 default: return 0; /* error */
49 }
50
51 /* ajustement */
52 switch (coded & 0x60) {
53 case (0 << 5): break;
54 case (1 << 5): freq = (freq * 999) / 1000; break;
55 case (2 << 5): freq = (freq * 1001) / 1000; break;
56 default: return 0; /* error */
57 }
58 return freq;
59}
60
61/*
62 * Granualrity
63 */
64
65#define LOLA_MAXFREQ_AT_GRANULARITY_MIN 48000
66#define LOLA_MAXFREQ_AT_GRANULARITY_BELOW_MAX 96000
67
68static bool check_gran_clock_compatibility(struct lola *chip,
69 unsigned int val,
70 unsigned int freq)
71{
72 if (!chip->granularity)
73 return true;
74
75 if (val < LOLA_GRANULARITY_MIN || val > LOLA_GRANULARITY_MAX ||
76 (val % LOLA_GRANULARITY_STEP) != 0)
77 return false;
78
79 if (val == LOLA_GRANULARITY_MIN) {
80 if (freq > LOLA_MAXFREQ_AT_GRANULARITY_MIN)
81 return false;
82 } else if (val < LOLA_GRANULARITY_MAX) {
83 if (freq > LOLA_MAXFREQ_AT_GRANULARITY_BELOW_MAX)
84 return false;
85 }
86 return true;
87}
88
89int lola_set_granularity(struct lola *chip, unsigned int val, bool force)
90{
91 int err;
92
93 if (!force) {
94 if (val == chip->granularity)
95 return 0;
96#if 0
97 /* change Gran only if there are no streams allocated ! */
98 if (chip->audio_in_alloc_mask || chip->audio_out_alloc_mask)
99 return -EBUSY;
100#endif
101 if (!check_gran_clock_compatibility(chip, val,
102 chip->clock.cur_freq))
103 return -EINVAL;
104 }
105
106 chip->granularity = val;
107 val /= LOLA_GRANULARITY_STEP;
108
109 /* audio function group */
110 err = lola_codec_write(chip, 1, LOLA_VERB_SET_GRANULARITY_STEPS,
111 val, 0);
112 if (err < 0)
113 return err;
114 /* this can be a very slow function !!! */
115 usleep_range(400 * val, 20000);
116 return lola_codec_flush(chip);
117}
118
119/*
120 * Clock widget handling
121 */
122
123int __devinit lola_init_clock_widget(struct lola *chip, int nid)
124{
125 unsigned int val;
126 int i, j, nitems, nb_verbs, idx, idx_list;
127 int err;
128
129 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
130 if (err < 0) {
131 printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
132 return err;
133 }
134
135 if ((val & 0xfff00000) != 0x01f00000) { /* test SubType and Type */
136 snd_printdd("No valid clock widget\n");
137 return 0;
138 }
139
140 chip->clock.nid = nid;
141 chip->clock.items = val & 0xff;
142 snd_printdd("clock_list nid=%x, entries=%d\n", nid,
143 chip->clock.items);
144 if (chip->clock.items > MAX_SAMPLE_CLOCK_COUNT) {
145 printk(KERN_ERR SFX "CLOCK_LIST too big: %d\n",
146 chip->clock.items);
147 return -EINVAL;
148 }
149
150 nitems = chip->clock.items;
151 nb_verbs = (nitems + 3) / 4;
152 idx = 0;
153 idx_list = 0;
154 for (i = 0; i < nb_verbs; i++) {
155 unsigned int res_ex;
156 unsigned short items[4];
157
158 err = lola_codec_read(chip, nid, LOLA_VERB_GET_CLOCK_LIST,
159 idx, 0, &val, &res_ex);
160 if (err < 0) {
161 printk(KERN_ERR SFX "Can't read CLOCK_LIST\n");
162 return -EINVAL;
163 }
164
165 items[0] = val & 0xfff;
166 items[1] = (val >> 16) & 0xfff;
167 items[2] = res_ex & 0xfff;
168 items[3] = (res_ex >> 16) & 0xfff;
169
170 for (j = 0; j < 4; j++) {
171 unsigned char type = items[j] >> 8;
172 unsigned int freq = items[j] & 0xff;
173 int format = LOLA_CLOCK_FORMAT_NONE;
174 bool add_clock = true;
175 if (type == LOLA_CLOCK_TYPE_INTERNAL) {
176 freq = lola_sample_rate_convert(freq);
177 if (freq < chip->sample_rate_min)
178 add_clock = false;
179 else if (freq == 48000) {
180 chip->clock.cur_index = idx_list;
181 chip->clock.cur_freq = 48000;
182 chip->clock.cur_valid = true;
183 }
184 } else if (type == LOLA_CLOCK_TYPE_VIDEO) {
185 freq = lola_sample_rate_convert(freq);
186 if (freq < chip->sample_rate_min)
187 add_clock = false;
188 /* video clock has a format (0:NTSC, 1:PAL)*/
189 if (items[j] & 0x80)
190 format = LOLA_CLOCK_FORMAT_NTSC;
191 else
192 format = LOLA_CLOCK_FORMAT_PAL;
193 }
194 if (add_clock) {
195 struct lola_sample_clock *sc;
196 sc = &chip->clock.sample_clock[idx_list];
197 sc->type = type;
198 sc->format = format;
199 sc->freq = freq;
200 /* keep the index used with the board */
201 chip->clock.idx_lookup[idx_list] = idx;
202 idx_list++;
203 } else {
204 chip->clock.items--;
205 }
206 if (++idx >= nitems)
207 break;
208 }
209 }
210 return 0;
211}
212
213/* enable unsolicited events of the clock widget */
214int lola_enable_clock_events(struct lola *chip)
215{
216 unsigned int res;
217 int err;
218
219 err = lola_codec_read(chip, chip->clock.nid,
220 LOLA_VERB_SET_UNSOLICITED_ENABLE,
221 LOLA_UNSOLICITED_ENABLE | LOLA_UNSOLICITED_TAG,
222 0, &res, NULL);
223 if (err < 0)
224 return err;
225 if (res) {
226 printk(KERN_WARNING SFX "error in enable_clock_events %d\n",
227 res);
228 return -EINVAL;
229 }
230 return 0;
231}
232
233int lola_set_clock_index(struct lola *chip, unsigned int idx)
234{
235 unsigned int res;
236 int err;
237
238 err = lola_codec_read(chip, chip->clock.nid,
239 LOLA_VERB_SET_CLOCK_SELECT,
240 chip->clock.idx_lookup[idx],
241 0, &res, NULL);
242 if (err < 0)
243 return err;
244 if (res) {
245 printk(KERN_WARNING SFX "error in set_clock %d\n", res);
246 return -EINVAL;
247 }
248 return 0;
249}
250
251bool lola_update_ext_clock_freq(struct lola *chip, unsigned int val)
252{
253 unsigned int tag;
254
255 /* the current EXTERNAL clock information gets updated by interrupt
256 * with an unsolicited response
257 */
258 if (!val)
259 return false;
260 tag = (val >> LOLA_UNSOL_RESP_TAG_OFFSET) & LOLA_UNSOLICITED_TAG_MASK;
261 if (tag != LOLA_UNSOLICITED_TAG)
262 return false;
263
264 /* only for current = external clocks */
265 if (chip->clock.sample_clock[chip->clock.cur_index].type !=
266 LOLA_CLOCK_TYPE_INTERNAL) {
267 chip->clock.cur_freq = lola_sample_rate_convert(val & 0x7f);
268 chip->clock.cur_valid = (val & 0x100) != 0;
269 }
270 return true;
271}
272
273int lola_set_clock(struct lola *chip, int idx)
274{
275 int freq = 0;
276 bool valid = false;
277
278 if (idx == chip->clock.cur_index) {
279 /* current clock is allowed */
280 freq = chip->clock.cur_freq;
281 valid = chip->clock.cur_valid;
282 } else if (chip->clock.sample_clock[idx].type ==
283 LOLA_CLOCK_TYPE_INTERNAL) {
284 /* internal clocks allowed */
285 freq = chip->clock.sample_clock[idx].freq;
286 valid = true;
287 }
288
289 if (!freq || !valid)
290 return -EINVAL;
291
292 if (!check_gran_clock_compatibility(chip, chip->granularity, freq))
293 return -EINVAL;
294
295 if (idx != chip->clock.cur_index) {
296 int err = lola_set_clock_index(chip, idx);
297 if (err < 0)
298 return err;
299 /* update new settings */
300 chip->clock.cur_index = idx;
301 chip->clock.cur_freq = freq;
302 chip->clock.cur_valid = true;
303 }
304 return 0;
305}
306
307int lola_set_sample_rate(struct lola *chip, int rate)
308{
309 int i;
310
311 if (chip->clock.cur_freq == rate && chip->clock.cur_valid)
312 return 0;
313 /* search for new dwClockIndex */
314 for (i = 0; i < chip->clock.items; i++) {
315 if (chip->clock.sample_clock[i].type == LOLA_CLOCK_TYPE_INTERNAL &&
316 chip->clock.sample_clock[i].freq == rate)
317 break;
318 }
319 if (i >= chip->clock.items)
320 return -EINVAL;
321 return lola_set_clock(chip, i);
322}
323
diff --git a/sound/pci/lola/lola_mixer.c b/sound/pci/lola/lola_mixer.c
new file mode 100644
index 000000000000..5d518f1a712c
--- /dev/null
+++ b/sound/pci/lola/lola_mixer.c
@@ -0,0 +1,839 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/vmalloc.h>
24#include <linux/io.h>
25#include <sound/core.h>
26#include <sound/control.h>
27#include <sound/pcm.h>
28#include <sound/tlv.h>
29#include "lola.h"
30
31static int __devinit lola_init_pin(struct lola *chip, struct lola_pin *pin,
32 int dir, int nid)
33{
34 unsigned int val;
35 int err;
36
37 pin->nid = nid;
38 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
39 if (err < 0) {
40 printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
41 return err;
42 }
43 val &= 0x00f00fff; /* test TYPE and bits 0..11 */
44 if (val == 0x00400200) /* Type = 4, Digital = 1 */
45 pin->is_analog = false;
46 else if (val == 0x0040000a && dir == CAPT) /* Dig=0, InAmp/ovrd */
47 pin->is_analog = true;
48 else if (val == 0x0040000c && dir == PLAY) /* Dig=0, OutAmp/ovrd */
49 pin->is_analog = true;
50 else {
51 printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n", val, nid);
52 return -EINVAL;
53 }
54
55 /* analog parameters only following, so continue in case of Digital pin
56 */
57 if (!pin->is_analog)
58 return 0;
59
60 if (dir == PLAY)
61 err = lola_read_param(chip, nid, LOLA_PAR_AMP_OUT_CAP, &val);
62 else
63 err = lola_read_param(chip, nid, LOLA_PAR_AMP_IN_CAP, &val);
64 if (err < 0) {
65 printk(KERN_ERR SFX "Can't read AMP-caps for 0x%x\n", nid);
66 return err;
67 }
68
69 pin->amp_mute = LOLA_AMP_MUTE_CAPABLE(val);
70 pin->amp_step_size = LOLA_AMP_STEP_SIZE(val);
71 pin->amp_num_steps = LOLA_AMP_NUM_STEPS(val);
72 if (pin->amp_num_steps) {
73 /* zero as mute state */
74 pin->amp_num_steps++;
75 pin->amp_step_size++;
76 }
77 pin->amp_offset = LOLA_AMP_OFFSET(val);
78
79 err = lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val,
80 NULL);
81 if (err < 0) {
82 printk(KERN_ERR SFX "Can't get MAX_LEVEL 0x%x\n", nid);
83 return err;
84 }
85 pin->max_level = val & 0x3ff; /* 10 bits */
86
87 pin->config_default_reg = 0;
88 pin->fixed_gain_list_len = 0;
89 pin->cur_gain_step = 0;
90
91 return 0;
92}
93
94int __devinit lola_init_pins(struct lola *chip, int dir, int *nidp)
95{
96 int i, err, nid;
97 nid = *nidp;
98 for (i = 0; i < chip->pin[dir].num_pins; i++, nid++) {
99 err = lola_init_pin(chip, &chip->pin[dir].pins[i], dir, nid);
100 if (err < 0)
101 return err;
102 if (chip->pin[dir].pins[i].is_analog)
103 chip->pin[dir].num_analog_pins++;
104 }
105 *nidp = nid;
106 return 0;
107}
108
109void lola_free_mixer(struct lola *chip)
110{
111 if (chip->mixer.array_saved)
112 vfree(chip->mixer.array_saved);
113}
114
115int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
116{
117 unsigned int val;
118 int err;
119
120 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
121 if (err < 0) {
122 printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
123 return err;
124 }
125
126 if ((val & 0xfff00000) != 0x02f00000) { /* test SubType and Type */
127 snd_printdd("No valid mixer widget\n");
128 return 0;
129 }
130
131 chip->mixer.nid = nid;
132 chip->mixer.caps = val;
133 chip->mixer.array = (struct lola_mixer_array __iomem *)
134 (chip->bar[BAR1].remap_addr + LOLA_BAR1_SOURCE_GAIN_ENABLE);
135
136 /* reserve memory to copy mixer data for sleep mode transitions */
137 chip->mixer.array_saved = vmalloc(sizeof(struct lola_mixer_array));
138
139 /* mixer matrix sources are physical input data and play streams */
140 chip->mixer.src_stream_outs = chip->pcm[PLAY].num_streams;
141 chip->mixer.src_phys_ins = chip->pin[CAPT].num_pins;
142
143 /* mixer matrix destinations are record streams and physical output */
144 chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams;
145 chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins;
146
147 /* mixer matrix can have unused areas between PhysIn and
148 * Play or Record and PhysOut zones
149 */
150 chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
151 LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
152 chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
153 LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(val);
154
155 /* example : MixerMatrix of LoLa881
156 * 0-------8------16-------8------16
157 * | | | | |
158 * | INPUT | | INPUT | |
159 * | -> |unused | -> |unused |
160 * | RECORD| | OUTPUT| |
161 * | | | | |
162 * 8--------------------------------
163 * | | | | |
164 * | | | | |
165 * |unused |unused |unused |unused |
166 * | | | | |
167 * | | | | |
168 * 16-------------------------------
169 * | | | | |
170 * | PLAY | | PLAY | |
171 * | -> |unused | -> |unused |
172 * | RECORD| | OUTPUT| |
173 * | | | | |
174 * 8--------------------------------
175 * | | | | |
176 * | | | | |
177 * |unused |unused |unused |unused |
178 * | | | | |
179 * | | | | |
180 * 16-------------------------------
181 */
182 if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
183 chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) {
184 printk(KERN_ERR SFX "Invalid mixer widget size\n");
185 return -EINVAL;
186 }
187
188 chip->mixer.src_mask = ((1U << chip->mixer.src_phys_ins) - 1) |
189 (((1U << chip->mixer.src_stream_outs) - 1)
190 << chip->mixer.src_stream_out_ofs);
191 chip->mixer.dest_mask = ((1U << chip->mixer.dest_stream_ins) - 1) |
192 (((1U << chip->mixer.dest_phys_outs) - 1)
193 << chip->mixer.dest_phys_out_ofs);
194
195 return 0;
196}
197
198static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
199 unsigned short gain, bool on)
200{
201 unsigned int oldval, val;
202
203 if (!(chip->mixer.src_mask & (1 << id)))
204 return -EINVAL;
205 writew(gain, &chip->mixer.array->src_gain[id]);
206 oldval = val = readl(&chip->mixer.array->src_gain_enable);
207 if (on)
208 val |= (1 << id);
209 else
210 val &= ~(1 << id);
211 writel(val, &chip->mixer.array->src_gain_enable);
212 lola_codec_flush(chip);
213 /* inform micro-controller about the new source gain */
214 return lola_codec_write(chip, chip->mixer.nid,
215 LOLA_VERB_SET_SOURCE_GAIN, id, 0);
216}
217
218#if 0 /* not used */
219static int lola_mixer_set_src_gains(struct lola *chip, unsigned int mask,
220 unsigned short *gains)
221{
222 int i;
223
224 if ((chip->mixer.src_mask & mask) != mask)
225 return -EINVAL;
226 for (i = 0; i < LOLA_MIXER_DIM; i++) {
227 if (mask & (1 << i)) {
228 writew(*gains, &chip->mixer.array->src_gain[i]);
229 gains++;
230 }
231 }
232 writel(mask, &chip->mixer.array->src_gain_enable);
233 lola_codec_flush(chip);
234 if (chip->mixer.caps & LOLA_PEAK_METER_CAN_AGC_MASK) {
235 /* update for all srcs at once */
236 return lola_codec_write(chip, chip->mixer.nid,
237 LOLA_VERB_SET_SOURCE_GAIN, 0x80, 0);
238 }
239 /* update manually */
240 for (i = 0; i < LOLA_MIXER_DIM; i++) {
241 if (mask & (1 << i)) {
242 lola_codec_write(chip, chip->mixer.nid,
243 LOLA_VERB_SET_SOURCE_GAIN, i, 0);
244 }
245 }
246 return 0;
247}
248#endif /* not used */
249
250static int lola_mixer_set_mapping_gain(struct lola *chip,
251 unsigned int src, unsigned int dest,
252 unsigned short gain, bool on)
253{
254 unsigned int val;
255
256 if (!(chip->mixer.src_mask & (1 << src)) ||
257 !(chip->mixer.dest_mask & (1 << dest)))
258 return -EINVAL;
259 if (on)
260 writew(gain, &chip->mixer.array->dest_mix_gain[dest][src]);
261 val = readl(&chip->mixer.array->dest_mix_gain_enable[dest]);
262 if (on)
263 val |= (1 << src);
264 else
265 val &= ~(1 << src);
266 writel(val, &chip->mixer.array->dest_mix_gain_enable[dest]);
267 lola_codec_flush(chip);
268 return lola_codec_write(chip, chip->mixer.nid, LOLA_VERB_SET_MIX_GAIN,
269 src, dest);
270}
271
272static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
273 unsigned int mask, unsigned short *gains)
274{
275 int i;
276
277 if (!(chip->mixer.dest_mask & (1 << id)) ||
278 (chip->mixer.src_mask & mask) != mask)
279 return -EINVAL;
280 for (i = 0; i < LOLA_MIXER_DIM; i++) {
281 if (mask & (1 << i)) {
282 writew(*gains, &chip->mixer.array->dest_mix_gain[id][i]);
283 gains++;
284 }
285 }
286 writel(mask, &chip->mixer.array->dest_mix_gain_enable[id]);
287 lola_codec_flush(chip);
288 /* update for all dests at once */
289 return lola_codec_write(chip, chip->mixer.nid,
290 LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
291}
292
293/*
294 */
295
296static int set_analog_volume(struct lola *chip, int dir,
297 unsigned int idx, unsigned int val,
298 bool external_call);
299
300int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute)
301{
302 struct lola_pin *pin;
303 int idx, max_idx;
304
305 pin = chip->pin[dir].pins;
306 max_idx = chip->pin[dir].num_pins;
307 for (idx = 0; idx < max_idx; idx++) {
308 if (pin[idx].is_analog) {
309 unsigned int val = mute ? 0 : pin[idx].cur_gain_step;
310 /* set volume and do not save the value */
311 set_analog_volume(chip, dir, idx, val, false);
312 }
313 }
314 return lola_codec_flush(chip);
315}
316
317void lola_save_mixer(struct lola *chip)
318{
319 /* mute analog output */
320 if (chip->mixer.array_saved) {
321 /* store contents of mixer array */
322 memcpy_fromio(chip->mixer.array_saved, chip->mixer.array,
323 sizeof(*chip->mixer.array));
324 }
325 lola_setup_all_analog_gains(chip, PLAY, true); /* output mute */
326}
327
328void lola_restore_mixer(struct lola *chip)
329{
330 int i;
331
332 /*lola_reset_setups(chip);*/
333 if (chip->mixer.array_saved) {
334 /* restore contents of mixer array */
335 memcpy_toio(chip->mixer.array, chip->mixer.array_saved,
336 sizeof(*chip->mixer.array));
337 /* inform micro-controller about all restored values
338 * and ignore return values
339 */
340 for (i = 0; i < chip->mixer.src_phys_ins; i++)
341 lola_codec_write(chip, chip->mixer.nid,
342 LOLA_VERB_SET_SOURCE_GAIN,
343 i, 0);
344 for (i = 0; i < chip->mixer.src_stream_outs; i++)
345 lola_codec_write(chip, chip->mixer.nid,
346 LOLA_VERB_SET_SOURCE_GAIN,
347 chip->mixer.src_stream_out_ofs + i, 0);
348 for (i = 0; i < chip->mixer.dest_stream_ins; i++)
349 lola_codec_write(chip, chip->mixer.nid,
350 LOLA_VERB_SET_DESTINATION_GAIN,
351 i, 0);
352 for (i = 0; i < chip->mixer.dest_phys_outs; i++)
353 lola_codec_write(chip, chip->mixer.nid,
354 LOLA_VERB_SET_DESTINATION_GAIN,
355 chip->mixer.dest_phys_out_ofs + i, 0);
356 lola_codec_flush(chip);
357 }
358}
359
360/*
361 */
362
363static int set_analog_volume(struct lola *chip, int dir,
364 unsigned int idx, unsigned int val,
365 bool external_call)
366{
367 struct lola_pin *pin;
368 int err;
369
370 if (idx >= chip->pin[dir].num_pins)
371 return -EINVAL;
372 pin = &chip->pin[dir].pins[idx];
373 if (!pin->is_analog || pin->amp_num_steps <= val)
374 return -EINVAL;
375 if (external_call && pin->cur_gain_step == val)
376 return 0;
377 if (external_call)
378 lola_codec_flush(chip);
379 err = lola_codec_write(chip, pin->nid,
380 LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
381 if (err < 0)
382 return err;
383 if (external_call)
384 pin->cur_gain_step = val;
385 return 0;
386}
387
388int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update)
389{
390 int ret = 0;
391 int success = 0;
392 int n, err;
393
394 /* SRC can be activated and the dwInputSRCMask is valid? */
395 if ((chip->input_src_caps_mask & src_mask) != src_mask)
396 return -EINVAL;
397 /* handle all even Inputs - SRC is a stereo setting !!! */
398 for (n = 0; n < chip->pin[CAPT].num_pins; n += 2) {
399 unsigned int mask = 3U << n; /* handle the stereo case */
400 unsigned int new_src, src_state;
401 if (!(chip->input_src_caps_mask & mask))
402 continue;
403 /* if one IO needs SRC, both stereo IO will get SRC */
404 new_src = (src_mask & mask) != 0;
405 if (update) {
406 src_state = (chip->input_src_mask & mask) != 0;
407 if (src_state == new_src)
408 continue; /* nothing to change for this IO */
409 }
410 err = lola_codec_write(chip, chip->pcm[CAPT].streams[n].nid,
411 LOLA_VERB_SET_SRC, new_src, 0);
412 if (!err)
413 success++;
414 else
415 ret = err;
416 }
417 if (success)
418 ret = lola_codec_flush(chip);
419 if (!ret)
420 chip->input_src_mask = src_mask;
421 return ret;
422}
423
424/*
425 */
426static int init_mixer_values(struct lola *chip)
427{
428 int i;
429
430 /* all src on */
431 lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false);
432
433 /* clear all matrix */
434 memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array));
435 /* set src gain to 0dB */
436 for (i = 0; i < chip->mixer.src_phys_ins; i++)
437 lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */
438 for (i = 0; i < chip->mixer.src_stream_outs; i++)
439 lola_mixer_set_src_gain(chip,
440 i + chip->mixer.src_stream_out_ofs,
441 336, true); /* 0dB */
442 /* set 1:1 dest gain */
443 for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
444 int src = i % chip->mixer.src_phys_ins;
445 lola_mixer_set_mapping_gain(chip, src, i, 336, true);
446 }
447 for (i = 0; i < chip->mixer.src_stream_outs; i++) {
448 int src = chip->mixer.src_stream_out_ofs + i;
449 int dst = chip->mixer.dest_phys_out_ofs +
450 i % chip->mixer.dest_phys_outs;
451 lola_mixer_set_mapping_gain(chip, src, dst, 336, true);
452 }
453 return 0;
454}
455
456/*
457 * analog mixer control element
458 */
459static int lola_analog_vol_info(struct snd_kcontrol *kcontrol,
460 struct snd_ctl_elem_info *uinfo)
461{
462 struct lola *chip = snd_kcontrol_chip(kcontrol);
463 int dir = kcontrol->private_value;
464
465 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
466 uinfo->count = chip->pin[dir].num_pins;
467 uinfo->value.integer.min = 0;
468 uinfo->value.integer.max = chip->pin[dir].pins[0].amp_num_steps;
469 return 0;
470}
471
472static int lola_analog_vol_get(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_value *ucontrol)
474{
475 struct lola *chip = snd_kcontrol_chip(kcontrol);
476 int dir = kcontrol->private_value;
477 int i;
478
479 for (i = 0; i < chip->pin[dir].num_pins; i++)
480 ucontrol->value.integer.value[i] =
481 chip->pin[dir].pins[i].cur_gain_step;
482 return 0;
483}
484
485static int lola_analog_vol_put(struct snd_kcontrol *kcontrol,
486 struct snd_ctl_elem_value *ucontrol)
487{
488 struct lola *chip = snd_kcontrol_chip(kcontrol);
489 int dir = kcontrol->private_value;
490 int i, err;
491
492 for (i = 0; i < chip->pin[dir].num_pins; i++) {
493 err = set_analog_volume(chip, dir, i,
494 ucontrol->value.integer.value[i],
495 true);
496 if (err < 0)
497 return err;
498 }
499 return 0;
500}
501
502static int lola_analog_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
503 unsigned int size, unsigned int __user *tlv)
504{
505 struct lola *chip = snd_kcontrol_chip(kcontrol);
506 int dir = kcontrol->private_value;
507 unsigned int val1, val2;
508 struct lola_pin *pin;
509
510 if (size < 4 * sizeof(unsigned int))
511 return -ENOMEM;
512 pin = &chip->pin[dir].pins[0];
513
514 val2 = pin->amp_step_size * 25;
515 val1 = -1 * (int)pin->amp_offset * (int)val2;
516#ifdef TLV_DB_SCALE_MUTE
517 val2 |= TLV_DB_SCALE_MUTE;
518#endif
519 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, tlv))
520 return -EFAULT;
521 if (put_user(2 * sizeof(unsigned int), tlv + 1))
522 return -EFAULT;
523 if (put_user(val1, tlv + 2))
524 return -EFAULT;
525 if (put_user(val2, tlv + 3))
526 return -EFAULT;
527 return 0;
528}
529
530static struct snd_kcontrol_new lola_analog_mixer __devinitdata = {
531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
532 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
533 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
534 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK),
535 .info = lola_analog_vol_info,
536 .get = lola_analog_vol_get,
537 .put = lola_analog_vol_put,
538 .tlv.c = lola_analog_vol_tlv,
539};
540
541static int __devinit create_analog_mixer(struct lola *chip, int dir, char *name)
542{
543 if (!chip->pin[dir].num_pins)
544 return 0;
545 /* no analog volumes on digital only adapters */
546 if (chip->pin[dir].num_pins != chip->pin[dir].num_analog_pins)
547 return 0;
548 lola_analog_mixer.name = name;
549 lola_analog_mixer.private_value = dir;
550 return snd_ctl_add(chip->card,
551 snd_ctl_new1(&lola_analog_mixer, chip));
552}
553
554/*
555 * Hardware sample rate converter on digital input
556 */
557static int lola_input_src_info(struct snd_kcontrol *kcontrol,
558 struct snd_ctl_elem_info *uinfo)
559{
560 struct lola *chip = snd_kcontrol_chip(kcontrol);
561
562 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
563 uinfo->count = chip->pin[CAPT].num_pins;
564 uinfo->value.integer.min = 0;
565 uinfo->value.integer.max = 1;
566 return 0;
567}
568
569static int lola_input_src_get(struct snd_kcontrol *kcontrol,
570 struct snd_ctl_elem_value *ucontrol)
571{
572 struct lola *chip = snd_kcontrol_chip(kcontrol);
573 int i;
574
575 for (i = 0; i < chip->pin[CAPT].num_pins; i++)
576 ucontrol->value.integer.value[i] =
577 !!(chip->input_src_mask & (1 << i));
578 return 0;
579}
580
581static int lola_input_src_put(struct snd_kcontrol *kcontrol,
582 struct snd_ctl_elem_value *ucontrol)
583{
584 struct lola *chip = snd_kcontrol_chip(kcontrol);
585 int i;
586 unsigned int mask;
587
588 mask = 0;
589 for (i = 0; i < chip->pin[CAPT].num_pins; i++)
590 if (ucontrol->value.integer.value[i])
591 mask |= 1 << i;
592 return lola_set_src_config(chip, mask, true);
593}
594
595static struct snd_kcontrol_new lola_input_src_mixer __devinitdata = {
596 .name = "Digital SRC Capture Switch",
597 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
598 .info = lola_input_src_info,
599 .get = lola_input_src_get,
600 .put = lola_input_src_put,
601};
602
603/*
604 * Lola16161 or Lola881 can have Hardware sample rate converters
605 * on its digital input pins
606 */
607static int __devinit create_input_src_mixer(struct lola *chip)
608{
609 if (!chip->input_src_caps_mask)
610 return 0;
611
612 return snd_ctl_add(chip->card,
613 snd_ctl_new1(&lola_input_src_mixer, chip));
614}
615
616/*
617 * src gain mixer
618 */
619static int lola_src_gain_info(struct snd_kcontrol *kcontrol,
620 struct snd_ctl_elem_info *uinfo)
621{
622 unsigned int count = (kcontrol->private_value >> 8) & 0xff;
623
624 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
625 uinfo->count = count;
626 uinfo->value.integer.min = 0;
627 uinfo->value.integer.max = 409;
628 return 0;
629}
630
631static int lola_src_gain_get(struct snd_kcontrol *kcontrol,
632 struct snd_ctl_elem_value *ucontrol)
633{
634 struct lola *chip = snd_kcontrol_chip(kcontrol);
635 unsigned int ofs = kcontrol->private_value & 0xff;
636 unsigned int count = (kcontrol->private_value >> 8) & 0xff;
637 unsigned int mask, i;
638
639 mask = readl(&chip->mixer.array->src_gain_enable);
640 for (i = 0; i < count; i++) {
641 unsigned int idx = ofs + i;
642 unsigned short val;
643 if (!(chip->mixer.src_mask & (1 << idx)))
644 return -EINVAL;
645 if (mask & (1 << idx))
646 val = readw(&chip->mixer.array->src_gain[idx]) + 1;
647 else
648 val = 0;
649 ucontrol->value.integer.value[i] = val;
650 }
651 return 0;
652}
653
654static int lola_src_gain_put(struct snd_kcontrol *kcontrol,
655 struct snd_ctl_elem_value *ucontrol)
656{
657 struct lola *chip = snd_kcontrol_chip(kcontrol);
658 unsigned int ofs = kcontrol->private_value & 0xff;
659 unsigned int count = (kcontrol->private_value >> 8) & 0xff;
660 int i, err;
661
662 for (i = 0; i < count; i++) {
663 unsigned int idx = ofs + i;
664 unsigned short val = ucontrol->value.integer.value[i];
665 if (val)
666 val--;
667 err = lola_mixer_set_src_gain(chip, idx, val, !!val);
668 if (err < 0)
669 return err;
670 }
671 return 0;
672}
673
674/* raw value: 0 = -84dB, 336 = 0dB, 408=18dB, incremented 1 for mute */
675static const DECLARE_TLV_DB_SCALE(lola_src_gain_tlv, -8425, 25, 1);
676
677static struct snd_kcontrol_new lola_src_gain_mixer __devinitdata = {
678 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
679 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
680 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
681 .info = lola_src_gain_info,
682 .get = lola_src_gain_get,
683 .put = lola_src_gain_put,
684 .tlv.p = lola_src_gain_tlv,
685};
686
687static int __devinit create_src_gain_mixer(struct lola *chip,
688 int num, int ofs, char *name)
689{
690 lola_src_gain_mixer.name = name;
691 lola_src_gain_mixer.private_value = ofs + (num << 8);
692 return snd_ctl_add(chip->card,
693 snd_ctl_new1(&lola_src_gain_mixer, chip));
694}
695
696/*
697 * destination gain (matrix-like) mixer
698 */
699static int lola_dest_gain_info(struct snd_kcontrol *kcontrol,
700 struct snd_ctl_elem_info *uinfo)
701{
702 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
703
704 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
705 uinfo->count = src_num;
706 uinfo->value.integer.min = 0;
707 uinfo->value.integer.max = 433;
708 return 0;
709}
710
711static int lola_dest_gain_get(struct snd_kcontrol *kcontrol,
712 struct snd_ctl_elem_value *ucontrol)
713{
714 struct lola *chip = snd_kcontrol_chip(kcontrol);
715 unsigned int src_ofs = kcontrol->private_value & 0xff;
716 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
717 unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
718 unsigned int dst, mask, i;
719
720 dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
721 mask = readl(&chip->mixer.array->dest_mix_gain_enable[dst]);
722 for (i = 0; i < src_num; i++) {
723 unsigned int src = src_ofs + i;
724 unsigned short val;
725 if (!(chip->mixer.src_mask & (1 << src)))
726 return -EINVAL;
727 if (mask & (1 << dst))
728 val = readw(&chip->mixer.array->dest_mix_gain[dst][src]) + 1;
729 else
730 val = 0;
731 ucontrol->value.integer.value[i] = val;
732 }
733 return 0;
734}
735
736static int lola_dest_gain_put(struct snd_kcontrol *kcontrol,
737 struct snd_ctl_elem_value *ucontrol)
738{
739 struct lola *chip = snd_kcontrol_chip(kcontrol);
740 unsigned int src_ofs = kcontrol->private_value & 0xff;
741 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
742 unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
743 unsigned int dst, mask;
744 unsigned short gains[MAX_STREAM_COUNT];
745 int i, num;
746
747 mask = 0;
748 num = 0;
749 for (i = 0; i < src_num; i++) {
750 unsigned short val = ucontrol->value.integer.value[i];
751 if (val) {
752 gains[num++] = val - 1;
753 mask |= 1 << i;
754 }
755 }
756 mask <<= src_ofs;
757 dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
758 return lola_mixer_set_dest_gains(chip, dst, mask, gains);
759}
760
761static const DECLARE_TLV_DB_SCALE(lola_dest_gain_tlv, -8425, 25, 1);
762
763static struct snd_kcontrol_new lola_dest_gain_mixer __devinitdata = {
764 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
765 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
766 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
767 .info = lola_dest_gain_info,
768 .get = lola_dest_gain_get,
769 .put = lola_dest_gain_put,
770 .tlv.p = lola_dest_gain_tlv,
771};
772
773static int __devinit create_dest_gain_mixer(struct lola *chip,
774 int src_num, int src_ofs,
775 int num, int ofs, char *name)
776{
777 lola_dest_gain_mixer.count = num;
778 lola_dest_gain_mixer.name = name;
779 lola_dest_gain_mixer.private_value =
780 src_ofs + (src_num << 8) + (ofs << 16) + (num << 24);
781 return snd_ctl_add(chip->card,
782 snd_ctl_new1(&lola_dest_gain_mixer, chip));
783}
784
785/*
786 */
787int __devinit lola_create_mixer(struct lola *chip)
788{
789 int err;
790
791 err = create_analog_mixer(chip, PLAY, "Analog Playback Volume");
792 if (err < 0)
793 return err;
794 err = create_analog_mixer(chip, CAPT, "Analog Capture Volume");
795 if (err < 0)
796 return err;
797 err = create_input_src_mixer(chip);
798 if (err < 0)
799 return err;
800 err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
801 "Line Source Gain Volume");
802 if (err < 0)
803 return err;
804 err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
805 chip->mixer.src_stream_out_ofs,
806 "Stream Source Gain Volume");
807 if (err < 0)
808 return err;
809 err = create_dest_gain_mixer(chip,
810 chip->mixer.src_phys_ins, 0,
811 chip->mixer.dest_stream_ins, 0,
812 "Line Capture Volume");
813 if (err < 0)
814 return err;
815 err = create_dest_gain_mixer(chip,
816 chip->mixer.src_stream_outs,
817 chip->mixer.src_stream_out_ofs,
818 chip->mixer.dest_stream_ins, 0,
819 "Stream-Loopback Capture Volume");
820 if (err < 0)
821 return err;
822 err = create_dest_gain_mixer(chip,
823 chip->mixer.src_phys_ins, 0,
824 chip->mixer.dest_phys_outs,
825 chip->mixer.dest_phys_out_ofs,
826 "Line-Loopback Playback Volume");
827 if (err < 0)
828 return err;
829 err = create_dest_gain_mixer(chip,
830 chip->mixer.src_stream_outs,
831 chip->mixer.src_stream_out_ofs,
832 chip->mixer.dest_phys_outs,
833 chip->mixer.dest_phys_out_ofs,
834 "Stream Playback Volume");
835 if (err < 0)
836 return err;
837
838 return init_mixer_values(chip);
839}
diff --git a/sound/pci/lola/lola_pcm.c b/sound/pci/lola/lola_pcm.c
new file mode 100644
index 000000000000..c44db68eecb5
--- /dev/null
+++ b/sound/pci/lola/lola_pcm.c
@@ -0,0 +1,706 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/dma-mapping.h>
24#include <linux/pci.h>
25#include <linux/delay.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include "lola.h"
29
30#define LOLA_MAX_BDL_ENTRIES 8
31#define LOLA_MAX_BUF_SIZE (1024*1024*1024)
32#define LOLA_BDL_ENTRY_SIZE (16 * 16)
33
34static struct lola_pcm *lola_get_pcm(struct snd_pcm_substream *substream)
35{
36 struct lola *chip = snd_pcm_substream_chip(substream);
37 return &chip->pcm[substream->stream];
38}
39
40static struct lola_stream *lola_get_stream(struct snd_pcm_substream *substream)
41{
42 struct lola_pcm *pcm = lola_get_pcm(substream);
43 unsigned int idx = substream->number;
44 return &pcm->streams[idx];
45}
46
47static unsigned int lola_get_lrc(struct lola *chip)
48{
49 return lola_readl(chip, BAR1, LRC);
50}
51
52static unsigned int lola_get_tstamp(struct lola *chip, bool quick_no_sync)
53{
54 unsigned int tstamp = lola_get_lrc(chip) >> 8;
55 if (chip->granularity) {
56 unsigned int wait_banks = quick_no_sync ? 0 : 8;
57 tstamp += (wait_banks + 1) * chip->granularity - 1;
58 tstamp -= tstamp % chip->granularity;
59 }
60 return tstamp << 8;
61}
62
63/* clear any pending interrupt status */
64static void lola_stream_clear_pending_irq(struct lola *chip,
65 struct lola_stream *str)
66{
67 unsigned int val = lola_dsd_read(chip, str->dsd, STS);
68 val &= LOLA_DSD_STS_DESE | LOLA_DSD_STS_BCIS;
69 if (val)
70 lola_dsd_write(chip, str->dsd, STS, val);
71}
72
73static void lola_stream_start(struct lola *chip, struct lola_stream *str,
74 unsigned int tstamp)
75{
76 lola_stream_clear_pending_irq(chip, str);
77 lola_dsd_write(chip, str->dsd, CTL,
78 LOLA_DSD_CTL_SRUN |
79 LOLA_DSD_CTL_IOCE |
80 LOLA_DSD_CTL_DEIE |
81 LOLA_DSD_CTL_VLRCV |
82 tstamp);
83}
84
85static void lola_stream_stop(struct lola *chip, struct lola_stream *str,
86 unsigned int tstamp)
87{
88 lola_dsd_write(chip, str->dsd, CTL,
89 LOLA_DSD_CTL_IOCE |
90 LOLA_DSD_CTL_DEIE |
91 LOLA_DSD_CTL_VLRCV |
92 tstamp);
93 lola_stream_clear_pending_irq(chip, str);
94}
95
96static void wait_for_srst_clear(struct lola *chip, struct lola_stream *str)
97{
98 unsigned long end_time = jiffies + msecs_to_jiffies(200);
99 while (time_before(jiffies, end_time)) {
100 unsigned int val;
101 val = lola_dsd_read(chip, str->dsd, CTL);
102 if (!(val & LOLA_DSD_CTL_SRST))
103 return;
104 msleep(1);
105 }
106 printk(KERN_WARNING SFX "SRST not clear (stream %d)\n", str->dsd);
107}
108
109static int lola_stream_wait_for_fifo(struct lola *chip,
110 struct lola_stream *str,
111 bool ready)
112{
113 unsigned int val = ready ? LOLA_DSD_STS_FIFORDY : 0;
114 unsigned long end_time = jiffies + msecs_to_jiffies(200);
115 while (time_before(jiffies, end_time)) {
116 unsigned int reg = lola_dsd_read(chip, str->dsd, STS);
117 if ((reg & LOLA_DSD_STS_FIFORDY) == val)
118 return 0;
119 msleep(1);
120 }
121 printk(KERN_WARNING SFX "FIFO not ready (stream %d)\n", str->dsd);
122 return -EIO;
123}
124
125/* sync for FIFO ready/empty for all linked streams;
126 * clear paused flag when FIFO gets ready again
127 */
128static int lola_sync_wait_for_fifo(struct lola *chip,
129 struct snd_pcm_substream *substream,
130 bool ready)
131{
132 unsigned int val = ready ? LOLA_DSD_STS_FIFORDY : 0;
133 unsigned long end_time = jiffies + msecs_to_jiffies(200);
134 struct snd_pcm_substream *s;
135 int pending = 0;
136
137 while (time_before(jiffies, end_time)) {
138 pending = 0;
139 snd_pcm_group_for_each_entry(s, substream) {
140 struct lola_stream *str;
141 if (s->pcm->card != substream->pcm->card)
142 continue;
143 str = lola_get_stream(s);
144 if (str->prepared && str->paused) {
145 unsigned int reg;
146 reg = lola_dsd_read(chip, str->dsd, STS);
147 if ((reg & LOLA_DSD_STS_FIFORDY) != val) {
148 pending = str->dsd + 1;
149 break;
150 }
151 if (ready)
152 str->paused = 0;
153 }
154 }
155 if (!pending)
156 return 0;
157 msleep(1);
158 }
159 printk(KERN_WARNING SFX "FIFO not ready (pending %d)\n", pending - 1);
160 return -EIO;
161}
162
163/* finish pause - prepare for a new resume */
164static void lola_sync_pause(struct lola *chip,
165 struct snd_pcm_substream *substream)
166{
167 struct snd_pcm_substream *s;
168
169 lola_sync_wait_for_fifo(chip, substream, false);
170 snd_pcm_group_for_each_entry(s, substream) {
171 struct lola_stream *str;
172 if (s->pcm->card != substream->pcm->card)
173 continue;
174 str = lola_get_stream(s);
175 if (str->paused && str->prepared)
176 lola_dsd_write(chip, str->dsd, CTL, LOLA_DSD_CTL_SRUN |
177 LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE);
178 }
179 lola_sync_wait_for_fifo(chip, substream, true);
180}
181
182static void lola_stream_reset(struct lola *chip, struct lola_stream *str)
183{
184 if (str->prepared) {
185 if (str->paused)
186 lola_sync_pause(chip, str->substream);
187 str->prepared = 0;
188 lola_dsd_write(chip, str->dsd, CTL,
189 LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE);
190 lola_stream_wait_for_fifo(chip, str, false);
191 lola_stream_clear_pending_irq(chip, str);
192 lola_dsd_write(chip, str->dsd, CTL, LOLA_DSD_CTL_SRST);
193 lola_dsd_write(chip, str->dsd, LVI, 0);
194 lola_dsd_write(chip, str->dsd, BDPU, 0);
195 lola_dsd_write(chip, str->dsd, BDPL, 0);
196 wait_for_srst_clear(chip, str);
197 }
198}
199
200static struct snd_pcm_hardware lola_pcm_hw = {
201 .info = (SNDRV_PCM_INFO_MMAP |
202 SNDRV_PCM_INFO_INTERLEAVED |
203 SNDRV_PCM_INFO_BLOCK_TRANSFER |
204 SNDRV_PCM_INFO_MMAP_VALID |
205 SNDRV_PCM_INFO_PAUSE),
206 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
207 SNDRV_PCM_FMTBIT_S24_LE |
208 SNDRV_PCM_FMTBIT_S32_LE |
209 SNDRV_PCM_FMTBIT_FLOAT_LE),
210 .rates = SNDRV_PCM_RATE_8000_192000,
211 .rate_min = 8000,
212 .rate_max = 192000,
213 .channels_min = 1,
214 .channels_max = 2,
215 .buffer_bytes_max = LOLA_MAX_BUF_SIZE,
216 .period_bytes_min = 128,
217 .period_bytes_max = LOLA_MAX_BUF_SIZE / 2,
218 .periods_min = 2,
219 .periods_max = LOLA_MAX_BDL_ENTRIES,
220 .fifo_size = 0,
221};
222
223static int lola_pcm_open(struct snd_pcm_substream *substream)
224{
225 struct lola *chip = snd_pcm_substream_chip(substream);
226 struct lola_pcm *pcm = lola_get_pcm(substream);
227 struct lola_stream *str = lola_get_stream(substream);
228 struct snd_pcm_runtime *runtime = substream->runtime;
229
230 mutex_lock(&chip->open_mutex);
231 if (str->opened) {
232 mutex_unlock(&chip->open_mutex);
233 return -EBUSY;
234 }
235 str->substream = substream;
236 str->master = NULL;
237 str->opened = 1;
238 runtime->hw = lola_pcm_hw;
239 runtime->hw.channels_max = pcm->num_streams - str->index;
240 if (chip->sample_rate) {
241 /* sample rate is locked */
242 runtime->hw.rate_min = chip->sample_rate;
243 runtime->hw.rate_max = chip->sample_rate;
244 } else {
245 runtime->hw.rate_min = chip->sample_rate_min;
246 runtime->hw.rate_max = chip->sample_rate_max;
247 }
248 chip->ref_count_rate++;
249 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
250 /* period size = multiple of chip->granularity (8, 16 or 32 frames)*/
251 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
252 chip->granularity);
253 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
254 chip->granularity);
255 mutex_unlock(&chip->open_mutex);
256 return 0;
257}
258
259static void lola_cleanup_slave_streams(struct lola_pcm *pcm,
260 struct lola_stream *str)
261{
262 int i;
263 for (i = str->index + 1; i < pcm->num_streams; i++) {
264 struct lola_stream *s = &pcm->streams[i];
265 if (s->master != str)
266 break;
267 s->master = NULL;
268 s->opened = 0;
269 }
270}
271
272static int lola_pcm_close(struct snd_pcm_substream *substream)
273{
274 struct lola *chip = snd_pcm_substream_chip(substream);
275 struct lola_stream *str = lola_get_stream(substream);
276
277 mutex_lock(&chip->open_mutex);
278 if (str->substream == substream) {
279 str->substream = NULL;
280 str->opened = 0;
281 }
282 if (--chip->ref_count_rate == 0) {
283 /* release sample rate */
284 chip->sample_rate = 0;
285 }
286 mutex_unlock(&chip->open_mutex);
287 return 0;
288}
289
290static int lola_pcm_hw_params(struct snd_pcm_substream *substream,
291 struct snd_pcm_hw_params *hw_params)
292{
293 struct lola_stream *str = lola_get_stream(substream);
294
295 str->bufsize = 0;
296 str->period_bytes = 0;
297 str->format_verb = 0;
298 return snd_pcm_lib_malloc_pages(substream,
299 params_buffer_bytes(hw_params));
300}
301
302static int lola_pcm_hw_free(struct snd_pcm_substream *substream)
303{
304 struct lola *chip = snd_pcm_substream_chip(substream);
305 struct lola_pcm *pcm = lola_get_pcm(substream);
306 struct lola_stream *str = lola_get_stream(substream);
307
308 mutex_lock(&chip->open_mutex);
309 lola_stream_reset(chip, str);
310 lola_cleanup_slave_streams(pcm, str);
311 mutex_unlock(&chip->open_mutex);
312 return snd_pcm_lib_free_pages(substream);
313}
314
315/*
316 * set up a BDL entry
317 */
318static int setup_bdle(struct snd_pcm_substream *substream,
319 struct lola_stream *str, u32 **bdlp,
320 int ofs, int size)
321{
322 u32 *bdl = *bdlp;
323
324 while (size > 0) {
325 dma_addr_t addr;
326 int chunk;
327
328 if (str->frags >= LOLA_MAX_BDL_ENTRIES)
329 return -EINVAL;
330
331 addr = snd_pcm_sgbuf_get_addr(substream, ofs);
332 /* program the address field of the BDL entry */
333 bdl[0] = cpu_to_le32((u32)addr);
334 bdl[1] = cpu_to_le32(upper_32_bits(addr));
335 /* program the size field of the BDL entry */
336 chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size);
337 bdl[2] = cpu_to_le32(chunk);
338 /* program the IOC to enable interrupt
339 * only when the whole fragment is processed
340 */
341 size -= chunk;
342 bdl[3] = size ? 0 : cpu_to_le32(0x01);
343 bdl += 4;
344 str->frags++;
345 ofs += chunk;
346 }
347 *bdlp = bdl;
348 return ofs;
349}
350
351/*
352 * set up BDL entries
353 */
354static int lola_setup_periods(struct lola *chip, struct lola_pcm *pcm,
355 struct snd_pcm_substream *substream,
356 struct lola_stream *str)
357{
358 u32 *bdl;
359 int i, ofs, periods, period_bytes;
360
361 period_bytes = str->period_bytes;
362 periods = str->bufsize / period_bytes;
363
364 /* program the initial BDL entries */
365 bdl = (u32 *)(pcm->bdl.area + LOLA_BDL_ENTRY_SIZE * str->index);
366 ofs = 0;
367 str->frags = 0;
368 for (i = 0; i < periods; i++) {
369 ofs = setup_bdle(substream, str, &bdl, ofs, period_bytes);
370 if (ofs < 0)
371 goto error;
372 }
373 return 0;
374
375 error:
376 snd_printk(KERN_ERR SFX "Too many BDL entries: buffer=%d, period=%d\n",
377 str->bufsize, period_bytes);
378 return -EINVAL;
379}
380
381static unsigned int lola_get_format_verb(struct snd_pcm_substream *substream)
382{
383 unsigned int verb;
384
385 switch (substream->runtime->format) {
386 case SNDRV_PCM_FORMAT_S16_LE:
387 verb = 0x00000000;
388 break;
389 case SNDRV_PCM_FORMAT_S24_LE:
390 verb = 0x00000200;
391 break;
392 case SNDRV_PCM_FORMAT_S32_LE:
393 verb = 0x00000300;
394 break;
395 case SNDRV_PCM_FORMAT_FLOAT_LE:
396 verb = 0x00001300;
397 break;
398 default:
399 return 0;
400 }
401 verb |= substream->runtime->channels;
402 return verb;
403}
404
405static int lola_set_stream_config(struct lola *chip,
406 struct lola_stream *str,
407 int channels)
408{
409 int i, err;
410 unsigned int verb, val;
411
412 /* set format info for all channels
413 * (with only one command for the first channel)
414 */
415 err = lola_codec_read(chip, str->nid, LOLA_VERB_SET_STREAM_FORMAT,
416 str->format_verb, 0, &val, NULL);
417 if (err < 0) {
418 printk(KERN_ERR SFX "Cannot set stream format 0x%x\n",
419 str->format_verb);
420 return err;
421 }
422
423 /* update stream - channel config */
424 for (i = 0; i < channels; i++) {
425 verb = (str->index << 6) | i;
426 err = lola_codec_read(chip, str[i].nid,
427 LOLA_VERB_SET_CHANNEL_STREAMID, 0, verb,
428 &val, NULL);
429 if (err < 0) {
430 printk(KERN_ERR SFX "Cannot set stream channel %d\n", i);
431 return err;
432 }
433 }
434 return 0;
435}
436
437/*
438 * set up the SD for streaming
439 */
440static int lola_setup_controller(struct lola *chip, struct lola_pcm *pcm,
441 struct lola_stream *str)
442{
443 dma_addr_t bdl;
444
445 if (str->prepared)
446 return -EINVAL;
447
448 /* set up BDL */
449 bdl = pcm->bdl.addr + LOLA_BDL_ENTRY_SIZE * str->index;
450 lola_dsd_write(chip, str->dsd, BDPL, (u32)bdl);
451 lola_dsd_write(chip, str->dsd, BDPU, upper_32_bits(bdl));
452 /* program the stream LVI (last valid index) of the BDL */
453 lola_dsd_write(chip, str->dsd, LVI, str->frags - 1);
454 lola_stream_clear_pending_irq(chip, str);
455
456 lola_dsd_write(chip, str->dsd, CTL,
457 LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE | LOLA_DSD_CTL_SRUN);
458
459 str->prepared = 1;
460
461 return lola_stream_wait_for_fifo(chip, str, true);
462}
463
464static int lola_pcm_prepare(struct snd_pcm_substream *substream)
465{
466 struct lola *chip = snd_pcm_substream_chip(substream);
467 struct lola_pcm *pcm = lola_get_pcm(substream);
468 struct lola_stream *str = lola_get_stream(substream);
469 struct snd_pcm_runtime *runtime = substream->runtime;
470 unsigned int bufsize, period_bytes, format_verb;
471 int i, err;
472
473 mutex_lock(&chip->open_mutex);
474 lola_stream_reset(chip, str);
475 lola_cleanup_slave_streams(pcm, str);
476 if (str->index + runtime->channels > pcm->num_streams) {
477 mutex_unlock(&chip->open_mutex);
478 return -EINVAL;
479 }
480 for (i = 1; i < runtime->channels; i++) {
481 str[i].master = str;
482 str[i].opened = 1;
483 }
484 mutex_unlock(&chip->open_mutex);
485
486 bufsize = snd_pcm_lib_buffer_bytes(substream);
487 period_bytes = snd_pcm_lib_period_bytes(substream);
488 format_verb = lola_get_format_verb(substream);
489
490 str->bufsize = bufsize;
491 str->period_bytes = period_bytes;
492 str->format_verb = format_verb;
493
494 err = lola_setup_periods(chip, pcm, substream, str);
495 if (err < 0)
496 return err;
497
498 err = lola_set_sample_rate(chip, runtime->rate);
499 if (err < 0)
500 return err;
501 chip->sample_rate = runtime->rate; /* sample rate gets locked */
502
503 err = lola_set_stream_config(chip, str, runtime->channels);
504 if (err < 0)
505 return err;
506
507 err = lola_setup_controller(chip, pcm, str);
508 if (err < 0) {
509 lola_stream_reset(chip, str);
510 return err;
511 }
512
513 return 0;
514}
515
516static int lola_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
517{
518 struct lola *chip = snd_pcm_substream_chip(substream);
519 struct lola_stream *str;
520 struct snd_pcm_substream *s;
521 unsigned int start;
522 unsigned int tstamp;
523 bool sync_streams;
524
525 switch (cmd) {
526 case SNDRV_PCM_TRIGGER_START:
527 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
528 case SNDRV_PCM_TRIGGER_RESUME:
529 start = 1;
530 break;
531 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
532 case SNDRV_PCM_TRIGGER_SUSPEND:
533 case SNDRV_PCM_TRIGGER_STOP:
534 start = 0;
535 break;
536 default:
537 return -EINVAL;
538 }
539
540 /*
541 * sample correct synchronization is only needed starting several
542 * streams. On stop or if only one stream do as quick as possible
543 */
544 sync_streams = (start && snd_pcm_stream_linked(substream));
545 tstamp = lola_get_tstamp(chip, !sync_streams);
546 spin_lock(&chip->reg_lock);
547 snd_pcm_group_for_each_entry(s, substream) {
548 if (s->pcm->card != substream->pcm->card)
549 continue;
550 str = lola_get_stream(s);
551 if (start)
552 lola_stream_start(chip, str, tstamp);
553 else
554 lola_stream_stop(chip, str, tstamp);
555 str->running = start;
556 str->paused = !start;
557 snd_pcm_trigger_done(s, substream);
558 }
559 spin_unlock(&chip->reg_lock);
560 return 0;
561}
562
563static snd_pcm_uframes_t lola_pcm_pointer(struct snd_pcm_substream *substream)
564{
565 struct lola *chip = snd_pcm_substream_chip(substream);
566 struct lola_stream *str = lola_get_stream(substream);
567 unsigned int pos = lola_dsd_read(chip, str->dsd, LPIB);
568
569 if (pos >= str->bufsize)
570 pos = 0;
571 return bytes_to_frames(substream->runtime, pos);
572}
573
574void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits)
575{
576 int i;
577
578 for (i = 0; bits && i < pcm->num_streams; i++) {
579 if (bits & (1 << i)) {
580 struct lola_stream *str = &pcm->streams[i];
581 if (str->substream && str->running)
582 snd_pcm_period_elapsed(str->substream);
583 bits &= ~(1 << i);
584 }
585 }
586}
587
588static struct snd_pcm_ops lola_pcm_ops = {
589 .open = lola_pcm_open,
590 .close = lola_pcm_close,
591 .ioctl = snd_pcm_lib_ioctl,
592 .hw_params = lola_pcm_hw_params,
593 .hw_free = lola_pcm_hw_free,
594 .prepare = lola_pcm_prepare,
595 .trigger = lola_pcm_trigger,
596 .pointer = lola_pcm_pointer,
597 .page = snd_pcm_sgbuf_ops_page,
598};
599
600int __devinit lola_create_pcm(struct lola *chip)
601{
602 struct snd_pcm *pcm;
603 int i, err;
604
605 for (i = 0; i < 2; i++) {
606 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
607 snd_dma_pci_data(chip->pci),
608 PAGE_SIZE, &chip->pcm[i].bdl);
609 if (err < 0)
610 return err;
611 }
612
613 err = snd_pcm_new(chip->card, "Digigram Lola", 0,
614 chip->pcm[SNDRV_PCM_STREAM_PLAYBACK].num_streams,
615 chip->pcm[SNDRV_PCM_STREAM_CAPTURE].num_streams,
616 &pcm);
617 if (err < 0)
618 return err;
619 strlcpy(pcm->name, "Digigram Lola", sizeof(pcm->name));
620 pcm->private_data = chip;
621 for (i = 0; i < 2; i++) {
622 if (chip->pcm[i].num_streams)
623 snd_pcm_set_ops(pcm, i, &lola_pcm_ops);
624 }
625 /* buffer pre-allocation */
626 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
627 snd_dma_pci_data(chip->pci),
628 1024 * 64, 32 * 1024 * 1024);
629 return 0;
630}
631
632void lola_free_pcm(struct lola *chip)
633{
634 snd_dma_free_pages(&chip->pcm[0].bdl);
635 snd_dma_free_pages(&chip->pcm[1].bdl);
636}
637
638/*
639 */
640
641static int lola_init_stream(struct lola *chip, struct lola_stream *str,
642 int idx, int nid, int dir)
643{
644 unsigned int val;
645 int err;
646
647 str->nid = nid;
648 str->index = idx;
649 str->dsd = idx;
650 if (dir == PLAY)
651 str->dsd += MAX_STREAM_IN_COUNT;
652 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
653 if (err < 0) {
654 printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
655 return err;
656 }
657 if (dir == PLAY) {
658 /* test TYPE and bits 0..11 (no test bit9 : Digital = 0/1) */
659 if ((val & 0x00f00dff) != 0x00000010) {
660 printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n",
661 val, nid);
662 return -EINVAL;
663 }
664 } else {
665 /* test TYPE and bits 0..11 (no test bit9 : Digital = 0/1)
666 * (bug : ignore bit8: Conn list = 0/1)
667 */
668 if ((val & 0x00f00cff) != 0x00100010) {
669 printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n",
670 val, nid);
671 return -EINVAL;
672 }
673 /* test bit9:DIGITAL and bit12:SRC_PRESENT*/
674 if ((val & 0x00001200) == 0x00001200)
675 chip->input_src_caps_mask |= (1 << idx);
676 }
677
678 err = lola_read_param(chip, nid, LOLA_PAR_STREAM_FORMATS, &val);
679 if (err < 0) {
680 printk(KERN_ERR SFX "Can't read FORMATS 0x%x\n", nid);
681 return err;
682 }
683 val &= 3;
684 if (val == 3)
685 str->can_float = true;
686 if (!(val & 1)) {
687 printk(KERN_ERR SFX "Invalid formats 0x%x for 0x%x", val, nid);
688 return -EINVAL;
689 }
690 return 0;
691}
692
693int __devinit lola_init_pcm(struct lola *chip, int dir, int *nidp)
694{
695 struct lola_pcm *pcm = &chip->pcm[dir];
696 int i, nid, err;
697
698 nid = *nidp;
699 for (i = 0; i < pcm->num_streams; i++, nid++) {
700 err = lola_init_stream(chip, &pcm->streams[i], i, nid, dir);
701 if (err < 0)
702 return err;
703 }
704 *nidp = nid;
705 return 0;
706}
diff --git a/sound/pci/lola/lola_proc.c b/sound/pci/lola/lola_proc.c
new file mode 100644
index 000000000000..9d7daf897c9d
--- /dev/null
+++ b/sound/pci/lola/lola_proc.c
@@ -0,0 +1,222 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/io.h>
24#include <sound/core.h>
25#include <sound/info.h>
26#include <sound/pcm.h>
27#include "lola.h"
28
29static void print_audio_widget(struct snd_info_buffer *buffer,
30 struct lola *chip, int nid, const char *name)
31{
32 unsigned int val;
33
34 lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
35 snd_iprintf(buffer, "Node 0x%02x %s wcaps 0x%x\n", nid, name, val);
36 lola_read_param(chip, nid, LOLA_PAR_STREAM_FORMATS, &val);
37 snd_iprintf(buffer, " Formats: 0x%x\n", val);
38}
39
40static void print_pin_widget(struct snd_info_buffer *buffer,
41 struct lola *chip, int nid, unsigned int ampcap,
42 const char *name)
43{
44 unsigned int val;
45
46 lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
47 snd_iprintf(buffer, "Node 0x%02x %s wcaps 0x%x\n", nid, name, val);
48 if (val == 0x00400200)
49 return;
50 lola_read_param(chip, nid, ampcap, &val);
51 snd_iprintf(buffer, " Amp-Caps: 0x%x\n", val);
52 snd_iprintf(buffer, " mute=%d, step-size=%d, steps=%d, ofs=%d\n",
53 LOLA_AMP_MUTE_CAPABLE(val),
54 LOLA_AMP_STEP_SIZE(val),
55 LOLA_AMP_NUM_STEPS(val),
56 LOLA_AMP_OFFSET(val));
57 lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val, NULL);
58 snd_iprintf(buffer, " Max-level: 0x%x\n", val);
59}
60
61static void print_clock_widget(struct snd_info_buffer *buffer,
62 struct lola *chip, int nid)
63{
64 int i, j, num_clocks;
65 unsigned int val;
66
67 lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
68 snd_iprintf(buffer, "Node 0x%02x [Clock] wcaps 0x%x\n", nid, val);
69 num_clocks = val & 0xff;
70 for (i = 0; i < num_clocks; i += 4) {
71 unsigned int res_ex;
72 unsigned short items[4];
73 const char *name;
74
75 lola_codec_read(chip, nid, LOLA_VERB_GET_CLOCK_LIST,
76 i, 0, &val, &res_ex);
77 items[0] = val & 0xfff;
78 items[1] = (val >> 16) & 0xfff;
79 items[2] = res_ex & 0xfff;
80 items[3] = (res_ex >> 16) & 0xfff;
81 for (j = 0; j < 4; j++) {
82 unsigned char type = items[j] >> 8;
83 unsigned int freq = items[j] & 0xff;
84 if (i + j >= num_clocks)
85 break;
86 if (type == LOLA_CLOCK_TYPE_INTERNAL) {
87 name = "Internal";
88 freq = lola_sample_rate_convert(freq);
89 } else if (type == LOLA_CLOCK_TYPE_VIDEO) {
90 name = "Video";
91 freq = lola_sample_rate_convert(freq);
92 } else {
93 name = "Other";
94 }
95 snd_iprintf(buffer, " Clock %d: Type %d:%s, freq=%d\n",
96 i + j, type, name, freq);
97 }
98 }
99}
100
101static void print_mixer_widget(struct snd_info_buffer *buffer,
102 struct lola *chip, int nid)
103{
104 unsigned int val;
105
106 lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
107 snd_iprintf(buffer, "Node 0x%02x [Mixer] wcaps 0x%x\n", nid, val);
108}
109
110static void lola_proc_codec_read(struct snd_info_entry *entry,
111 struct snd_info_buffer *buffer)
112{
113 struct lola *chip = entry->private_data;
114 unsigned int val;
115 int i, nid;
116
117 lola_read_param(chip, 0, LOLA_PAR_VENDOR_ID, &val);
118 snd_iprintf(buffer, "Vendor: 0x%08x\n", val);
119 lola_read_param(chip, 1, LOLA_PAR_FUNCTION_TYPE, &val);
120 snd_iprintf(buffer, "Function Type: %d\n", val);
121 lola_read_param(chip, 1, LOLA_PAR_SPECIFIC_CAPS, &val);
122 snd_iprintf(buffer, "Specific-Caps: 0x%08x\n", val);
123 snd_iprintf(buffer, " Pins-In %d, Pins-Out %d\n",
124 chip->pin[CAPT].num_pins, chip->pin[PLAY].num_pins);
125 nid = 2;
126 for (i = 0; i < chip->pcm[CAPT].num_streams; i++, nid++)
127 print_audio_widget(buffer, chip, nid, "[Audio-In]");
128 for (i = 0; i < chip->pcm[PLAY].num_streams; i++, nid++)
129 print_audio_widget(buffer, chip, nid, "[Audio-Out]");
130 for (i = 0; i < chip->pin[CAPT].num_pins; i++, nid++)
131 print_pin_widget(buffer, chip, nid, LOLA_PAR_AMP_IN_CAP,
132 "[Pin-In]");
133 for (i = 0; i < chip->pin[PLAY].num_pins; i++, nid++)
134 print_pin_widget(buffer, chip, nid, LOLA_PAR_AMP_OUT_CAP,
135 "[Pin-Out]");
136 if (LOLA_AFG_CLOCK_WIDGET_PRESENT(chip->lola_caps)) {
137 print_clock_widget(buffer, chip, nid);
138 nid++;
139 }
140 if (LOLA_AFG_MIXER_WIDGET_PRESENT(chip->lola_caps)) {
141 print_mixer_widget(buffer, chip, nid);
142 nid++;
143 }
144}
145
146/* direct codec access for debugging */
147static void lola_proc_codec_rw_write(struct snd_info_entry *entry,
148 struct snd_info_buffer *buffer)
149{
150 struct lola *chip = entry->private_data;
151 char line[64];
152 unsigned int id, verb, data, extdata;
153 while (!snd_info_get_line(buffer, line, sizeof(line))) {
154 if (sscanf(line, "%i %i %i %i", &id, &verb, &data, &extdata) != 4)
155 continue;
156 lola_codec_read(chip, id, verb, data, extdata,
157 &chip->debug_res,
158 &chip->debug_res_ex);
159 }
160}
161
162static void lola_proc_codec_rw_read(struct snd_info_entry *entry,
163 struct snd_info_buffer *buffer)
164{
165 struct lola *chip = entry->private_data;
166 snd_iprintf(buffer, "0x%x 0x%x\n", chip->debug_res, chip->debug_res_ex);
167}
168
169/*
170 * dump some registers
171 */
172static void lola_proc_regs_read(struct snd_info_entry *entry,
173 struct snd_info_buffer *buffer)
174{
175 struct lola *chip = entry->private_data;
176 int i;
177
178 for (i = 0; i < 0x40; i += 4) {
179 snd_iprintf(buffer, "BAR0 %02x: %08x\n", i,
180 readl(chip->bar[BAR0].remap_addr + i));
181 }
182 snd_iprintf(buffer, "\n");
183 for (i = 0; i < 0x30; i += 4) {
184 snd_iprintf(buffer, "BAR1 %02x: %08x\n", i,
185 readl(chip->bar[BAR1].remap_addr + i));
186 }
187 snd_iprintf(buffer, "\n");
188 for (i = 0x80; i < 0xa0; i += 4) {
189 snd_iprintf(buffer, "BAR1 %02x: %08x\n", i,
190 readl(chip->bar[BAR1].remap_addr + i));
191 }
192 snd_iprintf(buffer, "\n");
193 for (i = 0; i < 32; i++) {
194 snd_iprintf(buffer, "DSD %02x STS %08x\n", i,
195 lola_dsd_read(chip, i, STS));
196 snd_iprintf(buffer, "DSD %02x LPIB %08x\n", i,
197 lola_dsd_read(chip, i, LPIB));
198 snd_iprintf(buffer, "DSD %02x CTL %08x\n", i,
199 lola_dsd_read(chip, i, CTL));
200 snd_iprintf(buffer, "DSD %02x LVIL %08x\n", i,
201 lola_dsd_read(chip, i, LVI));
202 snd_iprintf(buffer, "DSD %02x BDPL %08x\n", i,
203 lola_dsd_read(chip, i, BDPL));
204 snd_iprintf(buffer, "DSD %02x BDPU %08x\n", i,
205 lola_dsd_read(chip, i, BDPU));
206 }
207}
208
209void __devinit lola_proc_debug_new(struct lola *chip)
210{
211 struct snd_info_entry *entry;
212
213 if (!snd_card_proc_new(chip->card, "codec", &entry))
214 snd_info_set_text_ops(entry, chip, lola_proc_codec_read);
215 if (!snd_card_proc_new(chip->card, "codec_rw", &entry)) {
216 snd_info_set_text_ops(entry, chip, lola_proc_codec_rw_read);
217 entry->mode |= S_IWUSR;
218 entry->c.text.write = lola_proc_codec_rw_write;
219 }
220 if (!snd_card_proc_new(chip->card, "regs", &entry))
221 snd_info_set_text_ops(entry, chip, lola_proc_regs_read);
222}
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 961d98297695..9cea84c3e0c6 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -1000,7 +1000,7 @@ static void device_change_handler(struct work_struct *work)
1000 chip->lineout_sw_ctl); 1000 chip->lineout_sw_ctl);
1001 if (mix->anded_reset) 1001 if (mix->anded_reset)
1002 msleep(10); 1002 msleep(10);
1003 check_mute(chip, &mix->amp_mute, 1, mix->auto_mute_notify, 1003 check_mute(chip, &mix->amp_mute, !IS_G4DA, mix->auto_mute_notify,
1004 chip->speaker_sw_ctl); 1004 chip->speaker_sw_ctl);
1005 } else { 1005 } else {
1006 /* unmute speaker, mute others */ 1006 /* unmute speaker, mute others */
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index af3c73053ee4..28afbbf69ce0 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -184,7 +184,7 @@ static struct snd_soc_dai_link at91sam9g20ek_dai = {
184 .codec_dai_name = "wm8731-hifi", 184 .codec_dai_name = "wm8731-hifi",
185 .init = at91sam9g20ek_wm8731_init, 185 .init = at91sam9g20ek_wm8731_init,
186 .platform_name = "atmel-pcm-audio", 186 .platform_name = "atmel-pcm-audio",
187 .codec_name = "wm8731-codec.0-001b", 187 .codec_name = "wm8731.0-001b",
188 .ops = &at91sam9g20ek_ops, 188 .ops = &at91sam9g20ek_ops,
189}; 189};
190 190
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index cb99f04abe88..1d3e258c9ea8 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -77,7 +77,7 @@ static struct snd_soc_dai_link db1200_i2s_dai = {
77 .codec_dai_name = "wm8731-hifi", 77 .codec_dai_name = "wm8731-hifi",
78 .cpu_dai_name = "au1xpsc_i2s.1", 78 .cpu_dai_name = "au1xpsc_i2s.1",
79 .platform_name = "au1xpsc-pcm.1", 79 .platform_name = "au1xpsc-pcm.1",
80 .codec_name = "wm8731-codec.0-001b", 80 .codec_name = "wm8731.0-001b",
81 .ops = &db1200_i2s_wm8731_ops, 81 .ops = &db1200_i2s_wm8731_ops,
82}; 82};
83 83
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 5a2fd8abaefa..98b44b316e78 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -243,6 +243,9 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
243 243
244static int bf5xx_pcm_open(struct snd_pcm_substream *substream) 244static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
245{ 245{
246 struct snd_soc_pcm_runtime *rtd = substream->private_data;
247 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
248 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
246 struct snd_pcm_runtime *runtime = substream->runtime; 249 struct snd_pcm_runtime *runtime = substream->runtime;
247 int ret; 250 int ret;
248 251
@@ -314,6 +317,9 @@ static struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
314 317
315static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) 318static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
316{ 319{
320 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
321 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
322 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
317 struct snd_pcm_substream *substream = pcm->streams[stream].substream; 323 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
318 struct snd_dma_buffer *buf = &substream->dma_buffer; 324 struct snd_dma_buffer *buf = &substream->dma_buffer;
319 size_t size = bf5xx_pcm_hardware.buffer_bytes_max 325 size_t size = bf5xx_pcm_hardware.buffer_bytes_max
@@ -377,6 +383,9 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
377 struct snd_dma_buffer *buf; 383 struct snd_dma_buffer *buf;
378 int stream; 384 int stream;
379#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT) 385#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
386 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
387 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
388 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
380 size_t size = bf5xx_pcm_hardware.buffer_bytes_max * 389 size_t size = bf5xx_pcm_hardware.buffer_bytes_max *
381 sizeof(struct ac97_frame) / 4; 390 sizeof(struct ac97_frame) / 4;
382#endif 391#endif
@@ -405,8 +414,6 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
405 } 414 }
406#endif 415#endif
407 } 416 }
408 if (sport_handle)
409 sport_done(sport_handle);
410} 417}
411 418
412static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); 419static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
@@ -458,7 +465,7 @@ static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
458 465
459static struct platform_driver bf5xx_pcm_driver = { 466static struct platform_driver bf5xx_pcm_driver = {
460 .driver = { 467 .driver = {
461 .name = "bf5xx-pcm-audio", 468 .name = "bfin-ac97-pcm-audio",
462 .owner = THIS_MODULE, 469 .owner = THIS_MODULE,
463 }, 470 },
464 471
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index ffbac26b9bce..6d2162590889 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -41,48 +41,7 @@
41 * anomaly does not affect blackfin sound drivers. 41 * anomaly does not affect blackfin sound drivers.
42*/ 42*/
43 43
44static int *cmd_count; 44static struct sport_device *ac97_sport_handle;
45static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
46
47#define SPORT_REQ(x) \
48 [x] = {P_SPORT##x##_TFS, P_SPORT##x##_DTPRI, P_SPORT##x##_TSCLK, \
49 P_SPORT##x##_RFS, P_SPORT##x##_DRPRI, P_SPORT##x##_RSCLK, 0}
50static u16 sport_req[][7] = {
51#ifdef SPORT0_TCR1
52 SPORT_REQ(0),
53#endif
54#ifdef SPORT1_TCR1
55 SPORT_REQ(1),
56#endif
57#ifdef SPORT2_TCR1
58 SPORT_REQ(2),
59#endif
60#ifdef SPORT3_TCR1
61 SPORT_REQ(3),
62#endif
63};
64
65#define SPORT_PARAMS(x) \
66 [x] = { \
67 .dma_rx_chan = CH_SPORT##x##_RX, \
68 .dma_tx_chan = CH_SPORT##x##_TX, \
69 .err_irq = IRQ_SPORT##x##_ERROR, \
70 .regs = (struct sport_register *)SPORT##x##_TCR1, \
71 }
72static struct sport_param sport_params[4] = {
73#ifdef SPORT0_TCR1
74 SPORT_PARAMS(0),
75#endif
76#ifdef SPORT1_TCR1
77 SPORT_PARAMS(1),
78#endif
79#ifdef SPORT2_TCR1
80 SPORT_PARAMS(2),
81#endif
82#ifdef SPORT3_TCR1
83 SPORT_PARAMS(3),
84#endif
85};
86 45
87void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src, 46void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src,
88 size_t count, unsigned int chan_mask) 47 size_t count, unsigned int chan_mask)
@@ -140,7 +99,8 @@ static unsigned int sport_tx_curr_frag(struct sport_device *sport)
140 99
141static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data) 100static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
142{ 101{
143 struct sport_device *sport = sport_handle; 102 struct sport_device *sport = ac97_sport_handle;
103 int *cmd_count = sport->private_data;
144 int nextfrag = sport_tx_curr_frag(sport); 104 int nextfrag = sport_tx_curr_frag(sport);
145 struct ac97_frame *nextwrite; 105 struct ac97_frame *nextwrite;
146 106
@@ -161,6 +121,7 @@ static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
161static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97, 121static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97,
162 unsigned short reg) 122 unsigned short reg)
163{ 123{
124 struct sport_device *sport_handle = ac97_sport_handle;
164 struct ac97_frame out_frame[2], in_frame[2]; 125 struct ac97_frame out_frame[2], in_frame[2];
165 126
166 pr_debug("%s enter 0x%x\n", __func__, reg); 127 pr_debug("%s enter 0x%x\n", __func__, reg);
@@ -185,6 +146,8 @@ static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97,
185void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, 146void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
186 unsigned short val) 147 unsigned short val)
187{ 148{
149 struct sport_device *sport_handle = ac97_sport_handle;
150
188 pr_debug("%s enter 0x%x:0x%04x\n", __func__, reg, val); 151 pr_debug("%s enter 0x%x:0x%04x\n", __func__, reg, val);
189 152
190 if (sport_handle->tx_run) { 153 if (sport_handle->tx_run) {
@@ -203,28 +166,19 @@ void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
203 166
204static void bf5xx_ac97_warm_reset(struct snd_ac97 *ac97) 167static void bf5xx_ac97_warm_reset(struct snd_ac97 *ac97)
205{ 168{
206#if defined(CONFIG_BF54x) || defined(CONFIG_BF561) || \ 169 struct sport_device *sport_handle = ac97_sport_handle;
207 (defined(BF537_FAMILY) && (CONFIG_SND_BF5XX_SPORT_NUM == 1)) 170 u16 gpio = P_IDENT(sport_handle->pin_req[3]);
208
209#define CONCAT(a, b, c) a ## b ## c
210#define BFIN_SPORT_RFS(x) CONCAT(P_SPORT, x, _RFS)
211
212 u16 per = BFIN_SPORT_RFS(CONFIG_SND_BF5XX_SPORT_NUM);
213 u16 gpio = P_IDENT(BFIN_SPORT_RFS(CONFIG_SND_BF5XX_SPORT_NUM));
214 171
215 pr_debug("%s enter\n", __func__); 172 pr_debug("%s enter\n", __func__);
216 173
217 peripheral_free(per); 174 peripheral_free_list(sport_handle->pin_req);
218 gpio_request(gpio, "bf5xx-ac97"); 175 gpio_request(gpio, "bf5xx-ac97");
219 gpio_direction_output(gpio, 1); 176 gpio_direction_output(gpio, 1);
220 udelay(2); 177 udelay(2);
221 gpio_set_value(gpio, 0); 178 gpio_set_value(gpio, 0);
222 udelay(1); 179 udelay(1);
223 gpio_free(gpio); 180 gpio_free(gpio);
224 peripheral_request(per, "soc-audio"); 181 peripheral_request_list(sport_handle->pin_req, "soc-audio");
225#else
226 pr_info("%s: Not implemented\n", __func__);
227#endif
228} 182}
229 183
230static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97) 184static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97)
@@ -306,18 +260,32 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
306#define bf5xx_ac97_resume NULL 260#define bf5xx_ac97_resume NULL
307#endif 261#endif
308 262
309static int bf5xx_ac97_probe(struct snd_soc_dai *dai) 263static struct snd_soc_dai_driver bfin_ac97_dai = {
264 .ac97_control = 1,
265 .suspend = bf5xx_ac97_suspend,
266 .resume = bf5xx_ac97_resume,
267 .playback = {
268 .stream_name = "AC97 Playback",
269 .channels_min = 2,
270#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
271 .channels_max = 6,
272#else
273 .channels_max = 2,
274#endif
275 .rates = SNDRV_PCM_RATE_48000,
276 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
277 .capture = {
278 .stream_name = "AC97 Capture",
279 .channels_min = 2,
280 .channels_max = 2,
281 .rates = SNDRV_PCM_RATE_48000,
282 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
283};
284
285static int __devinit asoc_bfin_ac97_probe(struct platform_device *pdev)
310{ 286{
311 int ret = 0; 287 struct sport_device *sport_handle;
312 cmd_count = (int *)get_zeroed_page(GFP_KERNEL); 288 int ret;
313 if (cmd_count == NULL)
314 return -ENOMEM;
315
316 if (peripheral_request_list(sport_req[sport_num], "soc-audio")) {
317 pr_err("Requesting Peripherals failed\n");
318 ret = -EFAULT;
319 goto peripheral_err;
320 }
321 289
322#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 290#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
323 /* Request PB3 as reset pin */ 291 /* Request PB3 as reset pin */
@@ -329,12 +297,14 @@ static int bf5xx_ac97_probe(struct snd_soc_dai *dai)
329 } 297 }
330 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1); 298 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
331#endif 299#endif
332 sport_handle = sport_init(&sport_params[sport_num], 2, \ 300
333 sizeof(struct ac97_frame), NULL); 301 sport_handle = sport_init(pdev, 2, sizeof(struct ac97_frame),
302 PAGE_SIZE);
334 if (!sport_handle) { 303 if (!sport_handle) {
335 ret = -ENODEV; 304 ret = -ENODEV;
336 goto sport_err; 305 goto sport_err;
337 } 306 }
307
338 /*SPORT works in TDM mode to simulate AC97 transfers*/ 308 /*SPORT works in TDM mode to simulate AC97 transfers*/
339#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT) 309#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
340 ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 1); 310 ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 1);
@@ -361,67 +331,37 @@ static int bf5xx_ac97_probe(struct snd_soc_dai *dai)
361 goto sport_config_err; 331 goto sport_config_err;
362 } 332 }
363 333
334 ret = snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai);
335 if (ret) {
336 pr_err("Failed to register DAI: %d\n", ret);
337 goto sport_config_err;
338 }
339
340 ac97_sport_handle = sport_handle;
341
364 return 0; 342 return 0;
365 343
366sport_config_err: 344sport_config_err:
367 kfree(sport_handle); 345 sport_done(sport_handle);
368sport_err: 346sport_err:
369#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 347#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
370 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); 348 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
371gpio_err: 349gpio_err:
372#endif 350#endif
373 peripheral_free_list(sport_req[sport_num]);
374peripheral_err:
375 free_page((unsigned long)cmd_count);
376 cmd_count = NULL;
377 351
378 return ret; 352 return ret;
379} 353}
380 354
381static int bf5xx_ac97_remove(struct snd_soc_dai *dai) 355static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev)
382{ 356{
383 free_page((unsigned long)cmd_count); 357 struct sport_device *sport_handle = platform_get_drvdata(pdev);
384 cmd_count = NULL; 358
385 peripheral_free_list(sport_req[sport_num]); 359 snd_soc_unregister_dai(&pdev->dev);
360 sport_done(sport_handle);
386#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 361#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
387 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); 362 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
388#endif 363#endif
389 return 0;
390}
391
392struct snd_soc_dai_driver bfin_ac97_dai = {
393 .ac97_control = 1,
394 .probe = bf5xx_ac97_probe,
395 .remove = bf5xx_ac97_remove,
396 .suspend = bf5xx_ac97_suspend,
397 .resume = bf5xx_ac97_resume,
398 .playback = {
399 .stream_name = "AC97 Playback",
400 .channels_min = 2,
401#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
402 .channels_max = 6,
403#else
404 .channels_max = 2,
405#endif
406 .rates = SNDRV_PCM_RATE_48000,
407 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
408 .capture = {
409 .stream_name = "AC97 Capture",
410 .channels_min = 2,
411 .channels_max = 2,
412 .rates = SNDRV_PCM_RATE_48000,
413 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
414};
415EXPORT_SYMBOL_GPL(bfin_ac97_dai);
416
417static __devinit int asoc_bfin_ac97_probe(struct platform_device *pdev)
418{
419 return snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai);
420}
421 364
422static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev)
423{
424 snd_soc_unregister_dai(&pdev->dev);
425 return 0; 365 return 0;
426} 366}
427 367
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index 83012da9dfc2..ea4951cf5526 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -29,22 +29,12 @@
29#include <asm/portmux.h> 29#include <asm/portmux.h>
30 30
31#include "../codecs/ad1836.h" 31#include "../codecs/ad1836.h"
32#include "bf5xx-sport.h"
33 32
34#include "bf5xx-tdm-pcm.h" 33#include "bf5xx-tdm-pcm.h"
35#include "bf5xx-tdm.h" 34#include "bf5xx-tdm.h"
36 35
37static struct snd_soc_card bf5xx_ad1836; 36static struct snd_soc_card bf5xx_ad1836;
38 37
39static int bf5xx_ad1836_startup(struct snd_pcm_substream *substream)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
43
44 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
45 return 0;
46}
47
48static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream, 38static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
49 struct snd_pcm_hw_params *params) 39 struct snd_pcm_hw_params *params)
50{ 40{
@@ -75,23 +65,33 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
75} 65}
76 66
77static struct snd_soc_ops bf5xx_ad1836_ops = { 67static struct snd_soc_ops bf5xx_ad1836_ops = {
78 .startup = bf5xx_ad1836_startup,
79 .hw_params = bf5xx_ad1836_hw_params, 68 .hw_params = bf5xx_ad1836_hw_params,
80}; 69};
81 70
82static struct snd_soc_dai_link bf5xx_ad1836_dai = { 71static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
83 .name = "ad1836", 72 {
84 .stream_name = "AD1836", 73 .name = "ad1836",
85 .cpu_dai_name = "bf5xx-tdm", 74 .stream_name = "AD1836",
86 .codec_dai_name = "ad1836-hifi", 75 .cpu_dai_name = "bfin-tdm.0",
87 .platform_name = "bf5xx-tdm-pcm-audio", 76 .codec_dai_name = "ad1836-hifi",
88 .codec_name = "ad1836-codec.0", 77 .platform_name = "bfin-tdm-pcm-audio",
89 .ops = &bf5xx_ad1836_ops, 78 .codec_name = "ad1836.0",
79 .ops = &bf5xx_ad1836_ops,
80 },
81 {
82 .name = "ad1836",
83 .stream_name = "AD1836",
84 .cpu_dai_name = "bfin-tdm.1",
85 .codec_dai_name = "ad1836-hifi",
86 .platform_name = "bfin-tdm-pcm-audio",
87 .codec_name = "ad1836.0",
88 .ops = &bf5xx_ad1836_ops,
89 },
90}; 90};
91 91
92static struct snd_soc_card bf5xx_ad1836 = { 92static struct snd_soc_card bf5xx_ad1836 = {
93 .name = "bf5xx_ad1836", 93 .name = "bfin-ad1836",
94 .dai_link = &bf5xx_ad1836_dai, 94 .dai_link = &bf5xx_ad1836_dai[CONFIG_SND_BF5XX_SPORT_NUM],
95 .num_links = 1, 95 .num_links = 1,
96}; 96};
97 97
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c
index d3ccb926b5e4..d6651c033cb7 100644
--- a/sound/soc/blackfin/bf5xx-ad193x.c
+++ b/sound/soc/blackfin/bf5xx-ad193x.c
@@ -38,30 +38,28 @@
38#include <asm/portmux.h> 38#include <asm/portmux.h>
39 39
40#include "../codecs/ad193x.h" 40#include "../codecs/ad193x.h"
41#include "bf5xx-sport.h"
42 41
43#include "bf5xx-tdm-pcm.h" 42#include "bf5xx-tdm-pcm.h"
44#include "bf5xx-tdm.h" 43#include "bf5xx-tdm.h"
45 44
46static struct snd_soc_card bf5xx_ad193x; 45static struct snd_soc_card bf5xx_ad193x;
47 46
48static int bf5xx_ad193x_startup(struct snd_pcm_substream *substream)
49{
50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
51 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
52
53 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
54 return 0;
55}
56
57static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream, 47static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
58 struct snd_pcm_hw_params *params) 48 struct snd_pcm_hw_params *params)
59{ 49{
60 struct snd_soc_pcm_runtime *rtd = substream->private_data; 50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
61 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 51 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
62 struct snd_soc_dai *codec_dai = rtd->codec_dai; 52 struct snd_soc_dai *codec_dai = rtd->codec_dai;
53 unsigned int clk = 0;
63 unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7}; 54 unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7};
64 int ret = 0; 55 int ret = 0;
56
57 switch (params_rate(params)) {
58 case 48000:
59 clk = 12288000;
60 break;
61 }
62
65 /* set cpu DAI configuration */ 63 /* set cpu DAI configuration */
66 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | 64 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
67 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); 65 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
@@ -74,6 +72,12 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
74 if (ret < 0) 72 if (ret < 0)
75 return ret; 73 return ret;
76 74
75 /* set the codec system clock for DAC and ADC */
76 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
77 SND_SOC_CLOCK_IN);
78 if (ret < 0)
79 return ret;
80
77 /* set codec DAI slots, 8 channels, all channels are enabled */ 81 /* set codec DAI slots, 8 channels, all channels are enabled */
78 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 0xFF, 8, 32); 82 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 0xFF, 8, 32);
79 if (ret < 0) 83 if (ret < 0)
@@ -89,23 +93,33 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
89} 93}
90 94
91static struct snd_soc_ops bf5xx_ad193x_ops = { 95static struct snd_soc_ops bf5xx_ad193x_ops = {
92 .startup = bf5xx_ad193x_startup,
93 .hw_params = bf5xx_ad193x_hw_params, 96 .hw_params = bf5xx_ad193x_hw_params,
94}; 97};
95 98
96static struct snd_soc_dai_link bf5xx_ad193x_dai = { 99static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
97 .name = "ad193x", 100 {
98 .stream_name = "AD193X", 101 .name = "ad193x",
99 .cpu_dai_name = "bf5xx-tdm", 102 .stream_name = "AD193X",
100 .codec_dai_name ="ad193x-hifi", 103 .cpu_dai_name = "bfin-tdm.0",
101 .platform_name = "bf5xx-tdm-pcm-audio", 104 .codec_dai_name ="ad193x-hifi",
102 .codec_name = "ad193x-codec.5", 105 .platform_name = "bfin-tdm-pcm-audio",
103 .ops = &bf5xx_ad193x_ops, 106 .codec_name = "ad193x.5",
107 .ops = &bf5xx_ad193x_ops,
108 },
109 {
110 .name = "ad193x",
111 .stream_name = "AD193X",
112 .cpu_dai_name = "bfin-tdm.1",
113 .codec_dai_name ="ad193x-hifi",
114 .platform_name = "bfin-tdm-pcm-audio",
115 .codec_name = "ad193x.5",
116 .ops = &bf5xx_ad193x_ops,
117 },
104}; 118};
105 119
106static struct snd_soc_card bf5xx_ad193x = { 120static struct snd_soc_card bf5xx_ad193x = {
107 .name = "bf5xx_ad193x", 121 .name = "bfin-ad193x",
108 .dai_link = &bf5xx_ad193x_dai, 122 .dai_link = &bf5xx_ad193x_dai[CONFIG_SND_BF5XX_SPORT_NUM],
109 .num_links = 1, 123 .num_links = 1,
110}; 124};
111 125
diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c
index d57c9c9c9883..06a84b211b52 100644
--- a/sound/soc/blackfin/bf5xx-ad1980.c
+++ b/sound/soc/blackfin/bf5xx-ad1980.c
@@ -47,39 +47,34 @@
47#include <asm/portmux.h> 47#include <asm/portmux.h>
48 48
49#include "../codecs/ad1980.h" 49#include "../codecs/ad1980.h"
50#include "bf5xx-sport.h" 50
51#include "bf5xx-ac97-pcm.h" 51#include "bf5xx-ac97-pcm.h"
52#include "bf5xx-ac97.h" 52#include "bf5xx-ac97.h"
53 53
54static struct snd_soc_card bf5xx_board; 54static struct snd_soc_card bf5xx_board;
55 55
56static int bf5xx_board_startup(struct snd_pcm_substream *substream) 56static struct snd_soc_dai_link bf5xx_board_dai[] = {
57{ 57 {
58 struct snd_soc_pcm_runtime *rtd = substream->private_data; 58 .name = "AC97",
59 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 59 .stream_name = "AC97 HiFi",
60 60 .cpu_dai_name = "bfin-ac97.0",
61 pr_debug("%s enter\n", __func__); 61 .codec_dai_name = "ad1980-hifi",
62 snd_soc_dai_set_drvdata(cpu_dai, sport_handle); 62 .platform_name = "bfin-ac97-pcm-audio",
63 return 0; 63 .codec_name = "ad1980",
64} 64 },
65 65 {
66static struct snd_soc_ops bf5xx_board_ops = { 66 .name = "AC97",
67 .startup = bf5xx_board_startup, 67 .stream_name = "AC97 HiFi",
68}; 68 .cpu_dai_name = "bfin-ac97.1",
69 69 .codec_dai_name = "ad1980-hifi",
70static struct snd_soc_dai_link bf5xx_board_dai = { 70 .platform_name = "bfin-ac97-pcm-audio",
71 .name = "AC97", 71 .codec_name = "ad1980",
72 .stream_name = "AC97 HiFi", 72 },
73 .cpu_dai_name = "bfin-ac97",
74 .codec_dai_name = "ad1980-hifi",
75 .platform_name = "bfin-pcm-audio",
76 .codec_name = "ad1980-codec",
77 .ops = &bf5xx_board_ops,
78}; 73};
79 74
80static struct snd_soc_card bf5xx_board = { 75static struct snd_soc_card bf5xx_board = {
81 .name = "bf5xx-board", 76 .name = "bfin-ad1980",
82 .dai_link = &bf5xx_board_dai, 77 .dai_link = &bf5xx_board_dai[CONFIG_SND_BF5XX_SPORT_NUM],
83 .num_links = 1, 78 .num_links = 1,
84}; 79};
85 80
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index 732fb8bad076..732a247f2527 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -145,16 +145,6 @@ static int bf5xx_probe(struct platform_device *pdev)
145 return 0; 145 return 0;
146} 146}
147 147
148static int bf5xx_ad73311_startup(struct snd_pcm_substream *substream)
149{
150 struct snd_soc_pcm_runtime *rtd = substream->private_data;
151 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
152
153 pr_debug("%s enter\n", __func__);
154 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
155 return 0;
156}
157
158static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream, 148static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,
159 struct snd_pcm_hw_params *params) 149 struct snd_pcm_hw_params *params)
160{ 150{
@@ -176,24 +166,34 @@ static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,
176 166
177 167
178static struct snd_soc_ops bf5xx_ad73311_ops = { 168static struct snd_soc_ops bf5xx_ad73311_ops = {
179 .startup = bf5xx_ad73311_startup,
180 .hw_params = bf5xx_ad73311_hw_params, 169 .hw_params = bf5xx_ad73311_hw_params,
181}; 170};
182 171
183static struct snd_soc_dai_link bf5xx_ad73311_dai = { 172static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
184 .name = "ad73311", 173 {
185 .stream_name = "AD73311", 174 .name = "ad73311",
186 .cpu_dai_name = "bf5xx-i2s", 175 .stream_name = "AD73311",
187 .codec_dai_name = "ad73311-hifi", 176 .cpu_dai_name = "bfin-i2s.0",
188 .platform_name = "bfin-pcm-audio", 177 .codec_dai_name = "ad73311-hifi",
189 .codec_name = "ad73311-codec", 178 .platform_name = "bfin-i2s-pcm-audio",
190 .ops = &bf5xx_ad73311_ops, 179 .codec_name = "ad73311",
180 .ops = &bf5xx_ad73311_ops,
181 },
182 {
183 .name = "ad73311",
184 .stream_name = "AD73311",
185 .cpu_dai_name = "bfin-i2s.1",
186 .codec_dai_name = "ad73311-hifi",
187 .platform_name = "bfin-i2s-pcm-audio",
188 .codec_name = "ad73311",
189 .ops = &bf5xx_ad73311_ops,
190 },
191}; 191};
192 192
193static struct snd_soc_card bf5xx_ad73311 = { 193static struct snd_soc_card bf5xx_ad73311 = {
194 .name = "bf5xx_ad73311", 194 .name = "bfin-ad73311",
195 .probe = bf5xx_probe, 195 .probe = bf5xx_probe,
196 .dai_link = &bf5xx_ad73311_dai, 196 .dai_link = &bf5xx_ad73311_dai[CONFIG_SND_BF5XX_SPORT_NUM],
197 .num_links = 1, 197 .num_links = 1,
198}; 198};
199 199
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 890a0dccf902..b5101efd1c87 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -148,10 +148,15 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
148 148
149static int bf5xx_pcm_open(struct snd_pcm_substream *substream) 149static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
150{ 150{
151 struct snd_soc_pcm_runtime *rtd = substream->private_data;
152 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
153 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
151 struct snd_pcm_runtime *runtime = substream->runtime; 154 struct snd_pcm_runtime *runtime = substream->runtime;
155 struct snd_dma_buffer *buf = &substream->dma_buffer;
152 int ret; 156 int ret;
153 157
154 pr_debug("%s enter\n", __func__); 158 pr_debug("%s enter\n", __func__);
159
155 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware); 160 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
156 161
157 ret = snd_pcm_hw_constraint_integer(runtime, \ 162 ret = snd_pcm_hw_constraint_integer(runtime, \
@@ -159,9 +164,14 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
159 if (ret < 0) 164 if (ret < 0)
160 goto out; 165 goto out;
161 166
162 if (sport_handle != NULL) 167 if (sport_handle != NULL) {
168 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
169 sport_handle->tx_buf = buf->area;
170 else
171 sport_handle->rx_buf = buf->area;
172
163 runtime->private_data = sport_handle; 173 runtime->private_data = sport_handle;
164 else { 174 } else {
165 pr_err("sport_handle is NULL\n"); 175 pr_err("sport_handle is NULL\n");
166 return -1; 176 return -1;
167 } 177 }
@@ -214,11 +224,6 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
214 pr_debug("%s, area:%p, size:0x%08lx\n", __func__, 224 pr_debug("%s, area:%p, size:0x%08lx\n", __func__,
215 buf->area, buf->bytes); 225 buf->area, buf->bytes);
216 226
217 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
218 sport_handle->tx_buf = buf->area;
219 else
220 sport_handle->rx_buf = buf->area;
221
222 return 0; 227 return 0;
223} 228}
224 229
@@ -239,8 +244,6 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
239 dma_free_coherent(NULL, buf->bytes, buf->area, 0); 244 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
240 buf->area = NULL; 245 buf->area = NULL;
241 } 246 }
242 if (sport_handle)
243 sport_done(sport_handle);
244} 247}
245 248
246static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); 249static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
@@ -292,7 +295,7 @@ static int __devexit bfin_i2s_soc_platform_remove(struct platform_device *pdev)
292 295
293static struct platform_driver bfin_i2s_pcm_driver = { 296static struct platform_driver bfin_i2s_pcm_driver = {
294 .driver = { 297 .driver = {
295 .name = "bfin-pcm-audio", 298 .name = "bfin-i2s-pcm-audio",
296 .owner = THIS_MODULE, 299 .owner = THIS_MODULE,
297 }, 300 },
298 301
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index d453b1e9d607..00cc3e00b2fe 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -51,59 +51,24 @@ struct bf5xx_i2s_port {
51 int configured; 51 int configured;
52}; 52};
53 53
54static struct bf5xx_i2s_port bf5xx_i2s;
55static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
56
57static struct sport_param sport_params[2] = {
58 {
59 .dma_rx_chan = CH_SPORT0_RX,
60 .dma_tx_chan = CH_SPORT0_TX,
61 .err_irq = IRQ_SPORT0_ERROR,
62 .regs = (struct sport_register *)SPORT0_TCR1,
63 },
64 {
65 .dma_rx_chan = CH_SPORT1_RX,
66 .dma_tx_chan = CH_SPORT1_TX,
67 .err_irq = IRQ_SPORT1_ERROR,
68 .regs = (struct sport_register *)SPORT1_TCR1,
69 }
70};
71
72/*
73 * Setting the TFS pin selector for SPORT 0 based on whether the selected
74 * port id F or G. If the port is F then no conflict should exist for the
75 * TFS. When Port G is selected and EMAC then there is a conflict between
76 * the PHY interrupt line and TFS. Current settings prevent the conflict
77 * by ignoring the TFS pin when Port G is selected. This allows both
78 * codecs and EMAC using Port G concurrently.
79 */
80#ifdef CONFIG_BF527_SPORT0_PORTG
81#define LOCAL_SPORT0_TFS (0)
82#else
83#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
84#endif
85
86static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
87 P_SPORT0_DRPRI, P_SPORT0_RSCLK, LOCAL_SPORT0_TFS, 0},
88 {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, P_SPORT1_DRPRI,
89 P_SPORT1_RSCLK, P_SPORT1_TFS, 0} };
90
91static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 54static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
92 unsigned int fmt) 55 unsigned int fmt)
93{ 56{
57 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
58 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
94 int ret = 0; 59 int ret = 0;
95 60
96 /* interface format:support I2S,slave mode */ 61 /* interface format:support I2S,slave mode */
97 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 62 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
98 case SND_SOC_DAIFMT_I2S: 63 case SND_SOC_DAIFMT_I2S:
99 bf5xx_i2s.tcr1 |= TFSR | TCKFE; 64 bf5xx_i2s->tcr1 |= TFSR | TCKFE;
100 bf5xx_i2s.rcr1 |= RFSR | RCKFE; 65 bf5xx_i2s->rcr1 |= RFSR | RCKFE;
101 bf5xx_i2s.tcr2 |= TSFSE; 66 bf5xx_i2s->tcr2 |= TSFSE;
102 bf5xx_i2s.rcr2 |= RSFSE; 67 bf5xx_i2s->rcr2 |= RSFSE;
103 break; 68 break;
104 case SND_SOC_DAIFMT_DSP_A: 69 case SND_SOC_DAIFMT_DSP_A:
105 bf5xx_i2s.tcr1 |= TFSR; 70 bf5xx_i2s->tcr1 |= TFSR;
106 bf5xx_i2s.rcr1 |= RFSR; 71 bf5xx_i2s->rcr1 |= RFSR;
107 break; 72 break;
108 case SND_SOC_DAIFMT_LEFT_J: 73 case SND_SOC_DAIFMT_LEFT_J:
109 ret = -EINVAL; 74 ret = -EINVAL;
@@ -135,29 +100,35 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
135 struct snd_pcm_hw_params *params, 100 struct snd_pcm_hw_params *params,
136 struct snd_soc_dai *dai) 101 struct snd_soc_dai *dai)
137{ 102{
103 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
104 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
138 int ret = 0; 105 int ret = 0;
139 106
140 bf5xx_i2s.tcr2 &= ~0x1f; 107 bf5xx_i2s->tcr2 &= ~0x1f;
141 bf5xx_i2s.rcr2 &= ~0x1f; 108 bf5xx_i2s->rcr2 &= ~0x1f;
142 switch (params_format(params)) { 109 switch (params_format(params)) {
110 case SNDRV_PCM_FORMAT_S8:
111 bf5xx_i2s->tcr2 |= 7;
112 bf5xx_i2s->rcr2 |= 7;
113 sport_handle->wdsize = 1;
143 case SNDRV_PCM_FORMAT_S16_LE: 114 case SNDRV_PCM_FORMAT_S16_LE:
144 bf5xx_i2s.tcr2 |= 15; 115 bf5xx_i2s->tcr2 |= 15;
145 bf5xx_i2s.rcr2 |= 15; 116 bf5xx_i2s->rcr2 |= 15;
146 sport_handle->wdsize = 2; 117 sport_handle->wdsize = 2;
147 break; 118 break;
148 case SNDRV_PCM_FORMAT_S24_LE: 119 case SNDRV_PCM_FORMAT_S24_LE:
149 bf5xx_i2s.tcr2 |= 23; 120 bf5xx_i2s->tcr2 |= 23;
150 bf5xx_i2s.rcr2 |= 23; 121 bf5xx_i2s->rcr2 |= 23;
151 sport_handle->wdsize = 3; 122 sport_handle->wdsize = 3;
152 break; 123 break;
153 case SNDRV_PCM_FORMAT_S32_LE: 124 case SNDRV_PCM_FORMAT_S32_LE:
154 bf5xx_i2s.tcr2 |= 31; 125 bf5xx_i2s->tcr2 |= 31;
155 bf5xx_i2s.rcr2 |= 31; 126 bf5xx_i2s->rcr2 |= 31;
156 sport_handle->wdsize = 4; 127 sport_handle->wdsize = 4;
157 break; 128 break;
158 } 129 }
159 130
160 if (!bf5xx_i2s.configured) { 131 if (!bf5xx_i2s->configured) {
161 /* 132 /*
162 * TX and RX are not independent,they are enabled at the 133 * TX and RX are not independent,they are enabled at the
163 * same time, even if only one side is running. So, we 134 * same time, even if only one side is running. So, we
@@ -166,16 +137,16 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
166 * 137 *
167 * CPU DAI:slave mode. 138 * CPU DAI:slave mode.
168 */ 139 */
169 bf5xx_i2s.configured = 1; 140 bf5xx_i2s->configured = 1;
170 ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1, 141 ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1,
171 bf5xx_i2s.rcr2, 0, 0); 142 bf5xx_i2s->rcr2, 0, 0);
172 if (ret) { 143 if (ret) {
173 pr_err("SPORT is busy!\n"); 144 pr_err("SPORT is busy!\n");
174 return -EBUSY; 145 return -EBUSY;
175 } 146 }
176 147
177 ret = sport_config_tx(sport_handle, bf5xx_i2s.tcr1, 148 ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1,
178 bf5xx_i2s.tcr2, 0, 0); 149 bf5xx_i2s->tcr2, 0, 0);
179 if (ret) { 150 if (ret) {
180 pr_err("SPORT is busy!\n"); 151 pr_err("SPORT is busy!\n");
181 return -EBUSY; 152 return -EBUSY;
@@ -188,41 +159,19 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
188static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream, 159static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
189 struct snd_soc_dai *dai) 160 struct snd_soc_dai *dai)
190{ 161{
162 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
163 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
164
191 pr_debug("%s enter\n", __func__); 165 pr_debug("%s enter\n", __func__);
192 /* No active stream, SPORT is allowed to be configured again. */ 166 /* No active stream, SPORT is allowed to be configured again. */
193 if (!dai->active) 167 if (!dai->active)
194 bf5xx_i2s.configured = 0; 168 bf5xx_i2s->configured = 0;
195}
196
197static int bf5xx_i2s_probe(struct snd_soc_dai *dai)
198{
199 pr_debug("%s enter\n", __func__);
200 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
201 pr_err("Requesting Peripherals failed\n");
202 return -EFAULT;
203 }
204
205 /* request DMA for SPORT */
206 sport_handle = sport_init(&sport_params[sport_num], 4, \
207 2 * sizeof(u32), NULL);
208 if (!sport_handle) {
209 peripheral_free_list(&sport_req[sport_num][0]);
210 return -ENODEV;
211 }
212
213 return 0;
214}
215
216static int bf5xx_i2s_remove(struct snd_soc_dai *dai)
217{
218 pr_debug("%s enter\n", __func__);
219 peripheral_free_list(&sport_req[sport_num][0]);
220 return 0;
221} 169}
222 170
223#ifdef CONFIG_PM 171#ifdef CONFIG_PM
224static int bf5xx_i2s_suspend(struct snd_soc_dai *dai) 172static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
225{ 173{
174 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
226 175
227 pr_debug("%s : sport %d\n", __func__, dai->id); 176 pr_debug("%s : sport %d\n", __func__, dai->id);
228 177
@@ -235,19 +184,21 @@ static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
235 184
236static int bf5xx_i2s_resume(struct snd_soc_dai *dai) 185static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
237{ 186{
187 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
188 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
238 int ret; 189 int ret;
239 190
240 pr_debug("%s : sport %d\n", __func__, dai->id); 191 pr_debug("%s : sport %d\n", __func__, dai->id);
241 192
242 ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1, 193 ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1,
243 bf5xx_i2s.rcr2, 0, 0); 194 bf5xx_i2s->rcr2, 0, 0);
244 if (ret) { 195 if (ret) {
245 pr_err("SPORT is busy!\n"); 196 pr_err("SPORT is busy!\n");
246 return -EBUSY; 197 return -EBUSY;
247 } 198 }
248 199
249 ret = sport_config_tx(sport_handle, bf5xx_i2s.tcr1, 200 ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1,
250 bf5xx_i2s.tcr2, 0, 0); 201 bf5xx_i2s->tcr2, 0, 0);
251 if (ret) { 202 if (ret) {
252 pr_err("SPORT is busy!\n"); 203 pr_err("SPORT is busy!\n");
253 return -EBUSY; 204 return -EBUSY;
@@ -266,8 +217,11 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
266 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \ 217 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
267 SNDRV_PCM_RATE_96000) 218 SNDRV_PCM_RATE_96000)
268 219
269#define BF5XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\ 220#define BF5XX_I2S_FORMATS \
270 SNDRV_PCM_FMTBIT_S32_LE) 221 (SNDRV_PCM_FMTBIT_S8 | \
222 SNDRV_PCM_FMTBIT_S16_LE | \
223 SNDRV_PCM_FMTBIT_S24_LE | \
224 SNDRV_PCM_FMTBIT_S32_LE)
271 225
272static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = { 226static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
273 .shutdown = bf5xx_i2s_shutdown, 227 .shutdown = bf5xx_i2s_shutdown,
@@ -276,8 +230,6 @@ static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
276}; 230};
277 231
278static struct snd_soc_dai_driver bf5xx_i2s_dai = { 232static struct snd_soc_dai_driver bf5xx_i2s_dai = {
279 .probe = bf5xx_i2s_probe,
280 .remove = bf5xx_i2s_remove,
281 .suspend = bf5xx_i2s_suspend, 233 .suspend = bf5xx_i2s_suspend,
282 .resume = bf5xx_i2s_resume, 234 .resume = bf5xx_i2s_resume,
283 .playback = { 235 .playback = {
@@ -293,23 +245,45 @@ static struct snd_soc_dai_driver bf5xx_i2s_dai = {
293 .ops = &bf5xx_i2s_dai_ops, 245 .ops = &bf5xx_i2s_dai_ops,
294}; 246};
295 247
296static int bfin_i2s_drv_probe(struct platform_device *pdev) 248static int __devinit bf5xx_i2s_probe(struct platform_device *pdev)
297{ 249{
298 return snd_soc_register_dai(&pdev->dev, &bf5xx_i2s_dai); 250 struct sport_device *sport_handle;
251 int ret;
252
253 /* configure SPORT for I2S */
254 sport_handle = sport_init(pdev, 4, 2 * sizeof(u32),
255 sizeof(struct bf5xx_i2s_port));
256 if (!sport_handle)
257 return -ENODEV;
258
259 /* register with the ASoC layers */
260 ret = snd_soc_register_dai(&pdev->dev, &bf5xx_i2s_dai);
261 if (ret) {
262 pr_err("Failed to register DAI: %d\n", ret);
263 sport_done(sport_handle);
264 return ret;
265 }
266
267 return 0;
299} 268}
300 269
301static int __devexit bfin_i2s_drv_remove(struct platform_device *pdev) 270static int __devexit bf5xx_i2s_remove(struct platform_device *pdev)
302{ 271{
272 struct sport_device *sport_handle = platform_get_drvdata(pdev);
273
274 pr_debug("%s enter\n", __func__);
275
303 snd_soc_unregister_dai(&pdev->dev); 276 snd_soc_unregister_dai(&pdev->dev);
277 sport_done(sport_handle);
278
304 return 0; 279 return 0;
305} 280}
306 281
307static struct platform_driver bfin_i2s_driver = { 282static struct platform_driver bfin_i2s_driver = {
308 .probe = bfin_i2s_drv_probe, 283 .probe = bf5xx_i2s_probe,
309 .remove = __devexit_p(bfin_i2s_drv_remove), 284 .remove = __devexit_p(bf5xx_i2s_remove),
310
311 .driver = { 285 .driver = {
312 .name = "bf5xx-i2s", 286 .name = "bfin-i2s",
313 .owner = THIS_MODULE, 287 .owner = THIS_MODULE,
314 }, 288 },
315}; 289};
diff --git a/sound/soc/blackfin/bf5xx-sport.c b/sound/soc/blackfin/bf5xx-sport.c
index 99051ff0954e..a2d40349fcc4 100644
--- a/sound/soc/blackfin/bf5xx-sport.c
+++ b/sound/soc/blackfin/bf5xx-sport.c
@@ -42,8 +42,6 @@
42/* delay between frame sync pulse and first data bit in multichannel mode */ 42/* delay between frame sync pulse and first data bit in multichannel mode */
43#define FRAME_DELAY (1<<12) 43#define FRAME_DELAY (1<<12)
44 44
45struct sport_device *sport_handle;
46EXPORT_SYMBOL(sport_handle);
47/* note: multichannel is in units of 8 channels, 45/* note: multichannel is in units of 8 channels,
48 * tdm_count is # channels NOT / 8 ! */ 46 * tdm_count is # channels NOT / 8 ! */
49int sport_set_multichannel(struct sport_device *sport, 47int sport_set_multichannel(struct sport_device *sport,
@@ -798,86 +796,164 @@ int sport_set_err_callback(struct sport_device *sport,
798} 796}
799EXPORT_SYMBOL(sport_set_err_callback); 797EXPORT_SYMBOL(sport_set_err_callback);
800 798
801struct sport_device *sport_init(struct sport_param *param, unsigned wdsize, 799static int sport_config_pdev(struct platform_device *pdev, struct sport_param *param)
802 unsigned dummy_count, void *private_data)
803{ 800{
804 int ret; 801 /* Extract settings from platform data */
802 struct device *dev = &pdev->dev;
803 struct bfin_snd_platform_data *pdata = dev->platform_data;
804 struct resource *res;
805
806 param->num = pdev->id;
807
808 if (!pdata) {
809 dev_err(dev, "no platform_data\n");
810 return -ENODEV;
811 }
812 param->pin_req = pdata->pin_req;
813
814 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
815 if (!res) {
816 dev_err(dev, "no MEM resource\n");
817 return -ENODEV;
818 }
819 param->regs = (struct sport_register *)res->start;
820
821 /* first RX, then TX */
822 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
823 if (!res) {
824 dev_err(dev, "no rx DMA resource\n");
825 return -ENODEV;
826 }
827 param->dma_rx_chan = res->start;
828
829 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
830 if (!res) {
831 dev_err(dev, "no tx DMA resource\n");
832 return -ENODEV;
833 }
834 param->dma_tx_chan = res->start;
835
836 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
837 if (!res) {
838 dev_err(dev, "no irq resource\n");
839 return -ENODEV;
840 }
841 param->err_irq = res->start;
842
843 return 0;
844}
845
846struct sport_device *sport_init(struct platform_device *pdev,
847 unsigned int wdsize, unsigned int dummy_count, size_t priv_size)
848{
849 struct device *dev = &pdev->dev;
850 struct sport_param param;
805 struct sport_device *sport; 851 struct sport_device *sport;
806 pr_debug("%s enter\n", __func__); 852 int ret;
807 BUG_ON(param == NULL); 853
808 BUG_ON(wdsize == 0 || dummy_count == 0); 854 dev_dbg(dev, "%s enter\n", __func__);
809 sport = kmalloc(sizeof(struct sport_device), GFP_KERNEL); 855
810 if (!sport) { 856 param.wdsize = wdsize;
811 pr_err("Failed to allocate for sport device\n"); 857 param.dummy_count = dummy_count;
858 BUG_ON(param.wdsize == 0 || param.dummy_count == 0);
859
860 ret = sport_config_pdev(pdev, &param);
861 if (ret)
862 return NULL;
863
864 if (peripheral_request_list(param.pin_req, "soc-audio")) {
865 dev_err(dev, "requesting Peripherals failed\n");
812 return NULL; 866 return NULL;
813 } 867 }
814 868
815 memset(sport, 0, sizeof(struct sport_device)); 869 sport = kzalloc(sizeof(*sport), GFP_KERNEL);
816 sport->dma_rx_chan = param->dma_rx_chan; 870 if (!sport) {
817 sport->dma_tx_chan = param->dma_tx_chan; 871 dev_err(dev, "failed to allocate for sport device\n");
818 sport->err_irq = param->err_irq; 872 goto __init_err0;
819 sport->regs = param->regs; 873 }
820 sport->private_data = private_data; 874
875 sport->num = param.num;
876 sport->dma_rx_chan = param.dma_rx_chan;
877 sport->dma_tx_chan = param.dma_tx_chan;
878 sport->err_irq = param.err_irq;
879 sport->regs = param.regs;
880 sport->pin_req = param.pin_req;
821 881
822 if (request_dma(sport->dma_rx_chan, "SPORT RX Data") == -EBUSY) { 882 if (request_dma(sport->dma_rx_chan, "SPORT RX Data") == -EBUSY) {
823 pr_err("Failed to request RX dma %d\n", \ 883 dev_err(dev, "failed to request RX dma %d\n", sport->dma_rx_chan);
824 sport->dma_rx_chan);
825 goto __init_err1; 884 goto __init_err1;
826 } 885 }
827 if (set_dma_callback(sport->dma_rx_chan, rx_handler, sport) != 0) { 886 if (set_dma_callback(sport->dma_rx_chan, rx_handler, sport) != 0) {
828 pr_err("Failed to request RX irq %d\n", \ 887 dev_err(dev, "failed to request RX irq %d\n", sport->dma_rx_chan);
829 sport->dma_rx_chan);
830 goto __init_err2; 888 goto __init_err2;
831 } 889 }
832 890
833 if (request_dma(sport->dma_tx_chan, "SPORT TX Data") == -EBUSY) { 891 if (request_dma(sport->dma_tx_chan, "SPORT TX Data") == -EBUSY) {
834 pr_err("Failed to request TX dma %d\n", \ 892 dev_err(dev, "failed to request TX dma %d\n", sport->dma_tx_chan);
835 sport->dma_tx_chan);
836 goto __init_err2; 893 goto __init_err2;
837 } 894 }
838 895
839 if (set_dma_callback(sport->dma_tx_chan, tx_handler, sport) != 0) { 896 if (set_dma_callback(sport->dma_tx_chan, tx_handler, sport) != 0) {
840 pr_err("Failed to request TX irq %d\n", \ 897 dev_err(dev, "failed to request TX irq %d\n", sport->dma_tx_chan);
841 sport->dma_tx_chan);
842 goto __init_err3; 898 goto __init_err3;
843 } 899 }
844 900
845 if (request_irq(sport->err_irq, err_handler, IRQF_SHARED, "SPORT err", 901 if (request_irq(sport->err_irq, err_handler, IRQF_SHARED, "SPORT err",
846 sport) < 0) { 902 sport) < 0) {
847 pr_err("Failed to request err irq:%d\n", \ 903 dev_err(dev, "failed to request err irq %d\n", sport->err_irq);
848 sport->err_irq);
849 goto __init_err3; 904 goto __init_err3;
850 } 905 }
851 906
852 pr_err("dma rx:%d tx:%d, err irq:%d, regs:%p\n", 907 dev_info(dev, "dma rx:%d tx:%d, err irq:%d, regs:%p\n",
853 sport->dma_rx_chan, sport->dma_tx_chan, 908 sport->dma_rx_chan, sport->dma_tx_chan,
854 sport->err_irq, sport->regs); 909 sport->err_irq, sport->regs);
855 910
856 sport->wdsize = wdsize; 911 sport->wdsize = param.wdsize;
857 sport->dummy_count = dummy_count; 912 sport->dummy_count = param.dummy_count;
913
914 sport->private_data = kzalloc(priv_size, GFP_KERNEL);
915 if (!sport->private_data) {
916 dev_err(dev, "could not alloc priv data %zu bytes\n", priv_size);
917 goto __init_err4;
918 }
858 919
859 if (L1_DATA_A_LENGTH) 920 if (L1_DATA_A_LENGTH)
860 sport->dummy_buf = l1_data_sram_zalloc(dummy_count * 2); 921 sport->dummy_buf = l1_data_sram_zalloc(param.dummy_count * 2);
861 else 922 else
862 sport->dummy_buf = kzalloc(dummy_count * 2, GFP_KERNEL); 923 sport->dummy_buf = kzalloc(param.dummy_count * 2, GFP_KERNEL);
863 if (sport->dummy_buf == NULL) { 924 if (sport->dummy_buf == NULL) {
864 pr_err("Failed to allocate dummy buffer\n"); 925 dev_err(dev, "failed to allocate dummy buffer\n");
865 goto __error; 926 goto __error1;
866 } 927 }
867 928
868 ret = sport_config_rx_dummy(sport); 929 ret = sport_config_rx_dummy(sport);
869 if (ret) { 930 if (ret) {
870 pr_err("Failed to config rx dummy ring\n"); 931 dev_err(dev, "failed to config rx dummy ring\n");
871 goto __error; 932 goto __error2;
872 } 933 }
873 ret = sport_config_tx_dummy(sport); 934 ret = sport_config_tx_dummy(sport);
874 if (ret) { 935 if (ret) {
875 pr_err("Failed to config tx dummy ring\n"); 936 dev_err(dev, "failed to config tx dummy ring\n");
876 goto __error; 937 goto __error3;
877 } 938 }
878 939
940 platform_set_drvdata(pdev, sport);
941
879 return sport; 942 return sport;
880__error: 943__error3:
944 if (L1_DATA_A_LENGTH)
945 l1_data_sram_free(sport->dummy_rx_desc);
946 else
947 dma_free_coherent(NULL, 2*sizeof(struct dmasg),
948 sport->dummy_rx_desc, 0);
949__error2:
950 if (L1_DATA_A_LENGTH)
951 l1_data_sram_free(sport->dummy_buf);
952 else
953 kfree(sport->dummy_buf);
954__error1:
955 kfree(sport->private_data);
956__init_err4:
881 free_irq(sport->err_irq, sport); 957 free_irq(sport->err_irq, sport);
882__init_err3: 958__init_err3:
883 free_dma(sport->dma_tx_chan); 959 free_dma(sport->dma_tx_chan);
@@ -885,6 +961,8 @@ __init_err2:
885 free_dma(sport->dma_rx_chan); 961 free_dma(sport->dma_rx_chan);
886__init_err1: 962__init_err1:
887 kfree(sport); 963 kfree(sport);
964__init_err0:
965 peripheral_free_list(param.pin_req);
888 return NULL; 966 return NULL;
889} 967}
890EXPORT_SYMBOL(sport_init); 968EXPORT_SYMBOL(sport_init);
@@ -917,8 +995,9 @@ void sport_done(struct sport_device *sport)
917 free_dma(sport->dma_tx_chan); 995 free_dma(sport->dma_tx_chan);
918 free_irq(sport->err_irq, sport); 996 free_irq(sport->err_irq, sport);
919 997
998 kfree(sport->private_data);
999 peripheral_free_list(sport->pin_req);
920 kfree(sport); 1000 kfree(sport);
921 sport = NULL;
922} 1001}
923EXPORT_SYMBOL(sport_done); 1002EXPORT_SYMBOL(sport_done);
924 1003
diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h
index a86e8cc0b2d3..5ab60bd613ea 100644
--- a/sound/soc/blackfin/bf5xx-sport.h
+++ b/sound/soc/blackfin/bf5xx-sport.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * File: bf5xx_ac97_sport.h 2 * File: bf5xx_sport.h
3 * Based on: 3 * Based on:
4 * Author: Roy Huang <roy.huang@analog.com> 4 * Author: Roy Huang <roy.huang@analog.com>
5 * 5 *
@@ -33,15 +33,18 @@
33#include <linux/types.h> 33#include <linux/types.h>
34#include <linux/wait.h> 34#include <linux/wait.h>
35#include <linux/workqueue.h> 35#include <linux/workqueue.h>
36#include <linux/platform_device.h>
36#include <asm/dma.h> 37#include <asm/dma.h>
37#include <asm/bfin_sport.h> 38#include <asm/bfin_sport.h>
38 39
39#define DESC_ELEMENT_COUNT 9 40#define DESC_ELEMENT_COUNT 9
40 41
41struct sport_device { 42struct sport_device {
43 int num;
42 int dma_rx_chan; 44 int dma_rx_chan;
43 int dma_tx_chan; 45 int dma_tx_chan;
44 int err_irq; 46 int err_irq;
47 const unsigned short *pin_req;
45 struct sport_register *regs; 48 struct sport_register *regs;
46 49
47 unsigned char *rx_buf; 50 unsigned char *rx_buf;
@@ -103,17 +106,20 @@ struct sport_device {
103 void *private_data; 106 void *private_data;
104}; 107};
105 108
106extern struct sport_device *sport_handle;
107
108struct sport_param { 109struct sport_param {
110 int num;
109 int dma_rx_chan; 111 int dma_rx_chan;
110 int dma_tx_chan; 112 int dma_tx_chan;
111 int err_irq; 113 int err_irq;
114 const unsigned short *pin_req;
112 struct sport_register *regs; 115 struct sport_register *regs;
116 unsigned int wdsize;
117 unsigned int dummy_count;
118 void *private_data;
113}; 119};
114 120
115struct sport_device *sport_init(struct sport_param *param, unsigned wdsize, 121struct sport_device *sport_init(struct platform_device *pdev,
116 unsigned dummy_count, void *private_data); 122 unsigned int wdsize, unsigned int dummy_count, size_t priv_size);
117 123
118void sport_done(struct sport_device *sport); 124void sport_done(struct sport_device *sport);
119 125
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index ad28663f5bbd..767e772a815d 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -44,16 +44,6 @@
44 44
45static struct snd_soc_card bf5xx_ssm2602; 45static struct snd_soc_card bf5xx_ssm2602;
46 46
47static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream)
48{
49 struct snd_soc_pcm_runtime *rtd = substream->private_data;
50 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
51
52 pr_debug("%s enter\n", __func__);
53 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
54 return 0;
55}
56
57static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream, 47static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
58 struct snd_pcm_hw_params *params) 48 struct snd_pcm_hw_params *params)
59{ 49{
@@ -109,23 +99,33 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
109} 99}
110 100
111static struct snd_soc_ops bf5xx_ssm2602_ops = { 101static struct snd_soc_ops bf5xx_ssm2602_ops = {
112 .startup = bf5xx_ssm2602_startup,
113 .hw_params = bf5xx_ssm2602_hw_params, 102 .hw_params = bf5xx_ssm2602_hw_params,
114}; 103};
115 104
116static struct snd_soc_dai_link bf5xx_ssm2602_dai = { 105static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = {
117 .name = "ssm2602", 106 {
118 .stream_name = "SSM2602", 107 .name = "ssm2602",
119 .cpu_dai_name = "bf5xx-i2s", 108 .stream_name = "SSM2602",
120 .codec_dai_name = "ssm2602-hifi", 109 .cpu_dai_name = "bfin-i2s.0",
121 .platform_name = "bf5xx-pcm-audio", 110 .codec_dai_name = "ssm2602-hifi",
122 .codec_name = "ssm2602-codec.0-001b", 111 .platform_name = "bfin-i2s-pcm-audio",
123 .ops = &bf5xx_ssm2602_ops, 112 .codec_name = "ssm2602.0-001b",
113 .ops = &bf5xx_ssm2602_ops,
114 },
115 {
116 .name = "ssm2602",
117 .stream_name = "SSM2602",
118 .cpu_dai_name = "bfin-i2s.1",
119 .codec_dai_name = "ssm2602-hifi",
120 .platform_name = "bfin-i2s-pcm-audio",
121 .codec_name = "ssm2602.0-001b",
122 .ops = &bf5xx_ssm2602_ops,
123 },
124}; 124};
125 125
126static struct snd_soc_card bf5xx_ssm2602 = { 126static struct snd_soc_card bf5xx_ssm2602 = {
127 .name = "bf5xx_ssm2602", 127 .name = "bfin-ssm2602",
128 .dai_link = &bf5xx_ssm2602_dai, 128 .dai_link = &bf5xx_ssm2602_dai[CONFIG_SND_BF5XX_SPORT_NUM],
129 .num_links = 1, 129 .num_links = 1,
130}; 130};
131 131
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
index 74cf759b78a6..07cfc7a9e49a 100644
--- a/sound/soc/blackfin/bf5xx-tdm-pcm.c
+++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c
@@ -154,7 +154,12 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
154 154
155static int bf5xx_pcm_open(struct snd_pcm_substream *substream) 155static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
156{ 156{
157 struct snd_soc_pcm_runtime *rtd = substream->private_data;
158 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
159 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
157 struct snd_pcm_runtime *runtime = substream->runtime; 160 struct snd_pcm_runtime *runtime = substream->runtime;
161 struct snd_dma_buffer *buf = &substream->dma_buffer;
162
158 int ret = 0; 163 int ret = 0;
159 164
160 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware); 165 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
@@ -164,9 +169,14 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
164 if (ret < 0) 169 if (ret < 0)
165 goto out; 170 goto out;
166 171
167 if (sport_handle != NULL) 172 if (sport_handle != NULL) {
173 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
174 sport_handle->tx_buf = buf->area;
175 else
176 sport_handle->rx_buf = buf->area;
177
168 runtime->private_data = sport_handle; 178 runtime->private_data = sport_handle;
169 else { 179 } else {
170 pr_err("sport_handle is NULL\n"); 180 pr_err("sport_handle is NULL\n");
171 ret = -ENODEV; 181 ret = -ENODEV;
172 } 182 }
@@ -249,11 +259,6 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
249 } 259 }
250 buf->bytes = size; 260 buf->bytes = size;
251 261
252 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
253 sport_handle->tx_buf = buf->area;
254 else
255 sport_handle->rx_buf = buf->area;
256
257 return 0; 262 return 0;
258} 263}
259 264
@@ -274,8 +279,6 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
274 dma_free_coherent(NULL, buf->bytes, buf->area, 0); 279 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
275 buf->area = NULL; 280 buf->area = NULL;
276 } 281 }
277 if (sport_handle)
278 sport_done(sport_handle);
279} 282}
280 283
281static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); 284static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
@@ -326,7 +329,7 @@ static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
326 329
327static struct platform_driver bfin_tdm_driver = { 330static struct platform_driver bfin_tdm_driver = {
328 .driver = { 331 .driver = {
329 .name = "bf5xx-tdm-pcm-audio", 332 .name = "bfin-tdm-pcm-audio",
330 .owner = THIS_MODULE, 333 .owner = THIS_MODULE,
331 }, 334 },
332 335
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
index 5515ac9e05c7..a822d1ee1380 100644
--- a/sound/soc/blackfin/bf5xx-tdm.c
+++ b/sound/soc/blackfin/bf5xx-tdm.c
@@ -46,43 +46,6 @@
46#include "bf5xx-sport.h" 46#include "bf5xx-sport.h"
47#include "bf5xx-tdm.h" 47#include "bf5xx-tdm.h"
48 48
49static struct bf5xx_tdm_port bf5xx_tdm;
50static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
51
52static struct sport_param sport_params[2] = {
53 {
54 .dma_rx_chan = CH_SPORT0_RX,
55 .dma_tx_chan = CH_SPORT0_TX,
56 .err_irq = IRQ_SPORT0_ERROR,
57 .regs = (struct sport_register *)SPORT0_TCR1,
58 },
59 {
60 .dma_rx_chan = CH_SPORT1_RX,
61 .dma_tx_chan = CH_SPORT1_TX,
62 .err_irq = IRQ_SPORT1_ERROR,
63 .regs = (struct sport_register *)SPORT1_TCR1,
64 }
65};
66
67/*
68 * Setting the TFS pin selector for SPORT 0 based on whether the selected
69 * port id F or G. If the port is F then no conflict should exist for the
70 * TFS. When Port G is selected and EMAC then there is a conflict between
71 * the PHY interrupt line and TFS. Current settings prevent the conflict
72 * by ignoring the TFS pin when Port G is selected. This allows both
73 * codecs and EMAC using Port G concurrently.
74 */
75#ifdef CONFIG_BF527_SPORT0_PORTG
76#define LOCAL_SPORT0_TFS (0)
77#else
78#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
79#endif
80
81static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
82 P_SPORT0_DRPRI, P_SPORT0_RSCLK, LOCAL_SPORT0_TFS, 0},
83 {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, P_SPORT1_DRPRI,
84 P_SPORT1_RSCLK, P_SPORT1_TFS, 0} };
85
86static int bf5xx_tdm_set_dai_fmt(struct snd_soc_dai *cpu_dai, 49static int bf5xx_tdm_set_dai_fmt(struct snd_soc_dai *cpu_dai,
87 unsigned int fmt) 50 unsigned int fmt)
88{ 51{
@@ -119,14 +82,16 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream,
119 struct snd_pcm_hw_params *params, 82 struct snd_pcm_hw_params *params,
120 struct snd_soc_dai *dai) 83 struct snd_soc_dai *dai)
121{ 84{
85 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
86 struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
122 int ret = 0; 87 int ret = 0;
123 88
124 bf5xx_tdm.tcr2 &= ~0x1f; 89 bf5xx_tdm->tcr2 &= ~0x1f;
125 bf5xx_tdm.rcr2 &= ~0x1f; 90 bf5xx_tdm->rcr2 &= ~0x1f;
126 switch (params_format(params)) { 91 switch (params_format(params)) {
127 case SNDRV_PCM_FORMAT_S32_LE: 92 case SNDRV_PCM_FORMAT_S32_LE:
128 bf5xx_tdm.tcr2 |= 31; 93 bf5xx_tdm->tcr2 |= 31;
129 bf5xx_tdm.rcr2 |= 31; 94 bf5xx_tdm->rcr2 |= 31;
130 sport_handle->wdsize = 4; 95 sport_handle->wdsize = 4;
131 break; 96 break;
132 /* at present, we only support 32bit transfer */ 97 /* at present, we only support 32bit transfer */
@@ -136,7 +101,7 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream,
136 break; 101 break;
137 } 102 }
138 103
139 if (!bf5xx_tdm.configured) { 104 if (!bf5xx_tdm->configured) {
140 /* 105 /*
141 * TX and RX are not independent,they are enabled at the 106 * TX and RX are not independent,they are enabled at the
142 * same time, even if only one side is running. So, we 107 * same time, even if only one side is running. So, we
@@ -145,21 +110,21 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream,
145 * 110 *
146 * CPU DAI:slave mode. 111 * CPU DAI:slave mode.
147 */ 112 */
148 ret = sport_config_rx(sport_handle, bf5xx_tdm.rcr1, 113 ret = sport_config_rx(sport_handle, bf5xx_tdm->rcr1,
149 bf5xx_tdm.rcr2, 0, 0); 114 bf5xx_tdm->rcr2, 0, 0);
150 if (ret) { 115 if (ret) {
151 pr_err("SPORT is busy!\n"); 116 pr_err("SPORT is busy!\n");
152 return -EBUSY; 117 return -EBUSY;
153 } 118 }
154 119
155 ret = sport_config_tx(sport_handle, bf5xx_tdm.tcr1, 120 ret = sport_config_tx(sport_handle, bf5xx_tdm->tcr1,
156 bf5xx_tdm.tcr2, 0, 0); 121 bf5xx_tdm->tcr2, 0, 0);
157 if (ret) { 122 if (ret) {
158 pr_err("SPORT is busy!\n"); 123 pr_err("SPORT is busy!\n");
159 return -EBUSY; 124 return -EBUSY;
160 } 125 }
161 126
162 bf5xx_tdm.configured = 1; 127 bf5xx_tdm->configured = 1;
163 } 128 }
164 129
165 return 0; 130 return 0;
@@ -168,15 +133,20 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream,
168static void bf5xx_tdm_shutdown(struct snd_pcm_substream *substream, 133static void bf5xx_tdm_shutdown(struct snd_pcm_substream *substream,
169 struct snd_soc_dai *dai) 134 struct snd_soc_dai *dai)
170{ 135{
136 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
137 struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
138
171 /* No active stream, SPORT is allowed to be configured again. */ 139 /* No active stream, SPORT is allowed to be configured again. */
172 if (!dai->active) 140 if (!dai->active)
173 bf5xx_tdm.configured = 0; 141 bf5xx_tdm->configured = 0;
174} 142}
175 143
176static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai, 144static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
177 unsigned int tx_num, unsigned int *tx_slot, 145 unsigned int tx_num, unsigned int *tx_slot,
178 unsigned int rx_num, unsigned int *rx_slot) 146 unsigned int rx_num, unsigned int *rx_slot)
179{ 147{
148 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
149 struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
180 int i; 150 int i;
181 unsigned int slot; 151 unsigned int slot;
182 unsigned int tx_mapped = 0, rx_mapped = 0; 152 unsigned int tx_mapped = 0, rx_mapped = 0;
@@ -189,7 +159,7 @@ static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
189 slot = tx_slot[i]; 159 slot = tx_slot[i];
190 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) && 160 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
191 (!(tx_mapped & (1 << slot)))) { 161 (!(tx_mapped & (1 << slot)))) {
192 bf5xx_tdm.tx_map[i] = slot; 162 bf5xx_tdm->tx_map[i] = slot;
193 tx_mapped |= 1 << slot; 163 tx_mapped |= 1 << slot;
194 } else 164 } else
195 return -EINVAL; 165 return -EINVAL;
@@ -198,7 +168,7 @@ static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
198 slot = rx_slot[i]; 168 slot = rx_slot[i];
199 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) && 169 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
200 (!(rx_mapped & (1 << slot)))) { 170 (!(rx_mapped & (1 << slot)))) {
201 bf5xx_tdm.rx_map[i] = slot; 171 bf5xx_tdm->rx_map[i] = slot;
202 rx_mapped |= 1 << slot; 172 rx_mapped |= 1 << slot;
203 } else 173 } else
204 return -EINVAL; 174 return -EINVAL;
@@ -212,12 +182,14 @@ static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
212{ 182{
213 struct sport_device *sport = snd_soc_dai_get_drvdata(dai); 183 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
214 184
215 if (!dai->active)
216 return 0;
217 if (dai->capture_active)
218 sport_rx_stop(sport);
219 if (dai->playback_active) 185 if (dai->playback_active)
220 sport_tx_stop(sport); 186 sport_tx_stop(sport);
187 if (dai->capture_active)
188 sport_rx_stop(sport);
189
190 /* isolate sync/clock pins from codec while sports resume */
191 peripheral_free_list(sport->pin_req);
192
221 return 0; 193 return 0;
222} 194}
223 195
@@ -226,9 +198,6 @@ static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
226 int ret; 198 int ret;
227 struct sport_device *sport = snd_soc_dai_get_drvdata(dai); 199 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
228 200
229 if (!dai->active)
230 return 0;
231
232 ret = sport_set_multichannel(sport, 8, 0xFF, 1); 201 ret = sport_set_multichannel(sport, 8, 0xFF, 1);
233 if (ret) { 202 if (ret) {
234 pr_err("SPORT is busy!\n"); 203 pr_err("SPORT is busy!\n");
@@ -247,6 +216,8 @@ static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
247 ret = -EBUSY; 216 ret = -EBUSY;
248 } 217 }
249 218
219 peripheral_request_list(sport->pin_req, "soc-audio");
220
250 return 0; 221 return 0;
251} 222}
252 223
@@ -280,20 +251,14 @@ static struct snd_soc_dai_driver bf5xx_tdm_dai = {
280 251
281static int __devinit bfin_tdm_probe(struct platform_device *pdev) 252static int __devinit bfin_tdm_probe(struct platform_device *pdev)
282{ 253{
283 int ret = 0; 254 struct sport_device *sport_handle;
284 255 int ret;
285 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
286 pr_err("Requesting Peripherals failed\n");
287 return -EFAULT;
288 }
289 256
290 /* request DMA for SPORT */ 257 /* configure SPORT for TDM */
291 sport_handle = sport_init(&sport_params[sport_num], 4, \ 258 sport_handle = sport_init(pdev, 4, 8 * sizeof(u32),
292 8 * sizeof(u32), NULL); 259 sizeof(struct bf5xx_tdm_port));
293 if (!sport_handle) { 260 if (!sport_handle)
294 peripheral_free_list(&sport_req[sport_num][0]);
295 return -ENODEV; 261 return -ENODEV;
296 }
297 262
298 /* SPORT works in TDM mode */ 263 /* SPORT works in TDM mode */
299 ret = sport_set_multichannel(sport_handle, 8, 0xFF, 1); 264 ret = sport_set_multichannel(sport_handle, 8, 0xFF, 1);
@@ -323,18 +288,19 @@ static int __devinit bfin_tdm_probe(struct platform_device *pdev)
323 goto sport_config_err; 288 goto sport_config_err;
324 } 289 }
325 290
326 sport_handle->private_data = &bf5xx_tdm;
327 return 0; 291 return 0;
328 292
329sport_config_err: 293sport_config_err:
330 peripheral_free_list(&sport_req[sport_num][0]); 294 sport_done(sport_handle);
331 return ret; 295 return ret;
332} 296}
333 297
334static int __devexit bfin_tdm_remove(struct platform_device *pdev) 298static int __devexit bfin_tdm_remove(struct platform_device *pdev)
335{ 299{
336 peripheral_free_list(&sport_req[sport_num][0]); 300 struct sport_device *sport_handle = platform_get_drvdata(pdev);
301
337 snd_soc_unregister_dai(&pdev->dev); 302 snd_soc_unregister_dai(&pdev->dev);
303 sport_done(sport_handle);
338 304
339 return 0; 305 return 0;
340} 306}
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 06b6981b8d6d..19241576b6b5 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -120,7 +120,7 @@
120 */ 120 */
121#define PM860X_DAPM_OUTPUT(wname, wevent) \ 121#define PM860X_DAPM_OUTPUT(wname, wevent) \
122{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ 122{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \
123 .shift = 0, .invert = 0, .kcontrols = NULL, \ 123 .shift = 0, .invert = 0, .kcontrol_news = NULL, \
124 .num_kcontrols = 0, .event = wevent, \ 124 .num_kcontrols = 0, .event = wevent, \
125 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD, } 125 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD, }
126 126
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 6943e24a74a1..98175a096df2 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -16,10 +16,11 @@ config SND_SOC_ALL_CODECS
16 select SND_SOC_AD1836 if SPI_MASTER 16 select SND_SOC_AD1836 if SPI_MASTER
17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI 17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI
18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
19 select SND_SOC_AD73311
19 select SND_SOC_ADS117X 20 select SND_SOC_ADS117X
20 select SND_SOC_AD73311 if I2C
21 select SND_SOC_AK4104 if SPI_MASTER 21 select SND_SOC_AK4104 if SPI_MASTER
22 select SND_SOC_AK4535 if I2C 22 select SND_SOC_AK4535 if I2C
23 select SND_SOC_AK4641 if I2C
23 select SND_SOC_AK4642 if I2C 24 select SND_SOC_AK4642 if I2C
24 select SND_SOC_AK4671 if I2C 25 select SND_SOC_AK4671 if I2C
25 select SND_SOC_ALC5623 if I2C 26 select SND_SOC_ALC5623 if I2C
@@ -33,13 +34,14 @@ config SND_SOC_ALL_CODECS
33 select SND_SOC_JZ4740_CODEC if SOC_JZ4740 34 select SND_SOC_JZ4740_CODEC if SOC_JZ4740
34 select SND_SOC_LM4857 if I2C 35 select SND_SOC_LM4857 if I2C
35 select SND_SOC_MAX98088 if I2C 36 select SND_SOC_MAX98088 if I2C
37 select SND_SOC_MAX98095 if I2C
36 select SND_SOC_MAX9850 if I2C 38 select SND_SOC_MAX9850 if I2C
37 select SND_SOC_MAX9877 if I2C 39 select SND_SOC_MAX9877 if I2C
38 select SND_SOC_PCM3008 40 select SND_SOC_PCM3008
39 select SND_SOC_SGTL5000 if I2C 41 select SND_SOC_SGTL5000 if I2C
40 select SND_SOC_SN95031 if INTEL_SCU_IPC 42 select SND_SOC_SN95031 if INTEL_SCU_IPC
41 select SND_SOC_SPDIF 43 select SND_SOC_SPDIF
42 select SND_SOC_SSM2602 if I2C 44 select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI
43 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 45 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
44 select SND_SOC_TLV320AIC23 if I2C 46 select SND_SOC_TLV320AIC23 if I2C
45 select SND_SOC_TLV320AIC26 if SPI_MASTER 47 select SND_SOC_TLV320AIC26 if SPI_MASTER
@@ -52,6 +54,7 @@ config SND_SOC_ALL_CODECS
52 select SND_SOC_UDA134X 54 select SND_SOC_UDA134X
53 select SND_SOC_UDA1380 if I2C 55 select SND_SOC_UDA1380 if I2C
54 select SND_SOC_WL1273 if MFD_WL1273_CORE 56 select SND_SOC_WL1273 if MFD_WL1273_CORE
57 select SND_SOC_WM1250_EV1 if I2C
55 select SND_SOC_WM2000 if I2C 58 select SND_SOC_WM2000 if I2C
56 select SND_SOC_WM8350 if MFD_WM8350 59 select SND_SOC_WM8350 if MFD_WM8350
57 select SND_SOC_WM8400 if MFD_WM8400 60 select SND_SOC_WM8400 if MFD_WM8400
@@ -72,6 +75,7 @@ config SND_SOC_ALL_CODECS
72 select SND_SOC_WM8900 if I2C 75 select SND_SOC_WM8900 if I2C
73 select SND_SOC_WM8903 if I2C 76 select SND_SOC_WM8903 if I2C
74 select SND_SOC_WM8904 if I2C 77 select SND_SOC_WM8904 if I2C
78 select SND_SOC_WM8915 if I2C
75 select SND_SOC_WM8940 if I2C 79 select SND_SOC_WM8940 if I2C
76 select SND_SOC_WM8955 if I2C 80 select SND_SOC_WM8955 if I2C
77 select SND_SOC_WM8960 if I2C 81 select SND_SOC_WM8960 if I2C
@@ -136,6 +140,9 @@ config SND_SOC_AK4104
136config SND_SOC_AK4535 140config SND_SOC_AK4535
137 tristate 141 tristate
138 142
143config SND_SOC_AK4641
144 tristate
145
139config SND_SOC_AK4642 146config SND_SOC_AK4642
140 tristate 147 tristate
141 148
@@ -187,6 +194,9 @@ config SND_SOC_DMIC
187config SND_SOC_MAX98088 194config SND_SOC_MAX98088
188 tristate 195 tristate
189 196
197config SND_SOC_MAX98095
198 tristate
199
190config SND_SOC_MAX9850 200config SND_SOC_MAX9850
191 tristate 201 tristate
192 202
@@ -241,6 +251,9 @@ config SND_SOC_UDA1380
241config SND_SOC_WL1273 251config SND_SOC_WL1273
242 tristate 252 tristate
243 253
254config SND_SOC_WM1250_EV1
255 tristate
256
244config SND_SOC_WM8350 257config SND_SOC_WM8350
245 tristate 258 tristate
246 259
@@ -298,6 +311,9 @@ config SND_SOC_WM8903
298config SND_SOC_WM8904 311config SND_SOC_WM8904
299 tristate 312 tristate
300 313
314config SND_SOC_WM8915
315 tristate
316
301config SND_SOC_WM8940 317config SND_SOC_WM8940
302 tristate 318 tristate
303 319
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 379bc55f0723..fd8558406ef0 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -7,6 +7,7 @@ snd-soc-ad73311-objs := ad73311.o
7snd-soc-ads117x-objs := ads117x.o 7snd-soc-ads117x-objs := ads117x.o
8snd-soc-ak4104-objs := ak4104.o 8snd-soc-ak4104-objs := ak4104.o
9snd-soc-ak4535-objs := ak4535.o 9snd-soc-ak4535-objs := ak4535.o
10snd-soc-ak4641-objs := ak4641.o
10snd-soc-ak4642-objs := ak4642.o 11snd-soc-ak4642-objs := ak4642.o
11snd-soc-ak4671-objs := ak4671.o 12snd-soc-ak4671-objs := ak4671.o
12snd-soc-cq93vc-objs := cq93vc.o 13snd-soc-cq93vc-objs := cq93vc.o
@@ -19,6 +20,7 @@ snd-soc-dfbmcs320-objs := dfbmcs320.o
19snd-soc-dmic-objs := dmic.o 20snd-soc-dmic-objs := dmic.o
20snd-soc-l3-objs := l3.o 21snd-soc-l3-objs := l3.o
21snd-soc-max98088-objs := max98088.o 22snd-soc-max98088-objs := max98088.o
23snd-soc-max98095-objs := max98095.o
22snd-soc-max9850-objs := max9850.o 24snd-soc-max9850-objs := max9850.o
23snd-soc-pcm3008-objs := pcm3008.o 25snd-soc-pcm3008-objs := pcm3008.o
24snd-soc-sgtl5000-objs := sgtl5000.o 26snd-soc-sgtl5000-objs := sgtl5000.o
@@ -37,6 +39,7 @@ snd-soc-twl6040-objs := twl6040.o
37snd-soc-uda134x-objs := uda134x.o 39snd-soc-uda134x-objs := uda134x.o
38snd-soc-uda1380-objs := uda1380.o 40snd-soc-uda1380-objs := uda1380.o
39snd-soc-wl1273-objs := wl1273.o 41snd-soc-wl1273-objs := wl1273.o
42snd-soc-wm1250-ev1-objs := wm1250-ev1.o
40snd-soc-wm8350-objs := wm8350.o 43snd-soc-wm8350-objs := wm8350.o
41snd-soc-wm8400-objs := wm8400.o 44snd-soc-wm8400-objs := wm8400.o
42snd-soc-wm8510-objs := wm8510.o 45snd-soc-wm8510-objs := wm8510.o
@@ -56,6 +59,7 @@ snd-soc-wm8804-objs := wm8804.o
56snd-soc-wm8900-objs := wm8900.o 59snd-soc-wm8900-objs := wm8900.o
57snd-soc-wm8903-objs := wm8903.o 60snd-soc-wm8903-objs := wm8903.o
58snd-soc-wm8904-objs := wm8904.o 61snd-soc-wm8904-objs := wm8904.o
62snd-soc-wm8915-objs := wm8915.o
59snd-soc-wm8940-objs := wm8940.o 63snd-soc-wm8940-objs := wm8940.o
60snd-soc-wm8955-objs := wm8955.o 64snd-soc-wm8955-objs := wm8955.o
61snd-soc-wm8960-objs := wm8960.o 65snd-soc-wm8960-objs := wm8960.o
@@ -69,7 +73,7 @@ snd-soc-wm8988-objs := wm8988.o
69snd-soc-wm8990-objs := wm8990.o 73snd-soc-wm8990-objs := wm8990.o
70snd-soc-wm8991-objs := wm8991.o 74snd-soc-wm8991-objs := wm8991.o
71snd-soc-wm8993-objs := wm8993.o 75snd-soc-wm8993-objs := wm8993.o
72snd-soc-wm8994-objs := wm8994.o wm8994-tables.o 76snd-soc-wm8994-objs := wm8994.o wm8994-tables.o wm8958-dsp2.o
73snd-soc-wm8995-objs := wm8995.o 77snd-soc-wm8995-objs := wm8995.o
74snd-soc-wm9081-objs := wm9081.o 78snd-soc-wm9081-objs := wm9081.o
75snd-soc-wm9705-objs := wm9705.o 79snd-soc-wm9705-objs := wm9705.o
@@ -94,6 +98,7 @@ obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
94obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o 98obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
95obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 99obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
96obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 100obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
101obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o
97obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 102obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
98obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 103obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
99obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o 104obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
@@ -108,6 +113,7 @@ obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
108obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 113obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
109obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 114obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
110obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o 115obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
116obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
111obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 117obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
112obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 118obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
113obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o 119obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
@@ -125,6 +131,7 @@ obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
125obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o 131obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
126obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 132obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
127obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o 133obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
134obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
128obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o 135obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
129obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o 136obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
130obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 137obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
@@ -144,6 +151,7 @@ obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o
144obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o 151obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
145obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o 152obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
146obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o 153obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o
154obj-$(CONFIG_SND_SOC_WM8915) += snd-soc-wm8915.o
147obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o 155obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
148obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o 156obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o
149obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o 157obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index da46479bfcfa..2374ca5ffe68 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -23,8 +23,7 @@
23 23
24/* codec private data */ 24/* codec private data */
25struct ad193x_priv { 25struct ad193x_priv {
26 enum snd_soc_control_type bus_type; 26 enum snd_soc_control_type control_type;
27 void *control_data;
28 int sysclk; 27 int sysclk;
29}; 28};
30 29
@@ -354,14 +353,12 @@ static int ad193x_probe(struct snd_soc_codec *codec)
354 struct snd_soc_dapm_context *dapm = &codec->dapm; 353 struct snd_soc_dapm_context *dapm = &codec->dapm;
355 int ret; 354 int ret;
356 355
357 codec->control_data = ad193x->control_data; 356 if (ad193x->control_type == SND_SOC_I2C)
358 if (ad193x->bus_type == SND_SOC_I2C) 357 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->control_type);
359 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->bus_type);
360 else 358 else
361 ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->bus_type); 359 ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->control_type);
362 if (ret < 0) { 360 if (ret < 0) {
363 dev_err(codec->dev, "failed to set cache I/O: %d\n", 361 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
364 ret);
365 return ret; 362 return ret;
366 } 363 }
367 364
@@ -408,8 +405,7 @@ static int __devinit ad193x_spi_probe(struct spi_device *spi)
408 return -ENOMEM; 405 return -ENOMEM;
409 406
410 spi_set_drvdata(spi, ad193x); 407 spi_set_drvdata(spi, ad193x);
411 ad193x->control_data = spi; 408 ad193x->control_type = SND_SOC_SPI;
412 ad193x->bus_type = SND_SOC_SPI;
413 409
414 ret = snd_soc_register_codec(&spi->dev, 410 ret = snd_soc_register_codec(&spi->dev,
415 &soc_codec_dev_ad193x, &ad193x_dai, 1); 411 &soc_codec_dev_ad193x, &ad193x_dai, 1);
@@ -427,7 +423,7 @@ static int __devexit ad193x_spi_remove(struct spi_device *spi)
427 423
428static struct spi_driver ad193x_spi_driver = { 424static struct spi_driver ad193x_spi_driver = {
429 .driver = { 425 .driver = {
430 .name = "ad193x-codec", 426 .name = "ad193x",
431 .owner = THIS_MODULE, 427 .owner = THIS_MODULE,
432 }, 428 },
433 .probe = ad193x_spi_probe, 429 .probe = ad193x_spi_probe,
@@ -454,8 +450,7 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client,
454 return -ENOMEM; 450 return -ENOMEM;
455 451
456 i2c_set_clientdata(client, ad193x); 452 i2c_set_clientdata(client, ad193x);
457 ad193x->control_data = client; 453 ad193x->control_type = SND_SOC_I2C;
458 ad193x->bus_type = SND_SOC_I2C;
459 454
460 ret = snd_soc_register_codec(&client->dev, 455 ret = snd_soc_register_codec(&client->dev,
461 &soc_codec_dev_ad193x, &ad193x_dai, 1); 456 &soc_codec_dev_ad193x, &ad193x_dai, 1);
@@ -473,7 +468,7 @@ static int __devexit ad193x_i2c_remove(struct i2c_client *client)
473 468
474static struct i2c_driver ad193x_i2c_driver = { 469static struct i2c_driver ad193x_i2c_driver = {
475 .driver = { 470 .driver = {
476 .name = "ad193x-codec", 471 .name = "ad193x",
477 }, 472 },
478 .probe = ad193x_i2c_probe, 473 .probe = ad193x_i2c_probe,
479 .remove = __devexit_p(ad193x_i2c_remove), 474 .remove = __devexit_p(ad193x_i2c_remove),
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 34cb51ef2156..923b364a3e41 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -266,7 +266,7 @@ static int __devexit ad1980_remove(struct platform_device *pdev)
266 266
267static struct platform_driver ad1980_codec_driver = { 267static struct platform_driver ad1980_codec_driver = {
268 .driver = { 268 .driver = {
269 .name = "ad1980-codec", 269 .name = "ad1980",
270 .owner = THIS_MODULE, 270 .owner = THIS_MODULE,
271 }, 271 },
272 272
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index de799cd1ba72..8d793e993e9a 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -55,7 +55,7 @@ static int __devexit ad73311_remove(struct platform_device *pdev)
55 55
56static struct platform_driver ad73311_codec_driver = { 56static struct platform_driver ad73311_codec_driver = {
57 .driver = { 57 .driver = {
58 .name = "ad73311-codec", 58 .name = "ad73311",
59 .owner = THIS_MODULE, 59 .owner = THIS_MODULE,
60 }, 60 },
61 61
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 8b38739c88f8..e1a214ee757f 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -230,7 +230,7 @@ static const struct snd_soc_dapm_widget ak4535_dapm_widgets[] = {
230 SND_SOC_DAPM_INPUT("AIN"), 230 SND_SOC_DAPM_INPUT("AIN"),
231}; 231};
232 232
233static const struct snd_soc_dapm_route audio_map[] = { 233static const struct snd_soc_dapm_route ak4535_audio_map[] = {
234 /*stereo mixer */ 234 /*stereo mixer */
235 {"Stereo Mixer", "Playback Switch", "DAC"}, 235 {"Stereo Mixer", "Playback Switch", "DAC"},
236 {"Stereo Mixer", "Mic Sidetone Switch", "Mic"}, 236 {"Stereo Mixer", "Mic Sidetone Switch", "Mic"},
@@ -287,17 +287,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
287 {"Input Mixer", "Aux Capture Switch", "Aux In"}, 287 {"Input Mixer", "Aux Capture Switch", "Aux In"},
288}; 288};
289 289
290static int ak4535_add_widgets(struct snd_soc_codec *codec)
291{
292 struct snd_soc_dapm_context *dapm = &codec->dapm;
293
294 snd_soc_dapm_new_controls(dapm, ak4535_dapm_widgets,
295 ARRAY_SIZE(ak4535_dapm_widgets));
296 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
297
298 return 0;
299}
300
301static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai, 290static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai,
302 int clk_id, unsigned int freq, int dir) 291 int clk_id, unsigned int freq, int dir)
303{ 292{
@@ -457,8 +446,6 @@ static int ak4535_probe(struct snd_soc_codec *codec)
457 446
458 snd_soc_add_controls(codec, ak4535_snd_controls, 447 snd_soc_add_controls(codec, ak4535_snd_controls,
459 ARRAY_SIZE(ak4535_snd_controls)); 448 ARRAY_SIZE(ak4535_snd_controls));
460 ak4535_add_widgets(codec);
461
462 return 0; 449 return 0;
463} 450}
464 451
@@ -480,6 +467,10 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
480 .reg_cache_size = ARRAY_SIZE(ak4535_reg), 467 .reg_cache_size = ARRAY_SIZE(ak4535_reg),
481 .reg_word_size = sizeof(u8), 468 .reg_word_size = sizeof(u8),
482 .reg_cache_default = ak4535_reg, 469 .reg_cache_default = ak4535_reg,
470 .dapm_widgets = ak4535_dapm_widgets,
471 .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets),
472 .dapm_routes = ak4535_audio_map,
473 .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map),
483}; 474};
484 475
485#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 476#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c
new file mode 100644
index 000000000000..ed96f247c2da
--- /dev/null
+++ b/sound/soc/codecs/ak4641.c
@@ -0,0 +1,664 @@
1/*
2 * ak4641.c -- AK4641 ALSA Soc Audio driver
3 *
4 * Copyright (C) 2008 Harald Welte <laforge@gnufiish.org>
5 * Copyright (C) 2011 Dmitry Artamonow <mad_soft@inbox.ru>
6 *
7 * Based on ak4535.c by Richard Purdie
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/gpio.h>
18#include <linux/pm.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28#include <sound/ak4641.h>
29
30#include "ak4641.h"
31
32/* codec private data */
33struct ak4641_priv {
34 struct snd_soc_codec *codec;
35 unsigned int sysclk;
36 int deemph;
37 int playback_fs;
38};
39
40/*
41 * ak4641 register cache
42 */
43static const u8 ak4641_reg[AK4641_CACHEREGNUM] = {
44 0x00, 0x80, 0x00, 0x80,
45 0x02, 0x00, 0x11, 0x05,
46 0x00, 0x00, 0x36, 0x10,
47 0x00, 0x00, 0x57, 0x00,
48 0x88, 0x88, 0x08, 0x08
49};
50
51static const int deemph_settings[] = {44100, 0, 48000, 32000};
52
53static int ak4641_set_deemph(struct snd_soc_codec *codec)
54{
55 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
56 int i, best = 0;
57
58 for (i = 0 ; i < ARRAY_SIZE(deemph_settings); i++) {
59 /* if deemphasis is on, select the nearest available rate */
60 if (ak4641->deemph && deemph_settings[i] != 0 &&
61 abs(deemph_settings[i] - ak4641->playback_fs) <
62 abs(deemph_settings[best] - ak4641->playback_fs))
63 best = i;
64
65 if (!ak4641->deemph && deemph_settings[i] == 0)
66 best = i;
67 }
68
69 dev_dbg(codec->dev, "Set deemphasis %d\n", best);
70
71 return snd_soc_update_bits(codec, AK4641_DAC, 0x3, best);
72}
73
74static int ak4641_put_deemph(struct snd_kcontrol *kcontrol,
75 struct snd_ctl_elem_value *ucontrol)
76{
77 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
78 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
79 int deemph = ucontrol->value.enumerated.item[0];
80
81 if (deemph > 1)
82 return -EINVAL;
83
84 ak4641->deemph = deemph;
85
86 return ak4641_set_deemph(codec);
87}
88
89static int ak4641_get_deemph(struct snd_kcontrol *kcontrol,
90 struct snd_ctl_elem_value *ucontrol)
91{
92 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
93 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
94
95 ucontrol->value.enumerated.item[0] = ak4641->deemph;
96 return 0;
97};
98
99static const char *ak4641_mono_out[] = {"(L + R)/2", "Hi-Z"};
100static const char *ak4641_hp_out[] = {"Stereo", "Mono"};
101static const char *ak4641_mic_select[] = {"Internal", "External"};
102static const char *ak4641_mic_or_dac[] = {"Microphone", "Voice DAC"};
103
104
105static const DECLARE_TLV_DB_SCALE(mono_gain_tlv, -1700, 2300, 0);
106static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, 0, 2000, 0);
107static const DECLARE_TLV_DB_SCALE(eq_tlv, -1050, 150, 0);
108static const DECLARE_TLV_DB_SCALE(master_tlv, -12750, 50, 0);
109static const DECLARE_TLV_DB_SCALE(mic_stereo_sidetone_tlv, -2700, 300, 0);
110static const DECLARE_TLV_DB_SCALE(mic_mono_sidetone_tlv, -400, 400, 0);
111static const DECLARE_TLV_DB_SCALE(capture_tlv, -800, 50, 0);
112static const DECLARE_TLV_DB_SCALE(alc_tlv, -800, 50, 0);
113static const DECLARE_TLV_DB_SCALE(aux_in_tlv, -2100, 300, 0);
114
115
116static const struct soc_enum ak4641_mono_out_enum =
117 SOC_ENUM_SINGLE(AK4641_SIG1, 6, 2, ak4641_mono_out);
118static const struct soc_enum ak4641_hp_out_enum =
119 SOC_ENUM_SINGLE(AK4641_MODE2, 2, 2, ak4641_hp_out);
120static const struct soc_enum ak4641_mic_select_enum =
121 SOC_ENUM_SINGLE(AK4641_MIC, 1, 2, ak4641_mic_select);
122static const struct soc_enum ak4641_mic_or_dac_enum =
123 SOC_ENUM_SINGLE(AK4641_BTIF, 4, 2, ak4641_mic_or_dac);
124
125static const struct snd_kcontrol_new ak4641_snd_controls[] = {
126 SOC_ENUM("Mono 1 Output", ak4641_mono_out_enum),
127 SOC_SINGLE_TLV("Mono 1 Gain Volume", AK4641_SIG1, 7, 1, 1,
128 mono_gain_tlv),
129 SOC_ENUM("Headphone Output", ak4641_hp_out_enum),
130 SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
131 ak4641_get_deemph, ak4641_put_deemph),
132
133 SOC_SINGLE_TLV("Mic Boost Volume", AK4641_MIC, 0, 1, 0, mic_boost_tlv),
134
135 SOC_SINGLE("ALC Operation Time", AK4641_TIMER, 0, 3, 0),
136 SOC_SINGLE("ALC Recovery Time", AK4641_TIMER, 2, 3, 0),
137 SOC_SINGLE("ALC ZC Time", AK4641_TIMER, 4, 3, 0),
138
139 SOC_SINGLE("ALC 1 Switch", AK4641_ALC1, 5, 1, 0),
140
141 SOC_SINGLE_TLV("ALC Volume", AK4641_ALC2, 0, 71, 0, alc_tlv),
142 SOC_SINGLE("Left Out Enable Switch", AK4641_SIG2, 1, 1, 0),
143 SOC_SINGLE("Right Out Enable Switch", AK4641_SIG2, 0, 1, 0),
144
145 SOC_SINGLE_TLV("Capture Volume", AK4641_PGA, 0, 71, 0, capture_tlv),
146
147 SOC_DOUBLE_R_TLV("Master Playback Volume", AK4641_LATT,
148 AK4641_RATT, 0, 255, 1, master_tlv),
149
150 SOC_SINGLE_TLV("AUX In Volume", AK4641_VOL, 0, 15, 0, aux_in_tlv),
151
152 SOC_SINGLE("Equalizer Switch", AK4641_DAC, 2, 1, 0),
153 SOC_SINGLE_TLV("EQ1 100 Hz Volume", AK4641_EQLO, 0, 15, 1, eq_tlv),
154 SOC_SINGLE_TLV("EQ2 250 Hz Volume", AK4641_EQLO, 4, 15, 1, eq_tlv),
155 SOC_SINGLE_TLV("EQ3 1 kHz Volume", AK4641_EQMID, 0, 15, 1, eq_tlv),
156 SOC_SINGLE_TLV("EQ4 3.5 kHz Volume", AK4641_EQMID, 4, 15, 1, eq_tlv),
157 SOC_SINGLE_TLV("EQ5 10 kHz Volume", AK4641_EQHI, 0, 15, 1, eq_tlv),
158};
159
160/* Mono 1 Mixer */
161static const struct snd_kcontrol_new ak4641_mono1_mixer_controls[] = {
162 SOC_DAPM_SINGLE_TLV("Mic Mono Sidetone Volume", AK4641_VOL, 7, 1, 0,
163 mic_mono_sidetone_tlv),
164 SOC_DAPM_SINGLE("Mic Mono Sidetone Switch", AK4641_SIG1, 4, 1, 0),
165 SOC_DAPM_SINGLE("Mono Playback Switch", AK4641_SIG1, 5, 1, 0),
166};
167
168/* Stereo Mixer */
169static const struct snd_kcontrol_new ak4641_stereo_mixer_controls[] = {
170 SOC_DAPM_SINGLE_TLV("Mic Sidetone Volume", AK4641_VOL, 4, 7, 0,
171 mic_stereo_sidetone_tlv),
172 SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4641_SIG2, 4, 1, 0),
173 SOC_DAPM_SINGLE("Playback Switch", AK4641_SIG2, 7, 1, 0),
174 SOC_DAPM_SINGLE("Aux Bypass Switch", AK4641_SIG2, 5, 1, 0),
175};
176
177/* Input Mixer */
178static const struct snd_kcontrol_new ak4641_input_mixer_controls[] = {
179 SOC_DAPM_SINGLE("Mic Capture Switch", AK4641_MIC, 2, 1, 0),
180 SOC_DAPM_SINGLE("Aux Capture Switch", AK4641_MIC, 5, 1, 0),
181};
182
183/* Mic mux */
184static const struct snd_kcontrol_new ak4641_mic_mux_control =
185 SOC_DAPM_ENUM("Mic Select", ak4641_mic_select_enum);
186
187/* Input mux */
188static const struct snd_kcontrol_new ak4641_input_mux_control =
189 SOC_DAPM_ENUM("Input Select", ak4641_mic_or_dac_enum);
190
191/* mono 2 switch */
192static const struct snd_kcontrol_new ak4641_mono2_control =
193 SOC_DAPM_SINGLE("Switch", AK4641_SIG1, 0, 1, 0);
194
195/* ak4641 dapm widgets */
196static const struct snd_soc_dapm_widget ak4641_dapm_widgets[] = {
197 SND_SOC_DAPM_MIXER("Stereo Mixer", SND_SOC_NOPM, 0, 0,
198 &ak4641_stereo_mixer_controls[0],
199 ARRAY_SIZE(ak4641_stereo_mixer_controls)),
200 SND_SOC_DAPM_MIXER("Mono1 Mixer", SND_SOC_NOPM, 0, 0,
201 &ak4641_mono1_mixer_controls[0],
202 ARRAY_SIZE(ak4641_mono1_mixer_controls)),
203 SND_SOC_DAPM_MIXER("Input Mixer", SND_SOC_NOPM, 0, 0,
204 &ak4641_input_mixer_controls[0],
205 ARRAY_SIZE(ak4641_input_mixer_controls)),
206 SND_SOC_DAPM_MUX("Mic Mux", SND_SOC_NOPM, 0, 0,
207 &ak4641_mic_mux_control),
208 SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
209 &ak4641_input_mux_control),
210 SND_SOC_DAPM_SWITCH("Mono 2 Enable", SND_SOC_NOPM, 0, 0,
211 &ak4641_mono2_control),
212
213 SND_SOC_DAPM_OUTPUT("LOUT"),
214 SND_SOC_DAPM_OUTPUT("ROUT"),
215 SND_SOC_DAPM_OUTPUT("MOUT1"),
216 SND_SOC_DAPM_OUTPUT("MOUT2"),
217 SND_SOC_DAPM_OUTPUT("MICOUT"),
218
219 SND_SOC_DAPM_ADC("ADC", "HiFi Capture", AK4641_PM1, 0, 0),
220 SND_SOC_DAPM_PGA("Mic", AK4641_PM1, 1, 0, NULL, 0),
221 SND_SOC_DAPM_PGA("AUX In", AK4641_PM1, 2, 0, NULL, 0),
222 SND_SOC_DAPM_PGA("Mono Out", AK4641_PM1, 3, 0, NULL, 0),
223 SND_SOC_DAPM_PGA("Line Out", AK4641_PM1, 4, 0, NULL, 0),
224
225 SND_SOC_DAPM_DAC("DAC", "HiFi Playback", AK4641_PM2, 0, 0),
226 SND_SOC_DAPM_PGA("Mono Out 2", AK4641_PM2, 3, 0, NULL, 0),
227
228 SND_SOC_DAPM_ADC("Voice ADC", "Voice Capture", AK4641_BTIF, 0, 0),
229 SND_SOC_DAPM_ADC("Voice DAC", "Voice Playback", AK4641_BTIF, 1, 0),
230
231 SND_SOC_DAPM_MICBIAS("Mic Int Bias", AK4641_MIC, 3, 0),
232 SND_SOC_DAPM_MICBIAS("Mic Ext Bias", AK4641_MIC, 4, 0),
233
234 SND_SOC_DAPM_INPUT("MICIN"),
235 SND_SOC_DAPM_INPUT("MICEXT"),
236 SND_SOC_DAPM_INPUT("AUX"),
237 SND_SOC_DAPM_INPUT("AIN"),
238};
239
240static const struct snd_soc_dapm_route ak4641_audio_map[] = {
241 /* Stereo Mixer */
242 {"Stereo Mixer", "Playback Switch", "DAC"},
243 {"Stereo Mixer", "Mic Sidetone Switch", "Input Mux"},
244 {"Stereo Mixer", "Aux Bypass Switch", "AUX In"},
245
246 /* Mono 1 Mixer */
247 {"Mono1 Mixer", "Mic Mono Sidetone Switch", "Input Mux"},
248 {"Mono1 Mixer", "Mono Playback Switch", "DAC"},
249
250 /* Mic */
251 {"Mic", NULL, "AIN"},
252 {"Mic Mux", "Internal", "Mic Int Bias"},
253 {"Mic Mux", "External", "Mic Ext Bias"},
254 {"Mic Int Bias", NULL, "MICIN"},
255 {"Mic Ext Bias", NULL, "MICEXT"},
256 {"MICOUT", NULL, "Mic Mux"},
257
258 /* Input Mux */
259 {"Input Mux", "Microphone", "Mic"},
260 {"Input Mux", "Voice DAC", "Voice DAC"},
261
262 /* Line Out */
263 {"LOUT", NULL, "Line Out"},
264 {"ROUT", NULL, "Line Out"},
265 {"Line Out", NULL, "Stereo Mixer"},
266
267 /* Mono 1 Out */
268 {"MOUT1", NULL, "Mono Out"},
269 {"Mono Out", NULL, "Mono1 Mixer"},
270
271 /* Mono 2 Out */
272 {"MOUT2", NULL, "Mono 2 Enable"},
273 {"Mono 2 Enable", "Switch", "Mono Out 2"},
274 {"Mono Out 2", NULL, "Stereo Mixer"},
275
276 {"Voice ADC", NULL, "Mono 2 Enable"},
277
278 /* Aux In */
279 {"AUX In", NULL, "AUX"},
280
281 /* ADC */
282 {"ADC", NULL, "Input Mixer"},
283 {"Input Mixer", "Mic Capture Switch", "Mic"},
284 {"Input Mixer", "Aux Capture Switch", "AUX In"},
285};
286
287static int ak4641_set_dai_sysclk(struct snd_soc_dai *codec_dai,
288 int clk_id, unsigned int freq, int dir)
289{
290 struct snd_soc_codec *codec = codec_dai->codec;
291 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
292
293 ak4641->sysclk = freq;
294 return 0;
295}
296
297static int ak4641_i2s_hw_params(struct snd_pcm_substream *substream,
298 struct snd_pcm_hw_params *params,
299 struct snd_soc_dai *dai)
300{
301 struct snd_soc_pcm_runtime *rtd = substream->private_data;
302 struct snd_soc_codec *codec = rtd->codec;
303 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
304 int rate = params_rate(params), fs = 256;
305 u8 mode2;
306
307 if (rate)
308 fs = ak4641->sysclk / rate;
309 else
310 return -EINVAL;
311
312 /* set fs */
313 switch (fs) {
314 case 1024:
315 mode2 = (0x2 << 5);
316 break;
317 case 512:
318 mode2 = (0x1 << 5);
319 break;
320 case 256:
321 mode2 = (0x0 << 5);
322 break;
323 default:
324 dev_err(codec->dev, "Error: unsupported fs=%d\n", fs);
325 return -EINVAL;
326 }
327
328 snd_soc_update_bits(codec, AK4641_MODE2, (0x3 << 5), mode2);
329
330 /* Update de-emphasis filter for the new rate */
331 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
332 ak4641->playback_fs = rate;
333 ak4641_set_deemph(codec);
334 };
335
336 return 0;
337}
338
339static int ak4641_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
340 unsigned int fmt)
341{
342 struct snd_soc_codec *codec = codec_dai->codec;
343 u8 btif;
344
345 /* interface format */
346 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
347 case SND_SOC_DAIFMT_I2S:
348 btif = (0x3 << 5);
349 break;
350 case SND_SOC_DAIFMT_LEFT_J:
351 btif = (0x2 << 5);
352 break;
353 case SND_SOC_DAIFMT_DSP_A: /* MSB after FRM */
354 btif = (0x0 << 5);
355 break;
356 case SND_SOC_DAIFMT_DSP_B: /* MSB during FRM */
357 btif = (0x1 << 5);
358 break;
359 default:
360 return -EINVAL;
361 }
362
363 return snd_soc_update_bits(codec, AK4641_BTIF, (0x3 << 5), btif);
364}
365
366static int ak4641_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
367 unsigned int fmt)
368{
369 struct snd_soc_codec *codec = codec_dai->codec;
370 u8 mode1 = 0;
371
372 /* interface format */
373 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
374 case SND_SOC_DAIFMT_I2S:
375 mode1 = 0x02;
376 break;
377 case SND_SOC_DAIFMT_LEFT_J:
378 mode1 = 0x01;
379 break;
380 default:
381 return -EINVAL;
382 }
383
384 return snd_soc_write(codec, AK4641_MODE1, mode1);
385}
386
387static int ak4641_mute(struct snd_soc_dai *dai, int mute)
388{
389 struct snd_soc_codec *codec = dai->codec;
390
391 return snd_soc_update_bits(codec, AK4641_DAC, 0x20, mute ? 0x20 : 0);
392}
393
394static int ak4641_set_bias_level(struct snd_soc_codec *codec,
395 enum snd_soc_bias_level level)
396{
397 struct ak4641_platform_data *pdata = codec->dev->platform_data;
398 int ret;
399
400 switch (level) {
401 case SND_SOC_BIAS_ON:
402 /* unmute */
403 snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0);
404 break;
405 case SND_SOC_BIAS_PREPARE:
406 /* mute */
407 snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0x20);
408 break;
409 case SND_SOC_BIAS_STANDBY:
410 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
411 if (pdata && gpio_is_valid(pdata->gpio_power))
412 gpio_set_value(pdata->gpio_power, 1);
413 mdelay(1);
414 if (pdata && gpio_is_valid(pdata->gpio_npdn))
415 gpio_set_value(pdata->gpio_npdn, 1);
416 mdelay(1);
417
418 ret = snd_soc_cache_sync(codec);
419 if (ret) {
420 dev_err(codec->dev,
421 "Failed to sync cache: %d\n", ret);
422 return ret;
423 }
424 }
425 snd_soc_update_bits(codec, AK4641_PM1, 0x80, 0x80);
426 snd_soc_update_bits(codec, AK4641_PM2, 0x80, 0);
427 break;
428 case SND_SOC_BIAS_OFF:
429 snd_soc_update_bits(codec, AK4641_PM1, 0x80, 0);
430 if (pdata && gpio_is_valid(pdata->gpio_npdn))
431 gpio_set_value(pdata->gpio_npdn, 0);
432 if (pdata && gpio_is_valid(pdata->gpio_power))
433 gpio_set_value(pdata->gpio_power, 0);
434 codec->cache_sync = 1;
435 break;
436 }
437 codec->dapm.bias_level = level;
438 return 0;
439}
440
441#define AK4641_RATES (SNDRV_PCM_RATE_8000_48000)
442#define AK4641_RATES_BT (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
443 SNDRV_PCM_RATE_16000)
444#define AK4641_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
445
446static struct snd_soc_dai_ops ak4641_i2s_dai_ops = {
447 .hw_params = ak4641_i2s_hw_params,
448 .set_fmt = ak4641_i2s_set_dai_fmt,
449 .digital_mute = ak4641_mute,
450 .set_sysclk = ak4641_set_dai_sysclk,
451};
452
453static struct snd_soc_dai_ops ak4641_pcm_dai_ops = {
454 .hw_params = NULL, /* rates are controlled by BT chip */
455 .set_fmt = ak4641_pcm_set_dai_fmt,
456 .digital_mute = ak4641_mute,
457 .set_sysclk = ak4641_set_dai_sysclk,
458};
459
460struct snd_soc_dai_driver ak4641_dai[] = {
461{
462 .name = "ak4641-hifi",
463 .id = 1,
464 .playback = {
465 .stream_name = "HiFi Playback",
466 .channels_min = 1,
467 .channels_max = 2,
468 .rates = AK4641_RATES,
469 .formats = AK4641_FORMATS,
470 },
471 .capture = {
472 .stream_name = "HiFi Capture",
473 .channels_min = 1,
474 .channels_max = 2,
475 .rates = AK4641_RATES,
476 .formats = AK4641_FORMATS,
477 },
478 .ops = &ak4641_i2s_dai_ops,
479 .symmetric_rates = 1,
480},
481{
482 .name = "ak4641-voice",
483 .id = 1,
484 .playback = {
485 .stream_name = "Voice Playback",
486 .channels_min = 1,
487 .channels_max = 1,
488 .rates = AK4641_RATES_BT,
489 .formats = AK4641_FORMATS,
490 },
491 .capture = {
492 .stream_name = "Voice Capture",
493 .channels_min = 1,
494 .channels_max = 1,
495 .rates = AK4641_RATES_BT,
496 .formats = AK4641_FORMATS,
497 },
498 .ops = &ak4641_pcm_dai_ops,
499 .symmetric_rates = 1,
500},
501};
502
503static int ak4641_suspend(struct snd_soc_codec *codec, pm_message_t state)
504{
505 ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF);
506 return 0;
507}
508
509static int ak4641_resume(struct snd_soc_codec *codec)
510{
511 ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
512 return 0;
513}
514
515static int ak4641_probe(struct snd_soc_codec *codec)
516{
517 struct ak4641_platform_data *pdata = codec->dev->platform_data;
518 int ret;
519
520
521 if (pdata) {
522 if (gpio_is_valid(pdata->gpio_power)) {
523 ret = gpio_request_one(pdata->gpio_power,
524 GPIOF_OUT_INIT_LOW, "ak4641 power");
525 if (ret)
526 goto err_out;
527 }
528 if (gpio_is_valid(pdata->gpio_npdn)) {
529 ret = gpio_request_one(pdata->gpio_npdn,
530 GPIOF_OUT_INIT_LOW, "ak4641 npdn");
531 if (ret)
532 goto err_gpio;
533
534 udelay(1); /* > 150 ns */
535 gpio_set_value(pdata->gpio_npdn, 1);
536 }
537 }
538
539 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
540 if (ret != 0) {
541 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
542 goto err_register;
543 }
544
545 /* power on device */
546 ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
547
548 return 0;
549
550err_register:
551 if (pdata) {
552 if (gpio_is_valid(pdata->gpio_power))
553 gpio_set_value(pdata->gpio_power, 0);
554 if (gpio_is_valid(pdata->gpio_npdn))
555 gpio_free(pdata->gpio_npdn);
556 }
557err_gpio:
558 if (pdata && gpio_is_valid(pdata->gpio_power))
559 gpio_free(pdata->gpio_power);
560err_out:
561 return ret;
562}
563
564static int ak4641_remove(struct snd_soc_codec *codec)
565{
566 struct ak4641_platform_data *pdata = codec->dev->platform_data;
567
568 ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF);
569
570 if (pdata) {
571 if (gpio_is_valid(pdata->gpio_power)) {
572 gpio_set_value(pdata->gpio_power, 0);
573 gpio_free(pdata->gpio_power);
574 }
575 if (gpio_is_valid(pdata->gpio_npdn))
576 gpio_free(pdata->gpio_npdn);
577 }
578 return 0;
579}
580
581
582static struct snd_soc_codec_driver soc_codec_dev_ak4641 = {
583 .probe = ak4641_probe,
584 .remove = ak4641_remove,
585 .suspend = ak4641_suspend,
586 .resume = ak4641_resume,
587 .controls = ak4641_snd_controls,
588 .num_controls = ARRAY_SIZE(ak4641_snd_controls),
589 .dapm_widgets = ak4641_dapm_widgets,
590 .num_dapm_widgets = ARRAY_SIZE(ak4641_dapm_widgets),
591 .dapm_routes = ak4641_audio_map,
592 .num_dapm_routes = ARRAY_SIZE(ak4641_audio_map),
593 .set_bias_level = ak4641_set_bias_level,
594 .reg_cache_size = ARRAY_SIZE(ak4641_reg),
595 .reg_word_size = sizeof(u8),
596 .reg_cache_default = ak4641_reg,
597 .reg_cache_step = 1,
598};
599
600
601static int __devinit ak4641_i2c_probe(struct i2c_client *i2c,
602 const struct i2c_device_id *id)
603{
604 struct ak4641_priv *ak4641;
605 int ret;
606
607 ak4641 = kzalloc(sizeof(struct ak4641_priv), GFP_KERNEL);
608 if (!ak4641)
609 return -ENOMEM;
610
611 i2c_set_clientdata(i2c, ak4641);
612
613 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4641,
614 ak4641_dai, ARRAY_SIZE(ak4641_dai));
615 if (ret < 0)
616 kfree(ak4641);
617
618 return ret;
619}
620
621static int __devexit ak4641_i2c_remove(struct i2c_client *i2c)
622{
623 snd_soc_unregister_codec(&i2c->dev);
624 kfree(i2c_get_clientdata(i2c));
625 return 0;
626}
627
628static const struct i2c_device_id ak4641_i2c_id[] = {
629 { "ak4641", 0 },
630 { }
631};
632MODULE_DEVICE_TABLE(i2c, ak4641_i2c_id);
633
634static struct i2c_driver ak4641_i2c_driver = {
635 .driver = {
636 .name = "ak4641",
637 .owner = THIS_MODULE,
638 },
639 .probe = ak4641_i2c_probe,
640 .remove = __devexit_p(ak4641_i2c_remove),
641 .id_table = ak4641_i2c_id,
642};
643
644static int __init ak4641_modinit(void)
645{
646 int ret;
647
648 ret = i2c_add_driver(&ak4641_i2c_driver);
649 if (ret != 0)
650 pr_err("Failed to register AK4641 I2C driver: %d\n", ret);
651
652 return ret;
653}
654module_init(ak4641_modinit);
655
656static void __exit ak4641_exit(void)
657{
658 i2c_del_driver(&ak4641_i2c_driver);
659}
660module_exit(ak4641_exit);
661
662MODULE_DESCRIPTION("SoC AK4641 driver");
663MODULE_AUTHOR("Harald Welte <laforge@gnufiish.org>");
664MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4641.h b/sound/soc/codecs/ak4641.h
new file mode 100644
index 000000000000..4a263248efea
--- /dev/null
+++ b/sound/soc/codecs/ak4641.h
@@ -0,0 +1,47 @@
1/*
2 * ak4641.h -- AK4641 SoC Audio driver
3 *
4 * Copyright 2008 Harald Welte <laforge@gnufiish.org>
5 *
6 * Based on ak4535.h
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _AK4641_H
14#define _AK4641_H
15
16/* AK4641 register space */
17
18#define AK4641_PM1 0x00
19#define AK4641_PM2 0x01
20#define AK4641_SIG1 0x02
21#define AK4641_SIG2 0x03
22#define AK4641_MODE1 0x04
23#define AK4641_MODE2 0x05
24#define AK4641_DAC 0x06
25#define AK4641_MIC 0x07
26#define AK4641_TIMER 0x08
27#define AK4641_ALC1 0x09
28#define AK4641_ALC2 0x0a
29#define AK4641_PGA 0x0b
30#define AK4641_LATT 0x0c
31#define AK4641_RATT 0x0d
32#define AK4641_VOL 0x0e
33#define AK4641_STATUS 0x0f
34#define AK4641_EQLO 0x10
35#define AK4641_EQMID 0x11
36#define AK4641_EQHI 0x12
37#define AK4641_BTIF 0x13
38
39#define AK4641_CACHEREGNUM 0x14
40
41
42
43#define AK4641_DAI_HIFI 0
44#define AK4641_DAI_VOICE 1
45
46
47#endif
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 2ec75abfa3e9..88b29f8c748b 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -352,7 +352,7 @@ static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = {
352 SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0), 352 SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0),
353}; 353};
354 354
355static const struct snd_soc_dapm_route intercon[] = { 355static const struct snd_soc_dapm_route ak4671_intercon[] = {
356 {"DAC Left", "NULL", "PMPLL"}, 356 {"DAC Left", "NULL", "PMPLL"},
357 {"DAC Right", "NULL", "PMPLL"}, 357 {"DAC Right", "NULL", "PMPLL"},
358 {"ADC Left", "NULL", "PMPLL"}, 358 {"ADC Left", "NULL", "PMPLL"},
@@ -433,17 +433,6 @@ static const struct snd_soc_dapm_route intercon[] = {
433 {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"}, 433 {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"},
434}; 434};
435 435
436static int ak4671_add_widgets(struct snd_soc_codec *codec)
437{
438 struct snd_soc_dapm_context *dapm = &codec->dapm;
439
440 snd_soc_dapm_new_controls(dapm, ak4671_dapm_widgets,
441 ARRAY_SIZE(ak4671_dapm_widgets));
442 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
443
444 return 0;
445}
446
447static int ak4671_hw_params(struct snd_pcm_substream *substream, 436static int ak4671_hw_params(struct snd_pcm_substream *substream,
448 struct snd_pcm_hw_params *params, 437 struct snd_pcm_hw_params *params,
449 struct snd_soc_dai *dai) 438 struct snd_soc_dai *dai)
@@ -650,7 +639,6 @@ static int ak4671_probe(struct snd_soc_codec *codec)
650 639
651 snd_soc_add_controls(codec, ak4671_snd_controls, 640 snd_soc_add_controls(codec, ak4671_snd_controls,
652 ARRAY_SIZE(ak4671_snd_controls)); 641 ARRAY_SIZE(ak4671_snd_controls));
653 ak4671_add_widgets(codec);
654 642
655 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 643 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
656 644
@@ -670,6 +658,10 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
670 .reg_cache_size = AK4671_CACHEREGNUM, 658 .reg_cache_size = AK4671_CACHEREGNUM,
671 .reg_word_size = sizeof(u8), 659 .reg_word_size = sizeof(u8),
672 .reg_cache_default = ak4671_reg, 660 .reg_cache_default = ak4671_reg,
661 .dapm_widgets = ak4671_dapm_widgets,
662 .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets),
663 .dapm_routes = ak4671_intercon,
664 .num_dapm_routes = ARRAY_SIZE(ak4671_intercon),
673}; 665};
674 666
675static int __devinit ak4671_i2c_probe(struct i2c_client *client, 667static int __devinit ak4671_i2c_probe(struct i2c_client *client,
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 0bb424af956f..d68ea532cc7f 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -86,18 +86,6 @@ static const struct snd_soc_dapm_route cx20442_audio_map[] = {
86 {"ADC", NULL, "Input Mixer"}, 86 {"ADC", NULL, "Input Mixer"},
87}; 87};
88 88
89static int cx20442_add_widgets(struct snd_soc_codec *codec)
90{
91 struct snd_soc_dapm_context *dapm = &codec->dapm;
92
93 snd_soc_dapm_new_controls(dapm, cx20442_dapm_widgets,
94 ARRAY_SIZE(cx20442_dapm_widgets));
95 snd_soc_dapm_add_routes(dapm, cx20442_audio_map,
96 ARRAY_SIZE(cx20442_audio_map));
97
98 return 0;
99}
100
101static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec, 89static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec,
102 unsigned int reg) 90 unsigned int reg)
103{ 91{
@@ -344,8 +332,6 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec)
344 return -ENOMEM; 332 return -ENOMEM;
345 snd_soc_codec_set_drvdata(codec, cx20442); 333 snd_soc_codec_set_drvdata(codec, cx20442);
346 334
347 cx20442_add_widgets(codec);
348
349 cx20442->control_data = NULL; 335 cx20442->control_data = NULL;
350 codec->hw_write = NULL; 336 codec->hw_write = NULL;
351 codec->card->pop_time = 0; 337 codec->card->pop_time = 0;
@@ -377,6 +363,10 @@ static struct snd_soc_codec_driver cx20442_codec_dev = {
377 .reg_word_size = sizeof(u8), 363 .reg_word_size = sizeof(u8),
378 .read = cx20442_read_reg_cache, 364 .read = cx20442_read_reg_cache,
379 .write = cx20442_write, 365 .write = cx20442_write,
366 .dapm_widgets = cx20442_dapm_widgets,
367 .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets),
368 .dapm_routes = cx20442_audio_map,
369 .num_dapm_routes = ARRAY_SIZE(cx20442_audio_map),
380}; 370};
381 371
382static int cx20442_platform_probe(struct platform_device *pdev) 372static int cx20442_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index 57e9dac88d38..f9a87737ec16 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -39,7 +39,31 @@ static struct snd_soc_dai_driver dmic_dai = {
39 }, 39 },
40}; 40};
41 41
42static struct snd_soc_codec_driver soc_dmic = {}; 42static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = {
43 SND_SOC_DAPM_AIF_OUT("DMIC AIF", "Capture", 0,
44 SND_SOC_NOPM, 0, 0),
45 SND_SOC_DAPM_INPUT("DMic"),
46};
47
48static const struct snd_soc_dapm_route intercon[] = {
49 {"DMIC AIF", NULL, "DMic"},
50};
51
52static int dmic_probe(struct snd_soc_codec *codec)
53{
54 struct snd_soc_dapm_context *dapm = &codec->dapm;
55
56 snd_soc_dapm_new_controls(dapm, dmic_dapm_widgets,
57 ARRAY_SIZE(dmic_dapm_widgets));
58 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
59 snd_soc_dapm_new_widgets(dapm);
60
61 return 0;
62}
63
64static struct snd_soc_codec_driver soc_dmic = {
65 .probe = dmic_probe,
66};
43 67
44static int __devinit dmic_dev_probe(struct platform_device *pdev) 68static int __devinit dmic_dev_probe(struct platform_device *pdev)
45{ 69{
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index f5ccdbf7ebc6..e373f8f06907 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -294,20 +294,9 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
294 294
295static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) 295static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
296{ 296{
297 struct snd_soc_dapm_context *dapm = &codec->dapm;
298
299 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, 297 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
300 JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); 298 JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
301 299
302 snd_soc_add_controls(codec, jz4740_codec_controls,
303 ARRAY_SIZE(jz4740_codec_controls));
304
305 snd_soc_dapm_new_controls(dapm, jz4740_codec_dapm_widgets,
306 ARRAY_SIZE(jz4740_codec_dapm_widgets));
307
308 snd_soc_dapm_add_routes(dapm, jz4740_codec_dapm_routes,
309 ARRAY_SIZE(jz4740_codec_dapm_routes));
310
311 jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 300 jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
312 301
313 return 0; 302 return 0;
@@ -348,6 +337,13 @@ static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
348 .reg_cache_default = jz4740_codec_regs, 337 .reg_cache_default = jz4740_codec_regs,
349 .reg_word_size = sizeof(u32), 338 .reg_word_size = sizeof(u32),
350 .reg_cache_size = 2, 339 .reg_cache_size = 2,
340
341 .controls = jz4740_codec_controls,
342 .num_controls = ARRAY_SIZE(jz4740_codec_controls),
343 .dapm_widgets = jz4740_codec_dapm_widgets,
344 .num_dapm_widgets = ARRAY_SIZE(jz4740_codec_dapm_widgets),
345 .dapm_routes = jz4740_codec_dapm_routes,
346 .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes),
351}; 347};
352 348
353static int __devinit jz4740_codec_probe(struct platform_device *pdev) 349static int __devinit jz4740_codec_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index bd0517cb7980..4173b67c94d1 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -656,8 +656,6 @@ static const struct soc_enum max98088_exmode_enum =
656 ARRAY_SIZE(max98088_exmode_texts), 656 ARRAY_SIZE(max98088_exmode_texts),
657 max98088_exmode_texts, 657 max98088_exmode_texts,
658 max98088_exmode_values); 658 max98088_exmode_values);
659static const struct snd_kcontrol_new max98088_exmode_controls =
660 SOC_DAPM_VALUE_ENUM("Route", max98088_exmode_enum);
661 659
662static const char *max98088_ex_thresh[] = { /* volts PP */ 660static const char *max98088_ex_thresh[] = { /* volts PP */
663 "0.6", "1.2", "1.8", "2.4", "3.0", "3.6", "4.2", "4.8"}; 661 "0.6", "1.2", "1.8", "2.4", "3.0", "3.6", "4.2", "4.8"};
@@ -783,6 +781,7 @@ static const struct snd_kcontrol_new max98088_snd_controls[] = {
783 SOC_SINGLE("EQ1 Switch", M98088_REG_49_CFG_LEVEL, 0, 1, 0), 781 SOC_SINGLE("EQ1 Switch", M98088_REG_49_CFG_LEVEL, 0, 1, 0),
784 SOC_SINGLE("EQ2 Switch", M98088_REG_49_CFG_LEVEL, 1, 1, 0), 782 SOC_SINGLE("EQ2 Switch", M98088_REG_49_CFG_LEVEL, 1, 1, 0),
785 783
784 SOC_ENUM("EX Limiter Mode", max98088_exmode_enum),
786 SOC_ENUM("EX Limiter Threshold", max98088_ex_thresh_enum), 785 SOC_ENUM("EX Limiter Threshold", max98088_ex_thresh_enum),
787 786
788 SOC_ENUM("DAI1 Filter Mode", max98088_filter_mode_enum), 787 SOC_ENUM("DAI1 Filter Mode", max98088_filter_mode_enum),
@@ -808,10 +807,10 @@ static const struct snd_kcontrol_new max98088_snd_controls[] = {
808 807
809/* Left speaker mixer switch */ 808/* Left speaker mixer switch */
810static const struct snd_kcontrol_new max98088_left_speaker_mixer_controls[] = { 809static const struct snd_kcontrol_new max98088_left_speaker_mixer_controls[] = {
811 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0), 810 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0),
812 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0), 811 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0),
813 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0), 812 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0),
814 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0), 813 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0),
815 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 5, 1, 0), 814 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 5, 1, 0),
816 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 6, 1, 0), 815 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 6, 1, 0),
817 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 1, 1, 0), 816 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 1, 1, 0),
@@ -836,10 +835,10 @@ static const struct snd_kcontrol_new max98088_right_speaker_mixer_controls[] = {
836 835
837/* Left headphone mixer switch */ 836/* Left headphone mixer switch */
838static const struct snd_kcontrol_new max98088_left_hp_mixer_controls[] = { 837static const struct snd_kcontrol_new max98088_left_hp_mixer_controls[] = {
839 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0), 838 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0),
840 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0), 839 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0),
841 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0), 840 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0),
842 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0), 841 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0),
843 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_25_MIX_HP_LEFT, 5, 1, 0), 842 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_25_MIX_HP_LEFT, 5, 1, 0),
844 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_25_MIX_HP_LEFT, 6, 1, 0), 843 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_25_MIX_HP_LEFT, 6, 1, 0),
845 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_25_MIX_HP_LEFT, 1, 1, 0), 844 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_25_MIX_HP_LEFT, 1, 1, 0),
@@ -864,10 +863,10 @@ static const struct snd_kcontrol_new max98088_right_hp_mixer_controls[] = {
864 863
865/* Left earpiece/receiver mixer switch */ 864/* Left earpiece/receiver mixer switch */
866static const struct snd_kcontrol_new max98088_left_rec_mixer_controls[] = { 865static const struct snd_kcontrol_new max98088_left_rec_mixer_controls[] = {
867 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0), 866 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0),
868 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0), 867 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0),
869 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0), 868 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0),
870 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0), 869 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0),
871 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_28_MIX_REC_LEFT, 5, 1, 0), 870 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_28_MIX_REC_LEFT, 5, 1, 0),
872 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_28_MIX_REC_LEFT, 6, 1, 0), 871 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_28_MIX_REC_LEFT, 6, 1, 0),
873 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_28_MIX_REC_LEFT, 1, 1, 0), 872 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_28_MIX_REC_LEFT, 1, 1, 0),
@@ -1094,9 +1093,6 @@ static const struct snd_soc_dapm_widget max98088_dapm_widgets[] = {
1094 1093
1095 SND_SOC_DAPM_MICBIAS("MICBIAS", M98088_REG_4C_PWR_EN_IN, 3, 0), 1094 SND_SOC_DAPM_MICBIAS("MICBIAS", M98088_REG_4C_PWR_EN_IN, 3, 0),
1096 1095
1097 SND_SOC_DAPM_MUX("EX Limiter Mode", SND_SOC_NOPM, 0, 0,
1098 &max98088_exmode_controls),
1099
1100 SND_SOC_DAPM_OUTPUT("HPL"), 1096 SND_SOC_DAPM_OUTPUT("HPL"),
1101 SND_SOC_DAPM_OUTPUT("HPR"), 1097 SND_SOC_DAPM_OUTPUT("HPR"),
1102 SND_SOC_DAPM_OUTPUT("SPKL"), 1098 SND_SOC_DAPM_OUTPUT("SPKL"),
@@ -1112,7 +1108,7 @@ static const struct snd_soc_dapm_widget max98088_dapm_widgets[] = {
1112 SND_SOC_DAPM_INPUT("INB2"), 1108 SND_SOC_DAPM_INPUT("INB2"),
1113}; 1109};
1114 1110
1115static const struct snd_soc_dapm_route audio_map[] = { 1111static const struct snd_soc_dapm_route max98088_audio_map[] = {
1116 /* Left headphone output mixer */ 1112 /* Left headphone output mixer */
1117 {"Left HP Mixer", "Left DAC1 Switch", "DACL1"}, 1113 {"Left HP Mixer", "Left DAC1 Switch", "DACL1"},
1118 {"Left HP Mixer", "Left DAC2 Switch", "DACL2"}, 1114 {"Left HP Mixer", "Left DAC2 Switch", "DACL2"},
@@ -1226,22 +1222,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
1226 {"MIC2 Input", NULL, "MIC2"}, 1222 {"MIC2 Input", NULL, "MIC2"},
1227}; 1223};
1228 1224
1229static int max98088_add_widgets(struct snd_soc_codec *codec)
1230{
1231 struct snd_soc_dapm_context *dapm = &codec->dapm;
1232
1233 snd_soc_dapm_new_controls(dapm, max98088_dapm_widgets,
1234 ARRAY_SIZE(max98088_dapm_widgets));
1235
1236 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
1237
1238 snd_soc_add_controls(codec, max98088_snd_controls,
1239 ARRAY_SIZE(max98088_snd_controls));
1240
1241 snd_soc_dapm_new_widgets(dapm);
1242 return 0;
1243}
1244
1245/* codec mclk clock divider coefficients */ 1225/* codec mclk clock divider coefficients */
1246static const struct { 1226static const struct {
1247 u32 rate; 1227 u32 rate;
@@ -1586,6 +1566,36 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
1586 return 0; 1566 return 0;
1587} 1567}
1588 1568
1569static int max98088_dai1_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1570{
1571 struct snd_soc_codec *codec = codec_dai->codec;
1572 int reg;
1573
1574 if (mute)
1575 reg = M98088_DAI_MUTE;
1576 else
1577 reg = 0;
1578
1579 snd_soc_update_bits(codec, M98088_REG_2F_LVL_DAI1_PLAY,
1580 M98088_DAI_MUTE_MASK, reg);
1581 return 0;
1582}
1583
1584static int max98088_dai2_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1585{
1586 struct snd_soc_codec *codec = codec_dai->codec;
1587 int reg;
1588
1589 if (mute)
1590 reg = M98088_DAI_MUTE;
1591 else
1592 reg = 0;
1593
1594 snd_soc_update_bits(codec, M98088_REG_31_LVL_DAI2_PLAY,
1595 M98088_DAI_MUTE_MASK, reg);
1596 return 0;
1597}
1598
1589static void max98088_sync_cache(struct snd_soc_codec *codec) 1599static void max98088_sync_cache(struct snd_soc_codec *codec)
1590{ 1600{
1591 u16 *reg_cache = codec->reg_cache; 1601 u16 *reg_cache = codec->reg_cache;
@@ -1647,12 +1657,14 @@ static struct snd_soc_dai_ops max98088_dai1_ops = {
1647 .set_sysclk = max98088_dai_set_sysclk, 1657 .set_sysclk = max98088_dai_set_sysclk,
1648 .set_fmt = max98088_dai1_set_fmt, 1658 .set_fmt = max98088_dai1_set_fmt,
1649 .hw_params = max98088_dai1_hw_params, 1659 .hw_params = max98088_dai1_hw_params,
1660 .digital_mute = max98088_dai1_digital_mute,
1650}; 1661};
1651 1662
1652static struct snd_soc_dai_ops max98088_dai2_ops = { 1663static struct snd_soc_dai_ops max98088_dai2_ops = {
1653 .set_sysclk = max98088_dai_set_sysclk, 1664 .set_sysclk = max98088_dai_set_sysclk,
1654 .set_fmt = max98088_dai2_set_fmt, 1665 .set_fmt = max98088_dai2_set_fmt,
1655 .hw_params = max98088_dai2_hw_params, 1666 .hw_params = max98088_dai2_hw_params,
1667 .digital_mute = max98088_dai2_digital_mute,
1656}; 1668};
1657 1669
1658static struct snd_soc_dai_driver max98088_dai[] = { 1670static struct snd_soc_dai_driver max98088_dai[] = {
@@ -2010,7 +2022,8 @@ static int max98088_probe(struct snd_soc_codec *codec)
2010 2022
2011 max98088_handle_pdata(codec); 2023 max98088_handle_pdata(codec);
2012 2024
2013 max98088_add_widgets(codec); 2025 snd_soc_add_controls(codec, max98088_snd_controls,
2026 ARRAY_SIZE(max98088_snd_controls));
2014 2027
2015err_access: 2028err_access:
2016 return ret; 2029 return ret;
@@ -2036,6 +2049,10 @@ static struct snd_soc_codec_driver soc_codec_dev_max98088 = {
2036 .reg_word_size = sizeof(u8), 2049 .reg_word_size = sizeof(u8),
2037 .reg_cache_default = max98088_reg, 2050 .reg_cache_default = max98088_reg,
2038 .volatile_register = max98088_volatile_register, 2051 .volatile_register = max98088_volatile_register,
2052 .dapm_widgets = max98088_dapm_widgets,
2053 .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets),
2054 .dapm_routes = max98088_audio_map,
2055 .num_dapm_routes = ARRAY_SIZE(max98088_audio_map),
2039}; 2056};
2040 2057
2041static int max98088_i2c_probe(struct i2c_client *i2c, 2058static int max98088_i2c_probe(struct i2c_client *i2c,
diff --git a/sound/soc/codecs/max98088.h b/sound/soc/codecs/max98088.h
index 56554c797fef..be89a4f4aab8 100644
--- a/sound/soc/codecs/max98088.h
+++ b/sound/soc/codecs/max98088.h
@@ -133,6 +133,19 @@
133 #define M98088_REC_LINEMODE (1<<7) 133 #define M98088_REC_LINEMODE (1<<7)
134 #define M98088_REC_LINEMODE_MASK (1<<7) 134 #define M98088_REC_LINEMODE_MASK (1<<7)
135 135
136/* M98088_REG_2D_MIX_SPK_CNTL */
137 #define M98088_MIX_SPKR_GAIN_MASK (3<<2)
138 #define M98088_MIX_SPKR_GAIN_SHIFT 2
139 #define M98088_MIX_SPKL_GAIN_MASK (3<<0)
140 #define M98088_MIX_SPKL_GAIN_SHIFT 0
141
142/* M98088_REG_2F_LVL_DAI1_PLAY, M98088_REG_31_LVL_DAI2_PLAY */
143 #define M98088_DAI_MUTE (1<<7)
144 #define M98088_DAI_MUTE_MASK (1<<7)
145 #define M98088_DAI_VOICE_GAIN_MASK (3<<4)
146 #define M98088_DAI_ATTENUATION_MASK (0xF<<0)
147 #define M98088_DAI_ATTENUATION_SHIFT 0
148
136/* M98088_REG_35_LVL_MIC1, M98088_REG_36_LVL_MIC2 */ 149/* M98088_REG_35_LVL_MIC1, M98088_REG_36_LVL_MIC2 */
137 #define M98088_MICPRE_MASK (3<<5) 150 #define M98088_MICPRE_MASK (3<<5)
138 #define M98088_MICPRE_SHIFT 5 151 #define M98088_MICPRE_SHIFT 5
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
new file mode 100644
index 000000000000..e1d282d477da
--- /dev/null
+++ b/sound/soc/codecs/max98095.c
@@ -0,0 +1,2396 @@
1/*
2 * max98095.c -- MAX98095 ALSA SoC Audio driver
3 *
4 * Copyright 2011 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/delay.h>
16#include <linux/pm.h>
17#include <linux/i2c.h>
18#include <linux/platform_device.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc.h>
23#include <sound/initval.h>
24#include <sound/tlv.h>
25#include <linux/slab.h>
26#include <asm/div64.h>
27#include <sound/max98095.h>
28#include "max98095.h"
29
30enum max98095_type {
31 MAX98095,
32};
33
34struct max98095_cdata {
35 unsigned int rate;
36 unsigned int fmt;
37 int eq_sel;
38 int bq_sel;
39};
40
41struct max98095_priv {
42 enum max98095_type devtype;
43 void *control_data;
44 struct max98095_pdata *pdata;
45 unsigned int sysclk;
46 struct max98095_cdata dai[3];
47 const char **eq_texts;
48 const char **bq_texts;
49 struct soc_enum eq_enum;
50 struct soc_enum bq_enum;
51 int eq_textcnt;
52 int bq_textcnt;
53 u8 lin_state;
54 unsigned int mic1pre;
55 unsigned int mic2pre;
56};
57
58static const u8 max98095_reg_def[M98095_REG_CNT] = {
59 0x00, /* 00 */
60 0x00, /* 01 */
61 0x00, /* 02 */
62 0x00, /* 03 */
63 0x00, /* 04 */
64 0x00, /* 05 */
65 0x00, /* 06 */
66 0x00, /* 07 */
67 0x00, /* 08 */
68 0x00, /* 09 */
69 0x00, /* 0A */
70 0x00, /* 0B */
71 0x00, /* 0C */
72 0x00, /* 0D */
73 0x00, /* 0E */
74 0x00, /* 0F */
75 0x00, /* 10 */
76 0x00, /* 11 */
77 0x00, /* 12 */
78 0x00, /* 13 */
79 0x00, /* 14 */
80 0x00, /* 15 */
81 0x00, /* 16 */
82 0x00, /* 17 */
83 0x00, /* 18 */
84 0x00, /* 19 */
85 0x00, /* 1A */
86 0x00, /* 1B */
87 0x00, /* 1C */
88 0x00, /* 1D */
89 0x00, /* 1E */
90 0x00, /* 1F */
91 0x00, /* 20 */
92 0x00, /* 21 */
93 0x00, /* 22 */
94 0x00, /* 23 */
95 0x00, /* 24 */
96 0x00, /* 25 */
97 0x00, /* 26 */
98 0x00, /* 27 */
99 0x00, /* 28 */
100 0x00, /* 29 */
101 0x00, /* 2A */
102 0x00, /* 2B */
103 0x00, /* 2C */
104 0x00, /* 2D */
105 0x00, /* 2E */
106 0x00, /* 2F */
107 0x00, /* 30 */
108 0x00, /* 31 */
109 0x00, /* 32 */
110 0x00, /* 33 */
111 0x00, /* 34 */
112 0x00, /* 35 */
113 0x00, /* 36 */
114 0x00, /* 37 */
115 0x00, /* 38 */
116 0x00, /* 39 */
117 0x00, /* 3A */
118 0x00, /* 3B */
119 0x00, /* 3C */
120 0x00, /* 3D */
121 0x00, /* 3E */
122 0x00, /* 3F */
123 0x00, /* 40 */
124 0x00, /* 41 */
125 0x00, /* 42 */
126 0x00, /* 43 */
127 0x00, /* 44 */
128 0x00, /* 45 */
129 0x00, /* 46 */
130 0x00, /* 47 */
131 0x00, /* 48 */
132 0x00, /* 49 */
133 0x00, /* 4A */
134 0x00, /* 4B */
135 0x00, /* 4C */
136 0x00, /* 4D */
137 0x00, /* 4E */
138 0x00, /* 4F */
139 0x00, /* 50 */
140 0x00, /* 51 */
141 0x00, /* 52 */
142 0x00, /* 53 */
143 0x00, /* 54 */
144 0x00, /* 55 */
145 0x00, /* 56 */
146 0x00, /* 57 */
147 0x00, /* 58 */
148 0x00, /* 59 */
149 0x00, /* 5A */
150 0x00, /* 5B */
151 0x00, /* 5C */
152 0x00, /* 5D */
153 0x00, /* 5E */
154 0x00, /* 5F */
155 0x00, /* 60 */
156 0x00, /* 61 */
157 0x00, /* 62 */
158 0x00, /* 63 */
159 0x00, /* 64 */
160 0x00, /* 65 */
161 0x00, /* 66 */
162 0x00, /* 67 */
163 0x00, /* 68 */
164 0x00, /* 69 */
165 0x00, /* 6A */
166 0x00, /* 6B */
167 0x00, /* 6C */
168 0x00, /* 6D */
169 0x00, /* 6E */
170 0x00, /* 6F */
171 0x00, /* 70 */
172 0x00, /* 71 */
173 0x00, /* 72 */
174 0x00, /* 73 */
175 0x00, /* 74 */
176 0x00, /* 75 */
177 0x00, /* 76 */
178 0x00, /* 77 */
179 0x00, /* 78 */
180 0x00, /* 79 */
181 0x00, /* 7A */
182 0x00, /* 7B */
183 0x00, /* 7C */
184 0x00, /* 7D */
185 0x00, /* 7E */
186 0x00, /* 7F */
187 0x00, /* 80 */
188 0x00, /* 81 */
189 0x00, /* 82 */
190 0x00, /* 83 */
191 0x00, /* 84 */
192 0x00, /* 85 */
193 0x00, /* 86 */
194 0x00, /* 87 */
195 0x00, /* 88 */
196 0x00, /* 89 */
197 0x00, /* 8A */
198 0x00, /* 8B */
199 0x00, /* 8C */
200 0x00, /* 8D */
201 0x00, /* 8E */
202 0x00, /* 8F */
203 0x00, /* 90 */
204 0x00, /* 91 */
205 0x30, /* 92 */
206 0xF0, /* 93 */
207 0x00, /* 94 */
208 0x00, /* 95 */
209 0x3F, /* 96 */
210 0x00, /* 97 */
211 0x00, /* 98 */
212 0x00, /* 99 */
213 0x00, /* 9A */
214 0x00, /* 9B */
215 0x00, /* 9C */
216 0x00, /* 9D */
217 0x00, /* 9E */
218 0x00, /* 9F */
219 0x00, /* A0 */
220 0x00, /* A1 */
221 0x00, /* A2 */
222 0x00, /* A3 */
223 0x00, /* A4 */
224 0x00, /* A5 */
225 0x00, /* A6 */
226 0x00, /* A7 */
227 0x00, /* A8 */
228 0x00, /* A9 */
229 0x00, /* AA */
230 0x00, /* AB */
231 0x00, /* AC */
232 0x00, /* AD */
233 0x00, /* AE */
234 0x00, /* AF */
235 0x00, /* B0 */
236 0x00, /* B1 */
237 0x00, /* B2 */
238 0x00, /* B3 */
239 0x00, /* B4 */
240 0x00, /* B5 */
241 0x00, /* B6 */
242 0x00, /* B7 */
243 0x00, /* B8 */
244 0x00, /* B9 */
245 0x00, /* BA */
246 0x00, /* BB */
247 0x00, /* BC */
248 0x00, /* BD */
249 0x00, /* BE */
250 0x00, /* BF */
251 0x00, /* C0 */
252 0x00, /* C1 */
253 0x00, /* C2 */
254 0x00, /* C3 */
255 0x00, /* C4 */
256 0x00, /* C5 */
257 0x00, /* C6 */
258 0x00, /* C7 */
259 0x00, /* C8 */
260 0x00, /* C9 */
261 0x00, /* CA */
262 0x00, /* CB */
263 0x00, /* CC */
264 0x00, /* CD */
265 0x00, /* CE */
266 0x00, /* CF */
267 0x00, /* D0 */
268 0x00, /* D1 */
269 0x00, /* D2 */
270 0x00, /* D3 */
271 0x00, /* D4 */
272 0x00, /* D5 */
273 0x00, /* D6 */
274 0x00, /* D7 */
275 0x00, /* D8 */
276 0x00, /* D9 */
277 0x00, /* DA */
278 0x00, /* DB */
279 0x00, /* DC */
280 0x00, /* DD */
281 0x00, /* DE */
282 0x00, /* DF */
283 0x00, /* E0 */
284 0x00, /* E1 */
285 0x00, /* E2 */
286 0x00, /* E3 */
287 0x00, /* E4 */
288 0x00, /* E5 */
289 0x00, /* E6 */
290 0x00, /* E7 */
291 0x00, /* E8 */
292 0x00, /* E9 */
293 0x00, /* EA */
294 0x00, /* EB */
295 0x00, /* EC */
296 0x00, /* ED */
297 0x00, /* EE */
298 0x00, /* EF */
299 0x00, /* F0 */
300 0x00, /* F1 */
301 0x00, /* F2 */
302 0x00, /* F3 */
303 0x00, /* F4 */
304 0x00, /* F5 */
305 0x00, /* F6 */
306 0x00, /* F7 */
307 0x00, /* F8 */
308 0x00, /* F9 */
309 0x00, /* FA */
310 0x00, /* FB */
311 0x00, /* FC */
312 0x00, /* FD */
313 0x00, /* FE */
314 0x00, /* FF */
315};
316
317static struct {
318 int readable;
319 int writable;
320} max98095_access[M98095_REG_CNT] = {
321 { 0x00, 0x00 }, /* 00 */
322 { 0xFF, 0x00 }, /* 01 */
323 { 0xFF, 0x00 }, /* 02 */
324 { 0xFF, 0x00 }, /* 03 */
325 { 0xFF, 0x00 }, /* 04 */
326 { 0xFF, 0x00 }, /* 05 */
327 { 0xFF, 0x00 }, /* 06 */
328 { 0xFF, 0x00 }, /* 07 */
329 { 0xFF, 0x00 }, /* 08 */
330 { 0xFF, 0x00 }, /* 09 */
331 { 0xFF, 0x00 }, /* 0A */
332 { 0xFF, 0x00 }, /* 0B */
333 { 0xFF, 0x00 }, /* 0C */
334 { 0xFF, 0x00 }, /* 0D */
335 { 0xFF, 0x00 }, /* 0E */
336 { 0xFF, 0x9F }, /* 0F */
337 { 0xFF, 0xFF }, /* 10 */
338 { 0xFF, 0xFF }, /* 11 */
339 { 0xFF, 0xFF }, /* 12 */
340 { 0xFF, 0xFF }, /* 13 */
341 { 0xFF, 0xFF }, /* 14 */
342 { 0xFF, 0xFF }, /* 15 */
343 { 0xFF, 0xFF }, /* 16 */
344 { 0xFF, 0xFF }, /* 17 */
345 { 0xFF, 0xFF }, /* 18 */
346 { 0xFF, 0xFF }, /* 19 */
347 { 0xFF, 0xFF }, /* 1A */
348 { 0xFF, 0xFF }, /* 1B */
349 { 0xFF, 0xFF }, /* 1C */
350 { 0xFF, 0xFF }, /* 1D */
351 { 0xFF, 0x77 }, /* 1E */
352 { 0xFF, 0x77 }, /* 1F */
353 { 0xFF, 0x77 }, /* 20 */
354 { 0xFF, 0x77 }, /* 21 */
355 { 0xFF, 0x77 }, /* 22 */
356 { 0xFF, 0x77 }, /* 23 */
357 { 0xFF, 0xFF }, /* 24 */
358 { 0xFF, 0x7F }, /* 25 */
359 { 0xFF, 0x31 }, /* 26 */
360 { 0xFF, 0xFF }, /* 27 */
361 { 0xFF, 0xFF }, /* 28 */
362 { 0xFF, 0xFF }, /* 29 */
363 { 0xFF, 0xF7 }, /* 2A */
364 { 0xFF, 0x2F }, /* 2B */
365 { 0xFF, 0xEF }, /* 2C */
366 { 0xFF, 0xFF }, /* 2D */
367 { 0xFF, 0xFF }, /* 2E */
368 { 0xFF, 0xFF }, /* 2F */
369 { 0xFF, 0xFF }, /* 30 */
370 { 0xFF, 0xFF }, /* 31 */
371 { 0xFF, 0xFF }, /* 32 */
372 { 0xFF, 0xFF }, /* 33 */
373 { 0xFF, 0xF7 }, /* 34 */
374 { 0xFF, 0x2F }, /* 35 */
375 { 0xFF, 0xCF }, /* 36 */
376 { 0xFF, 0xFF }, /* 37 */
377 { 0xFF, 0xFF }, /* 38 */
378 { 0xFF, 0xFF }, /* 39 */
379 { 0xFF, 0xFF }, /* 3A */
380 { 0xFF, 0xFF }, /* 3B */
381 { 0xFF, 0xFF }, /* 3C */
382 { 0xFF, 0xFF }, /* 3D */
383 { 0xFF, 0xF7 }, /* 3E */
384 { 0xFF, 0x2F }, /* 3F */
385 { 0xFF, 0xCF }, /* 40 */
386 { 0xFF, 0xFF }, /* 41 */
387 { 0xFF, 0x77 }, /* 42 */
388 { 0xFF, 0xFF }, /* 43 */
389 { 0xFF, 0xFF }, /* 44 */
390 { 0xFF, 0xFF }, /* 45 */
391 { 0xFF, 0xFF }, /* 46 */
392 { 0xFF, 0xFF }, /* 47 */
393 { 0xFF, 0xFF }, /* 48 */
394 { 0xFF, 0x0F }, /* 49 */
395 { 0xFF, 0xFF }, /* 4A */
396 { 0xFF, 0xFF }, /* 4B */
397 { 0xFF, 0x3F }, /* 4C */
398 { 0xFF, 0x3F }, /* 4D */
399 { 0xFF, 0x3F }, /* 4E */
400 { 0xFF, 0xFF }, /* 4F */
401 { 0xFF, 0x7F }, /* 50 */
402 { 0xFF, 0x7F }, /* 51 */
403 { 0xFF, 0x0F }, /* 52 */
404 { 0xFF, 0x3F }, /* 53 */
405 { 0xFF, 0x3F }, /* 54 */
406 { 0xFF, 0x3F }, /* 55 */
407 { 0xFF, 0xFF }, /* 56 */
408 { 0xFF, 0xFF }, /* 57 */
409 { 0xFF, 0xBF }, /* 58 */
410 { 0xFF, 0x1F }, /* 59 */
411 { 0xFF, 0xBF }, /* 5A */
412 { 0xFF, 0x1F }, /* 5B */
413 { 0xFF, 0xBF }, /* 5C */
414 { 0xFF, 0x3F }, /* 5D */
415 { 0xFF, 0x3F }, /* 5E */
416 { 0xFF, 0x7F }, /* 5F */
417 { 0xFF, 0x7F }, /* 60 */
418 { 0xFF, 0x47 }, /* 61 */
419 { 0xFF, 0x9F }, /* 62 */
420 { 0xFF, 0x9F }, /* 63 */
421 { 0xFF, 0x9F }, /* 64 */
422 { 0xFF, 0x9F }, /* 65 */
423 { 0xFF, 0x9F }, /* 66 */
424 { 0xFF, 0xBF }, /* 67 */
425 { 0xFF, 0xBF }, /* 68 */
426 { 0xFF, 0xFF }, /* 69 */
427 { 0xFF, 0xFF }, /* 6A */
428 { 0xFF, 0x7F }, /* 6B */
429 { 0xFF, 0xF7 }, /* 6C */
430 { 0xFF, 0xFF }, /* 6D */
431 { 0xFF, 0xFF }, /* 6E */
432 { 0xFF, 0x1F }, /* 6F */
433 { 0xFF, 0xF7 }, /* 70 */
434 { 0xFF, 0xFF }, /* 71 */
435 { 0xFF, 0xFF }, /* 72 */
436 { 0xFF, 0x1F }, /* 73 */
437 { 0xFF, 0xF7 }, /* 74 */
438 { 0xFF, 0xFF }, /* 75 */
439 { 0xFF, 0xFF }, /* 76 */
440 { 0xFF, 0x1F }, /* 77 */
441 { 0xFF, 0xF7 }, /* 78 */
442 { 0xFF, 0xFF }, /* 79 */
443 { 0xFF, 0xFF }, /* 7A */
444 { 0xFF, 0x1F }, /* 7B */
445 { 0xFF, 0xF7 }, /* 7C */
446 { 0xFF, 0xFF }, /* 7D */
447 { 0xFF, 0xFF }, /* 7E */
448 { 0xFF, 0x1F }, /* 7F */
449 { 0xFF, 0xF7 }, /* 80 */
450 { 0xFF, 0xFF }, /* 81 */
451 { 0xFF, 0xFF }, /* 82 */
452 { 0xFF, 0x1F }, /* 83 */
453 { 0xFF, 0x7F }, /* 84 */
454 { 0xFF, 0x0F }, /* 85 */
455 { 0xFF, 0xD8 }, /* 86 */
456 { 0xFF, 0xFF }, /* 87 */
457 { 0xFF, 0xEF }, /* 88 */
458 { 0xFF, 0xFE }, /* 89 */
459 { 0xFF, 0xFE }, /* 8A */
460 { 0xFF, 0xFF }, /* 8B */
461 { 0xFF, 0xFF }, /* 8C */
462 { 0xFF, 0x3F }, /* 8D */
463 { 0xFF, 0xFF }, /* 8E */
464 { 0xFF, 0x3F }, /* 8F */
465 { 0xFF, 0x8F }, /* 90 */
466 { 0xFF, 0xFF }, /* 91 */
467 { 0xFF, 0x3F }, /* 92 */
468 { 0xFF, 0xFF }, /* 93 */
469 { 0xFF, 0xFF }, /* 94 */
470 { 0xFF, 0x0F }, /* 95 */
471 { 0xFF, 0x3F }, /* 96 */
472 { 0xFF, 0x8C }, /* 97 */
473 { 0x00, 0x00 }, /* 98 */
474 { 0x00, 0x00 }, /* 99 */
475 { 0x00, 0x00 }, /* 9A */
476 { 0x00, 0x00 }, /* 9B */
477 { 0x00, 0x00 }, /* 9C */
478 { 0x00, 0x00 }, /* 9D */
479 { 0x00, 0x00 }, /* 9E */
480 { 0x00, 0x00 }, /* 9F */
481 { 0x00, 0x00 }, /* A0 */
482 { 0x00, 0x00 }, /* A1 */
483 { 0x00, 0x00 }, /* A2 */
484 { 0x00, 0x00 }, /* A3 */
485 { 0x00, 0x00 }, /* A4 */
486 { 0x00, 0x00 }, /* A5 */
487 { 0x00, 0x00 }, /* A6 */
488 { 0x00, 0x00 }, /* A7 */
489 { 0x00, 0x00 }, /* A8 */
490 { 0x00, 0x00 }, /* A9 */
491 { 0x00, 0x00 }, /* AA */
492 { 0x00, 0x00 }, /* AB */
493 { 0x00, 0x00 }, /* AC */
494 { 0x00, 0x00 }, /* AD */
495 { 0x00, 0x00 }, /* AE */
496 { 0x00, 0x00 }, /* AF */
497 { 0x00, 0x00 }, /* B0 */
498 { 0x00, 0x00 }, /* B1 */
499 { 0x00, 0x00 }, /* B2 */
500 { 0x00, 0x00 }, /* B3 */
501 { 0x00, 0x00 }, /* B4 */
502 { 0x00, 0x00 }, /* B5 */
503 { 0x00, 0x00 }, /* B6 */
504 { 0x00, 0x00 }, /* B7 */
505 { 0x00, 0x00 }, /* B8 */
506 { 0x00, 0x00 }, /* B9 */
507 { 0x00, 0x00 }, /* BA */
508 { 0x00, 0x00 }, /* BB */
509 { 0x00, 0x00 }, /* BC */
510 { 0x00, 0x00 }, /* BD */
511 { 0x00, 0x00 }, /* BE */
512 { 0x00, 0x00 }, /* BF */
513 { 0x00, 0x00 }, /* C0 */
514 { 0x00, 0x00 }, /* C1 */
515 { 0x00, 0x00 }, /* C2 */
516 { 0x00, 0x00 }, /* C3 */
517 { 0x00, 0x00 }, /* C4 */
518 { 0x00, 0x00 }, /* C5 */
519 { 0x00, 0x00 }, /* C6 */
520 { 0x00, 0x00 }, /* C7 */
521 { 0x00, 0x00 }, /* C8 */
522 { 0x00, 0x00 }, /* C9 */
523 { 0x00, 0x00 }, /* CA */
524 { 0x00, 0x00 }, /* CB */
525 { 0x00, 0x00 }, /* CC */
526 { 0x00, 0x00 }, /* CD */
527 { 0x00, 0x00 }, /* CE */
528 { 0x00, 0x00 }, /* CF */
529 { 0x00, 0x00 }, /* D0 */
530 { 0x00, 0x00 }, /* D1 */
531 { 0x00, 0x00 }, /* D2 */
532 { 0x00, 0x00 }, /* D3 */
533 { 0x00, 0x00 }, /* D4 */
534 { 0x00, 0x00 }, /* D5 */
535 { 0x00, 0x00 }, /* D6 */
536 { 0x00, 0x00 }, /* D7 */
537 { 0x00, 0x00 }, /* D8 */
538 { 0x00, 0x00 }, /* D9 */
539 { 0x00, 0x00 }, /* DA */
540 { 0x00, 0x00 }, /* DB */
541 { 0x00, 0x00 }, /* DC */
542 { 0x00, 0x00 }, /* DD */
543 { 0x00, 0x00 }, /* DE */
544 { 0x00, 0x00 }, /* DF */
545 { 0x00, 0x00 }, /* E0 */
546 { 0x00, 0x00 }, /* E1 */
547 { 0x00, 0x00 }, /* E2 */
548 { 0x00, 0x00 }, /* E3 */
549 { 0x00, 0x00 }, /* E4 */
550 { 0x00, 0x00 }, /* E5 */
551 { 0x00, 0x00 }, /* E6 */
552 { 0x00, 0x00 }, /* E7 */
553 { 0x00, 0x00 }, /* E8 */
554 { 0x00, 0x00 }, /* E9 */
555 { 0x00, 0x00 }, /* EA */
556 { 0x00, 0x00 }, /* EB */
557 { 0x00, 0x00 }, /* EC */
558 { 0x00, 0x00 }, /* ED */
559 { 0x00, 0x00 }, /* EE */
560 { 0x00, 0x00 }, /* EF */
561 { 0x00, 0x00 }, /* F0 */
562 { 0x00, 0x00 }, /* F1 */
563 { 0x00, 0x00 }, /* F2 */
564 { 0x00, 0x00 }, /* F3 */
565 { 0x00, 0x00 }, /* F4 */
566 { 0x00, 0x00 }, /* F5 */
567 { 0x00, 0x00 }, /* F6 */
568 { 0x00, 0x00 }, /* F7 */
569 { 0x00, 0x00 }, /* F8 */
570 { 0x00, 0x00 }, /* F9 */
571 { 0x00, 0x00 }, /* FA */
572 { 0x00, 0x00 }, /* FB */
573 { 0x00, 0x00 }, /* FC */
574 { 0x00, 0x00 }, /* FD */
575 { 0x00, 0x00 }, /* FE */
576 { 0xFF, 0x00 }, /* FF */
577};
578
579static int max98095_readable(struct snd_soc_codec *codec, unsigned int reg)
580{
581 if (reg >= M98095_REG_CNT)
582 return 0;
583 return max98095_access[reg].readable != 0;
584}
585
586static int max98095_volatile(struct snd_soc_codec *codec, unsigned int reg)
587{
588 if (reg > M98095_REG_MAX_CACHED)
589 return 1;
590
591 switch (reg) {
592 case M98095_000_HOST_DATA:
593 case M98095_001_HOST_INT_STS:
594 case M98095_002_HOST_RSP_STS:
595 case M98095_003_HOST_CMD_STS:
596 case M98095_004_CODEC_STS:
597 case M98095_005_DAI1_ALC_STS:
598 case M98095_006_DAI2_ALC_STS:
599 case M98095_007_JACK_AUTO_STS:
600 case M98095_008_JACK_MANUAL_STS:
601 case M98095_009_JACK_VBAT_STS:
602 case M98095_00A_ACC_ADC_STS:
603 case M98095_00B_MIC_NG_AGC_STS:
604 case M98095_00C_SPK_L_VOLT_STS:
605 case M98095_00D_SPK_R_VOLT_STS:
606 case M98095_00E_TEMP_SENSOR_STS:
607 return 1;
608 }
609
610 return 0;
611}
612
613/*
614 * Filter coefficients are in a separate register segment
615 * and they share the address space of the normal registers.
616 * The coefficient registers do not need or share the cache.
617 */
618static int max98095_hw_write(struct snd_soc_codec *codec, unsigned int reg,
619 unsigned int value)
620{
621 u8 data[2];
622
623 data[0] = reg;
624 data[1] = value;
625 if (codec->hw_write(codec->control_data, data, 2) == 2)
626 return 0;
627 else
628 return -EIO;
629}
630
631/*
632 * Load equalizer DSP coefficient configurations registers
633 */
634static void m98095_eq_band(struct snd_soc_codec *codec, unsigned int dai,
635 unsigned int band, u16 *coefs)
636{
637 unsigned int eq_reg;
638 unsigned int i;
639
640 BUG_ON(band > 4);
641 BUG_ON(dai > 1);
642
643 /* Load the base register address */
644 eq_reg = dai ? M98095_142_DAI2_EQ_BASE : M98095_110_DAI1_EQ_BASE;
645
646 /* Add the band address offset, note adjustment for word address */
647 eq_reg += band * (M98095_COEFS_PER_BAND << 1);
648
649 /* Step through the registers and coefs */
650 for (i = 0; i < M98095_COEFS_PER_BAND; i++) {
651 max98095_hw_write(codec, eq_reg++, M98095_BYTE1(coefs[i]));
652 max98095_hw_write(codec, eq_reg++, M98095_BYTE0(coefs[i]));
653 }
654}
655
656/*
657 * Load biquad filter coefficient configurations registers
658 */
659static void m98095_biquad_band(struct snd_soc_codec *codec, unsigned int dai,
660 unsigned int band, u16 *coefs)
661{
662 unsigned int bq_reg;
663 unsigned int i;
664
665 BUG_ON(band > 1);
666 BUG_ON(dai > 1);
667
668 /* Load the base register address */
669 bq_reg = dai ? M98095_17E_DAI2_BQ_BASE : M98095_174_DAI1_BQ_BASE;
670
671 /* Add the band address offset, note adjustment for word address */
672 bq_reg += band * (M98095_COEFS_PER_BAND << 1);
673
674 /* Step through the registers and coefs */
675 for (i = 0; i < M98095_COEFS_PER_BAND; i++) {
676 max98095_hw_write(codec, bq_reg++, M98095_BYTE1(coefs[i]));
677 max98095_hw_write(codec, bq_reg++, M98095_BYTE0(coefs[i]));
678 }
679}
680
681static const char * const max98095_fltr_mode[] = { "Voice", "Music" };
682static const struct soc_enum max98095_dai1_filter_mode_enum[] = {
683 SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 7, 2, max98095_fltr_mode),
684};
685static const struct soc_enum max98095_dai2_filter_mode_enum[] = {
686 SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 7, 2, max98095_fltr_mode),
687};
688
689static const char * const max98095_extmic_text[] = { "None", "MIC1", "MIC2" };
690
691static const struct soc_enum max98095_extmic_enum =
692 SOC_ENUM_SINGLE(M98095_087_CFG_MIC, 0, 3, max98095_extmic_text);
693
694static const struct snd_kcontrol_new max98095_extmic_mux =
695 SOC_DAPM_ENUM("External MIC Mux", max98095_extmic_enum);
696
697static const char * const max98095_linein_text[] = { "INA", "INB" };
698
699static const struct soc_enum max98095_linein_enum =
700 SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 6, 2, max98095_linein_text);
701
702static const struct snd_kcontrol_new max98095_linein_mux =
703 SOC_DAPM_ENUM("Linein Input Mux", max98095_linein_enum);
704
705static const char * const max98095_line_mode_text[] = {
706 "Stereo", "Differential"};
707
708static const struct soc_enum max98095_linein_mode_enum =
709 SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 7, 2, max98095_line_mode_text);
710
711static const struct soc_enum max98095_lineout_mode_enum =
712 SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 4, 2, max98095_line_mode_text);
713
714static const char * const max98095_dai_fltr[] = {
715 "Off", "Elliptical-HPF-16k", "Butterworth-HPF-16k",
716 "Elliptical-HPF-8k", "Butterworth-HPF-8k", "Butterworth-HPF-Fs/240"};
717static const struct soc_enum max98095_dai1_dac_filter_enum[] = {
718 SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 0, 6, max98095_dai_fltr),
719};
720static const struct soc_enum max98095_dai2_dac_filter_enum[] = {
721 SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 0, 6, max98095_dai_fltr),
722};
723static const struct soc_enum max98095_dai3_dac_filter_enum[] = {
724 SOC_ENUM_SINGLE(M98095_042_DAI3_FILTERS, 0, 6, max98095_dai_fltr),
725};
726
727static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol,
728 struct snd_ctl_elem_value *ucontrol)
729{
730 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
731 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
732 unsigned int sel = ucontrol->value.integer.value[0];
733
734 max98095->mic1pre = sel;
735 snd_soc_update_bits(codec, M98095_05F_LVL_MIC1, M98095_MICPRE_MASK,
736 (1+sel)<<M98095_MICPRE_SHIFT);
737
738 return 0;
739}
740
741static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol,
742 struct snd_ctl_elem_value *ucontrol)
743{
744 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
745 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
746
747 ucontrol->value.integer.value[0] = max98095->mic1pre;
748 return 0;
749}
750
751static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol,
752 struct snd_ctl_elem_value *ucontrol)
753{
754 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
755 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
756 unsigned int sel = ucontrol->value.integer.value[0];
757
758 max98095->mic2pre = sel;
759 snd_soc_update_bits(codec, M98095_060_LVL_MIC2, M98095_MICPRE_MASK,
760 (1+sel)<<M98095_MICPRE_SHIFT);
761
762 return 0;
763}
764
765static int max98095_mic2pre_get(struct snd_kcontrol *kcontrol,
766 struct snd_ctl_elem_value *ucontrol)
767{
768 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
769 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
770
771 ucontrol->value.integer.value[0] = max98095->mic2pre;
772 return 0;
773}
774
775static const unsigned int max98095_micboost_tlv[] = {
776 TLV_DB_RANGE_HEAD(2),
777 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
778 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
779};
780
781static const DECLARE_TLV_DB_SCALE(max98095_mic_tlv, 0, 100, 0);
782static const DECLARE_TLV_DB_SCALE(max98095_adc_tlv, -1200, 100, 0);
783static const DECLARE_TLV_DB_SCALE(max98095_adcboost_tlv, 0, 600, 0);
784
785static const unsigned int max98095_hp_tlv[] = {
786 TLV_DB_RANGE_HEAD(5),
787 0, 6, TLV_DB_SCALE_ITEM(-6700, 400, 0),
788 7, 14, TLV_DB_SCALE_ITEM(-4000, 300, 0),
789 15, 21, TLV_DB_SCALE_ITEM(-1700, 200, 0),
790 22, 27, TLV_DB_SCALE_ITEM(-400, 100, 0),
791 28, 31, TLV_DB_SCALE_ITEM(150, 50, 0),
792};
793
794static const unsigned int max98095_spk_tlv[] = {
795 TLV_DB_RANGE_HEAD(4),
796 0, 10, TLV_DB_SCALE_ITEM(-5900, 400, 0),
797 11, 18, TLV_DB_SCALE_ITEM(-1700, 200, 0),
798 19, 27, TLV_DB_SCALE_ITEM(-200, 100, 0),
799 28, 39, TLV_DB_SCALE_ITEM(650, 50, 0),
800};
801
802static const unsigned int max98095_rcv_lout_tlv[] = {
803 TLV_DB_RANGE_HEAD(5),
804 0, 6, TLV_DB_SCALE_ITEM(-6200, 400, 0),
805 7, 14, TLV_DB_SCALE_ITEM(-3500, 300, 0),
806 15, 21, TLV_DB_SCALE_ITEM(-1200, 200, 0),
807 22, 27, TLV_DB_SCALE_ITEM(100, 100, 0),
808 28, 31, TLV_DB_SCALE_ITEM(650, 50, 0),
809};
810
811static const unsigned int max98095_lin_tlv[] = {
812 TLV_DB_RANGE_HEAD(3),
813 0, 2, TLV_DB_SCALE_ITEM(-600, 300, 0),
814 3, 3, TLV_DB_SCALE_ITEM(300, 1100, 0),
815 4, 5, TLV_DB_SCALE_ITEM(1400, 600, 0),
816};
817
818static const struct snd_kcontrol_new max98095_snd_controls[] = {
819
820 SOC_DOUBLE_R_TLV("Headphone Volume", M98095_064_LVL_HP_L,
821 M98095_065_LVL_HP_R, 0, 31, 0, max98095_hp_tlv),
822
823 SOC_DOUBLE_R_TLV("Speaker Volume", M98095_067_LVL_SPK_L,
824 M98095_068_LVL_SPK_R, 0, 39, 0, max98095_spk_tlv),
825
826 SOC_SINGLE_TLV("Receiver Volume", M98095_066_LVL_RCV,
827 0, 31, 0, max98095_rcv_lout_tlv),
828
829 SOC_DOUBLE_R_TLV("Lineout Volume", M98095_062_LVL_LINEOUT1,
830 M98095_063_LVL_LINEOUT2, 0, 31, 0, max98095_rcv_lout_tlv),
831
832 SOC_DOUBLE_R("Headphone Switch", M98095_064_LVL_HP_L,
833 M98095_065_LVL_HP_R, 7, 1, 1),
834
835 SOC_DOUBLE_R("Speaker Switch", M98095_067_LVL_SPK_L,
836 M98095_068_LVL_SPK_R, 7, 1, 1),
837
838 SOC_SINGLE("Receiver Switch", M98095_066_LVL_RCV, 7, 1, 1),
839
840 SOC_DOUBLE_R("Lineout Switch", M98095_062_LVL_LINEOUT1,
841 M98095_063_LVL_LINEOUT2, 7, 1, 1),
842
843 SOC_SINGLE_TLV("MIC1 Volume", M98095_05F_LVL_MIC1, 0, 20, 1,
844 max98095_mic_tlv),
845
846 SOC_SINGLE_TLV("MIC2 Volume", M98095_060_LVL_MIC2, 0, 20, 1,
847 max98095_mic_tlv),
848
849 SOC_SINGLE_EXT_TLV("MIC1 Boost Volume",
850 M98095_05F_LVL_MIC1, 5, 2, 0,
851 max98095_mic1pre_get, max98095_mic1pre_set,
852 max98095_micboost_tlv),
853 SOC_SINGLE_EXT_TLV("MIC2 Boost Volume",
854 M98095_060_LVL_MIC2, 5, 2, 0,
855 max98095_mic2pre_get, max98095_mic2pre_set,
856 max98095_micboost_tlv),
857
858 SOC_SINGLE_TLV("Linein Volume", M98095_061_LVL_LINEIN, 0, 5, 1,
859 max98095_lin_tlv),
860
861 SOC_SINGLE_TLV("ADCL Volume", M98095_05D_LVL_ADC_L, 0, 15, 1,
862 max98095_adc_tlv),
863 SOC_SINGLE_TLV("ADCR Volume", M98095_05E_LVL_ADC_R, 0, 15, 1,
864 max98095_adc_tlv),
865
866 SOC_SINGLE_TLV("ADCL Boost Volume", M98095_05D_LVL_ADC_L, 4, 3, 0,
867 max98095_adcboost_tlv),
868 SOC_SINGLE_TLV("ADCR Boost Volume", M98095_05E_LVL_ADC_R, 4, 3, 0,
869 max98095_adcboost_tlv),
870
871 SOC_SINGLE("EQ1 Switch", M98095_088_CFG_LEVEL, 0, 1, 0),
872 SOC_SINGLE("EQ2 Switch", M98095_088_CFG_LEVEL, 1, 1, 0),
873
874 SOC_SINGLE("Biquad1 Switch", M98095_088_CFG_LEVEL, 2, 1, 0),
875 SOC_SINGLE("Biquad2 Switch", M98095_088_CFG_LEVEL, 3, 1, 0),
876
877 SOC_ENUM("DAI1 Filter Mode", max98095_dai1_filter_mode_enum),
878 SOC_ENUM("DAI2 Filter Mode", max98095_dai2_filter_mode_enum),
879 SOC_ENUM("DAI1 DAC Filter", max98095_dai1_dac_filter_enum),
880 SOC_ENUM("DAI2 DAC Filter", max98095_dai2_dac_filter_enum),
881 SOC_ENUM("DAI3 DAC Filter", max98095_dai3_dac_filter_enum),
882
883 SOC_ENUM("Linein Mode", max98095_linein_mode_enum),
884 SOC_ENUM("Lineout Mode", max98095_lineout_mode_enum),
885};
886
887/* Left speaker mixer switch */
888static const struct snd_kcontrol_new max98095_left_speaker_mixer_controls[] = {
889 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_050_MIX_SPK_LEFT, 0, 1, 0),
890 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_050_MIX_SPK_LEFT, 6, 1, 0),
891 SOC_DAPM_SINGLE("Mono DAC2 Switch", M98095_050_MIX_SPK_LEFT, 3, 1, 0),
892 SOC_DAPM_SINGLE("Mono DAC3 Switch", M98095_050_MIX_SPK_LEFT, 3, 1, 0),
893 SOC_DAPM_SINGLE("MIC1 Switch", M98095_050_MIX_SPK_LEFT, 4, 1, 0),
894 SOC_DAPM_SINGLE("MIC2 Switch", M98095_050_MIX_SPK_LEFT, 5, 1, 0),
895 SOC_DAPM_SINGLE("IN1 Switch", M98095_050_MIX_SPK_LEFT, 1, 1, 0),
896 SOC_DAPM_SINGLE("IN2 Switch", M98095_050_MIX_SPK_LEFT, 2, 1, 0),
897};
898
899/* Right speaker mixer switch */
900static const struct snd_kcontrol_new max98095_right_speaker_mixer_controls[] = {
901 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_051_MIX_SPK_RIGHT, 6, 1, 0),
902 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_051_MIX_SPK_RIGHT, 0, 1, 0),
903 SOC_DAPM_SINGLE("Mono DAC2 Switch", M98095_051_MIX_SPK_RIGHT, 3, 1, 0),
904 SOC_DAPM_SINGLE("Mono DAC3 Switch", M98095_051_MIX_SPK_RIGHT, 3, 1, 0),
905 SOC_DAPM_SINGLE("MIC1 Switch", M98095_051_MIX_SPK_RIGHT, 5, 1, 0),
906 SOC_DAPM_SINGLE("MIC2 Switch", M98095_051_MIX_SPK_RIGHT, 4, 1, 0),
907 SOC_DAPM_SINGLE("IN1 Switch", M98095_051_MIX_SPK_RIGHT, 1, 1, 0),
908 SOC_DAPM_SINGLE("IN2 Switch", M98095_051_MIX_SPK_RIGHT, 2, 1, 0),
909};
910
911/* Left headphone mixer switch */
912static const struct snd_kcontrol_new max98095_left_hp_mixer_controls[] = {
913 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04C_MIX_HP_LEFT, 0, 1, 0),
914 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04C_MIX_HP_LEFT, 5, 1, 0),
915 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04C_MIX_HP_LEFT, 3, 1, 0),
916 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04C_MIX_HP_LEFT, 4, 1, 0),
917 SOC_DAPM_SINGLE("IN1 Switch", M98095_04C_MIX_HP_LEFT, 1, 1, 0),
918 SOC_DAPM_SINGLE("IN2 Switch", M98095_04C_MIX_HP_LEFT, 2, 1, 0),
919};
920
921/* Right headphone mixer switch */
922static const struct snd_kcontrol_new max98095_right_hp_mixer_controls[] = {
923 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04D_MIX_HP_RIGHT, 5, 1, 0),
924 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04D_MIX_HP_RIGHT, 0, 1, 0),
925 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04D_MIX_HP_RIGHT, 3, 1, 0),
926 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04D_MIX_HP_RIGHT, 4, 1, 0),
927 SOC_DAPM_SINGLE("IN1 Switch", M98095_04D_MIX_HP_RIGHT, 1, 1, 0),
928 SOC_DAPM_SINGLE("IN2 Switch", M98095_04D_MIX_HP_RIGHT, 2, 1, 0),
929};
930
931/* Receiver earpiece mixer switch */
932static const struct snd_kcontrol_new max98095_mono_rcv_mixer_controls[] = {
933 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04F_MIX_RCV, 0, 1, 0),
934 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04F_MIX_RCV, 5, 1, 0),
935 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04F_MIX_RCV, 3, 1, 0),
936 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04F_MIX_RCV, 4, 1, 0),
937 SOC_DAPM_SINGLE("IN1 Switch", M98095_04F_MIX_RCV, 1, 1, 0),
938 SOC_DAPM_SINGLE("IN2 Switch", M98095_04F_MIX_RCV, 2, 1, 0),
939};
940
941/* Left lineout mixer switch */
942static const struct snd_kcontrol_new max98095_left_lineout_mixer_controls[] = {
943 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_053_MIX_LINEOUT1, 5, 1, 0),
944 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_053_MIX_LINEOUT1, 0, 1, 0),
945 SOC_DAPM_SINGLE("MIC1 Switch", M98095_053_MIX_LINEOUT1, 3, 1, 0),
946 SOC_DAPM_SINGLE("MIC2 Switch", M98095_053_MIX_LINEOUT1, 4, 1, 0),
947 SOC_DAPM_SINGLE("IN1 Switch", M98095_053_MIX_LINEOUT1, 1, 1, 0),
948 SOC_DAPM_SINGLE("IN2 Switch", M98095_053_MIX_LINEOUT1, 2, 1, 0),
949};
950
951/* Right lineout mixer switch */
952static const struct snd_kcontrol_new max98095_right_lineout_mixer_controls[] = {
953 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_054_MIX_LINEOUT2, 0, 1, 0),
954 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_054_MIX_LINEOUT2, 5, 1, 0),
955 SOC_DAPM_SINGLE("MIC1 Switch", M98095_054_MIX_LINEOUT2, 3, 1, 0),
956 SOC_DAPM_SINGLE("MIC2 Switch", M98095_054_MIX_LINEOUT2, 4, 1, 0),
957 SOC_DAPM_SINGLE("IN1 Switch", M98095_054_MIX_LINEOUT2, 1, 1, 0),
958 SOC_DAPM_SINGLE("IN2 Switch", M98095_054_MIX_LINEOUT2, 2, 1, 0),
959};
960
961/* Left ADC mixer switch */
962static const struct snd_kcontrol_new max98095_left_ADC_mixer_controls[] = {
963 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04A_MIX_ADC_LEFT, 7, 1, 0),
964 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04A_MIX_ADC_LEFT, 6, 1, 0),
965 SOC_DAPM_SINGLE("IN1 Switch", M98095_04A_MIX_ADC_LEFT, 3, 1, 0),
966 SOC_DAPM_SINGLE("IN2 Switch", M98095_04A_MIX_ADC_LEFT, 2, 1, 0),
967};
968
969/* Right ADC mixer switch */
970static const struct snd_kcontrol_new max98095_right_ADC_mixer_controls[] = {
971 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04B_MIX_ADC_RIGHT, 7, 1, 0),
972 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04B_MIX_ADC_RIGHT, 6, 1, 0),
973 SOC_DAPM_SINGLE("IN1 Switch", M98095_04B_MIX_ADC_RIGHT, 3, 1, 0),
974 SOC_DAPM_SINGLE("IN2 Switch", M98095_04B_MIX_ADC_RIGHT, 2, 1, 0),
975};
976
977static int max98095_mic_event(struct snd_soc_dapm_widget *w,
978 struct snd_kcontrol *kcontrol, int event)
979{
980 struct snd_soc_codec *codec = w->codec;
981 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
982
983 switch (event) {
984 case SND_SOC_DAPM_POST_PMU:
985 if (w->reg == M98095_05F_LVL_MIC1) {
986 snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK,
987 (1+max98095->mic1pre)<<M98095_MICPRE_SHIFT);
988 } else {
989 snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK,
990 (1+max98095->mic2pre)<<M98095_MICPRE_SHIFT);
991 }
992 break;
993 case SND_SOC_DAPM_POST_PMD:
994 snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK, 0);
995 break;
996 default:
997 return -EINVAL;
998 }
999
1000 return 0;
1001}
1002
1003/*
1004 * The line inputs are stereo inputs with the left and right
1005 * channels sharing a common PGA power control signal.
1006 */
1007static int max98095_line_pga(struct snd_soc_dapm_widget *w,
1008 int event, u8 channel)
1009{
1010 struct snd_soc_codec *codec = w->codec;
1011 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1012 u8 *state;
1013
1014 BUG_ON(!((channel == 1) || (channel == 2)));
1015
1016 state = &max98095->lin_state;
1017
1018 switch (event) {
1019 case SND_SOC_DAPM_POST_PMU:
1020 *state |= channel;
1021 snd_soc_update_bits(codec, w->reg,
1022 (1 << w->shift), (1 << w->shift));
1023 break;
1024 case SND_SOC_DAPM_POST_PMD:
1025 *state &= ~channel;
1026 if (*state == 0) {
1027 snd_soc_update_bits(codec, w->reg,
1028 (1 << w->shift), 0);
1029 }
1030 break;
1031 default:
1032 return -EINVAL;
1033 }
1034
1035 return 0;
1036}
1037
1038static int max98095_pga_in1_event(struct snd_soc_dapm_widget *w,
1039 struct snd_kcontrol *k, int event)
1040{
1041 return max98095_line_pga(w, event, 1);
1042}
1043
1044static int max98095_pga_in2_event(struct snd_soc_dapm_widget *w,
1045 struct snd_kcontrol *k, int event)
1046{
1047 return max98095_line_pga(w, event, 2);
1048}
1049
1050/*
1051 * The stereo line out mixer outputs to two stereo line outs.
1052 * The 2nd pair has a separate set of enables.
1053 */
1054static int max98095_lineout_event(struct snd_soc_dapm_widget *w,
1055 struct snd_kcontrol *kcontrol, int event)
1056{
1057 struct snd_soc_codec *codec = w->codec;
1058
1059 switch (event) {
1060 case SND_SOC_DAPM_POST_PMU:
1061 snd_soc_update_bits(codec, w->reg,
1062 (1 << (w->shift+2)), (1 << (w->shift+2)));
1063 break;
1064 case SND_SOC_DAPM_POST_PMD:
1065 snd_soc_update_bits(codec, w->reg,
1066 (1 << (w->shift+2)), 0);
1067 break;
1068 default:
1069 return -EINVAL;
1070 }
1071
1072 return 0;
1073}
1074
1075static const struct snd_soc_dapm_widget max98095_dapm_widgets[] = {
1076
1077 SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", M98095_090_PWR_EN_IN, 0, 0),
1078 SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", M98095_090_PWR_EN_IN, 1, 0),
1079
1080 SND_SOC_DAPM_DAC("DACL1", "HiFi Playback",
1081 M98095_091_PWR_EN_OUT, 0, 0),
1082 SND_SOC_DAPM_DAC("DACR1", "HiFi Playback",
1083 M98095_091_PWR_EN_OUT, 1, 0),
1084 SND_SOC_DAPM_DAC("DACM2", "Aux Playback",
1085 M98095_091_PWR_EN_OUT, 2, 0),
1086 SND_SOC_DAPM_DAC("DACM3", "Voice Playback",
1087 M98095_091_PWR_EN_OUT, 2, 0),
1088
1089 SND_SOC_DAPM_PGA("HP Left Out", M98095_091_PWR_EN_OUT,
1090 6, 0, NULL, 0),
1091 SND_SOC_DAPM_PGA("HP Right Out", M98095_091_PWR_EN_OUT,
1092 7, 0, NULL, 0),
1093
1094 SND_SOC_DAPM_PGA("SPK Left Out", M98095_091_PWR_EN_OUT,
1095 4, 0, NULL, 0),
1096 SND_SOC_DAPM_PGA("SPK Right Out", M98095_091_PWR_EN_OUT,
1097 5, 0, NULL, 0),
1098
1099 SND_SOC_DAPM_PGA("RCV Mono Out", M98095_091_PWR_EN_OUT,
1100 3, 0, NULL, 0),
1101
1102 SND_SOC_DAPM_PGA_E("LINE Left Out", M98095_092_PWR_EN_OUT,
1103 0, 0, NULL, 0, max98095_lineout_event, SND_SOC_DAPM_PRE_PMD),
1104 SND_SOC_DAPM_PGA_E("LINE Right Out", M98095_092_PWR_EN_OUT,
1105 1, 0, NULL, 0, max98095_lineout_event, SND_SOC_DAPM_PRE_PMD),
1106
1107 SND_SOC_DAPM_MUX("External MIC", SND_SOC_NOPM, 0, 0,
1108 &max98095_extmic_mux),
1109
1110 SND_SOC_DAPM_MUX("Linein Mux", SND_SOC_NOPM, 0, 0,
1111 &max98095_linein_mux),
1112
1113 SND_SOC_DAPM_MIXER("Left Headphone Mixer", SND_SOC_NOPM, 0, 0,
1114 &max98095_left_hp_mixer_controls[0],
1115 ARRAY_SIZE(max98095_left_hp_mixer_controls)),
1116
1117 SND_SOC_DAPM_MIXER("Right Headphone Mixer", SND_SOC_NOPM, 0, 0,
1118 &max98095_right_hp_mixer_controls[0],
1119 ARRAY_SIZE(max98095_right_hp_mixer_controls)),
1120
1121 SND_SOC_DAPM_MIXER("Left Speaker Mixer", SND_SOC_NOPM, 0, 0,
1122 &max98095_left_speaker_mixer_controls[0],
1123 ARRAY_SIZE(max98095_left_speaker_mixer_controls)),
1124
1125 SND_SOC_DAPM_MIXER("Right Speaker Mixer", SND_SOC_NOPM, 0, 0,
1126 &max98095_right_speaker_mixer_controls[0],
1127 ARRAY_SIZE(max98095_right_speaker_mixer_controls)),
1128
1129 SND_SOC_DAPM_MIXER("Receiver Mixer", SND_SOC_NOPM, 0, 0,
1130 &max98095_mono_rcv_mixer_controls[0],
1131 ARRAY_SIZE(max98095_mono_rcv_mixer_controls)),
1132
1133 SND_SOC_DAPM_MIXER("Left Lineout Mixer", SND_SOC_NOPM, 0, 0,
1134 &max98095_left_lineout_mixer_controls[0],
1135 ARRAY_SIZE(max98095_left_lineout_mixer_controls)),
1136
1137 SND_SOC_DAPM_MIXER("Right Lineout Mixer", SND_SOC_NOPM, 0, 0,
1138 &max98095_right_lineout_mixer_controls[0],
1139 ARRAY_SIZE(max98095_right_lineout_mixer_controls)),
1140
1141 SND_SOC_DAPM_MIXER("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
1142 &max98095_left_ADC_mixer_controls[0],
1143 ARRAY_SIZE(max98095_left_ADC_mixer_controls)),
1144
1145 SND_SOC_DAPM_MIXER("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
1146 &max98095_right_ADC_mixer_controls[0],
1147 ARRAY_SIZE(max98095_right_ADC_mixer_controls)),
1148
1149 SND_SOC_DAPM_PGA_E("MIC1 Input", M98095_05F_LVL_MIC1,
1150 5, 0, NULL, 0, max98095_mic_event,
1151 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1152
1153 SND_SOC_DAPM_PGA_E("MIC2 Input", M98095_060_LVL_MIC2,
1154 5, 0, NULL, 0, max98095_mic_event,
1155 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1156
1157 SND_SOC_DAPM_PGA_E("IN1 Input", M98095_090_PWR_EN_IN,
1158 7, 0, NULL, 0, max98095_pga_in1_event,
1159 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1160
1161 SND_SOC_DAPM_PGA_E("IN2 Input", M98095_090_PWR_EN_IN,
1162 7, 0, NULL, 0, max98095_pga_in2_event,
1163 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1164
1165 SND_SOC_DAPM_MICBIAS("MICBIAS1", M98095_090_PWR_EN_IN, 2, 0),
1166 SND_SOC_DAPM_MICBIAS("MICBIAS2", M98095_090_PWR_EN_IN, 3, 0),
1167
1168 SND_SOC_DAPM_OUTPUT("HPL"),
1169 SND_SOC_DAPM_OUTPUT("HPR"),
1170 SND_SOC_DAPM_OUTPUT("SPKL"),
1171 SND_SOC_DAPM_OUTPUT("SPKR"),
1172 SND_SOC_DAPM_OUTPUT("RCV"),
1173 SND_SOC_DAPM_OUTPUT("OUT1"),
1174 SND_SOC_DAPM_OUTPUT("OUT2"),
1175 SND_SOC_DAPM_OUTPUT("OUT3"),
1176 SND_SOC_DAPM_OUTPUT("OUT4"),
1177
1178 SND_SOC_DAPM_INPUT("MIC1"),
1179 SND_SOC_DAPM_INPUT("MIC2"),
1180 SND_SOC_DAPM_INPUT("INA1"),
1181 SND_SOC_DAPM_INPUT("INA2"),
1182 SND_SOC_DAPM_INPUT("INB1"),
1183 SND_SOC_DAPM_INPUT("INB2"),
1184};
1185
1186static const struct snd_soc_dapm_route max98095_audio_map[] = {
1187 /* Left headphone output mixer */
1188 {"Left Headphone Mixer", "Left DAC1 Switch", "DACL1"},
1189 {"Left Headphone Mixer", "Right DAC1 Switch", "DACR1"},
1190 {"Left Headphone Mixer", "MIC1 Switch", "MIC1 Input"},
1191 {"Left Headphone Mixer", "MIC2 Switch", "MIC2 Input"},
1192 {"Left Headphone Mixer", "IN1 Switch", "IN1 Input"},
1193 {"Left Headphone Mixer", "IN2 Switch", "IN2 Input"},
1194
1195 /* Right headphone output mixer */
1196 {"Right Headphone Mixer", "Left DAC1 Switch", "DACL1"},
1197 {"Right Headphone Mixer", "Right DAC1 Switch", "DACR1"},
1198 {"Right Headphone Mixer", "MIC1 Switch", "MIC1 Input"},
1199 {"Right Headphone Mixer", "MIC2 Switch", "MIC2 Input"},
1200 {"Right Headphone Mixer", "IN1 Switch", "IN1 Input"},
1201 {"Right Headphone Mixer", "IN2 Switch", "IN2 Input"},
1202
1203 /* Left speaker output mixer */
1204 {"Left Speaker Mixer", "Left DAC1 Switch", "DACL1"},
1205 {"Left Speaker Mixer", "Right DAC1 Switch", "DACR1"},
1206 {"Left Speaker Mixer", "Mono DAC2 Switch", "DACM2"},
1207 {"Left Speaker Mixer", "Mono DAC3 Switch", "DACM3"},
1208 {"Left Speaker Mixer", "MIC1 Switch", "MIC1 Input"},
1209 {"Left Speaker Mixer", "MIC2 Switch", "MIC2 Input"},
1210 {"Left Speaker Mixer", "IN1 Switch", "IN1 Input"},
1211 {"Left Speaker Mixer", "IN2 Switch", "IN2 Input"},
1212
1213 /* Right speaker output mixer */
1214 {"Right Speaker Mixer", "Left DAC1 Switch", "DACL1"},
1215 {"Right Speaker Mixer", "Right DAC1 Switch", "DACR1"},
1216 {"Right Speaker Mixer", "Mono DAC2 Switch", "DACM2"},
1217 {"Right Speaker Mixer", "Mono DAC3 Switch", "DACM3"},
1218 {"Right Speaker Mixer", "MIC1 Switch", "MIC1 Input"},
1219 {"Right Speaker Mixer", "MIC2 Switch", "MIC2 Input"},
1220 {"Right Speaker Mixer", "IN1 Switch", "IN1 Input"},
1221 {"Right Speaker Mixer", "IN2 Switch", "IN2 Input"},
1222
1223 /* Earpiece/Receiver output mixer */
1224 {"Receiver Mixer", "Left DAC1 Switch", "DACL1"},
1225 {"Receiver Mixer", "Right DAC1 Switch", "DACR1"},
1226 {"Receiver Mixer", "MIC1 Switch", "MIC1 Input"},
1227 {"Receiver Mixer", "MIC2 Switch", "MIC2 Input"},
1228 {"Receiver Mixer", "IN1 Switch", "IN1 Input"},
1229 {"Receiver Mixer", "IN2 Switch", "IN2 Input"},
1230
1231 /* Left Lineout output mixer */
1232 {"Left Lineout Mixer", "Left DAC1 Switch", "DACL1"},
1233 {"Left Lineout Mixer", "Right DAC1 Switch", "DACR1"},
1234 {"Left Lineout Mixer", "MIC1 Switch", "MIC1 Input"},
1235 {"Left Lineout Mixer", "MIC2 Switch", "MIC2 Input"},
1236 {"Left Lineout Mixer", "IN1 Switch", "IN1 Input"},
1237 {"Left Lineout Mixer", "IN2 Switch", "IN2 Input"},
1238
1239 /* Right lineout output mixer */
1240 {"Right Lineout Mixer", "Left DAC1 Switch", "DACL1"},
1241 {"Right Lineout Mixer", "Right DAC1 Switch", "DACR1"},
1242 {"Right Lineout Mixer", "MIC1 Switch", "MIC1 Input"},
1243 {"Right Lineout Mixer", "MIC2 Switch", "MIC2 Input"},
1244 {"Right Lineout Mixer", "IN1 Switch", "IN1 Input"},
1245 {"Right Lineout Mixer", "IN2 Switch", "IN2 Input"},
1246
1247 {"HP Left Out", NULL, "Left Headphone Mixer"},
1248 {"HP Right Out", NULL, "Right Headphone Mixer"},
1249 {"SPK Left Out", NULL, "Left Speaker Mixer"},
1250 {"SPK Right Out", NULL, "Right Speaker Mixer"},
1251 {"RCV Mono Out", NULL, "Receiver Mixer"},
1252 {"LINE Left Out", NULL, "Left Lineout Mixer"},
1253 {"LINE Right Out", NULL, "Right Lineout Mixer"},
1254
1255 {"HPL", NULL, "HP Left Out"},
1256 {"HPR", NULL, "HP Right Out"},
1257 {"SPKL", NULL, "SPK Left Out"},
1258 {"SPKR", NULL, "SPK Right Out"},
1259 {"RCV", NULL, "RCV Mono Out"},
1260 {"OUT1", NULL, "LINE Left Out"},
1261 {"OUT2", NULL, "LINE Right Out"},
1262 {"OUT3", NULL, "LINE Left Out"},
1263 {"OUT4", NULL, "LINE Right Out"},
1264
1265 /* Left ADC input mixer */
1266 {"Left ADC Mixer", "MIC1 Switch", "MIC1 Input"},
1267 {"Left ADC Mixer", "MIC2 Switch", "MIC2 Input"},
1268 {"Left ADC Mixer", "IN1 Switch", "IN1 Input"},
1269 {"Left ADC Mixer", "IN2 Switch", "IN2 Input"},
1270
1271 /* Right ADC input mixer */
1272 {"Right ADC Mixer", "MIC1 Switch", "MIC1 Input"},
1273 {"Right ADC Mixer", "MIC2 Switch", "MIC2 Input"},
1274 {"Right ADC Mixer", "IN1 Switch", "IN1 Input"},
1275 {"Right ADC Mixer", "IN2 Switch", "IN2 Input"},
1276
1277 /* Inputs */
1278 {"ADCL", NULL, "Left ADC Mixer"},
1279 {"ADCR", NULL, "Right ADC Mixer"},
1280
1281 {"IN1 Input", NULL, "INA1"},
1282 {"IN2 Input", NULL, "INA2"},
1283
1284 {"MIC1 Input", NULL, "MIC1"},
1285 {"MIC2 Input", NULL, "MIC2"},
1286};
1287
1288static int max98095_add_widgets(struct snd_soc_codec *codec)
1289{
1290 snd_soc_add_controls(codec, max98095_snd_controls,
1291 ARRAY_SIZE(max98095_snd_controls));
1292
1293 return 0;
1294}
1295
1296/* codec mclk clock divider coefficients */
1297static const struct {
1298 u32 rate;
1299 u8 sr;
1300} rate_table[] = {
1301 {8000, 0x01},
1302 {11025, 0x02},
1303 {16000, 0x03},
1304 {22050, 0x04},
1305 {24000, 0x05},
1306 {32000, 0x06},
1307 {44100, 0x07},
1308 {48000, 0x08},
1309 {88200, 0x09},
1310 {96000, 0x0A},
1311};
1312
1313static int rate_value(int rate, u8 *value)
1314{
1315 int i;
1316
1317 for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
1318 if (rate_table[i].rate >= rate) {
1319 *value = rate_table[i].sr;
1320 return 0;
1321 }
1322 }
1323 *value = rate_table[0].sr;
1324 return -EINVAL;
1325}
1326
1327static int max98095_dai1_hw_params(struct snd_pcm_substream *substream,
1328 struct snd_pcm_hw_params *params,
1329 struct snd_soc_dai *dai)
1330{
1331 struct snd_soc_codec *codec = dai->codec;
1332 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1333 struct max98095_cdata *cdata;
1334 unsigned long long ni;
1335 unsigned int rate;
1336 u8 regval;
1337
1338 cdata = &max98095->dai[0];
1339
1340 rate = params_rate(params);
1341
1342 switch (params_format(params)) {
1343 case SNDRV_PCM_FORMAT_S16_LE:
1344 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
1345 M98095_DAI_WS, 0);
1346 break;
1347 case SNDRV_PCM_FORMAT_S24_LE:
1348 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
1349 M98095_DAI_WS, M98095_DAI_WS);
1350 break;
1351 default:
1352 return -EINVAL;
1353 }
1354
1355 if (rate_value(rate, &regval))
1356 return -EINVAL;
1357
1358 snd_soc_update_bits(codec, M98095_027_DAI1_CLKMODE,
1359 M98095_CLKMODE_MASK, regval);
1360 cdata->rate = rate;
1361
1362 /* Configure NI when operating as master */
1363 if (snd_soc_read(codec, M98095_02A_DAI1_FORMAT) & M98095_DAI_MAS) {
1364 if (max98095->sysclk == 0) {
1365 dev_err(codec->dev, "Invalid system clock frequency\n");
1366 return -EINVAL;
1367 }
1368 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
1369 * (unsigned long long int)rate;
1370 do_div(ni, (unsigned long long int)max98095->sysclk);
1371 snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI,
1372 (ni >> 8) & 0x7F);
1373 snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO,
1374 ni & 0xFF);
1375 }
1376
1377 /* Update sample rate mode */
1378 if (rate < 50000)
1379 snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS,
1380 M98095_DAI_DHF, 0);
1381 else
1382 snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS,
1383 M98095_DAI_DHF, M98095_DAI_DHF);
1384
1385 return 0;
1386}
1387
1388static int max98095_dai2_hw_params(struct snd_pcm_substream *substream,
1389 struct snd_pcm_hw_params *params,
1390 struct snd_soc_dai *dai)
1391{
1392 struct snd_soc_codec *codec = dai->codec;
1393 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1394 struct max98095_cdata *cdata;
1395 unsigned long long ni;
1396 unsigned int rate;
1397 u8 regval;
1398
1399 cdata = &max98095->dai[1];
1400
1401 rate = params_rate(params);
1402
1403 switch (params_format(params)) {
1404 case SNDRV_PCM_FORMAT_S16_LE:
1405 snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
1406 M98095_DAI_WS, 0);
1407 break;
1408 case SNDRV_PCM_FORMAT_S24_LE:
1409 snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
1410 M98095_DAI_WS, M98095_DAI_WS);
1411 break;
1412 default:
1413 return -EINVAL;
1414 }
1415
1416 if (rate_value(rate, &regval))
1417 return -EINVAL;
1418
1419 snd_soc_update_bits(codec, M98095_031_DAI2_CLKMODE,
1420 M98095_CLKMODE_MASK, regval);
1421 cdata->rate = rate;
1422
1423 /* Configure NI when operating as master */
1424 if (snd_soc_read(codec, M98095_034_DAI2_FORMAT) & M98095_DAI_MAS) {
1425 if (max98095->sysclk == 0) {
1426 dev_err(codec->dev, "Invalid system clock frequency\n");
1427 return -EINVAL;
1428 }
1429 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
1430 * (unsigned long long int)rate;
1431 do_div(ni, (unsigned long long int)max98095->sysclk);
1432 snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI,
1433 (ni >> 8) & 0x7F);
1434 snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO,
1435 ni & 0xFF);
1436 }
1437
1438 /* Update sample rate mode */
1439 if (rate < 50000)
1440 snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS,
1441 M98095_DAI_DHF, 0);
1442 else
1443 snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS,
1444 M98095_DAI_DHF, M98095_DAI_DHF);
1445
1446 return 0;
1447}
1448
1449static int max98095_dai3_hw_params(struct snd_pcm_substream *substream,
1450 struct snd_pcm_hw_params *params,
1451 struct snd_soc_dai *dai)
1452{
1453 struct snd_soc_codec *codec = dai->codec;
1454 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1455 struct max98095_cdata *cdata;
1456 unsigned long long ni;
1457 unsigned int rate;
1458 u8 regval;
1459
1460 cdata = &max98095->dai[2];
1461
1462 rate = params_rate(params);
1463
1464 switch (params_format(params)) {
1465 case SNDRV_PCM_FORMAT_S16_LE:
1466 snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
1467 M98095_DAI_WS, 0);
1468 break;
1469 case SNDRV_PCM_FORMAT_S24_LE:
1470 snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
1471 M98095_DAI_WS, M98095_DAI_WS);
1472 break;
1473 default:
1474 return -EINVAL;
1475 }
1476
1477 if (rate_value(rate, &regval))
1478 return -EINVAL;
1479
1480 snd_soc_update_bits(codec, M98095_03B_DAI3_CLKMODE,
1481 M98095_CLKMODE_MASK, regval);
1482 cdata->rate = rate;
1483
1484 /* Configure NI when operating as master */
1485 if (snd_soc_read(codec, M98095_03E_DAI3_FORMAT) & M98095_DAI_MAS) {
1486 if (max98095->sysclk == 0) {
1487 dev_err(codec->dev, "Invalid system clock frequency\n");
1488 return -EINVAL;
1489 }
1490 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
1491 * (unsigned long long int)rate;
1492 do_div(ni, (unsigned long long int)max98095->sysclk);
1493 snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI,
1494 (ni >> 8) & 0x7F);
1495 snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO,
1496 ni & 0xFF);
1497 }
1498
1499 /* Update sample rate mode */
1500 if (rate < 50000)
1501 snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS,
1502 M98095_DAI_DHF, 0);
1503 else
1504 snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS,
1505 M98095_DAI_DHF, M98095_DAI_DHF);
1506
1507 return 0;
1508}
1509
1510static int max98095_dai_set_sysclk(struct snd_soc_dai *dai,
1511 int clk_id, unsigned int freq, int dir)
1512{
1513 struct snd_soc_codec *codec = dai->codec;
1514 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1515
1516 /* Requested clock frequency is already setup */
1517 if (freq == max98095->sysclk)
1518 return 0;
1519
1520 max98095->sysclk = freq; /* remember current sysclk */
1521
1522 /* Setup clocks for slave mode, and using the PLL
1523 * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
1524 * 0x02 (when master clk is 20MHz to 40MHz)..
1525 * 0x03 (when master clk is 40MHz to 60MHz)..
1526 */
1527 if ((freq >= 10000000) && (freq < 20000000)) {
1528 snd_soc_write(codec, M98095_026_SYS_CLK, 0x10);
1529 } else if ((freq >= 20000000) && (freq < 40000000)) {
1530 snd_soc_write(codec, M98095_026_SYS_CLK, 0x20);
1531 } else if ((freq >= 40000000) && (freq < 60000000)) {
1532 snd_soc_write(codec, M98095_026_SYS_CLK, 0x30);
1533 } else {
1534 dev_err(codec->dev, "Invalid master clock frequency\n");
1535 return -EINVAL;
1536 }
1537
1538 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
1539
1540 max98095->sysclk = freq;
1541 return 0;
1542}
1543
1544static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai,
1545 unsigned int fmt)
1546{
1547 struct snd_soc_codec *codec = codec_dai->codec;
1548 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1549 struct max98095_cdata *cdata;
1550 u8 regval = 0;
1551
1552 cdata = &max98095->dai[0];
1553
1554 if (fmt != cdata->fmt) {
1555 cdata->fmt = fmt;
1556
1557 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1558 case SND_SOC_DAIFMT_CBS_CFS:
1559 /* Slave mode PLL */
1560 snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI,
1561 0x80);
1562 snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO,
1563 0x00);
1564 break;
1565 case SND_SOC_DAIFMT_CBM_CFM:
1566 /* Set to master mode */
1567 regval |= M98095_DAI_MAS;
1568 break;
1569 case SND_SOC_DAIFMT_CBS_CFM:
1570 case SND_SOC_DAIFMT_CBM_CFS:
1571 default:
1572 dev_err(codec->dev, "Clock mode unsupported");
1573 return -EINVAL;
1574 }
1575
1576 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1577 case SND_SOC_DAIFMT_I2S:
1578 regval |= M98095_DAI_DLY;
1579 break;
1580 case SND_SOC_DAIFMT_LEFT_J:
1581 break;
1582 default:
1583 return -EINVAL;
1584 }
1585
1586 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1587 case SND_SOC_DAIFMT_NB_NF:
1588 break;
1589 case SND_SOC_DAIFMT_NB_IF:
1590 regval |= M98095_DAI_WCI;
1591 break;
1592 case SND_SOC_DAIFMT_IB_NF:
1593 regval |= M98095_DAI_BCI;
1594 break;
1595 case SND_SOC_DAIFMT_IB_IF:
1596 regval |= M98095_DAI_BCI|M98095_DAI_WCI;
1597 break;
1598 default:
1599 return -EINVAL;
1600 }
1601
1602 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
1603 M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
1604 M98095_DAI_WCI, regval);
1605
1606 snd_soc_write(codec, M98095_02B_DAI1_CLOCK, M98095_DAI_BSEL64);
1607 }
1608
1609 return 0;
1610}
1611
1612static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai,
1613 unsigned int fmt)
1614{
1615 struct snd_soc_codec *codec = codec_dai->codec;
1616 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1617 struct max98095_cdata *cdata;
1618 u8 regval = 0;
1619
1620 cdata = &max98095->dai[1];
1621
1622 if (fmt != cdata->fmt) {
1623 cdata->fmt = fmt;
1624
1625 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1626 case SND_SOC_DAIFMT_CBS_CFS:
1627 /* Slave mode PLL */
1628 snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI,
1629 0x80);
1630 snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO,
1631 0x00);
1632 break;
1633 case SND_SOC_DAIFMT_CBM_CFM:
1634 /* Set to master mode */
1635 regval |= M98095_DAI_MAS;
1636 break;
1637 case SND_SOC_DAIFMT_CBS_CFM:
1638 case SND_SOC_DAIFMT_CBM_CFS:
1639 default:
1640 dev_err(codec->dev, "Clock mode unsupported");
1641 return -EINVAL;
1642 }
1643
1644 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1645 case SND_SOC_DAIFMT_I2S:
1646 regval |= M98095_DAI_DLY;
1647 break;
1648 case SND_SOC_DAIFMT_LEFT_J:
1649 break;
1650 default:
1651 return -EINVAL;
1652 }
1653
1654 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1655 case SND_SOC_DAIFMT_NB_NF:
1656 break;
1657 case SND_SOC_DAIFMT_NB_IF:
1658 regval |= M98095_DAI_WCI;
1659 break;
1660 case SND_SOC_DAIFMT_IB_NF:
1661 regval |= M98095_DAI_BCI;
1662 break;
1663 case SND_SOC_DAIFMT_IB_IF:
1664 regval |= M98095_DAI_BCI|M98095_DAI_WCI;
1665 break;
1666 default:
1667 return -EINVAL;
1668 }
1669
1670 snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
1671 M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
1672 M98095_DAI_WCI, regval);
1673
1674 snd_soc_write(codec, M98095_035_DAI2_CLOCK,
1675 M98095_DAI_BSEL64);
1676 }
1677
1678 return 0;
1679}
1680
1681static int max98095_dai3_set_fmt(struct snd_soc_dai *codec_dai,
1682 unsigned int fmt)
1683{
1684 struct snd_soc_codec *codec = codec_dai->codec;
1685 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1686 struct max98095_cdata *cdata;
1687 u8 regval = 0;
1688
1689 cdata = &max98095->dai[2];
1690
1691 if (fmt != cdata->fmt) {
1692 cdata->fmt = fmt;
1693
1694 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1695 case SND_SOC_DAIFMT_CBS_CFS:
1696 /* Slave mode PLL */
1697 snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI,
1698 0x80);
1699 snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO,
1700 0x00);
1701 break;
1702 case SND_SOC_DAIFMT_CBM_CFM:
1703 /* Set to master mode */
1704 regval |= M98095_DAI_MAS;
1705 break;
1706 case SND_SOC_DAIFMT_CBS_CFM:
1707 case SND_SOC_DAIFMT_CBM_CFS:
1708 default:
1709 dev_err(codec->dev, "Clock mode unsupported");
1710 return -EINVAL;
1711 }
1712
1713 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1714 case SND_SOC_DAIFMT_I2S:
1715 regval |= M98095_DAI_DLY;
1716 break;
1717 case SND_SOC_DAIFMT_LEFT_J:
1718 break;
1719 default:
1720 return -EINVAL;
1721 }
1722
1723 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1724 case SND_SOC_DAIFMT_NB_NF:
1725 break;
1726 case SND_SOC_DAIFMT_NB_IF:
1727 regval |= M98095_DAI_WCI;
1728 break;
1729 case SND_SOC_DAIFMT_IB_NF:
1730 regval |= M98095_DAI_BCI;
1731 break;
1732 case SND_SOC_DAIFMT_IB_IF:
1733 regval |= M98095_DAI_BCI|M98095_DAI_WCI;
1734 break;
1735 default:
1736 return -EINVAL;
1737 }
1738
1739 snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
1740 M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
1741 M98095_DAI_WCI, regval);
1742
1743 snd_soc_write(codec, M98095_03F_DAI3_CLOCK,
1744 M98095_DAI_BSEL64);
1745 }
1746
1747 return 0;
1748}
1749
1750static int max98095_set_bias_level(struct snd_soc_codec *codec,
1751 enum snd_soc_bias_level level)
1752{
1753 int ret;
1754
1755 switch (level) {
1756 case SND_SOC_BIAS_ON:
1757 break;
1758
1759 case SND_SOC_BIAS_PREPARE:
1760 break;
1761
1762 case SND_SOC_BIAS_STANDBY:
1763 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1764 ret = snd_soc_cache_sync(codec);
1765
1766 if (ret != 0) {
1767 dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
1768 return ret;
1769 }
1770 }
1771
1772 snd_soc_update_bits(codec, M98095_090_PWR_EN_IN,
1773 M98095_MBEN, M98095_MBEN);
1774 break;
1775
1776 case SND_SOC_BIAS_OFF:
1777 snd_soc_update_bits(codec, M98095_090_PWR_EN_IN,
1778 M98095_MBEN, 0);
1779 codec->cache_sync = 1;
1780 break;
1781 }
1782 codec->dapm.bias_level = level;
1783 return 0;
1784}
1785
1786#define MAX98095_RATES SNDRV_PCM_RATE_8000_96000
1787#define MAX98095_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
1788
1789static struct snd_soc_dai_ops max98095_dai1_ops = {
1790 .set_sysclk = max98095_dai_set_sysclk,
1791 .set_fmt = max98095_dai1_set_fmt,
1792 .hw_params = max98095_dai1_hw_params,
1793};
1794
1795static struct snd_soc_dai_ops max98095_dai2_ops = {
1796 .set_sysclk = max98095_dai_set_sysclk,
1797 .set_fmt = max98095_dai2_set_fmt,
1798 .hw_params = max98095_dai2_hw_params,
1799};
1800
1801static struct snd_soc_dai_ops max98095_dai3_ops = {
1802 .set_sysclk = max98095_dai_set_sysclk,
1803 .set_fmt = max98095_dai3_set_fmt,
1804 .hw_params = max98095_dai3_hw_params,
1805};
1806
1807static struct snd_soc_dai_driver max98095_dai[] = {
1808{
1809 .name = "HiFi",
1810 .playback = {
1811 .stream_name = "HiFi Playback",
1812 .channels_min = 1,
1813 .channels_max = 2,
1814 .rates = MAX98095_RATES,
1815 .formats = MAX98095_FORMATS,
1816 },
1817 .capture = {
1818 .stream_name = "HiFi Capture",
1819 .channels_min = 1,
1820 .channels_max = 2,
1821 .rates = MAX98095_RATES,
1822 .formats = MAX98095_FORMATS,
1823 },
1824 .ops = &max98095_dai1_ops,
1825},
1826{
1827 .name = "Aux",
1828 .playback = {
1829 .stream_name = "Aux Playback",
1830 .channels_min = 1,
1831 .channels_max = 1,
1832 .rates = MAX98095_RATES,
1833 .formats = MAX98095_FORMATS,
1834 },
1835 .ops = &max98095_dai2_ops,
1836},
1837{
1838 .name = "Voice",
1839 .playback = {
1840 .stream_name = "Voice Playback",
1841 .channels_min = 1,
1842 .channels_max = 1,
1843 .rates = MAX98095_RATES,
1844 .formats = MAX98095_FORMATS,
1845 },
1846 .ops = &max98095_dai3_ops,
1847}
1848
1849};
1850
1851static int max98095_get_eq_channel(const char *name)
1852{
1853 if (strcmp(name, "EQ1 Mode") == 0)
1854 return 0;
1855 if (strcmp(name, "EQ2 Mode") == 0)
1856 return 1;
1857 return -EINVAL;
1858}
1859
1860static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol,
1861 struct snd_ctl_elem_value *ucontrol)
1862{
1863 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1864 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1865 struct max98095_pdata *pdata = max98095->pdata;
1866 int channel = max98095_get_eq_channel(kcontrol->id.name);
1867 struct max98095_cdata *cdata;
1868 int sel = ucontrol->value.integer.value[0];
1869 struct max98095_eq_cfg *coef_set;
1870 int fs, best, best_val, i;
1871 int regmask, regsave;
1872
1873 BUG_ON(channel > 1);
1874
1875 if (!pdata || !max98095->eq_textcnt)
1876 return 0;
1877
1878 if (sel >= pdata->eq_cfgcnt)
1879 return -EINVAL;
1880
1881 cdata = &max98095->dai[channel];
1882 cdata->eq_sel = sel;
1883 fs = cdata->rate;
1884
1885 /* Find the selected configuration with nearest sample rate */
1886 best = 0;
1887 best_val = INT_MAX;
1888 for (i = 0; i < pdata->eq_cfgcnt; i++) {
1889 if (strcmp(pdata->eq_cfg[i].name, max98095->eq_texts[sel]) == 0 &&
1890 abs(pdata->eq_cfg[i].rate - fs) < best_val) {
1891 best = i;
1892 best_val = abs(pdata->eq_cfg[i].rate - fs);
1893 }
1894 }
1895
1896 dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
1897 pdata->eq_cfg[best].name,
1898 pdata->eq_cfg[best].rate, fs);
1899
1900 coef_set = &pdata->eq_cfg[best];
1901
1902 regmask = (channel == 0) ? M98095_EQ1EN : M98095_EQ2EN;
1903
1904 /* Disable filter while configuring, and save current on/off state */
1905 regsave = snd_soc_read(codec, M98095_088_CFG_LEVEL);
1906 snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, 0);
1907
1908 mutex_lock(&codec->mutex);
1909 snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
1910 m98095_eq_band(codec, channel, 0, coef_set->band1);
1911 m98095_eq_band(codec, channel, 1, coef_set->band2);
1912 m98095_eq_band(codec, channel, 2, coef_set->band3);
1913 m98095_eq_band(codec, channel, 3, coef_set->band4);
1914 m98095_eq_band(codec, channel, 4, coef_set->band5);
1915 snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, 0);
1916 mutex_unlock(&codec->mutex);
1917
1918 /* Restore the original on/off state */
1919 snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, regsave);
1920 return 0;
1921}
1922
1923static int max98095_get_eq_enum(struct snd_kcontrol *kcontrol,
1924 struct snd_ctl_elem_value *ucontrol)
1925{
1926 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1927 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1928 int channel = max98095_get_eq_channel(kcontrol->id.name);
1929 struct max98095_cdata *cdata;
1930
1931 cdata = &max98095->dai[channel];
1932 ucontrol->value.enumerated.item[0] = cdata->eq_sel;
1933
1934 return 0;
1935}
1936
1937static void max98095_handle_eq_pdata(struct snd_soc_codec *codec)
1938{
1939 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1940 struct max98095_pdata *pdata = max98095->pdata;
1941 struct max98095_eq_cfg *cfg;
1942 unsigned int cfgcnt;
1943 int i, j;
1944 const char **t;
1945 int ret;
1946
1947 struct snd_kcontrol_new controls[] = {
1948 SOC_ENUM_EXT("EQ1 Mode",
1949 max98095->eq_enum,
1950 max98095_get_eq_enum,
1951 max98095_put_eq_enum),
1952 SOC_ENUM_EXT("EQ2 Mode",
1953 max98095->eq_enum,
1954 max98095_get_eq_enum,
1955 max98095_put_eq_enum),
1956 };
1957
1958 cfg = pdata->eq_cfg;
1959 cfgcnt = pdata->eq_cfgcnt;
1960
1961 /* Setup an array of texts for the equalizer enum.
1962 * This is based on Mark Brown's equalizer driver code.
1963 */
1964 max98095->eq_textcnt = 0;
1965 max98095->eq_texts = NULL;
1966 for (i = 0; i < cfgcnt; i++) {
1967 for (j = 0; j < max98095->eq_textcnt; j++) {
1968 if (strcmp(cfg[i].name, max98095->eq_texts[j]) == 0)
1969 break;
1970 }
1971
1972 if (j != max98095->eq_textcnt)
1973 continue;
1974
1975 /* Expand the array */
1976 t = krealloc(max98095->eq_texts,
1977 sizeof(char *) * (max98095->eq_textcnt + 1),
1978 GFP_KERNEL);
1979 if (t == NULL)
1980 continue;
1981
1982 /* Store the new entry */
1983 t[max98095->eq_textcnt] = cfg[i].name;
1984 max98095->eq_textcnt++;
1985 max98095->eq_texts = t;
1986 }
1987
1988 /* Now point the soc_enum to .texts array items */
1989 max98095->eq_enum.texts = max98095->eq_texts;
1990 max98095->eq_enum.max = max98095->eq_textcnt;
1991
1992 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
1993 if (ret != 0)
1994 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
1995}
1996
1997static int max98095_get_bq_channel(const char *name)
1998{
1999 if (strcmp(name, "Biquad1 Mode") == 0)
2000 return 0;
2001 if (strcmp(name, "Biquad2 Mode") == 0)
2002 return 1;
2003 return -EINVAL;
2004}
2005
2006static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol,
2007 struct snd_ctl_elem_value *ucontrol)
2008{
2009 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2010 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2011 struct max98095_pdata *pdata = max98095->pdata;
2012 int channel = max98095_get_bq_channel(kcontrol->id.name);
2013 struct max98095_cdata *cdata;
2014 int sel = ucontrol->value.integer.value[0];
2015 struct max98095_biquad_cfg *coef_set;
2016 int fs, best, best_val, i;
2017 int regmask, regsave;
2018
2019 BUG_ON(channel > 1);
2020
2021 if (!pdata || !max98095->bq_textcnt)
2022 return 0;
2023
2024 if (sel >= pdata->bq_cfgcnt)
2025 return -EINVAL;
2026
2027 cdata = &max98095->dai[channel];
2028 cdata->bq_sel = sel;
2029 fs = cdata->rate;
2030
2031 /* Find the selected configuration with nearest sample rate */
2032 best = 0;
2033 best_val = INT_MAX;
2034 for (i = 0; i < pdata->bq_cfgcnt; i++) {
2035 if (strcmp(pdata->bq_cfg[i].name, max98095->bq_texts[sel]) == 0 &&
2036 abs(pdata->bq_cfg[i].rate - fs) < best_val) {
2037 best = i;
2038 best_val = abs(pdata->bq_cfg[i].rate - fs);
2039 }
2040 }
2041
2042 dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
2043 pdata->bq_cfg[best].name,
2044 pdata->bq_cfg[best].rate, fs);
2045
2046 coef_set = &pdata->bq_cfg[best];
2047
2048 regmask = (channel == 0) ? M98095_BQ1EN : M98095_BQ2EN;
2049
2050 /* Disable filter while configuring, and save current on/off state */
2051 regsave = snd_soc_read(codec, M98095_088_CFG_LEVEL);
2052 snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, 0);
2053
2054 mutex_lock(&codec->mutex);
2055 snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
2056 m98095_biquad_band(codec, channel, 0, coef_set->band1);
2057 m98095_biquad_band(codec, channel, 1, coef_set->band2);
2058 snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, 0);
2059 mutex_unlock(&codec->mutex);
2060
2061 /* Restore the original on/off state */
2062 snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, regsave);
2063 return 0;
2064}
2065
2066static int max98095_get_bq_enum(struct snd_kcontrol *kcontrol,
2067 struct snd_ctl_elem_value *ucontrol)
2068{
2069 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2070 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2071 int channel = max98095_get_bq_channel(kcontrol->id.name);
2072 struct max98095_cdata *cdata;
2073
2074 cdata = &max98095->dai[channel];
2075 ucontrol->value.enumerated.item[0] = cdata->bq_sel;
2076
2077 return 0;
2078}
2079
2080static void max98095_handle_bq_pdata(struct snd_soc_codec *codec)
2081{
2082 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2083 struct max98095_pdata *pdata = max98095->pdata;
2084 struct max98095_biquad_cfg *cfg;
2085 unsigned int cfgcnt;
2086 int i, j;
2087 const char **t;
2088 int ret;
2089
2090 struct snd_kcontrol_new controls[] = {
2091 SOC_ENUM_EXT("Biquad1 Mode",
2092 max98095->bq_enum,
2093 max98095_get_bq_enum,
2094 max98095_put_bq_enum),
2095 SOC_ENUM_EXT("Biquad2 Mode",
2096 max98095->bq_enum,
2097 max98095_get_bq_enum,
2098 max98095_put_bq_enum),
2099 };
2100
2101 cfg = pdata->bq_cfg;
2102 cfgcnt = pdata->bq_cfgcnt;
2103
2104 /* Setup an array of texts for the biquad enum.
2105 * This is based on Mark Brown's equalizer driver code.
2106 */
2107 max98095->bq_textcnt = 0;
2108 max98095->bq_texts = NULL;
2109 for (i = 0; i < cfgcnt; i++) {
2110 for (j = 0; j < max98095->bq_textcnt; j++) {
2111 if (strcmp(cfg[i].name, max98095->bq_texts[j]) == 0)
2112 break;
2113 }
2114
2115 if (j != max98095->bq_textcnt)
2116 continue;
2117
2118 /* Expand the array */
2119 t = krealloc(max98095->bq_texts,
2120 sizeof(char *) * (max98095->bq_textcnt + 1),
2121 GFP_KERNEL);
2122 if (t == NULL)
2123 continue;
2124
2125 /* Store the new entry */
2126 t[max98095->bq_textcnt] = cfg[i].name;
2127 max98095->bq_textcnt++;
2128 max98095->bq_texts = t;
2129 }
2130
2131 /* Now point the soc_enum to .texts array items */
2132 max98095->bq_enum.texts = max98095->bq_texts;
2133 max98095->bq_enum.max = max98095->bq_textcnt;
2134
2135 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
2136 if (ret != 0)
2137 dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret);
2138}
2139
2140static void max98095_handle_pdata(struct snd_soc_codec *codec)
2141{
2142 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2143 struct max98095_pdata *pdata = max98095->pdata;
2144 u8 regval = 0;
2145
2146 if (!pdata) {
2147 dev_dbg(codec->dev, "No platform data\n");
2148 return;
2149 }
2150
2151 /* Configure mic for analog/digital mic mode */
2152 if (pdata->digmic_left_mode)
2153 regval |= M98095_DIGMIC_L;
2154
2155 if (pdata->digmic_right_mode)
2156 regval |= M98095_DIGMIC_R;
2157
2158 snd_soc_write(codec, M98095_087_CFG_MIC, regval);
2159
2160 /* Configure equalizers */
2161 if (pdata->eq_cfgcnt)
2162 max98095_handle_eq_pdata(codec);
2163
2164 /* Configure bi-quad filters */
2165 if (pdata->bq_cfgcnt)
2166 max98095_handle_bq_pdata(codec);
2167}
2168
2169#ifdef CONFIG_PM
2170static int max98095_suspend(struct snd_soc_codec *codec, pm_message_t state)
2171{
2172 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
2173
2174 return 0;
2175}
2176
2177static int max98095_resume(struct snd_soc_codec *codec)
2178{
2179 max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2180
2181 return 0;
2182}
2183#else
2184#define max98095_suspend NULL
2185#define max98095_resume NULL
2186#endif
2187
2188static int max98095_reset(struct snd_soc_codec *codec)
2189{
2190 int i, ret;
2191
2192 /* Gracefully reset the DSP core and the codec hardware
2193 * in a proper sequence */
2194 ret = snd_soc_write(codec, M98095_00F_HOST_CFG, 0);
2195 if (ret < 0) {
2196 dev_err(codec->dev, "Failed to reset DSP: %d\n", ret);
2197 return ret;
2198 }
2199
2200 ret = snd_soc_write(codec, M98095_097_PWR_SYS, 0);
2201 if (ret < 0) {
2202 dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
2203 return ret;
2204 }
2205
2206 /* Reset to hardware default for registers, as there is not
2207 * a soft reset hardware control register */
2208 for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) {
2209 ret = snd_soc_write(codec, i, max98095_reg_def[i]);
2210 if (ret < 0) {
2211 dev_err(codec->dev, "Failed to reset: %d\n", ret);
2212 return ret;
2213 }
2214 }
2215
2216 return ret;
2217}
2218
2219static int max98095_probe(struct snd_soc_codec *codec)
2220{
2221 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2222 struct max98095_cdata *cdata;
2223 int ret = 0;
2224
2225 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
2226 if (ret != 0) {
2227 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2228 return ret;
2229 }
2230
2231 /* reset the codec, the DSP core, and disable all interrupts */
2232 max98095_reset(codec);
2233
2234 /* initialize private data */
2235
2236 max98095->sysclk = (unsigned)-1;
2237 max98095->eq_textcnt = 0;
2238 max98095->bq_textcnt = 0;
2239
2240 cdata = &max98095->dai[0];
2241 cdata->rate = (unsigned)-1;
2242 cdata->fmt = (unsigned)-1;
2243 cdata->eq_sel = 0;
2244 cdata->bq_sel = 0;
2245
2246 cdata = &max98095->dai[1];
2247 cdata->rate = (unsigned)-1;
2248 cdata->fmt = (unsigned)-1;
2249 cdata->eq_sel = 0;
2250 cdata->bq_sel = 0;
2251
2252 cdata = &max98095->dai[2];
2253 cdata->rate = (unsigned)-1;
2254 cdata->fmt = (unsigned)-1;
2255 cdata->eq_sel = 0;
2256 cdata->bq_sel = 0;
2257
2258 max98095->lin_state = 0;
2259 max98095->mic1pre = 0;
2260 max98095->mic2pre = 0;
2261
2262 ret = snd_soc_read(codec, M98095_0FF_REV_ID);
2263 if (ret < 0) {
2264 dev_err(codec->dev, "Failed to read device revision: %d\n",
2265 ret);
2266 goto err_access;
2267 }
2268 dev_info(codec->dev, "revision %c\n", ret + 'A');
2269
2270 snd_soc_write(codec, M98095_097_PWR_SYS, M98095_PWRSV);
2271
2272 /* initialize registers cache to hardware default */
2273 max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2274
2275 snd_soc_write(codec, M98095_048_MIX_DAC_LR,
2276 M98095_DAI1L_TO_DACL|M98095_DAI1R_TO_DACR);
2277
2278 snd_soc_write(codec, M98095_049_MIX_DAC_M,
2279 M98095_DAI2M_TO_DACM|M98095_DAI3M_TO_DACM);
2280
2281 snd_soc_write(codec, M98095_092_PWR_EN_OUT, M98095_SPK_SPREADSPECTRUM);
2282 snd_soc_write(codec, M98095_045_CFG_DSP, M98095_DSPNORMAL);
2283 snd_soc_write(codec, M98095_04E_CFG_HP, M98095_HPNORMAL);
2284
2285 snd_soc_write(codec, M98095_02C_DAI1_IOCFG,
2286 M98095_S1NORMAL|M98095_SDATA);
2287
2288 snd_soc_write(codec, M98095_036_DAI2_IOCFG,
2289 M98095_S2NORMAL|M98095_SDATA);
2290
2291 snd_soc_write(codec, M98095_040_DAI3_IOCFG,
2292 M98095_S3NORMAL|M98095_SDATA);
2293
2294 max98095_handle_pdata(codec);
2295
2296 /* take the codec out of the shut down */
2297 snd_soc_update_bits(codec, M98095_097_PWR_SYS, M98095_SHDNRUN,
2298 M98095_SHDNRUN);
2299
2300 max98095_add_widgets(codec);
2301
2302err_access:
2303 return ret;
2304}
2305
2306static int max98095_remove(struct snd_soc_codec *codec)
2307{
2308 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
2309
2310 return 0;
2311}
2312
2313static struct snd_soc_codec_driver soc_codec_dev_max98095 = {
2314 .probe = max98095_probe,
2315 .remove = max98095_remove,
2316 .suspend = max98095_suspend,
2317 .resume = max98095_resume,
2318 .set_bias_level = max98095_set_bias_level,
2319 .reg_cache_size = ARRAY_SIZE(max98095_reg_def),
2320 .reg_word_size = sizeof(u8),
2321 .reg_cache_default = max98095_reg_def,
2322 .readable_register = max98095_readable,
2323 .volatile_register = max98095_volatile,
2324 .dapm_widgets = max98095_dapm_widgets,
2325 .num_dapm_widgets = ARRAY_SIZE(max98095_dapm_widgets),
2326 .dapm_routes = max98095_audio_map,
2327 .num_dapm_routes = ARRAY_SIZE(max98095_audio_map),
2328};
2329
2330static int max98095_i2c_probe(struct i2c_client *i2c,
2331 const struct i2c_device_id *id)
2332{
2333 struct max98095_priv *max98095;
2334 int ret;
2335
2336 max98095 = kzalloc(sizeof(struct max98095_priv), GFP_KERNEL);
2337 if (max98095 == NULL)
2338 return -ENOMEM;
2339
2340 max98095->devtype = id->driver_data;
2341 i2c_set_clientdata(i2c, max98095);
2342 max98095->control_data = i2c;
2343 max98095->pdata = i2c->dev.platform_data;
2344
2345 ret = snd_soc_register_codec(&i2c->dev,
2346 &soc_codec_dev_max98095, &max98095_dai[0], 3);
2347 if (ret < 0)
2348 kfree(max98095);
2349 return ret;
2350}
2351
2352static int __devexit max98095_i2c_remove(struct i2c_client *client)
2353{
2354 snd_soc_unregister_codec(&client->dev);
2355 kfree(i2c_get_clientdata(client));
2356
2357 return 0;
2358}
2359
2360static const struct i2c_device_id max98095_i2c_id[] = {
2361 { "max98095", MAX98095 },
2362 { }
2363};
2364MODULE_DEVICE_TABLE(i2c, max98095_i2c_id);
2365
2366static struct i2c_driver max98095_i2c_driver = {
2367 .driver = {
2368 .name = "max98095",
2369 .owner = THIS_MODULE,
2370 },
2371 .probe = max98095_i2c_probe,
2372 .remove = __devexit_p(max98095_i2c_remove),
2373 .id_table = max98095_i2c_id,
2374};
2375
2376static int __init max98095_init(void)
2377{
2378 int ret;
2379
2380 ret = i2c_add_driver(&max98095_i2c_driver);
2381 if (ret)
2382 pr_err("Failed to register max98095 I2C driver: %d\n", ret);
2383
2384 return ret;
2385}
2386module_init(max98095_init);
2387
2388static void __exit max98095_exit(void)
2389{
2390 i2c_del_driver(&max98095_i2c_driver);
2391}
2392module_exit(max98095_exit);
2393
2394MODULE_DESCRIPTION("ALSA SoC MAX98095 driver");
2395MODULE_AUTHOR("Peter Hsiang");
2396MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98095.h b/sound/soc/codecs/max98095.h
new file mode 100644
index 000000000000..891584a0eb03
--- /dev/null
+++ b/sound/soc/codecs/max98095.h
@@ -0,0 +1,299 @@
1/*
2 * max98095.h -- MAX98095 ALSA SoC Audio driver
3 *
4 * Copyright 2011 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _MAX98095_H
12#define _MAX98095_H
13
14/*
15 * MAX98095 Registers Definition
16 */
17
18#define M98095_000_HOST_DATA 0x00
19#define M98095_001_HOST_INT_STS 0x01
20#define M98095_002_HOST_RSP_STS 0x02
21#define M98095_003_HOST_CMD_STS 0x03
22#define M98095_004_CODEC_STS 0x04
23#define M98095_005_DAI1_ALC_STS 0x05
24#define M98095_006_DAI2_ALC_STS 0x06
25#define M98095_007_JACK_AUTO_STS 0x07
26#define M98095_008_JACK_MANUAL_STS 0x08
27#define M98095_009_JACK_VBAT_STS 0x09
28#define M98095_00A_ACC_ADC_STS 0x0A
29#define M98095_00B_MIC_NG_AGC_STS 0x0B
30#define M98095_00C_SPK_L_VOLT_STS 0x0C
31#define M98095_00D_SPK_R_VOLT_STS 0x0D
32#define M98095_00E_TEMP_SENSOR_STS 0x0E
33#define M98095_00F_HOST_CFG 0x0F
34#define M98095_010_HOST_INT_CFG 0x10
35#define M98095_011_HOST_INT_EN 0x11
36#define M98095_012_CODEC_INT_EN 0x12
37#define M98095_013_JACK_INT_EN 0x13
38#define M98095_014_JACK_INT_EN 0x14
39#define M98095_015_DEC 0x15
40#define M98095_016_RESERVED 0x16
41#define M98095_017_RESERVED 0x17
42#define M98095_018_KEYCODE3 0x18
43#define M98095_019_KEYCODE2 0x19
44#define M98095_01A_KEYCODE1 0x1A
45#define M98095_01B_KEYCODE0 0x1B
46#define M98095_01C_OEMCODE1 0x1C
47#define M98095_01D_OEMCODE0 0x1D
48#define M98095_01E_XCFG1 0x1E
49#define M98095_01F_XCFG2 0x1F
50#define M98095_020_XCFG3 0x20
51#define M98095_021_XCFG4 0x21
52#define M98095_022_XCFG5 0x22
53#define M98095_023_XCFG6 0x23
54#define M98095_024_XGPIO 0x24
55#define M98095_025_XCLKCFG 0x25
56#define M98095_026_SYS_CLK 0x26
57#define M98095_027_DAI1_CLKMODE 0x27
58#define M98095_028_DAI1_CLKCFG_HI 0x28
59#define M98095_029_DAI1_CLKCFG_LO 0x29
60#define M98095_02A_DAI1_FORMAT 0x2A
61#define M98095_02B_DAI1_CLOCK 0x2B
62#define M98095_02C_DAI1_IOCFG 0x2C
63#define M98095_02D_DAI1_TDM 0x2D
64#define M98095_02E_DAI1_FILTERS 0x2E
65#define M98095_02F_DAI1_LVL1 0x2F
66#define M98095_030_DAI1_LVL2 0x30
67#define M98095_031_DAI2_CLKMODE 0x31
68#define M98095_032_DAI2_CLKCFG_HI 0x32
69#define M98095_033_DAI2_CLKCFG_LO 0x33
70#define M98095_034_DAI2_FORMAT 0x34
71#define M98095_035_DAI2_CLOCK 0x35
72#define M98095_036_DAI2_IOCFG 0x36
73#define M98095_037_DAI2_TDM 0x37
74#define M98095_038_DAI2_FILTERS 0x38
75#define M98095_039_DAI2_LVL1 0x39
76#define M98095_03A_DAI2_LVL2 0x3A
77#define M98095_03B_DAI3_CLKMODE 0x3B
78#define M98095_03C_DAI3_CLKCFG_HI 0x3C
79#define M98095_03D_DAI3_CLKCFG_LO 0x3D
80#define M98095_03E_DAI3_FORMAT 0x3E
81#define M98095_03F_DAI3_CLOCK 0x3F
82#define M98095_040_DAI3_IOCFG 0x40
83#define M98095_041_DAI3_TDM 0x41
84#define M98095_042_DAI3_FILTERS 0x42
85#define M98095_043_DAI3_LVL1 0x43
86#define M98095_044_DAI3_LVL2 0x44
87#define M98095_045_CFG_DSP 0x45
88#define M98095_046_DAC_CTRL1 0x46
89#define M98095_047_DAC_CTRL2 0x47
90#define M98095_048_MIX_DAC_LR 0x48
91#define M98095_049_MIX_DAC_M 0x49
92#define M98095_04A_MIX_ADC_LEFT 0x4A
93#define M98095_04B_MIX_ADC_RIGHT 0x4B
94#define M98095_04C_MIX_HP_LEFT 0x4C
95#define M98095_04D_MIX_HP_RIGHT 0x4D
96#define M98095_04E_CFG_HP 0x4E
97#define M98095_04F_MIX_RCV 0x4F
98#define M98095_050_MIX_SPK_LEFT 0x50
99#define M98095_051_MIX_SPK_RIGHT 0x51
100#define M98095_052_MIX_SPK_CFG 0x52
101#define M98095_053_MIX_LINEOUT1 0x53
102#define M98095_054_MIX_LINEOUT2 0x54
103#define M98095_055_MIX_LINEOUT_CFG 0x55
104#define M98095_056_LVL_SIDETONE_DAI12 0x56
105#define M98095_057_LVL_SIDETONE_DAI3 0x57
106#define M98095_058_LVL_DAI1_PLAY 0x58
107#define M98095_059_LVL_DAI1_EQ 0x59
108#define M98095_05A_LVL_DAI2_PLAY 0x5A
109#define M98095_05B_LVL_DAI2_EQ 0x5B
110#define M98095_05C_LVL_DAI3_PLAY 0x5C
111#define M98095_05D_LVL_ADC_L 0x5D
112#define M98095_05E_LVL_ADC_R 0x5E
113#define M98095_05F_LVL_MIC1 0x5F
114#define M98095_060_LVL_MIC2 0x60
115#define M98095_061_LVL_LINEIN 0x61
116#define M98095_062_LVL_LINEOUT1 0x62
117#define M98095_063_LVL_LINEOUT2 0x63
118#define M98095_064_LVL_HP_L 0x64
119#define M98095_065_LVL_HP_R 0x65
120#define M98095_066_LVL_RCV 0x66
121#define M98095_067_LVL_SPK_L 0x67
122#define M98095_068_LVL_SPK_R 0x68
123#define M98095_069_MICAGC_CFG 0x69
124#define M98095_06A_MICAGC_THRESH 0x6A
125#define M98095_06B_SPK_NOISEGATE 0x6B
126#define M98095_06C_DAI1_ALC1_TIME 0x6C
127#define M98095_06D_DAI1_ALC1_COMP 0x6D
128#define M98095_06E_DAI1_ALC1_EXPN 0x6E
129#define M98095_06F_DAI1_ALC1_GAIN 0x6F
130#define M98095_070_DAI1_ALC2_TIME 0x70
131#define M98095_071_DAI1_ALC2_COMP 0x71
132#define M98095_072_DAI1_ALC2_EXPN 0x72
133#define M98095_073_DAI1_ALC2_GAIN 0x73
134#define M98095_074_DAI1_ALC3_TIME 0x74
135#define M98095_075_DAI1_ALC3_COMP 0x75
136#define M98095_076_DAI1_ALC3_EXPN 0x76
137#define M98095_077_DAI1_ALC3_GAIN 0x77
138#define M98095_078_DAI2_ALC1_TIME 0x78
139#define M98095_079_DAI2_ALC1_COMP 0x79
140#define M98095_07A_DAI2_ALC1_EXPN 0x7A
141#define M98095_07B_DAI2_ALC1_GAIN 0x7B
142#define M98095_07C_DAI2_ALC2_TIME 0x7C
143#define M98095_07D_DAI2_ALC2_COMP 0x7D
144#define M98095_07E_DAI2_ALC2_EXPN 0x7E
145#define M98095_07F_DAI2_ALC2_GAIN 0x7F
146#define M98095_080_DAI2_ALC3_TIME 0x80
147#define M98095_081_DAI2_ALC3_COMP 0x81
148#define M98095_082_DAI2_ALC3_EXPN 0x82
149#define M98095_083_DAI2_ALC3_GAIN 0x83
150#define M98095_084_HP_NOISE_GATE 0x84
151#define M98095_085_AUX_ADC 0x85
152#define M98095_086_CFG_LINE 0x86
153#define M98095_087_CFG_MIC 0x87
154#define M98095_088_CFG_LEVEL 0x88
155#define M98095_089_JACK_DET_AUTO 0x89
156#define M98095_08A_JACK_DET_MANUAL 0x8A
157#define M98095_08B_JACK_KEYSCAN_DBC 0x8B
158#define M98095_08C_JACK_KEYSCAN_DLY 0x8C
159#define M98095_08D_JACK_KEY_THRESH 0x8D
160#define M98095_08E_JACK_DC_SLEW 0x8E
161#define M98095_08F_JACK_TEST_CFG 0x8F
162#define M98095_090_PWR_EN_IN 0x90
163#define M98095_091_PWR_EN_OUT 0x91
164#define M98095_092_PWR_EN_OUT 0x92
165#define M98095_093_BIAS_CTRL 0x93
166#define M98095_094_PWR_DAC_21 0x94
167#define M98095_095_PWR_DAC_03 0x95
168#define M98095_096_PWR_DAC_CK 0x96
169#define M98095_097_PWR_SYS 0x97
170
171#define M98095_0FF_REV_ID 0xFF
172
173#define M98095_REG_CNT (0xFF+1)
174#define M98095_REG_MAX_CACHED 0X97
175
176/* MAX98095 Registers Bit Fields */
177
178/* M98095_00F_HOST_CFG */
179 #define M98095_SEG (1<<0)
180 #define M98095_XTEN (1<<1)
181 #define M98095_MDLLEN (1<<2)
182
183/* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */
184 #define M98095_CLKMODE_MASK 0xFF
185
186/* M98095_02A_DAI1_FORMAT, M98095_034_DAI2_FORMAT, M98095_03E_DAI3_FORMAT */
187 #define M98095_DAI_MAS (1<<7)
188 #define M98095_DAI_WCI (1<<6)
189 #define M98095_DAI_BCI (1<<5)
190 #define M98095_DAI_DLY (1<<4)
191 #define M98095_DAI_TDM (1<<2)
192 #define M98095_DAI_FSW (1<<1)
193 #define M98095_DAI_WS (1<<0)
194
195/* M98095_02B_DAI1_CLOCK, M98095_035_DAI2_CLOCK, M98095_03F_DAI3_CLOCK */
196 #define M98095_DAI_BSEL64 (1<<0)
197 #define M98095_DAI_DOSR_DIV2 (0<<5)
198 #define M98095_DAI_DOSR_DIV4 (1<<5)
199
200/* M98095_02C_DAI1_IOCFG, M98095_036_DAI2_IOCFG, M98095_040_DAI3_IOCFG */
201 #define M98095_S1NORMAL (1<<6)
202 #define M98095_S2NORMAL (2<<6)
203 #define M98095_S3NORMAL (3<<6)
204 #define M98095_SDATA (3<<0)
205
206/* M98095_02E_DAI1_FILTERS, M98095_038_DAI2_FILTERS, M98095_042_DAI3_FILTERS */
207 #define M98095_DAI_DHF (1<<3)
208
209/* M98095_045_DSP_CFG */
210 #define M98095_DSPNORMAL (5<<4)
211
212/* M98095_048_MIX_DAC_LR */
213 #define M98095_DAI1L_TO_DACR (1<<7)
214 #define M98095_DAI1R_TO_DACR (1<<6)
215 #define M98095_DAI2M_TO_DACR (1<<5)
216 #define M98095_DAI1L_TO_DACL (1<<3)
217 #define M98095_DAI1R_TO_DACL (1<<2)
218 #define M98095_DAI2M_TO_DACL (1<<1)
219 #define M98095_DAI3M_TO_DACL (1<<0)
220
221/* M98095_049_MIX_DAC_M */
222 #define M98095_DAI1L_TO_DACM (1<<3)
223 #define M98095_DAI1R_TO_DACM (1<<2)
224 #define M98095_DAI2M_TO_DACM (1<<1)
225 #define M98095_DAI3M_TO_DACM (1<<0)
226
227/* M98095_04E_MIX_HP_CFG */
228 #define M98095_HPNORMAL (3<<4)
229
230/* M98095_05F_LVL_MIC1, M98095_060_LVL_MIC2 */
231 #define M98095_MICPRE_MASK (3<<5)
232 #define M98095_MICPRE_SHIFT 5
233
234/* M98095_064_LVL_HP_L, M98095_065_LVL_HP_R */
235 #define M98095_HP_MUTE (1<<7)
236
237/* M98095_066_LVL_RCV */
238 #define M98095_REC_MUTE (1<<7)
239
240/* M98095_067_LVL_SPK_L, M98095_068_LVL_SPK_R */
241 #define M98095_SP_MUTE (1<<7)
242
243/* M98095_087_CFG_MIC */
244 #define M98095_MICSEL_MASK (3<<0)
245 #define M98095_DIGMIC_L (1<<2)
246 #define M98095_DIGMIC_R (1<<3)
247 #define M98095_DIGMIC2L (1<<4)
248 #define M98095_DIGMIC2R (1<<5)
249
250/* M98095_088_CFG_LEVEL */
251 #define M98095_VSEN (1<<6)
252 #define M98095_ZDEN (1<<5)
253 #define M98095_BQ2EN (1<<3)
254 #define M98095_BQ1EN (1<<2)
255 #define M98095_EQ2EN (1<<1)
256 #define M98095_EQ1EN (1<<0)
257
258/* M98095_090_PWR_EN_IN */
259 #define M98095_INEN (1<<7)
260 #define M98095_MB2EN (1<<3)
261 #define M98095_MB1EN (1<<2)
262 #define M98095_MBEN (3<<2)
263 #define M98095_ADREN (1<<1)
264 #define M98095_ADLEN (1<<0)
265
266/* M98095_091_PWR_EN_OUT */
267 #define M98095_HPLEN (1<<7)
268 #define M98095_HPREN (1<<6)
269 #define M98095_SPLEN (1<<5)
270 #define M98095_SPREN (1<<4)
271 #define M98095_RECEN (1<<3)
272 #define M98095_DALEN (1<<1)
273 #define M98095_DAREN (1<<0)
274
275/* M98095_092_PWR_EN_OUT */
276 #define M98095_SPK_FIXEDSPECTRUM (0<<4)
277 #define M98095_SPK_SPREADSPECTRUM (1<<4)
278
279/* M98095_097_PWR_SYS */
280 #define M98095_SHDNRUN (1<<7)
281 #define M98095_PERFMODE (1<<3)
282 #define M98095_HPPLYBACK (1<<2)
283 #define M98095_PWRSV8K (1<<1)
284 #define M98095_PWRSV (1<<0)
285
286#define M98095_COEFS_PER_BAND 5
287
288#define M98095_BYTE1(w) ((w >> 8) & 0xff)
289#define M98095_BYTE0(w) (w & 0xff)
290
291/* Equalizer filter coefficients */
292#define M98095_110_DAI1_EQ_BASE 0x10
293#define M98095_142_DAI2_EQ_BASE 0x42
294
295/* Biquad filter coefficients */
296#define M98095_174_DAI1_BQ_BASE 0x74
297#define M98095_17E_DAI2_BQ_BASE 0x7E
298
299#endif
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index 4d9fb279e146..84ffdebb8a8b 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -827,8 +827,6 @@ EXPORT_SYMBOL_GPL(sn95031_jack_detection);
827/* codec registration */ 827/* codec registration */
828static int sn95031_codec_probe(struct snd_soc_codec *codec) 828static int sn95031_codec_probe(struct snd_soc_codec *codec)
829{ 829{
830 int ret;
831
832 pr_debug("codec_probe called\n"); 830 pr_debug("codec_probe called\n");
833 831
834 codec->dapm.bias_level = SND_SOC_BIAS_OFF; 832 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
@@ -879,16 +877,7 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
879 snd_soc_add_controls(codec, sn95031_snd_controls, 877 snd_soc_add_controls(codec, sn95031_snd_controls,
880 ARRAY_SIZE(sn95031_snd_controls)); 878 ARRAY_SIZE(sn95031_snd_controls));
881 879
882 ret = snd_soc_dapm_new_controls(&codec->dapm, sn95031_dapm_widgets, 880 return 0;
883 ARRAY_SIZE(sn95031_dapm_widgets));
884 if (ret)
885 pr_err("soc_dapm_new_control failed %d", ret);
886 ret = snd_soc_dapm_add_routes(&codec->dapm, sn95031_audio_map,
887 ARRAY_SIZE(sn95031_audio_map));
888 if (ret)
889 pr_err("soc_dapm_add_routes failed %d", ret);
890
891 return ret;
892} 881}
893 882
894static int sn95031_codec_remove(struct snd_soc_codec *codec) 883static int sn95031_codec_remove(struct snd_soc_codec *codec)
@@ -905,6 +894,10 @@ struct snd_soc_codec_driver sn95031_codec = {
905 .read = sn95031_read, 894 .read = sn95031_read,
906 .write = sn95031_write, 895 .write = sn95031_write,
907 .set_bias_level = sn95031_set_vaud_bias, 896 .set_bias_level = sn95031_set_vaud_bias,
897 .dapm_widgets = sn95031_dapm_widgets,
898 .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets),
899 .dapm_routes = sn95031_audio_map,
900 .num_dapm_routes = ARRAY_SIZE(sn95031_audio_map),
908}; 901};
909 902
910static int __devinit sn95031_device_probe(struct platform_device *pdev) 903static int __devinit sn95031_device_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transciever.c
index 4c32b54913ad..6a1a7e705cd7 100644
--- a/sound/soc/codecs/spdif_transciever.c
+++ b/sound/soc/codecs/spdif_transciever.c
@@ -21,7 +21,7 @@
21#include <sound/pcm.h> 21#include <sound/pcm.h>
22#include <sound/initval.h> 22#include <sound/initval.h>
23 23
24MODULE_LICENSE("GPL"); 24#define DRV_NAME "spdif-dit"
25 25
26#define STUB_RATES SNDRV_PCM_RATE_8000_96000 26#define STUB_RATES SNDRV_PCM_RATE_8000_96000
27#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE 27#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE
@@ -56,7 +56,7 @@ static struct platform_driver spdif_dit_driver = {
56 .probe = spdif_dit_probe, 56 .probe = spdif_dit_probe,
57 .remove = spdif_dit_remove, 57 .remove = spdif_dit_remove,
58 .driver = { 58 .driver = {
59 .name = "spdif-dit", 59 .name = DRV_NAME,
60 .owner = THIS_MODULE, 60 .owner = THIS_MODULE,
61 }, 61 },
62}; 62};
@@ -74,3 +74,7 @@ static void __exit dit_exit(void)
74module_init(dit_modinit); 74module_init(dit_modinit);
75module_exit(dit_exit); 75module_exit(dit_exit);
76 76
77MODULE_AUTHOR("Steve Chen <schen@mvista.com>");
78MODULE_DESCRIPTION("SPDIF dummy codec driver");
79MODULE_LICENSE("GPL");
80MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index b04d28039c16..84f4ad568556 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -32,6 +32,7 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/pm.h> 33#include <linux/pm.h>
34#include <linux/i2c.h> 34#include <linux/i2c.h>
35#include <linux/spi/spi.h>
35#include <linux/platform_device.h> 36#include <linux/platform_device.h>
36#include <linux/slab.h> 37#include <linux/slab.h>
37#include <sound/core.h> 38#include <sound/core.h>
@@ -39,18 +40,25 @@
39#include <sound/pcm_params.h> 40#include <sound/pcm_params.h>
40#include <sound/soc.h> 41#include <sound/soc.h>
41#include <sound/initval.h> 42#include <sound/initval.h>
43#include <sound/tlv.h>
42 44
43#include "ssm2602.h" 45#include "ssm2602.h"
44 46
45#define SSM2602_VERSION "0.1" 47#define SSM2602_VERSION "0.1"
46 48
49enum ssm2602_type {
50 SSM2602,
51 SSM2604,
52};
53
47/* codec private data */ 54/* codec private data */
48struct ssm2602_priv { 55struct ssm2602_priv {
49 unsigned int sysclk; 56 unsigned int sysclk;
50 enum snd_soc_control_type control_type; 57 enum snd_soc_control_type control_type;
51 void *control_data;
52 struct snd_pcm_substream *master_substream; 58 struct snd_pcm_substream *master_substream;
53 struct snd_pcm_substream *slave_substream; 59 struct snd_pcm_substream *slave_substream;
60
61 enum ssm2602_type type;
54}; 62};
55 63
56/* 64/*
@@ -60,60 +68,12 @@ struct ssm2602_priv {
60 * There is no point in caching the reset register 68 * There is no point in caching the reset register
61 */ 69 */
62static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = { 70static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = {
63 0x0017, 0x0017, 0x0079, 0x0079, 71 0x0097, 0x0097, 0x0079, 0x0079,
64 0x0000, 0x0000, 0x0000, 0x000a, 72 0x000a, 0x0008, 0x009f, 0x000a,
65 0x0000, 0x0000 73 0x0000, 0x0000
66}; 74};
67 75
68/* 76#define ssm2602_reset(c) snd_soc_write(c, SSM2602_RESET, 0)
69 * read ssm2602 register cache
70 */
71static inline unsigned int ssm2602_read_reg_cache(struct snd_soc_codec *codec,
72 unsigned int reg)
73{
74 u16 *cache = codec->reg_cache;
75 if (reg == SSM2602_RESET)
76 return 0;
77 if (reg >= SSM2602_CACHEREGNUM)
78 return -1;
79 return cache[reg];
80}
81
82/*
83 * write ssm2602 register cache
84 */
85static inline void ssm2602_write_reg_cache(struct snd_soc_codec *codec,
86 u16 reg, unsigned int value)
87{
88 u16 *cache = codec->reg_cache;
89 if (reg >= SSM2602_CACHEREGNUM)
90 return;
91 cache[reg] = value;
92}
93
94/*
95 * write to the ssm2602 register space
96 */
97static int ssm2602_write(struct snd_soc_codec *codec, unsigned int reg,
98 unsigned int value)
99{
100 u8 data[2];
101
102 /* data is
103 * D15..D9 ssm2602 register offset
104 * D8...D0 register data
105 */
106 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
107 data[1] = value & 0x00ff;
108
109 ssm2602_write_reg_cache(codec, reg, value);
110 if (codec->hw_write(codec->control_data, data, 2) == 2)
111 return 0;
112 else
113 return -EIO;
114}
115
116#define ssm2602_reset(c) ssm2602_write(c, SSM2602_RESET, 0)
117 77
118/*Appending several "None"s just for OSS mixer use*/ 78/*Appending several "None"s just for OSS mixer use*/
119static const char *ssm2602_input_select[] = { 79static const char *ssm2602_input_select[] = {
@@ -128,174 +88,187 @@ static const struct soc_enum ssm2602_enum[] = {
128 SOC_ENUM_SINGLE(SSM2602_APDIGI, 1, 4, ssm2602_deemph), 88 SOC_ENUM_SINGLE(SSM2602_APDIGI, 1, 4, ssm2602_deemph),
129}; 89};
130 90
131static const struct snd_kcontrol_new ssm2602_snd_controls[] = { 91static const unsigned int ssm260x_outmix_tlv[] = {
92 TLV_DB_RANGE_HEAD(2),
93 0, 47, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),
94 48, 127, TLV_DB_SCALE_ITEM(-7400, 100, 0),
95};
132 96
133SOC_DOUBLE_R("Master Playback Volume", SSM2602_LOUT1V, SSM2602_ROUT1V, 97static const DECLARE_TLV_DB_SCALE(ssm260x_inpga_tlv, -3450, 150, 0);
134 0, 127, 0), 98static const DECLARE_TLV_DB_SCALE(ssm260x_sidetone_tlv, -1500, 300, 0);
135SOC_DOUBLE_R("Master Playback ZC Switch", SSM2602_LOUT1V, SSM2602_ROUT1V,
136 7, 1, 0),
137 99
138SOC_DOUBLE_R("Capture Volume", SSM2602_LINVOL, SSM2602_RINVOL, 0, 31, 0), 100static const struct snd_kcontrol_new ssm260x_snd_controls[] = {
101SOC_DOUBLE_R_TLV("Capture Volume", SSM2602_LINVOL, SSM2602_RINVOL, 0, 45, 0,
102 ssm260x_inpga_tlv),
139SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1), 103SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1),
140 104
141SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0),
142SOC_SINGLE("Mic Boost2 (+20dB)", SSM2602_APANA, 8, 1, 0),
143SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1),
144
145SOC_SINGLE("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1),
146
147SOC_SINGLE("ADC High Pass Filter Switch", SSM2602_APDIGI, 0, 1, 1), 105SOC_SINGLE("ADC High Pass Filter Switch", SSM2602_APDIGI, 0, 1, 1),
148SOC_SINGLE("Store DC Offset Switch", SSM2602_APDIGI, 4, 1, 0), 106SOC_SINGLE("Store DC Offset Switch", SSM2602_APDIGI, 4, 1, 0),
149 107
150SOC_ENUM("Capture Source", ssm2602_enum[0]),
151
152SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]), 108SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]),
153}; 109};
154 110
111static const struct snd_kcontrol_new ssm2602_snd_controls[] = {
112SOC_DOUBLE_R_TLV("Master Playback Volume", SSM2602_LOUT1V, SSM2602_ROUT1V,
113 0, 127, 0, ssm260x_outmix_tlv),
114SOC_DOUBLE_R("Master Playback ZC Switch", SSM2602_LOUT1V, SSM2602_ROUT1V,
115 7, 1, 0),
116SOC_SINGLE_TLV("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1,
117 ssm260x_sidetone_tlv),
118
119SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0),
120SOC_SINGLE("Mic Boost2 (+20dB)", SSM2602_APANA, 8, 1, 0),
121SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1),
122};
123
155/* Output Mixer */ 124/* Output Mixer */
156static const struct snd_kcontrol_new ssm2602_output_mixer_controls[] = { 125static const struct snd_kcontrol_new ssm260x_output_mixer_controls[] = {
157SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0), 126SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0),
158SOC_DAPM_SINGLE("Mic Sidetone Switch", SSM2602_APANA, 5, 1, 0),
159SOC_DAPM_SINGLE("HiFi Playback Switch", SSM2602_APANA, 4, 1, 0), 127SOC_DAPM_SINGLE("HiFi Playback Switch", SSM2602_APANA, 4, 1, 0),
128SOC_DAPM_SINGLE("Mic Sidetone Switch", SSM2602_APANA, 5, 1, 0),
160}; 129};
161 130
162/* Input mux */ 131/* Input mux */
163static const struct snd_kcontrol_new ssm2602_input_mux_controls = 132static const struct snd_kcontrol_new ssm2602_input_mux_controls =
164SOC_DAPM_ENUM("Input Select", ssm2602_enum[0]); 133SOC_DAPM_ENUM("Input Select", ssm2602_enum[0]);
165 134
166static const struct snd_soc_dapm_widget ssm2602_dapm_widgets[] = { 135static const struct snd_soc_dapm_widget ssm260x_dapm_widgets[] = {
167SND_SOC_DAPM_MIXER("Output Mixer", SSM2602_PWR, 4, 1,
168 &ssm2602_output_mixer_controls[0],
169 ARRAY_SIZE(ssm2602_output_mixer_controls)),
170SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM2602_PWR, 3, 1), 136SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM2602_PWR, 3, 1),
137SND_SOC_DAPM_ADC("ADC", "HiFi Capture", SSM2602_PWR, 2, 1),
138SND_SOC_DAPM_PGA("Line Input", SSM2602_PWR, 0, 1, NULL, 0),
139
140SND_SOC_DAPM_SUPPLY("Digital Core Power", SSM2602_ACTIVE, 0, 0, NULL, 0),
141
171SND_SOC_DAPM_OUTPUT("LOUT"), 142SND_SOC_DAPM_OUTPUT("LOUT"),
172SND_SOC_DAPM_OUTPUT("LHPOUT"),
173SND_SOC_DAPM_OUTPUT("ROUT"), 143SND_SOC_DAPM_OUTPUT("ROUT"),
174SND_SOC_DAPM_OUTPUT("RHPOUT"), 144SND_SOC_DAPM_INPUT("RLINEIN"),
175SND_SOC_DAPM_ADC("ADC", "HiFi Capture", SSM2602_PWR, 2, 1), 145SND_SOC_DAPM_INPUT("LLINEIN"),
146};
147
148static const struct snd_soc_dapm_widget ssm2602_dapm_widgets[] = {
149SND_SOC_DAPM_MIXER("Output Mixer", SSM2602_PWR, 4, 1,
150 ssm260x_output_mixer_controls,
151 ARRAY_SIZE(ssm260x_output_mixer_controls)),
152
176SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &ssm2602_input_mux_controls), 153SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &ssm2602_input_mux_controls),
177SND_SOC_DAPM_PGA("Line Input", SSM2602_PWR, 0, 1, NULL, 0),
178SND_SOC_DAPM_MICBIAS("Mic Bias", SSM2602_PWR, 1, 1), 154SND_SOC_DAPM_MICBIAS("Mic Bias", SSM2602_PWR, 1, 1),
155
156SND_SOC_DAPM_OUTPUT("LHPOUT"),
157SND_SOC_DAPM_OUTPUT("RHPOUT"),
179SND_SOC_DAPM_INPUT("MICIN"), 158SND_SOC_DAPM_INPUT("MICIN"),
180SND_SOC_DAPM_INPUT("RLINEIN"),
181SND_SOC_DAPM_INPUT("LLINEIN"),
182}; 159};
183 160
184static const struct snd_soc_dapm_route audio_conn[] = { 161static const struct snd_soc_dapm_widget ssm2604_dapm_widgets[] = {
185 /* output mixer */ 162SND_SOC_DAPM_MIXER("Output Mixer", SND_SOC_NOPM, 0, 0,
163 ssm260x_output_mixer_controls,
164 ARRAY_SIZE(ssm260x_output_mixer_controls) - 1), /* Last element is the mic */
165};
166
167static const struct snd_soc_dapm_route ssm260x_routes[] = {
168 {"DAC", NULL, "Digital Core Power"},
169 {"ADC", NULL, "Digital Core Power"},
170
186 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 171 {"Output Mixer", "Line Bypass Switch", "Line Input"},
187 {"Output Mixer", "HiFi Playback Switch", "DAC"}, 172 {"Output Mixer", "HiFi Playback Switch", "DAC"},
173
174 {"ROUT", NULL, "Output Mixer"},
175 {"LOUT", NULL, "Output Mixer"},
176
177 {"Line Input", NULL, "LLINEIN"},
178 {"Line Input", NULL, "RLINEIN"},
179};
180
181static const struct snd_soc_dapm_route ssm2602_routes[] = {
188 {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"}, 182 {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
189 183
190 /* outputs */
191 {"RHPOUT", NULL, "Output Mixer"}, 184 {"RHPOUT", NULL, "Output Mixer"},
192 {"ROUT", NULL, "Output Mixer"},
193 {"LHPOUT", NULL, "Output Mixer"}, 185 {"LHPOUT", NULL, "Output Mixer"},
194 {"LOUT", NULL, "Output Mixer"},
195 186
196 /* input mux */
197 {"Input Mux", "Line", "Line Input"}, 187 {"Input Mux", "Line", "Line Input"},
198 {"Input Mux", "Mic", "Mic Bias"}, 188 {"Input Mux", "Mic", "Mic Bias"},
199 {"ADC", NULL, "Input Mux"}, 189 {"ADC", NULL, "Input Mux"},
200 190
201 /* inputs */
202 {"Line Input", NULL, "LLINEIN"},
203 {"Line Input", NULL, "RLINEIN"},
204 {"Mic Bias", NULL, "MICIN"}, 191 {"Mic Bias", NULL, "MICIN"},
205}; 192};
206 193
207static int ssm2602_add_widgets(struct snd_soc_codec *codec) 194static const struct snd_soc_dapm_route ssm2604_routes[] = {
208{ 195 {"ADC", NULL, "Line Input"},
209 struct snd_soc_dapm_context *dapm = &codec->dapm; 196};
210
211 snd_soc_dapm_new_controls(dapm, ssm2602_dapm_widgets,
212 ARRAY_SIZE(ssm2602_dapm_widgets));
213 snd_soc_dapm_add_routes(dapm, audio_conn, ARRAY_SIZE(audio_conn));
214
215 return 0;
216}
217 197
218struct _coeff_div { 198struct ssm2602_coeff {
219 u32 mclk; 199 u32 mclk;
220 u32 rate; 200 u32 rate;
221 u16 fs; 201 u8 srate;
222 u8 sr:4;
223 u8 bosr:1;
224 u8 usb:1;
225}; 202};
226 203
227/* codec mclk clock divider coefficients */ 204#define SSM2602_COEFF_SRATE(sr, bosr, usb) (((sr) << 2) | ((bosr) << 1) | (usb))
228static const struct _coeff_div coeff_div[] = { 205
206/* codec mclk clock coefficients */
207static const struct ssm2602_coeff ssm2602_coeff_table[] = {
229 /* 48k */ 208 /* 48k */
230 {12288000, 48000, 256, 0x0, 0x0, 0x0}, 209 {12288000, 48000, SSM2602_COEFF_SRATE(0x0, 0x0, 0x0)},
231 {18432000, 48000, 384, 0x0, 0x1, 0x0}, 210 {18432000, 48000, SSM2602_COEFF_SRATE(0x0, 0x1, 0x0)},
232 {12000000, 48000, 250, 0x0, 0x0, 0x1}, 211 {12000000, 48000, SSM2602_COEFF_SRATE(0x0, 0x0, 0x1)},
233 212
234 /* 32k */ 213 /* 32k */
235 {12288000, 32000, 384, 0x6, 0x0, 0x0}, 214 {12288000, 32000, SSM2602_COEFF_SRATE(0x6, 0x0, 0x0)},
236 {18432000, 32000, 576, 0x6, 0x1, 0x0}, 215 {18432000, 32000, SSM2602_COEFF_SRATE(0x6, 0x1, 0x0)},
237 {12000000, 32000, 375, 0x6, 0x0, 0x1}, 216 {12000000, 32000, SSM2602_COEFF_SRATE(0x6, 0x0, 0x1)},
238 217
239 /* 8k */ 218 /* 8k */
240 {12288000, 8000, 1536, 0x3, 0x0, 0x0}, 219 {12288000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x0)},
241 {18432000, 8000, 2304, 0x3, 0x1, 0x0}, 220 {18432000, 8000, SSM2602_COEFF_SRATE(0x3, 0x1, 0x0)},
242 {11289600, 8000, 1408, 0xb, 0x0, 0x0}, 221 {11289600, 8000, SSM2602_COEFF_SRATE(0xb, 0x0, 0x0)},
243 {16934400, 8000, 2112, 0xb, 0x1, 0x0}, 222 {16934400, 8000, SSM2602_COEFF_SRATE(0xb, 0x1, 0x0)},
244 {12000000, 8000, 1500, 0x3, 0x0, 0x1}, 223 {12000000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x1)},
245 224
246 /* 96k */ 225 /* 96k */
247 {12288000, 96000, 128, 0x7, 0x0, 0x0}, 226 {12288000, 96000, SSM2602_COEFF_SRATE(0x7, 0x0, 0x0)},
248 {18432000, 96000, 192, 0x7, 0x1, 0x0}, 227 {18432000, 96000, SSM2602_COEFF_SRATE(0x7, 0x1, 0x0)},
249 {12000000, 96000, 125, 0x7, 0x0, 0x1}, 228 {12000000, 96000, SSM2602_COEFF_SRATE(0x7, 0x0, 0x1)},
250 229
251 /* 44.1k */ 230 /* 44.1k */
252 {11289600, 44100, 256, 0x8, 0x0, 0x0}, 231 {11289600, 44100, SSM2602_COEFF_SRATE(0x8, 0x0, 0x0)},
253 {16934400, 44100, 384, 0x8, 0x1, 0x0}, 232 {16934400, 44100, SSM2602_COEFF_SRATE(0x8, 0x1, 0x0)},
254 {12000000, 44100, 272, 0x8, 0x1, 0x1}, 233 {12000000, 44100, SSM2602_COEFF_SRATE(0x8, 0x1, 0x1)},
255 234
256 /* 88.2k */ 235 /* 88.2k */
257 {11289600, 88200, 128, 0xf, 0x0, 0x0}, 236 {11289600, 88200, SSM2602_COEFF_SRATE(0xf, 0x0, 0x0)},
258 {16934400, 88200, 192, 0xf, 0x1, 0x0}, 237 {16934400, 88200, SSM2602_COEFF_SRATE(0xf, 0x1, 0x0)},
259 {12000000, 88200, 136, 0xf, 0x1, 0x1}, 238 {12000000, 88200, SSM2602_COEFF_SRATE(0xf, 0x1, 0x1)},
260}; 239};
261 240
262static inline int get_coeff(int mclk, int rate) 241static inline int ssm2602_get_coeff(int mclk, int rate)
263{ 242{
264 int i; 243 int i;
265 244
266 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { 245 for (i = 0; i < ARRAY_SIZE(ssm2602_coeff_table); i++) {
267 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) 246 if (ssm2602_coeff_table[i].rate == rate &&
268 return i; 247 ssm2602_coeff_table[i].mclk == mclk)
248 return ssm2602_coeff_table[i].srate;
269 } 249 }
270 return i; 250 return -EINVAL;
271} 251}
272 252
273static int ssm2602_hw_params(struct snd_pcm_substream *substream, 253static int ssm2602_hw_params(struct snd_pcm_substream *substream,
274 struct snd_pcm_hw_params *params, 254 struct snd_pcm_hw_params *params,
275 struct snd_soc_dai *dai) 255 struct snd_soc_dai *dai)
276{ 256{
277 u16 srate;
278 struct snd_soc_pcm_runtime *rtd = substream->private_data; 257 struct snd_soc_pcm_runtime *rtd = substream->private_data;
279 struct snd_soc_codec *codec = rtd->codec; 258 struct snd_soc_codec *codec = rtd->codec;
280 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 259 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
281 struct i2c_client *i2c = codec->control_data; 260 u16 iface = snd_soc_read(codec, SSM2602_IFACE) & 0xfff3;
282 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3; 261 int srate = ssm2602_get_coeff(ssm2602->sysclk, params_rate(params));
283 int i = get_coeff(ssm2602->sysclk, params_rate(params));
284 262
285 if (substream == ssm2602->slave_substream) { 263 if (substream == ssm2602->slave_substream) {
286 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n"); 264 dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n");
287 return 0; 265 return 0;
288 } 266 }
289 267
290 /*no match is found*/ 268 if (srate < 0)
291 if (i == ARRAY_SIZE(coeff_div)) 269 return srate;
292 return -EINVAL;
293 270
294 srate = (coeff_div[i].sr << 2) | 271 snd_soc_write(codec, SSM2602_SRATE, srate);
295 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
296
297 ssm2602_write(codec, SSM2602_ACTIVE, 0);
298 ssm2602_write(codec, SSM2602_SRATE, srate);
299 272
300 /* bit size */ 273 /* bit size */
301 switch (params_format(params)) { 274 switch (params_format(params)) {
@@ -311,8 +284,7 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
311 iface |= 0x000c; 284 iface |= 0x000c;
312 break; 285 break;
313 } 286 }
314 ssm2602_write(codec, SSM2602_IFACE, iface); 287 snd_soc_write(codec, SSM2602_IFACE, iface);
315 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
316 return 0; 288 return 0;
317} 289}
318 290
@@ -354,17 +326,6 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
354 return 0; 326 return 0;
355} 327}
356 328
357static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream,
358 struct snd_soc_dai *dai)
359{
360 struct snd_soc_pcm_runtime *rtd = substream->private_data;
361 struct snd_soc_codec *codec = rtd->codec;
362 /* set active */
363 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
364
365 return 0;
366}
367
368static void ssm2602_shutdown(struct snd_pcm_substream *substream, 329static void ssm2602_shutdown(struct snd_pcm_substream *substream,
369 struct snd_soc_dai *dai) 330 struct snd_soc_dai *dai)
370{ 331{
@@ -372,25 +333,22 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream,
372 struct snd_soc_codec *codec = rtd->codec; 333 struct snd_soc_codec *codec = rtd->codec;
373 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 334 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
374 335
375 /* deactivate */
376 if (!codec->active)
377 ssm2602_write(codec, SSM2602_ACTIVE, 0);
378
379 if (ssm2602->master_substream == substream) 336 if (ssm2602->master_substream == substream)
380 ssm2602->master_substream = ssm2602->slave_substream; 337 ssm2602->master_substream = ssm2602->slave_substream;
381 338
382 ssm2602->slave_substream = NULL; 339 ssm2602->slave_substream = NULL;
383} 340}
384 341
342
385static int ssm2602_mute(struct snd_soc_dai *dai, int mute) 343static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
386{ 344{
387 struct snd_soc_codec *codec = dai->codec; 345 struct snd_soc_codec *codec = dai->codec;
388 u16 mute_reg = ssm2602_read_reg_cache(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE; 346 u16 mute_reg = snd_soc_read(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE;
389 if (mute) 347 if (mute)
390 ssm2602_write(codec, SSM2602_APDIGI, 348 snd_soc_write(codec, SSM2602_APDIGI,
391 mute_reg | APDIGI_ENABLE_DAC_MUTE); 349 mute_reg | APDIGI_ENABLE_DAC_MUTE);
392 else 350 else
393 ssm2602_write(codec, SSM2602_APDIGI, mute_reg); 351 snd_soc_write(codec, SSM2602_APDIGI, mute_reg);
394 return 0; 352 return 0;
395} 353}
396 354
@@ -466,30 +424,29 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
466 } 424 }
467 425
468 /* set iface */ 426 /* set iface */
469 ssm2602_write(codec, SSM2602_IFACE, iface); 427 snd_soc_write(codec, SSM2602_IFACE, iface);
470 return 0; 428 return 0;
471} 429}
472 430
473static int ssm2602_set_bias_level(struct snd_soc_codec *codec, 431static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
474 enum snd_soc_bias_level level) 432 enum snd_soc_bias_level level)
475{ 433{
476 u16 reg = ssm2602_read_reg_cache(codec, SSM2602_PWR) & 0xff7f; 434 u16 reg = snd_soc_read(codec, SSM2602_PWR) & 0xff7f;
477 435
478 switch (level) { 436 switch (level) {
479 case SND_SOC_BIAS_ON: 437 case SND_SOC_BIAS_ON:
480 /* vref/mid, osc on, dac unmute */ 438 /* vref/mid, osc on, dac unmute */
481 ssm2602_write(codec, SSM2602_PWR, reg); 439 snd_soc_write(codec, SSM2602_PWR, reg);
482 break; 440 break;
483 case SND_SOC_BIAS_PREPARE: 441 case SND_SOC_BIAS_PREPARE:
484 break; 442 break;
485 case SND_SOC_BIAS_STANDBY: 443 case SND_SOC_BIAS_STANDBY:
486 /* everything off except vref/vmid, */ 444 /* everything off except vref/vmid, */
487 ssm2602_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN); 445 snd_soc_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN);
488 break; 446 break;
489 case SND_SOC_BIAS_OFF: 447 case SND_SOC_BIAS_OFF:
490 /* everything off, dac mute, inactive */ 448 /* everything off, dac mute, inactive */
491 ssm2602_write(codec, SSM2602_ACTIVE, 0); 449 snd_soc_write(codec, SSM2602_PWR, 0xffff);
492 ssm2602_write(codec, SSM2602_PWR, 0xffff);
493 break; 450 break;
494 451
495 } 452 }
@@ -506,7 +463,6 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
506 463
507static struct snd_soc_dai_ops ssm2602_dai_ops = { 464static struct snd_soc_dai_ops ssm2602_dai_ops = {
508 .startup = ssm2602_startup, 465 .startup = ssm2602_startup,
509 .prepare = ssm2602_pcm_prepare,
510 .hw_params = ssm2602_hw_params, 466 .hw_params = ssm2602_hw_params,
511 .shutdown = ssm2602_shutdown, 467 .shutdown = ssm2602_shutdown,
512 .digital_mute = ssm2602_mute, 468 .digital_mute = ssm2602_mute,
@@ -539,50 +495,87 @@ static int ssm2602_suspend(struct snd_soc_codec *codec, pm_message_t state)
539 495
540static int ssm2602_resume(struct snd_soc_codec *codec) 496static int ssm2602_resume(struct snd_soc_codec *codec)
541{ 497{
542 int i; 498 snd_soc_cache_sync(codec);
543 u8 data[2]; 499
544 u16 *cache = codec->reg_cache;
545
546 /* Sync reg_cache with the hardware */
547 for (i = 0; i < ARRAY_SIZE(ssm2602_reg); i++) {
548 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
549 data[1] = cache[i] & 0x00ff;
550 codec->hw_write(codec->control_data, data, 2);
551 }
552 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 500 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
501
553 return 0; 502 return 0;
554} 503}
555 504
556static int ssm2602_probe(struct snd_soc_codec *codec) 505static int ssm2602_probe(struct snd_soc_codec *codec)
557{ 506{
507 struct snd_soc_dapm_context *dapm = &codec->dapm;
508 int ret, reg;
509
510 reg = snd_soc_read(codec, SSM2602_LOUT1V);
511 snd_soc_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH);
512 reg = snd_soc_read(codec, SSM2602_ROUT1V);
513 snd_soc_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH);
514
515 ret = snd_soc_add_controls(codec, ssm2602_snd_controls,
516 ARRAY_SIZE(ssm2602_snd_controls));
517 if (ret)
518 return ret;
519
520 ret = snd_soc_dapm_new_controls(dapm, ssm2602_dapm_widgets,
521 ARRAY_SIZE(ssm2602_dapm_widgets));
522 if (ret)
523 return ret;
524
525 return snd_soc_dapm_add_routes(dapm, ssm2602_routes,
526 ARRAY_SIZE(ssm2602_routes));
527}
528
529static int ssm2604_probe(struct snd_soc_codec *codec)
530{
531 struct snd_soc_dapm_context *dapm = &codec->dapm;
532 int ret;
533
534 ret = snd_soc_dapm_new_controls(dapm, ssm2604_dapm_widgets,
535 ARRAY_SIZE(ssm2604_dapm_widgets));
536 if (ret)
537 return ret;
538
539 return snd_soc_dapm_add_routes(dapm, ssm2604_routes,
540 ARRAY_SIZE(ssm2604_routes));
541}
542
543static int ssm260x_probe(struct snd_soc_codec *codec)
544{
558 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 545 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
559 int ret = 0, reg; 546 int ret, reg;
560 547
561 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION); 548 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
562 549
563 codec->control_data = ssm2602->control_data; 550 ret = snd_soc_codec_set_cache_io(codec, 7, 9, ssm2602->control_type);
551 if (ret < 0) {
552 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
553 return ret;
554 }
564 555
565 ssm2602_reset(codec); 556 ret = ssm2602_reset(codec);
557 if (ret < 0) {
558 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
559 return ret;
560 }
566 561
567 /*power on device*/
568 ssm2602_write(codec, SSM2602_ACTIVE, 0);
569 /* set the update bits */ 562 /* set the update bits */
570 reg = ssm2602_read_reg_cache(codec, SSM2602_LINVOL); 563 reg = snd_soc_read(codec, SSM2602_LINVOL);
571 ssm2602_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH); 564 snd_soc_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH);
572 reg = ssm2602_read_reg_cache(codec, SSM2602_RINVOL); 565 reg = snd_soc_read(codec, SSM2602_RINVOL);
573 ssm2602_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH); 566 snd_soc_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH);
574 reg = ssm2602_read_reg_cache(codec, SSM2602_LOUT1V);
575 ssm2602_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH);
576 reg = ssm2602_read_reg_cache(codec, SSM2602_ROUT1V);
577 ssm2602_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH);
578 /*select Line in as default input*/ 567 /*select Line in as default input*/
579 ssm2602_write(codec, SSM2602_APANA, APANA_SELECT_DAC | 568 snd_soc_write(codec, SSM2602_APANA, APANA_SELECT_DAC |
580 APANA_ENABLE_MIC_BOOST); 569 APANA_ENABLE_MIC_BOOST);
581 ssm2602_write(codec, SSM2602_PWR, 0);
582 570
583 snd_soc_add_controls(codec, ssm2602_snd_controls, 571 switch (ssm2602->type) {
584 ARRAY_SIZE(ssm2602_snd_controls)); 572 case SSM2602:
585 ssm2602_add_widgets(codec); 573 ret = ssm2602_probe(codec);
574 break;
575 case SSM2604:
576 ret = ssm2604_probe(codec);
577 break;
578 }
586 579
587 return ret; 580 return ret;
588} 581}
@@ -595,18 +588,61 @@ static int ssm2602_remove(struct snd_soc_codec *codec)
595} 588}
596 589
597static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { 590static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
598 .probe = ssm2602_probe, 591 .probe = ssm260x_probe,
599 .remove = ssm2602_remove, 592 .remove = ssm2602_remove,
600 .suspend = ssm2602_suspend, 593 .suspend = ssm2602_suspend,
601 .resume = ssm2602_resume, 594 .resume = ssm2602_resume,
602 .read = ssm2602_read_reg_cache,
603 .write = ssm2602_write,
604 .set_bias_level = ssm2602_set_bias_level, 595 .set_bias_level = ssm2602_set_bias_level,
605 .reg_cache_size = ARRAY_SIZE(ssm2602_reg), 596 .reg_cache_size = ARRAY_SIZE(ssm2602_reg),
606 .reg_word_size = sizeof(u16), 597 .reg_word_size = sizeof(u16),
607 .reg_cache_default = ssm2602_reg, 598 .reg_cache_default = ssm2602_reg,
599
600 .controls = ssm260x_snd_controls,
601 .num_controls = ARRAY_SIZE(ssm260x_snd_controls),
602 .dapm_widgets = ssm260x_dapm_widgets,
603 .num_dapm_widgets = ARRAY_SIZE(ssm260x_dapm_widgets),
604 .dapm_routes = ssm260x_routes,
605 .num_dapm_routes = ARRAY_SIZE(ssm260x_routes),
608}; 606};
609 607
608#if defined(CONFIG_SPI_MASTER)
609static int __devinit ssm2602_spi_probe(struct spi_device *spi)
610{
611 struct ssm2602_priv *ssm2602;
612 int ret;
613
614 ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
615 if (ssm2602 == NULL)
616 return -ENOMEM;
617
618 spi_set_drvdata(spi, ssm2602);
619 ssm2602->control_type = SND_SOC_SPI;
620 ssm2602->type = SSM2602;
621
622 ret = snd_soc_register_codec(&spi->dev,
623 &soc_codec_dev_ssm2602, &ssm2602_dai, 1);
624 if (ret < 0)
625 kfree(ssm2602);
626 return ret;
627}
628
629static int __devexit ssm2602_spi_remove(struct spi_device *spi)
630{
631 snd_soc_unregister_codec(&spi->dev);
632 kfree(spi_get_drvdata(spi));
633 return 0;
634}
635
636static struct spi_driver ssm2602_spi_driver = {
637 .driver = {
638 .name = "ssm2602",
639 .owner = THIS_MODULE,
640 },
641 .probe = ssm2602_spi_probe,
642 .remove = __devexit_p(ssm2602_spi_remove),
643};
644#endif
645
610#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 646#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
611/* 647/*
612 * ssm2602 2 wire address is determined by GPIO5 648 * ssm2602 2 wire address is determined by GPIO5
@@ -625,8 +661,8 @@ static int __devinit ssm2602_i2c_probe(struct i2c_client *i2c,
625 return -ENOMEM; 661 return -ENOMEM;
626 662
627 i2c_set_clientdata(i2c, ssm2602); 663 i2c_set_clientdata(i2c, ssm2602);
628 ssm2602->control_data = i2c;
629 ssm2602->control_type = SND_SOC_I2C; 664 ssm2602->control_type = SND_SOC_I2C;
665 ssm2602->type = id->driver_data;
630 666
631 ret = snd_soc_register_codec(&i2c->dev, 667 ret = snd_soc_register_codec(&i2c->dev,
632 &soc_codec_dev_ssm2602, &ssm2602_dai, 1); 668 &soc_codec_dev_ssm2602, &ssm2602_dai, 1);
@@ -643,7 +679,9 @@ static int __devexit ssm2602_i2c_remove(struct i2c_client *client)
643} 679}
644 680
645static const struct i2c_device_id ssm2602_i2c_id[] = { 681static const struct i2c_device_id ssm2602_i2c_id[] = {
646 { "ssm2602", 0 }, 682 { "ssm2602", SSM2602 },
683 { "ssm2603", SSM2602 },
684 { "ssm2604", SSM2604 },
647 { } 685 { }
648}; 686};
649MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id); 687MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id);
@@ -651,7 +689,7 @@ MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id);
651/* corgi i2c codec control layer */ 689/* corgi i2c codec control layer */
652static struct i2c_driver ssm2602_i2c_driver = { 690static struct i2c_driver ssm2602_i2c_driver = {
653 .driver = { 691 .driver = {
654 .name = "ssm2602-codec", 692 .name = "ssm2602",
655 .owner = THIS_MODULE, 693 .owner = THIS_MODULE,
656 }, 694 },
657 .probe = ssm2602_i2c_probe, 695 .probe = ssm2602_i2c_probe,
@@ -664,25 +702,35 @@ static struct i2c_driver ssm2602_i2c_driver = {
664static int __init ssm2602_modinit(void) 702static int __init ssm2602_modinit(void)
665{ 703{
666 int ret = 0; 704 int ret = 0;
705
706#if defined(CONFIG_SPI_MASTER)
707 ret = spi_register_driver(&ssm2602_spi_driver);
708 if (ret)
709 return ret;
710#endif
711
667#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 712#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
668 ret = i2c_add_driver(&ssm2602_i2c_driver); 713 ret = i2c_add_driver(&ssm2602_i2c_driver);
669 if (ret != 0) { 714 if (ret)
670 printk(KERN_ERR "Failed to register SSM2602 I2C driver: %d\n", 715 return ret;
671 ret);
672 }
673#endif 716#endif
717
674 return ret; 718 return ret;
675} 719}
676module_init(ssm2602_modinit); 720module_init(ssm2602_modinit);
677 721
678static void __exit ssm2602_exit(void) 722static void __exit ssm2602_exit(void)
679{ 723{
724#if defined(CONFIG_SPI_MASTER)
725 spi_unregister_driver(&ssm2602_spi_driver);
726#endif
727
680#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 728#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
681 i2c_del_driver(&ssm2602_i2c_driver); 729 i2c_del_driver(&ssm2602_i2c_driver);
682#endif 730#endif
683} 731}
684module_exit(ssm2602_exit); 732module_exit(ssm2602_exit);
685 733
686MODULE_DESCRIPTION("ASoC ssm2602 driver"); 734MODULE_DESCRIPTION("ASoC SSM2602/SSM2603/SSM2604 driver");
687MODULE_AUTHOR("Cliff Cai"); 735MODULE_AUTHOR("Cliff Cai");
688MODULE_LICENSE("GPL"); 736MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ssm2602.h b/sound/soc/codecs/ssm2602.h
index 42a47d0f8e25..b98c69168036 100644
--- a/sound/soc/codecs/ssm2602.h
+++ b/sound/soc/codecs/ssm2602.h
@@ -117,11 +117,5 @@
117#define SSM2602_CACHEREGNUM 10 117#define SSM2602_CACHEREGNUM 10
118 118
119#define SSM2602_SYSCLK 0 119#define SSM2602_SYSCLK 0
120#define SSM2602_DAI 0
121
122struct ssm2602_setup_data {
123 int i2c_bus;
124 unsigned short i2c_address;
125};
126 120
127#endif 121#endif
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 54a30ef0ec8b..33bb52f3f683 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -212,7 +212,7 @@ static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
212 SND_SOC_DAPM_INPUT("MICIN"), 212 SND_SOC_DAPM_INPUT("MICIN"),
213}; 213};
214 214
215static const struct snd_soc_dapm_route intercon[] = { 215static const struct snd_soc_dapm_route tlv320aic23_intercon[] = {
216 /* Output Mixer */ 216 /* Output Mixer */
217 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 217 {"Output Mixer", "Line Bypass Switch", "Line Input"},
218 {"Output Mixer", "Playback Switch", "DAC"}, 218 {"Output Mixer", "Playback Switch", "DAC"},
@@ -388,18 +388,6 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
388 return 0; 388 return 0;
389} 389}
390 390
391static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
392{
393 struct snd_soc_dapm_context *dapm = &codec->dapm;
394
395 snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
396 ARRAY_SIZE(tlv320aic23_dapm_widgets));
397 /* set up audio path interconnects */
398 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
399
400 return 0;
401}
402
403static int tlv320aic23_hw_params(struct snd_pcm_substream *substream, 391static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
404 struct snd_pcm_hw_params *params, 392 struct snd_pcm_hw_params *params,
405 struct snd_soc_dai *dai) 393 struct snd_soc_dai *dai)
@@ -676,7 +664,6 @@ static int tlv320aic23_probe(struct snd_soc_codec *codec)
676 664
677 snd_soc_add_controls(codec, tlv320aic23_snd_controls, 665 snd_soc_add_controls(codec, tlv320aic23_snd_controls,
678 ARRAY_SIZE(tlv320aic23_snd_controls)); 666 ARRAY_SIZE(tlv320aic23_snd_controls));
679 tlv320aic23_add_widgets(codec);
680 667
681 return 0; 668 return 0;
682} 669}
@@ -698,6 +685,10 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
698 .read = tlv320aic23_read_reg_cache, 685 .read = tlv320aic23_read_reg_cache,
699 .write = tlv320aic23_write, 686 .write = tlv320aic23_write,
700 .set_bias_level = tlv320aic23_set_bias_level, 687 .set_bias_level = tlv320aic23_set_bias_level,
688 .dapm_widgets = tlv320aic23_dapm_widgets,
689 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
690 .dapm_routes = tlv320aic23_intercon,
691 .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon),
701}; 692};
702 693
703#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 694#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 6c43c13f0430..c3d96fc8c267 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -157,7 +157,8 @@ static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
157static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, 157static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
158 struct snd_ctl_elem_value *ucontrol) 158 struct snd_ctl_elem_value *ucontrol)
159{ 159{
160 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 160 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
161 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
161 struct soc_mixer_control *mc = 162 struct soc_mixer_control *mc =
162 (struct soc_mixer_control *)kcontrol->private_value; 163 (struct soc_mixer_control *)kcontrol->private_value;
163 unsigned int reg = mc->reg; 164 unsigned int reg = mc->reg;
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 082e9d51963f..faa5e9fb1471 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver 2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 * 3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> 4 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
5 * 5 *
6 * Copyright: (C) 2009 Nokia Corporation 6 * Copyright: (C) 2009 Nokia Corporation
7 * 7 *
@@ -587,6 +587,9 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
587 SND_SOC_DAPM_SUPPLY("Right DAC Power", 587 SND_SOC_DAPM_SUPPLY("Right DAC Power",
588 DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0), 588 DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0),
589 589
590 SND_SOC_DAPM_SUPPLY("Codec Power",
591 DAC33_PWR_CTRL, 4, 0, NULL, 0),
592
590 SND_SOC_DAPM_PRE("Pre Playback", dac33_playback_event), 593 SND_SOC_DAPM_PRE("Pre Playback", dac33_playback_event),
591 SND_SOC_DAPM_POST("Post Playback", dac33_playback_event), 594 SND_SOC_DAPM_POST("Post Playback", dac33_playback_event),
592}; 595};
@@ -619,6 +622,9 @@ static const struct snd_soc_dapm_route audio_map[] = {
619 /* output */ 622 /* output */
620 {"LEFT_LO", NULL, "Output Left Amplifier"}, 623 {"LEFT_LO", NULL, "Output Left Amplifier"},
621 {"RIGHT_LO", NULL, "Output Right Amplifier"}, 624 {"RIGHT_LO", NULL, "Output Right Amplifier"},
625
626 {"LEFT_LO", NULL, "Codec Power"},
627 {"RIGHT_LO", NULL, "Codec Power"},
622}; 628};
623 629
624static int dac33_add_widgets(struct snd_soc_codec *codec) 630static int dac33_add_widgets(struct snd_soc_codec *codec)
@@ -636,13 +642,10 @@ static int dac33_add_widgets(struct snd_soc_codec *codec)
636static int dac33_set_bias_level(struct snd_soc_codec *codec, 642static int dac33_set_bias_level(struct snd_soc_codec *codec,
637 enum snd_soc_bias_level level) 643 enum snd_soc_bias_level level)
638{ 644{
639 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
640 int ret; 645 int ret;
641 646
642 switch (level) { 647 switch (level) {
643 case SND_SOC_BIAS_ON: 648 case SND_SOC_BIAS_ON:
644 if (!dac33->substream)
645 dac33_soft_power(codec, 1);
646 break; 649 break;
647 case SND_SOC_BIAS_PREPARE: 650 case SND_SOC_BIAS_PREPARE:
648 break; 651 break;
@@ -943,8 +946,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
943 /* Write registers 0x08 and 0x09 (MSB, LSB) */ 946 /* Write registers 0x08 and 0x09 (MSB, LSB) */
944 dac33_write16(codec, DAC33_INT_OSC_FREQ_RAT_A, oscset); 947 dac33_write16(codec, DAC33_INT_OSC_FREQ_RAT_A, oscset);
945 948
946 /* calib time: 128 is a nice number ;) */ 949 /* OSC calibration time */
947 dac33_write(codec, DAC33_CALIB_TIME, 128); 950 dac33_write(codec, DAC33_CALIB_TIME, 96);
948 951
949 /* adjustment treshold & step */ 952 /* adjustment treshold & step */
950 dac33_write(codec, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) | 953 dac33_write(codec, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) |
@@ -1655,5 +1658,5 @@ module_exit(dac33_module_exit);
1655 1658
1656 1659
1657MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver"); 1660MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver");
1658MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@nokia.com>"); 1661MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
1659MODULE_LICENSE("GPL"); 1662MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320dac33.h b/sound/soc/codecs/tlv320dac33.h
index 7c318b5da437..ed69670747bf 100644
--- a/sound/soc/codecs/tlv320dac33.h
+++ b/sound/soc/codecs/tlv320dac33.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver 2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 * 3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> 4 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
5 * 5 *
6 * Copyright: (C) 2009 Nokia Corporation 6 * Copyright: (C) 2009 Nokia Corporation
7 * 7 *
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 1f1ac8110bef..239e0c461068 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) Nokia Corporation 4 * Copyright (C) Nokia Corporation
5 * 5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> 6 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
@@ -495,7 +495,7 @@ static void __exit tpa6130a2_exit(void)
495 i2c_del_driver(&tpa6130a2_i2c_driver); 495 i2c_del_driver(&tpa6130a2_i2c_driver);
496} 496}
497 497
498MODULE_AUTHOR("Peter Ujfalusi"); 498MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
499MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver"); 499MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver");
500MODULE_LICENSE("GPL"); 500MODULE_LICENSE("GPL");
501 501
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index 5df49c8756b2..417444020ba6 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) Nokia Corporation 4 * Copyright (C) Nokia Corporation
5 * 5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> 6 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 255901c4460d..4c336636d4f5 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -960,9 +960,9 @@ static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -600, 600, 0);
960 960
961/* 961/*
962 * AFMGAIN volume control: 962 * AFMGAIN volume control:
963 * from 18 to 24 dB in 6 dB steps 963 * from -18 to 24 dB in 6 dB steps
964 */ 964 */
965static DECLARE_TLV_DB_SCALE(afm_amp_tlv, 1800, 600, 0); 965static DECLARE_TLV_DB_SCALE(afm_amp_tlv, -1800, 600, 0);
966 966
967/* 967/*
968 * HSGAIN volume control: 968 * HSGAIN volume control:
@@ -1049,7 +1049,7 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = {
1049 1049
1050 /* AFM gains */ 1050 /* AFM gains */
1051 SOC_DOUBLE_TLV("Aux FM Volume", 1051 SOC_DOUBLE_TLV("Aux FM Volume",
1052 TWL6040_REG_LINEGAIN, 0, 4, 0xF, 0, afm_amp_tlv), 1052 TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv),
1053 1053
1054 /* Playback gains */ 1054 /* Playback gains */
1055 SOC_TWL6040_DOUBLE_TLV("Headset Playback Volume", 1055 SOC_TWL6040_DOUBLE_TLV("Headset Playback Volume",
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c
new file mode 100644
index 000000000000..14d0716bf009
--- /dev/null
+++ b/sound/soc/codecs/wm1250-ev1.c
@@ -0,0 +1,108 @@
1/*
2 * Driver for the 1250-EV1 audio I/O module
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/i2c.h>
16
17#include <sound/soc.h>
18#include <sound/soc-dapm.h>
19
20static const struct snd_soc_dapm_widget wm1250_ev1_dapm_widgets[] = {
21SND_SOC_DAPM_ADC("ADC", "wm1250-ev1 Capture", SND_SOC_NOPM, 0, 0),
22SND_SOC_DAPM_DAC("DAC", "wm1250-ev1 Playback", SND_SOC_NOPM, 0, 0),
23
24SND_SOC_DAPM_INPUT("WM1250 Input"),
25SND_SOC_DAPM_INPUT("WM1250 Output"),
26};
27
28static const struct snd_soc_dapm_route wm1250_ev1_dapm_routes[] = {
29 { "ADC", NULL, "WM1250 Input" },
30 { "WM1250 Output", NULL, "DAC" },
31};
32
33static struct snd_soc_dai_driver wm1250_ev1_dai = {
34 .name = "wm1250-ev1",
35 .playback = {
36 .stream_name = "Playback",
37 .channels_min = 1,
38 .channels_max = 1,
39 .rates = SNDRV_PCM_RATE_8000,
40 .formats = SNDRV_PCM_FMTBIT_S16_LE,
41 },
42 .capture = {
43 .stream_name = "Capture",
44 .channels_min = 1,
45 .channels_max = 1,
46 .rates = SNDRV_PCM_RATE_8000,
47 .formats = SNDRV_PCM_FMTBIT_S16_LE,
48 },
49};
50
51static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = {
52 .dapm_widgets = wm1250_ev1_dapm_widgets,
53 .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets),
54 .dapm_routes = wm1250_ev1_dapm_routes,
55 .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes),
56};
57
58static int __devinit wm1250_ev1_probe(struct i2c_client *i2c,
59 const struct i2c_device_id *id)
60{
61 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1,
62 &wm1250_ev1_dai, 1);
63}
64
65static int __devexit wm1250_ev1_remove(struct i2c_client *i2c)
66{
67 snd_soc_unregister_codec(&i2c->dev);
68
69 return 0;
70}
71
72static const struct i2c_device_id wm1250_ev1_i2c_id[] = {
73 { "wm1250-ev1", 0 },
74 { }
75};
76MODULE_DEVICE_TABLE(i2c, wm1250_ev1_i2c_id);
77
78static struct i2c_driver wm1250_ev1_i2c_driver = {
79 .driver = {
80 .name = "wm1250-ev1",
81 .owner = THIS_MODULE,
82 },
83 .probe = wm1250_ev1_probe,
84 .remove = __devexit_p(wm1250_ev1_remove),
85 .id_table = wm1250_ev1_i2c_id,
86};
87
88static int __init wm1250_ev1_modinit(void)
89{
90 int ret = 0;
91
92 ret = i2c_add_driver(&wm1250_ev1_i2c_driver);
93 if (ret != 0)
94 pr_err("Failed to register WM1250-EV1 I2C driver: %d\n", ret);
95
96 return ret;
97}
98module_init(wm1250_ev1_modinit);
99
100static void __exit wm1250_ev1_exit(void)
101{
102 i2c_del_driver(&wm1250_ev1_i2c_driver);
103}
104module_exit(wm1250_ev1_exit);
105
106MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
107MODULE_DESCRIPTION("WM1250-EV1 audio I/O module driver");
108MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 97c30382d3ff..a537e4af6ae7 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -77,7 +77,7 @@ SND_SOC_DAPM_OUTPUT("ROUT"),
77SND_SOC_DAPM_OUTPUT("RHPOUT"), 77SND_SOC_DAPM_OUTPUT("RHPOUT"),
78}; 78};
79 79
80static const struct snd_soc_dapm_route intercon[] = { 80static const struct snd_soc_dapm_route wm8711_intercon[] = {
81 /* output mixer */ 81 /* output mixer */
82 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 82 {"Output Mixer", "Line Bypass Switch", "Line Input"},
83 {"Output Mixer", "HiFi Playback Switch", "DAC"}, 83 {"Output Mixer", "HiFi Playback Switch", "DAC"},
@@ -89,17 +89,6 @@ static const struct snd_soc_dapm_route intercon[] = {
89 {"LOUT", NULL, "Output Mixer"}, 89 {"LOUT", NULL, "Output Mixer"},
90}; 90};
91 91
92static int wm8711_add_widgets(struct snd_soc_codec *codec)
93{
94 struct snd_soc_dapm_context *dapm = &codec->dapm;
95
96 snd_soc_dapm_new_controls(dapm, wm8711_dapm_widgets,
97 ARRAY_SIZE(wm8711_dapm_widgets));
98 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
99
100 return 0;
101}
102
103struct _coeff_div { 92struct _coeff_div {
104 u32 mclk; 93 u32 mclk;
105 u32 rate; 94 u32 rate;
@@ -398,7 +387,6 @@ static int wm8711_probe(struct snd_soc_codec *codec)
398 387
399 snd_soc_add_controls(codec, wm8711_snd_controls, 388 snd_soc_add_controls(codec, wm8711_snd_controls,
400 ARRAY_SIZE(wm8711_snd_controls)); 389 ARRAY_SIZE(wm8711_snd_controls));
401 wm8711_add_widgets(codec);
402 390
403 return ret; 391 return ret;
404 392
@@ -420,6 +408,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
420 .reg_cache_size = ARRAY_SIZE(wm8711_reg), 408 .reg_cache_size = ARRAY_SIZE(wm8711_reg),
421 .reg_word_size = sizeof(u16), 409 .reg_word_size = sizeof(u16),
422 .reg_cache_default = wm8711_reg, 410 .reg_cache_default = wm8711_reg,
411 .dapm_widgets = wm8711_dapm_widgets,
412 .num_dapm_widgets = ARRAY_SIZE(wm8711_dapm_widgets),
413 .dapm_routes = wm8711_intercon,
414 .num_dapm_routes = ARRAY_SIZE(wm8711_intercon),
423}; 415};
424 416
425#if defined(CONFIG_SPI_MASTER) 417#if defined(CONFIG_SPI_MASTER)
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 736b0352d0a7..86d4718d3a76 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -65,22 +65,11 @@ SND_SOC_DAPM_OUTPUT("VOUTL"),
65SND_SOC_DAPM_OUTPUT("VOUTR"), 65SND_SOC_DAPM_OUTPUT("VOUTR"),
66}; 66};
67 67
68static const struct snd_soc_dapm_route intercon[] = { 68static const struct snd_soc_dapm_route wm8728_intercon[] = {
69 {"VOUTL", NULL, "DAC"}, 69 {"VOUTL", NULL, "DAC"},
70 {"VOUTR", NULL, "DAC"}, 70 {"VOUTR", NULL, "DAC"},
71}; 71};
72 72
73static int wm8728_add_widgets(struct snd_soc_codec *codec)
74{
75 struct snd_soc_dapm_context *dapm = &codec->dapm;
76
77 snd_soc_dapm_new_controls(dapm, wm8728_dapm_widgets,
78 ARRAY_SIZE(wm8728_dapm_widgets));
79 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
80
81 return 0;
82}
83
84static int wm8728_mute(struct snd_soc_dai *dai, int mute) 73static int wm8728_mute(struct snd_soc_dai *dai, int mute)
85{ 74{
86 struct snd_soc_codec *codec = dai->codec; 75 struct snd_soc_codec *codec = dai->codec;
@@ -255,7 +244,6 @@ static int wm8728_probe(struct snd_soc_codec *codec)
255 244
256 snd_soc_add_controls(codec, wm8728_snd_controls, 245 snd_soc_add_controls(codec, wm8728_snd_controls,
257 ARRAY_SIZE(wm8728_snd_controls)); 246 ARRAY_SIZE(wm8728_snd_controls));
258 wm8728_add_widgets(codec);
259 247
260 return ret; 248 return ret;
261} 249}
@@ -275,6 +263,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
275 .reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults), 263 .reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults),
276 .reg_word_size = sizeof(u16), 264 .reg_word_size = sizeof(u16),
277 .reg_cache_default = wm8728_reg_defaults, 265 .reg_cache_default = wm8728_reg_defaults,
266 .dapm_widgets = wm8728_dapm_widgets,
267 .num_dapm_widgets = ARRAY_SIZE(wm8728_dapm_widgets),
268 .dapm_routes = wm8728_intercon,
269 .num_dapm_routes = ARRAY_SIZE(wm8728_intercon),
278}; 270};
279 271
280#if defined(CONFIG_SPI_MASTER) 272#if defined(CONFIG_SPI_MASTER)
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 0a67c31b2663..6dec7cee2cb4 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -201,7 +201,7 @@ static int wm8731_check_osc(struct snd_soc_dapm_widget *source,
201 return wm8731->sysclk_type == WM8731_SYSCLK_MCLK; 201 return wm8731->sysclk_type == WM8731_SYSCLK_MCLK;
202} 202}
203 203
204static const struct snd_soc_dapm_route intercon[] = { 204static const struct snd_soc_dapm_route wm8731_intercon[] = {
205 {"DAC", NULL, "OSC", wm8731_check_osc}, 205 {"DAC", NULL, "OSC", wm8731_check_osc},
206 {"ADC", NULL, "OSC", wm8731_check_osc}, 206 {"ADC", NULL, "OSC", wm8731_check_osc},
207 207
@@ -227,17 +227,6 @@ static const struct snd_soc_dapm_route intercon[] = {
227 {"Mic Bias", NULL, "MICIN"}, 227 {"Mic Bias", NULL, "MICIN"},
228}; 228};
229 229
230static int wm8731_add_widgets(struct snd_soc_codec *codec)
231{
232 struct snd_soc_dapm_context *dapm = &codec->dapm;
233
234 snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
235 ARRAY_SIZE(wm8731_dapm_widgets));
236 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
237
238 return 0;
239}
240
241struct _coeff_div { 230struct _coeff_div {
242 u32 mclk; 231 u32 mclk;
243 u32 rate; 232 u32 rate;
@@ -599,7 +588,6 @@ static int wm8731_probe(struct snd_soc_codec *codec)
599 588
600 snd_soc_add_controls(codec, wm8731_snd_controls, 589 snd_soc_add_controls(codec, wm8731_snd_controls,
601 ARRAY_SIZE(wm8731_snd_controls)); 590 ARRAY_SIZE(wm8731_snd_controls));
602 wm8731_add_widgets(codec);
603 591
604 /* Regulators will have been enabled by bias management */ 592 /* Regulators will have been enabled by bias management */
605 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 593 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
@@ -636,6 +624,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
636 .reg_cache_size = ARRAY_SIZE(wm8731_reg), 624 .reg_cache_size = ARRAY_SIZE(wm8731_reg),
637 .reg_word_size = sizeof(u16), 625 .reg_word_size = sizeof(u16),
638 .reg_cache_default = wm8731_reg, 626 .reg_cache_default = wm8731_reg,
627 .dapm_widgets = wm8731_dapm_widgets,
628 .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
629 .dapm_routes = wm8731_intercon,
630 .num_dapm_routes = ARRAY_SIZE(wm8731_intercon),
639}; 631};
640 632
641#if defined(CONFIG_SPI_MASTER) 633#if defined(CONFIG_SPI_MASTER)
@@ -667,7 +659,7 @@ static int __devexit wm8731_spi_remove(struct spi_device *spi)
667 659
668static struct spi_driver wm8731_spi_driver = { 660static struct spi_driver wm8731_spi_driver = {
669 .driver = { 661 .driver = {
670 .name = "wm8731-codec", 662 .name = "wm8731",
671 .owner = THIS_MODULE, 663 .owner = THIS_MODULE,
672 }, 664 },
673 .probe = wm8731_spi_probe, 665 .probe = wm8731_spi_probe,
@@ -711,7 +703,7 @@ MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
711 703
712static struct i2c_driver wm8731_i2c_driver = { 704static struct i2c_driver wm8731_i2c_driver = {
713 .driver = { 705 .driver = {
714 .name = "wm8731-codec", 706 .name = "wm8731",
715 .owner = THIS_MODULE, 707 .owner = THIS_MODULE,
716 }, 708 },
717 .probe = wm8731_i2c_probe, 709 .probe = wm8731_i2c_probe,
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 824d1c8c8a35..43e3d760766f 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -382,7 +382,8 @@ static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm,
382static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, 382static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
383 struct snd_ctl_elem_value *ucontrol) 383 struct snd_ctl_elem_value *ucontrol)
384{ 384{
385 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 385 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
386 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
386 struct snd_soc_codec *codec = widget->codec; 387 struct snd_soc_codec *codec = widget->codec;
387 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 388 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
388 u16 reg; 389 u16 reg;
@@ -634,6 +635,13 @@ static const struct soc_enum lsidetone_enum =
634static const struct soc_enum rsidetone_enum = 635static const struct soc_enum rsidetone_enum =
635 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text); 636 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text);
636 637
638static const char *adcinput_text[] = {
639 "ADC", "DMIC"
640};
641
642static const struct soc_enum adcinput_enum =
643 SOC_ENUM_SINGLE(WM8903_CLOCK_RATE_TEST_4, 9, 2, adcinput_text);
644
637static const char *aif_text[] = { 645static const char *aif_text[] = {
638 "Left", "Right" 646 "Left", "Right"
639}; 647};
@@ -767,6 +775,9 @@ static const struct snd_kcontrol_new lsidetone_mux =
767static const struct snd_kcontrol_new rsidetone_mux = 775static const struct snd_kcontrol_new rsidetone_mux =
768 SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum); 776 SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum);
769 777
778static const struct snd_kcontrol_new adcinput_mux =
779 SOC_DAPM_ENUM("ADC Input", adcinput_enum);
780
770static const struct snd_kcontrol_new lcapture_mux = 781static const struct snd_kcontrol_new lcapture_mux =
771 SOC_DAPM_ENUM("Left Capture Mux", lcapture_enum); 782 SOC_DAPM_ENUM("Left Capture Mux", lcapture_enum);
772 783
@@ -817,6 +828,7 @@ SND_SOC_DAPM_INPUT("IN2L"),
817SND_SOC_DAPM_INPUT("IN2R"), 828SND_SOC_DAPM_INPUT("IN2R"),
818SND_SOC_DAPM_INPUT("IN3L"), 829SND_SOC_DAPM_INPUT("IN3L"),
819SND_SOC_DAPM_INPUT("IN3R"), 830SND_SOC_DAPM_INPUT("IN3R"),
831SND_SOC_DAPM_INPUT("DMICDAT"),
820 832
821SND_SOC_DAPM_OUTPUT("HPOUTL"), 833SND_SOC_DAPM_OUTPUT("HPOUTL"),
822SND_SOC_DAPM_OUTPUT("HPOUTR"), 834SND_SOC_DAPM_OUTPUT("HPOUTR"),
@@ -842,6 +854,9 @@ SND_SOC_DAPM_MUX("Right Input Mode Mux", SND_SOC_NOPM, 0, 0, &rinput_mode_mux),
842SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0), 854SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0),
843SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0), 855SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0),
844 856
857SND_SOC_DAPM_MUX("Left ADC Input", SND_SOC_NOPM, 0, 0, &adcinput_mux),
858SND_SOC_DAPM_MUX("Right ADC Input", SND_SOC_NOPM, 0, 0, &adcinput_mux),
859
845SND_SOC_DAPM_ADC("ADCL", NULL, WM8903_POWER_MANAGEMENT_6, 1, 0), 860SND_SOC_DAPM_ADC("ADCL", NULL, WM8903_POWER_MANAGEMENT_6, 1, 0),
846SND_SOC_DAPM_ADC("ADCR", NULL, WM8903_POWER_MANAGEMENT_6, 0, 0), 861SND_SOC_DAPM_ADC("ADCR", NULL, WM8903_POWER_MANAGEMENT_6, 0, 0),
847 862
@@ -930,7 +945,7 @@ SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0),
930SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0), 945SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0),
931}; 946};
932 947
933static const struct snd_soc_dapm_route intercon[] = { 948static const struct snd_soc_dapm_route wm8903_intercon[] = {
934 949
935 { "CLK_DSP", NULL, "CLK_SYS" }, 950 { "CLK_DSP", NULL, "CLK_SYS" },
936 { "Mic Bias", NULL, "CLK_SYS" }, 951 { "Mic Bias", NULL, "CLK_SYS" },
@@ -979,6 +994,11 @@ static const struct snd_soc_dapm_route intercon[] = {
979 { "Left Input PGA", NULL, "Left Input Mode Mux" }, 994 { "Left Input PGA", NULL, "Left Input Mode Mux" },
980 { "Right Input PGA", NULL, "Right Input Mode Mux" }, 995 { "Right Input PGA", NULL, "Right Input Mode Mux" },
981 996
997 { "Left ADC Input", "ADC", "Left Input PGA" },
998 { "Left ADC Input", "DMIC", "DMICDAT" },
999 { "Right ADC Input", "ADC", "Right Input PGA" },
1000 { "Right ADC Input", "DMIC", "DMICDAT" },
1001
982 { "Left Capture Mux", "Left", "ADCL" }, 1002 { "Left Capture Mux", "Left", "ADCL" },
983 { "Left Capture Mux", "Right", "ADCR" }, 1003 { "Left Capture Mux", "Right", "ADCR" },
984 1004
@@ -988,9 +1008,9 @@ static const struct snd_soc_dapm_route intercon[] = {
988 { "AIFTXL", NULL, "Left Capture Mux" }, 1008 { "AIFTXL", NULL, "Left Capture Mux" },
989 { "AIFTXR", NULL, "Right Capture Mux" }, 1009 { "AIFTXR", NULL, "Right Capture Mux" },
990 1010
991 { "ADCL", NULL, "Left Input PGA" }, 1011 { "ADCL", NULL, "Left ADC Input" },
992 { "ADCL", NULL, "CLK_DSP" }, 1012 { "ADCL", NULL, "CLK_DSP" },
993 { "ADCR", NULL, "Right Input PGA" }, 1013 { "ADCR", NULL, "Right ADC Input" },
994 { "ADCR", NULL, "CLK_DSP" }, 1014 { "ADCR", NULL, "CLK_DSP" },
995 1015
996 { "Left Playback Mux", "Left", "AIFRXL" }, 1016 { "Left Playback Mux", "Left", "AIFRXL" },
@@ -1087,17 +1107,6 @@ static const struct snd_soc_dapm_route intercon[] = {
1087 { "Right Line Output PGA", NULL, "Charge Pump" }, 1107 { "Right Line Output PGA", NULL, "Charge Pump" },
1088}; 1108};
1089 1109
1090static int wm8903_add_widgets(struct snd_soc_codec *codec)
1091{
1092 struct snd_soc_dapm_context *dapm = &codec->dapm;
1093
1094 snd_soc_dapm_new_controls(dapm, wm8903_dapm_widgets,
1095 ARRAY_SIZE(wm8903_dapm_widgets));
1096 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
1097
1098 return 0;
1099}
1100
1101static int wm8903_set_bias_level(struct snd_soc_codec *codec, 1110static int wm8903_set_bias_level(struct snd_soc_codec *codec,
1102 enum snd_soc_bias_level level) 1111 enum snd_soc_bias_level level)
1103{ 1112{
@@ -2028,7 +2037,6 @@ static int wm8903_probe(struct snd_soc_codec *codec)
2028 2037
2029 snd_soc_add_controls(codec, wm8903_snd_controls, 2038 snd_soc_add_controls(codec, wm8903_snd_controls,
2030 ARRAY_SIZE(wm8903_snd_controls)); 2039 ARRAY_SIZE(wm8903_snd_controls));
2031 wm8903_add_widgets(codec);
2032 2040
2033 wm8903_init_gpio(codec); 2041 wm8903_init_gpio(codec);
2034 2042
@@ -2054,6 +2062,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
2054 .reg_cache_default = wm8903_reg_defaults, 2062 .reg_cache_default = wm8903_reg_defaults,
2055 .volatile_register = wm8903_volatile_register, 2063 .volatile_register = wm8903_volatile_register,
2056 .seq_notifier = wm8903_seq_notifier, 2064 .seq_notifier = wm8903_seq_notifier,
2065 .dapm_widgets = wm8903_dapm_widgets,
2066 .num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets),
2067 .dapm_routes = wm8903_intercon,
2068 .num_dapm_routes = ARRAY_SIZE(wm8903_intercon),
2057}; 2069};
2058 2070
2059#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 2071#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/wm8915.c b/sound/soc/codecs/wm8915.c
new file mode 100644
index 000000000000..ccc9bd832794
--- /dev/null
+++ b/sound/soc/codecs/wm8915.c
@@ -0,0 +1,2931 @@
1/*
2 * wm8915.c - WM8915 audio codec interface
3 *
4 * Copyright 2011 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/completion.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/gcd.h>
20#include <linux/gpio.h>
21#include <linux/i2c.h>
22#include <linux/delay.h>
23#include <linux/regulator/consumer.h>
24#include <linux/slab.h>
25#include <linux/workqueue.h>
26#include <sound/core.h>
27#include <sound/jack.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/initval.h>
32#include <sound/tlv.h>
33#include <trace/events/asoc.h>
34
35#include <sound/wm8915.h>
36#include "wm8915.h"
37
38#define WM8915_AIFS 2
39
40#define HPOUT1L 1
41#define HPOUT1R 2
42#define HPOUT2L 4
43#define HPOUT2R 8
44
45#define WM8915_NUM_SUPPLIES 6
46static const char *wm8915_supply_names[WM8915_NUM_SUPPLIES] = {
47 "DCVDD",
48 "DBVDD",
49 "AVDD1",
50 "AVDD2",
51 "CPVDD",
52 "MICVDD",
53};
54
55struct wm8915_priv {
56 struct snd_soc_codec *codec;
57
58 int ldo1ena;
59
60 int sysclk;
61
62 int fll_src;
63 int fll_fref;
64 int fll_fout;
65
66 struct completion fll_lock;
67
68 u16 dcs_pending;
69 struct completion dcs_done;
70
71 u16 hpout_ena;
72 u16 hpout_pending;
73
74 struct regulator_bulk_data supplies[WM8915_NUM_SUPPLIES];
75 struct notifier_block disable_nb[WM8915_NUM_SUPPLIES];
76
77 struct wm8915_pdata pdata;
78
79 int rx_rate[WM8915_AIFS];
80
81 /* Platform dependant ReTune mobile configuration */
82 int num_retune_mobile_texts;
83 const char **retune_mobile_texts;
84 int retune_mobile_cfg[2];
85 struct soc_enum retune_mobile_enum;
86
87 struct snd_soc_jack *jack;
88 bool detecting;
89 bool jack_mic;
90 wm8915_polarity_fn polarity_cb;
91
92#ifdef CONFIG_GPIOLIB
93 struct gpio_chip gpio_chip;
94#endif
95};
96
97/* We can't use the same notifier block for more than one supply and
98 * there's no way I can see to get from a callback to the caller
99 * except container_of().
100 */
101#define WM8915_REGULATOR_EVENT(n) \
102static int wm8915_regulator_event_##n(struct notifier_block *nb, \
103 unsigned long event, void *data) \
104{ \
105 struct wm8915_priv *wm8915 = container_of(nb, struct wm8915_priv, \
106 disable_nb[n]); \
107 if (event & REGULATOR_EVENT_DISABLE) { \
108 wm8915->codec->cache_sync = 1; \
109 } \
110 return 0; \
111}
112
113WM8915_REGULATOR_EVENT(0)
114WM8915_REGULATOR_EVENT(1)
115WM8915_REGULATOR_EVENT(2)
116WM8915_REGULATOR_EVENT(3)
117WM8915_REGULATOR_EVENT(4)
118WM8915_REGULATOR_EVENT(5)
119
120static const u16 wm8915_reg[WM8915_MAX_REGISTER] = {
121 [WM8915_SOFTWARE_RESET] = 0x8915,
122 [WM8915_POWER_MANAGEMENT_7] = 0x10,
123 [WM8915_DAC1_HPOUT1_VOLUME] = 0x88,
124 [WM8915_DAC2_HPOUT2_VOLUME] = 0x88,
125 [WM8915_DAC1_LEFT_VOLUME] = 0x2c0,
126 [WM8915_DAC1_RIGHT_VOLUME] = 0x2c0,
127 [WM8915_DAC2_LEFT_VOLUME] = 0x2c0,
128 [WM8915_DAC2_RIGHT_VOLUME] = 0x2c0,
129 [WM8915_OUTPUT1_LEFT_VOLUME] = 0x80,
130 [WM8915_OUTPUT1_RIGHT_VOLUME] = 0x80,
131 [WM8915_OUTPUT2_LEFT_VOLUME] = 0x80,
132 [WM8915_OUTPUT2_RIGHT_VOLUME] = 0x80,
133 [WM8915_MICBIAS_1] = 0x39,
134 [WM8915_MICBIAS_2] = 0x39,
135 [WM8915_LDO_1] = 0x3,
136 [WM8915_LDO_2] = 0x13,
137 [WM8915_ACCESSORY_DETECT_MODE_1] = 0x4,
138 [WM8915_HEADPHONE_DETECT_1] = 0x20,
139 [WM8915_MIC_DETECT_1] = 0x7600,
140 [WM8915_MIC_DETECT_2] = 0xbf,
141 [WM8915_CHARGE_PUMP_1] = 0x1f25,
142 [WM8915_CHARGE_PUMP_2] = 0xab19,
143 [WM8915_DC_SERVO_5] = 0x2a2a,
144 [WM8915_CONTROL_INTERFACE_1] = 0x8004,
145 [WM8915_CLOCKING_1] = 0x10,
146 [WM8915_AIF_RATE] = 0x83,
147 [WM8915_FLL_CONTROL_4] = 0x5dc0,
148 [WM8915_FLL_CONTROL_5] = 0xc84,
149 [WM8915_FLL_EFS_2] = 0x2,
150 [WM8915_AIF1_TX_LRCLK_1] = 0x80,
151 [WM8915_AIF1_TX_LRCLK_2] = 0x8,
152 [WM8915_AIF1_RX_LRCLK_1] = 0x80,
153 [WM8915_AIF1TX_DATA_CONFIGURATION_1] = 0x1818,
154 [WM8915_AIF1RX_DATA_CONFIGURATION] = 0x1818,
155 [WM8915_AIF1TX_TEST] = 0x7,
156 [WM8915_AIF2_TX_LRCLK_1] = 0x80,
157 [WM8915_AIF2_TX_LRCLK_2] = 0x8,
158 [WM8915_AIF2_RX_LRCLK_1] = 0x80,
159 [WM8915_AIF2TX_DATA_CONFIGURATION_1] = 0x1818,
160 [WM8915_AIF2RX_DATA_CONFIGURATION] = 0x1818,
161 [WM8915_AIF2TX_TEST] = 0x1,
162 [WM8915_DSP1_TX_LEFT_VOLUME] = 0xc0,
163 [WM8915_DSP1_TX_RIGHT_VOLUME] = 0xc0,
164 [WM8915_DSP1_RX_LEFT_VOLUME] = 0xc0,
165 [WM8915_DSP1_RX_RIGHT_VOLUME] = 0xc0,
166 [WM8915_DSP1_TX_FILTERS] = 0x2000,
167 [WM8915_DSP1_RX_FILTERS_1] = 0x200,
168 [WM8915_DSP1_RX_FILTERS_2] = 0x10,
169 [WM8915_DSP1_DRC_1] = 0x98,
170 [WM8915_DSP1_DRC_2] = 0x845,
171 [WM8915_DSP1_RX_EQ_GAINS_1] = 0x6318,
172 [WM8915_DSP1_RX_EQ_GAINS_2] = 0x6300,
173 [WM8915_DSP1_RX_EQ_BAND_1_A] = 0xfca,
174 [WM8915_DSP1_RX_EQ_BAND_1_B] = 0x400,
175 [WM8915_DSP1_RX_EQ_BAND_1_PG] = 0xd8,
176 [WM8915_DSP1_RX_EQ_BAND_2_A] = 0x1eb5,
177 [WM8915_DSP1_RX_EQ_BAND_2_B] = 0xf145,
178 [WM8915_DSP1_RX_EQ_BAND_2_C] = 0xb75,
179 [WM8915_DSP1_RX_EQ_BAND_2_PG] = 0x1c5,
180 [WM8915_DSP1_RX_EQ_BAND_3_A] = 0x1c58,
181 [WM8915_DSP1_RX_EQ_BAND_3_B] = 0xf373,
182 [WM8915_DSP1_RX_EQ_BAND_3_C] = 0xa54,
183 [WM8915_DSP1_RX_EQ_BAND_3_PG] = 0x558,
184 [WM8915_DSP1_RX_EQ_BAND_4_A] = 0x168e,
185 [WM8915_DSP1_RX_EQ_BAND_4_B] = 0xf829,
186 [WM8915_DSP1_RX_EQ_BAND_4_C] = 0x7ad,
187 [WM8915_DSP1_RX_EQ_BAND_4_PG] = 0x1103,
188 [WM8915_DSP1_RX_EQ_BAND_5_A] = 0x564,
189 [WM8915_DSP1_RX_EQ_BAND_5_B] = 0x559,
190 [WM8915_DSP1_RX_EQ_BAND_5_PG] = 0x4000,
191 [WM8915_DSP2_TX_LEFT_VOLUME] = 0xc0,
192 [WM8915_DSP2_TX_RIGHT_VOLUME] = 0xc0,
193 [WM8915_DSP2_RX_LEFT_VOLUME] = 0xc0,
194 [WM8915_DSP2_RX_RIGHT_VOLUME] = 0xc0,
195 [WM8915_DSP2_TX_FILTERS] = 0x2000,
196 [WM8915_DSP2_RX_FILTERS_1] = 0x200,
197 [WM8915_DSP2_RX_FILTERS_2] = 0x10,
198 [WM8915_DSP2_DRC_1] = 0x98,
199 [WM8915_DSP2_DRC_2] = 0x845,
200 [WM8915_DSP2_RX_EQ_GAINS_1] = 0x6318,
201 [WM8915_DSP2_RX_EQ_GAINS_2] = 0x6300,
202 [WM8915_DSP2_RX_EQ_BAND_1_A] = 0xfca,
203 [WM8915_DSP2_RX_EQ_BAND_1_B] = 0x400,
204 [WM8915_DSP2_RX_EQ_BAND_1_PG] = 0xd8,
205 [WM8915_DSP2_RX_EQ_BAND_2_A] = 0x1eb5,
206 [WM8915_DSP2_RX_EQ_BAND_2_B] = 0xf145,
207 [WM8915_DSP2_RX_EQ_BAND_2_C] = 0xb75,
208 [WM8915_DSP2_RX_EQ_BAND_2_PG] = 0x1c5,
209 [WM8915_DSP2_RX_EQ_BAND_3_A] = 0x1c58,
210 [WM8915_DSP2_RX_EQ_BAND_3_B] = 0xf373,
211 [WM8915_DSP2_RX_EQ_BAND_3_C] = 0xa54,
212 [WM8915_DSP2_RX_EQ_BAND_3_PG] = 0x558,
213 [WM8915_DSP2_RX_EQ_BAND_4_A] = 0x168e,
214 [WM8915_DSP2_RX_EQ_BAND_4_B] = 0xf829,
215 [WM8915_DSP2_RX_EQ_BAND_4_C] = 0x7ad,
216 [WM8915_DSP2_RX_EQ_BAND_4_PG] = 0x1103,
217 [WM8915_DSP2_RX_EQ_BAND_5_A] = 0x564,
218 [WM8915_DSP2_RX_EQ_BAND_5_B] = 0x559,
219 [WM8915_DSP2_RX_EQ_BAND_5_PG] = 0x4000,
220 [WM8915_OVERSAMPLING] = 0xd,
221 [WM8915_SIDETONE] = 0x1040,
222 [WM8915_GPIO_1] = 0xa101,
223 [WM8915_GPIO_2] = 0xa101,
224 [WM8915_GPIO_3] = 0xa101,
225 [WM8915_GPIO_4] = 0xa101,
226 [WM8915_GPIO_5] = 0xa101,
227 [WM8915_PULL_CONTROL_2] = 0x140,
228 [WM8915_INTERRUPT_STATUS_1_MASK] = 0x1f,
229 [WM8915_INTERRUPT_STATUS_2_MASK] = 0x1ecf,
230 [WM8915_RIGHT_PDM_SPEAKER] = 0x1,
231 [WM8915_PDM_SPEAKER_MUTE_SEQUENCE] = 0x69,
232 [WM8915_PDM_SPEAKER_VOLUME] = 0x66,
233 [WM8915_WRITE_SEQUENCER_0] = 0x1,
234 [WM8915_WRITE_SEQUENCER_1] = 0x1,
235 [WM8915_WRITE_SEQUENCER_3] = 0x6,
236 [WM8915_WRITE_SEQUENCER_4] = 0x40,
237 [WM8915_WRITE_SEQUENCER_5] = 0x1,
238 [WM8915_WRITE_SEQUENCER_6] = 0xf,
239 [WM8915_WRITE_SEQUENCER_7] = 0x6,
240 [WM8915_WRITE_SEQUENCER_8] = 0x1,
241 [WM8915_WRITE_SEQUENCER_9] = 0x3,
242 [WM8915_WRITE_SEQUENCER_10] = 0x104,
243 [WM8915_WRITE_SEQUENCER_12] = 0x60,
244 [WM8915_WRITE_SEQUENCER_13] = 0x11,
245 [WM8915_WRITE_SEQUENCER_14] = 0x401,
246 [WM8915_WRITE_SEQUENCER_16] = 0x50,
247 [WM8915_WRITE_SEQUENCER_17] = 0x3,
248 [WM8915_WRITE_SEQUENCER_18] = 0x100,
249 [WM8915_WRITE_SEQUENCER_20] = 0x51,
250 [WM8915_WRITE_SEQUENCER_21] = 0x3,
251 [WM8915_WRITE_SEQUENCER_22] = 0x104,
252 [WM8915_WRITE_SEQUENCER_23] = 0xa,
253 [WM8915_WRITE_SEQUENCER_24] = 0x60,
254 [WM8915_WRITE_SEQUENCER_25] = 0x3b,
255 [WM8915_WRITE_SEQUENCER_26] = 0x502,
256 [WM8915_WRITE_SEQUENCER_27] = 0x100,
257 [WM8915_WRITE_SEQUENCER_28] = 0x2fff,
258 [WM8915_WRITE_SEQUENCER_32] = 0x2fff,
259 [WM8915_WRITE_SEQUENCER_36] = 0x2fff,
260 [WM8915_WRITE_SEQUENCER_40] = 0x2fff,
261 [WM8915_WRITE_SEQUENCER_44] = 0x2fff,
262 [WM8915_WRITE_SEQUENCER_48] = 0x2fff,
263 [WM8915_WRITE_SEQUENCER_52] = 0x2fff,
264 [WM8915_WRITE_SEQUENCER_56] = 0x2fff,
265 [WM8915_WRITE_SEQUENCER_60] = 0x2fff,
266 [WM8915_WRITE_SEQUENCER_64] = 0x1,
267 [WM8915_WRITE_SEQUENCER_65] = 0x1,
268 [WM8915_WRITE_SEQUENCER_67] = 0x6,
269 [WM8915_WRITE_SEQUENCER_68] = 0x40,
270 [WM8915_WRITE_SEQUENCER_69] = 0x1,
271 [WM8915_WRITE_SEQUENCER_70] = 0xf,
272 [WM8915_WRITE_SEQUENCER_71] = 0x6,
273 [WM8915_WRITE_SEQUENCER_72] = 0x1,
274 [WM8915_WRITE_SEQUENCER_73] = 0x3,
275 [WM8915_WRITE_SEQUENCER_74] = 0x104,
276 [WM8915_WRITE_SEQUENCER_76] = 0x60,
277 [WM8915_WRITE_SEQUENCER_77] = 0x11,
278 [WM8915_WRITE_SEQUENCER_78] = 0x401,
279 [WM8915_WRITE_SEQUENCER_80] = 0x50,
280 [WM8915_WRITE_SEQUENCER_81] = 0x3,
281 [WM8915_WRITE_SEQUENCER_82] = 0x100,
282 [WM8915_WRITE_SEQUENCER_84] = 0x60,
283 [WM8915_WRITE_SEQUENCER_85] = 0x3b,
284 [WM8915_WRITE_SEQUENCER_86] = 0x502,
285 [WM8915_WRITE_SEQUENCER_87] = 0x100,
286 [WM8915_WRITE_SEQUENCER_88] = 0x2fff,
287 [WM8915_WRITE_SEQUENCER_92] = 0x2fff,
288 [WM8915_WRITE_SEQUENCER_96] = 0x2fff,
289 [WM8915_WRITE_SEQUENCER_100] = 0x2fff,
290 [WM8915_WRITE_SEQUENCER_104] = 0x2fff,
291 [WM8915_WRITE_SEQUENCER_108] = 0x2fff,
292 [WM8915_WRITE_SEQUENCER_112] = 0x2fff,
293 [WM8915_WRITE_SEQUENCER_116] = 0x2fff,
294 [WM8915_WRITE_SEQUENCER_120] = 0x2fff,
295 [WM8915_WRITE_SEQUENCER_124] = 0x2fff,
296 [WM8915_WRITE_SEQUENCER_128] = 0x1,
297 [WM8915_WRITE_SEQUENCER_129] = 0x1,
298 [WM8915_WRITE_SEQUENCER_131] = 0x6,
299 [WM8915_WRITE_SEQUENCER_132] = 0x40,
300 [WM8915_WRITE_SEQUENCER_133] = 0x1,
301 [WM8915_WRITE_SEQUENCER_134] = 0xf,
302 [WM8915_WRITE_SEQUENCER_135] = 0x6,
303 [WM8915_WRITE_SEQUENCER_136] = 0x1,
304 [WM8915_WRITE_SEQUENCER_137] = 0x3,
305 [WM8915_WRITE_SEQUENCER_138] = 0x106,
306 [WM8915_WRITE_SEQUENCER_140] = 0x61,
307 [WM8915_WRITE_SEQUENCER_141] = 0x11,
308 [WM8915_WRITE_SEQUENCER_142] = 0x401,
309 [WM8915_WRITE_SEQUENCER_144] = 0x50,
310 [WM8915_WRITE_SEQUENCER_145] = 0x3,
311 [WM8915_WRITE_SEQUENCER_146] = 0x102,
312 [WM8915_WRITE_SEQUENCER_148] = 0x51,
313 [WM8915_WRITE_SEQUENCER_149] = 0x3,
314 [WM8915_WRITE_SEQUENCER_150] = 0x106,
315 [WM8915_WRITE_SEQUENCER_151] = 0xa,
316 [WM8915_WRITE_SEQUENCER_152] = 0x61,
317 [WM8915_WRITE_SEQUENCER_153] = 0x3b,
318 [WM8915_WRITE_SEQUENCER_154] = 0x502,
319 [WM8915_WRITE_SEQUENCER_155] = 0x100,
320 [WM8915_WRITE_SEQUENCER_156] = 0x2fff,
321 [WM8915_WRITE_SEQUENCER_160] = 0x2fff,
322 [WM8915_WRITE_SEQUENCER_164] = 0x2fff,
323 [WM8915_WRITE_SEQUENCER_168] = 0x2fff,
324 [WM8915_WRITE_SEQUENCER_172] = 0x2fff,
325 [WM8915_WRITE_SEQUENCER_176] = 0x2fff,
326 [WM8915_WRITE_SEQUENCER_180] = 0x2fff,
327 [WM8915_WRITE_SEQUENCER_184] = 0x2fff,
328 [WM8915_WRITE_SEQUENCER_188] = 0x2fff,
329 [WM8915_WRITE_SEQUENCER_192] = 0x1,
330 [WM8915_WRITE_SEQUENCER_193] = 0x1,
331 [WM8915_WRITE_SEQUENCER_195] = 0x6,
332 [WM8915_WRITE_SEQUENCER_196] = 0x40,
333 [WM8915_WRITE_SEQUENCER_197] = 0x1,
334 [WM8915_WRITE_SEQUENCER_198] = 0xf,
335 [WM8915_WRITE_SEQUENCER_199] = 0x6,
336 [WM8915_WRITE_SEQUENCER_200] = 0x1,
337 [WM8915_WRITE_SEQUENCER_201] = 0x3,
338 [WM8915_WRITE_SEQUENCER_202] = 0x106,
339 [WM8915_WRITE_SEQUENCER_204] = 0x61,
340 [WM8915_WRITE_SEQUENCER_205] = 0x11,
341 [WM8915_WRITE_SEQUENCER_206] = 0x401,
342 [WM8915_WRITE_SEQUENCER_208] = 0x50,
343 [WM8915_WRITE_SEQUENCER_209] = 0x3,
344 [WM8915_WRITE_SEQUENCER_210] = 0x102,
345 [WM8915_WRITE_SEQUENCER_212] = 0x61,
346 [WM8915_WRITE_SEQUENCER_213] = 0x3b,
347 [WM8915_WRITE_SEQUENCER_214] = 0x502,
348 [WM8915_WRITE_SEQUENCER_215] = 0x100,
349 [WM8915_WRITE_SEQUENCER_216] = 0x2fff,
350 [WM8915_WRITE_SEQUENCER_220] = 0x2fff,
351 [WM8915_WRITE_SEQUENCER_224] = 0x2fff,
352 [WM8915_WRITE_SEQUENCER_228] = 0x2fff,
353 [WM8915_WRITE_SEQUENCER_232] = 0x2fff,
354 [WM8915_WRITE_SEQUENCER_236] = 0x2fff,
355 [WM8915_WRITE_SEQUENCER_240] = 0x2fff,
356 [WM8915_WRITE_SEQUENCER_244] = 0x2fff,
357 [WM8915_WRITE_SEQUENCER_248] = 0x2fff,
358 [WM8915_WRITE_SEQUENCER_252] = 0x2fff,
359 [WM8915_WRITE_SEQUENCER_256] = 0x60,
360 [WM8915_WRITE_SEQUENCER_258] = 0x601,
361 [WM8915_WRITE_SEQUENCER_260] = 0x50,
362 [WM8915_WRITE_SEQUENCER_262] = 0x100,
363 [WM8915_WRITE_SEQUENCER_264] = 0x1,
364 [WM8915_WRITE_SEQUENCER_266] = 0x104,
365 [WM8915_WRITE_SEQUENCER_267] = 0x100,
366 [WM8915_WRITE_SEQUENCER_268] = 0x2fff,
367 [WM8915_WRITE_SEQUENCER_272] = 0x2fff,
368 [WM8915_WRITE_SEQUENCER_276] = 0x2fff,
369 [WM8915_WRITE_SEQUENCER_280] = 0x2fff,
370 [WM8915_WRITE_SEQUENCER_284] = 0x2fff,
371 [WM8915_WRITE_SEQUENCER_288] = 0x2fff,
372 [WM8915_WRITE_SEQUENCER_292] = 0x2fff,
373 [WM8915_WRITE_SEQUENCER_296] = 0x2fff,
374 [WM8915_WRITE_SEQUENCER_300] = 0x2fff,
375 [WM8915_WRITE_SEQUENCER_304] = 0x2fff,
376 [WM8915_WRITE_SEQUENCER_308] = 0x2fff,
377 [WM8915_WRITE_SEQUENCER_312] = 0x2fff,
378 [WM8915_WRITE_SEQUENCER_316] = 0x2fff,
379 [WM8915_WRITE_SEQUENCER_320] = 0x61,
380 [WM8915_WRITE_SEQUENCER_322] = 0x601,
381 [WM8915_WRITE_SEQUENCER_324] = 0x50,
382 [WM8915_WRITE_SEQUENCER_326] = 0x102,
383 [WM8915_WRITE_SEQUENCER_328] = 0x1,
384 [WM8915_WRITE_SEQUENCER_330] = 0x106,
385 [WM8915_WRITE_SEQUENCER_331] = 0x100,
386 [WM8915_WRITE_SEQUENCER_332] = 0x2fff,
387 [WM8915_WRITE_SEQUENCER_336] = 0x2fff,
388 [WM8915_WRITE_SEQUENCER_340] = 0x2fff,
389 [WM8915_WRITE_SEQUENCER_344] = 0x2fff,
390 [WM8915_WRITE_SEQUENCER_348] = 0x2fff,
391 [WM8915_WRITE_SEQUENCER_352] = 0x2fff,
392 [WM8915_WRITE_SEQUENCER_356] = 0x2fff,
393 [WM8915_WRITE_SEQUENCER_360] = 0x2fff,
394 [WM8915_WRITE_SEQUENCER_364] = 0x2fff,
395 [WM8915_WRITE_SEQUENCER_368] = 0x2fff,
396 [WM8915_WRITE_SEQUENCER_372] = 0x2fff,
397 [WM8915_WRITE_SEQUENCER_376] = 0x2fff,
398 [WM8915_WRITE_SEQUENCER_380] = 0x2fff,
399 [WM8915_WRITE_SEQUENCER_384] = 0x60,
400 [WM8915_WRITE_SEQUENCER_386] = 0x601,
401 [WM8915_WRITE_SEQUENCER_388] = 0x61,
402 [WM8915_WRITE_SEQUENCER_390] = 0x601,
403 [WM8915_WRITE_SEQUENCER_392] = 0x50,
404 [WM8915_WRITE_SEQUENCER_394] = 0x300,
405 [WM8915_WRITE_SEQUENCER_396] = 0x1,
406 [WM8915_WRITE_SEQUENCER_398] = 0x304,
407 [WM8915_WRITE_SEQUENCER_400] = 0x40,
408 [WM8915_WRITE_SEQUENCER_402] = 0xf,
409 [WM8915_WRITE_SEQUENCER_404] = 0x1,
410 [WM8915_WRITE_SEQUENCER_407] = 0x100,
411};
412
413static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0);
414static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0);
415static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
416static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0);
417static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0);
418static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0);
419static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
420
421static const char *sidetone_hpf_text[] = {
422 "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz"
423};
424
425static const struct soc_enum sidetone_hpf =
426 SOC_ENUM_SINGLE(WM8915_SIDETONE, 7, 6, sidetone_hpf_text);
427
428static const char *hpf_mode_text[] = {
429 "HiFi", "Custom", "Voice"
430};
431
432static const struct soc_enum dsp1tx_hpf_mode =
433 SOC_ENUM_SINGLE(WM8915_DSP1_TX_FILTERS, 3, 3, hpf_mode_text);
434
435static const struct soc_enum dsp2tx_hpf_mode =
436 SOC_ENUM_SINGLE(WM8915_DSP2_TX_FILTERS, 3, 3, hpf_mode_text);
437
438static const char *hpf_cutoff_text[] = {
439 "50Hz", "75Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
440};
441
442static const struct soc_enum dsp1tx_hpf_cutoff =
443 SOC_ENUM_SINGLE(WM8915_DSP1_TX_FILTERS, 0, 7, hpf_cutoff_text);
444
445static const struct soc_enum dsp2tx_hpf_cutoff =
446 SOC_ENUM_SINGLE(WM8915_DSP2_TX_FILTERS, 0, 7, hpf_cutoff_text);
447
448static void wm8915_set_retune_mobile(struct snd_soc_codec *codec, int block)
449{
450 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
451 struct wm8915_pdata *pdata = &wm8915->pdata;
452 int base, best, best_val, save, i, cfg, iface;
453
454 if (!wm8915->num_retune_mobile_texts)
455 return;
456
457 switch (block) {
458 case 0:
459 base = WM8915_DSP1_RX_EQ_GAINS_1;
460 if (snd_soc_read(codec, WM8915_POWER_MANAGEMENT_8) &
461 WM8915_DSP1RX_SRC)
462 iface = 1;
463 else
464 iface = 0;
465 break;
466 case 1:
467 base = WM8915_DSP1_RX_EQ_GAINS_2;
468 if (snd_soc_read(codec, WM8915_POWER_MANAGEMENT_8) &
469 WM8915_DSP2RX_SRC)
470 iface = 1;
471 else
472 iface = 0;
473 break;
474 default:
475 return;
476 }
477
478 /* Find the version of the currently selected configuration
479 * with the nearest sample rate. */
480 cfg = wm8915->retune_mobile_cfg[block];
481 best = 0;
482 best_val = INT_MAX;
483 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
484 if (strcmp(pdata->retune_mobile_cfgs[i].name,
485 wm8915->retune_mobile_texts[cfg]) == 0 &&
486 abs(pdata->retune_mobile_cfgs[i].rate
487 - wm8915->rx_rate[iface]) < best_val) {
488 best = i;
489 best_val = abs(pdata->retune_mobile_cfgs[i].rate
490 - wm8915->rx_rate[iface]);
491 }
492 }
493
494 dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
495 block,
496 pdata->retune_mobile_cfgs[best].name,
497 pdata->retune_mobile_cfgs[best].rate,
498 wm8915->rx_rate[iface]);
499
500 /* The EQ will be disabled while reconfiguring it, remember the
501 * current configuration.
502 */
503 save = snd_soc_read(codec, base);
504 save &= WM8915_DSP1RX_EQ_ENA;
505
506 for (i = 0; i < ARRAY_SIZE(pdata->retune_mobile_cfgs[best].regs); i++)
507 snd_soc_update_bits(codec, base + i, 0xffff,
508 pdata->retune_mobile_cfgs[best].regs[i]);
509
510 snd_soc_update_bits(codec, base, WM8915_DSP1RX_EQ_ENA, save);
511}
512
513/* Icky as hell but saves code duplication */
514static int wm8915_get_retune_mobile_block(const char *name)
515{
516 if (strcmp(name, "DSP1 EQ Mode") == 0)
517 return 0;
518 if (strcmp(name, "DSP2 EQ Mode") == 0)
519 return 1;
520 return -EINVAL;
521}
522
523static int wm8915_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol)
525{
526 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
527 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
528 struct wm8915_pdata *pdata = &wm8915->pdata;
529 int block = wm8915_get_retune_mobile_block(kcontrol->id.name);
530 int value = ucontrol->value.integer.value[0];
531
532 if (block < 0)
533 return block;
534
535 if (value >= pdata->num_retune_mobile_cfgs)
536 return -EINVAL;
537
538 wm8915->retune_mobile_cfg[block] = value;
539
540 wm8915_set_retune_mobile(codec, block);
541
542 return 0;
543}
544
545static int wm8915_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
546 struct snd_ctl_elem_value *ucontrol)
547{
548 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
549 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
550 int block = wm8915_get_retune_mobile_block(kcontrol->id.name);
551
552 ucontrol->value.enumerated.item[0] = wm8915->retune_mobile_cfg[block];
553
554 return 0;
555}
556
557static const struct snd_kcontrol_new wm8915_snd_controls[] = {
558SOC_DOUBLE_R_TLV("Capture Volume", WM8915_LEFT_LINE_INPUT_VOLUME,
559 WM8915_RIGHT_LINE_INPUT_VOLUME, 0, 31, 0, inpga_tlv),
560SOC_DOUBLE_R("Capture ZC Switch", WM8915_LEFT_LINE_INPUT_VOLUME,
561 WM8915_RIGHT_LINE_INPUT_VOLUME, 5, 1, 0),
562
563SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8915_DAC1_MIXER_VOLUMES,
564 0, 5, 24, 0, sidetone_tlv),
565SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8915_DAC2_MIXER_VOLUMES,
566 0, 5, 24, 0, sidetone_tlv),
567SOC_SINGLE("Sidetone LPF Switch", WM8915_SIDETONE, 12, 1, 0),
568SOC_ENUM("Sidetone HPF Cut-off", sidetone_hpf),
569SOC_SINGLE("Sidetone HPF Switch", WM8915_SIDETONE, 6, 1, 0),
570
571SOC_DOUBLE_R_TLV("DSP1 Capture Volume", WM8915_DSP1_TX_LEFT_VOLUME,
572 WM8915_DSP1_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
573SOC_DOUBLE_R_TLV("DSP2 Capture Volume", WM8915_DSP2_TX_LEFT_VOLUME,
574 WM8915_DSP2_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
575
576SOC_SINGLE("DSP1 Capture Notch Filter Switch", WM8915_DSP1_TX_FILTERS,
577 13, 1, 0),
578SOC_DOUBLE("DSP1 Capture HPF Switch", WM8915_DSP1_TX_FILTERS, 12, 11, 1, 0),
579SOC_ENUM("DSP1 Capture HPF Mode", dsp1tx_hpf_mode),
580SOC_ENUM("DSP1 Capture HPF Cutoff", dsp1tx_hpf_cutoff),
581
582SOC_SINGLE("DSP2 Capture Notch Filter Switch", WM8915_DSP2_TX_FILTERS,
583 13, 1, 0),
584SOC_DOUBLE("DSP2 Capture HPF Switch", WM8915_DSP2_TX_FILTERS, 12, 11, 1, 0),
585SOC_ENUM("DSP2 Capture HPF Mode", dsp2tx_hpf_mode),
586SOC_ENUM("DSP2 Capture HPF Cutoff", dsp2tx_hpf_cutoff),
587
588SOC_DOUBLE_R_TLV("DSP1 Playback Volume", WM8915_DSP1_RX_LEFT_VOLUME,
589 WM8915_DSP1_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
590SOC_SINGLE("DSP1 Playback Switch", WM8915_DSP1_RX_FILTERS_1, 9, 1, 1),
591
592SOC_DOUBLE_R_TLV("DSP2 Playback Volume", WM8915_DSP2_RX_LEFT_VOLUME,
593 WM8915_DSP2_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
594SOC_SINGLE("DSP2 Playback Switch", WM8915_DSP2_RX_FILTERS_1, 9, 1, 1),
595
596SOC_DOUBLE_R_TLV("DAC1 Volume", WM8915_DAC1_LEFT_VOLUME,
597 WM8915_DAC1_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
598SOC_DOUBLE_R("DAC1 Switch", WM8915_DAC1_LEFT_VOLUME,
599 WM8915_DAC1_RIGHT_VOLUME, 9, 1, 1),
600
601SOC_DOUBLE_R_TLV("DAC2 Volume", WM8915_DAC2_LEFT_VOLUME,
602 WM8915_DAC2_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
603SOC_DOUBLE_R("DAC2 Switch", WM8915_DAC2_LEFT_VOLUME,
604 WM8915_DAC2_RIGHT_VOLUME, 9, 1, 1),
605
606SOC_SINGLE("Speaker High Performance Switch", WM8915_OVERSAMPLING, 3, 1, 0),
607SOC_SINGLE("DMIC High Performance Switch", WM8915_OVERSAMPLING, 2, 1, 0),
608SOC_SINGLE("ADC High Performance Switch", WM8915_OVERSAMPLING, 1, 1, 0),
609SOC_SINGLE("DAC High Performance Switch", WM8915_OVERSAMPLING, 0, 1, 0),
610
611SOC_SINGLE("DAC Soft Mute Switch", WM8915_DAC_SOFTMUTE, 1, 1, 0),
612SOC_SINGLE("DAC Slow Soft Mute Switch", WM8915_DAC_SOFTMUTE, 0, 1, 0),
613
614SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8915_DAC1_HPOUT1_VOLUME, 0, 4,
615 8, 0, out_digital_tlv),
616SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8915_DAC2_HPOUT2_VOLUME, 0, 4,
617 8, 0, out_digital_tlv),
618
619SOC_DOUBLE_R_TLV("Output 1 Volume", WM8915_OUTPUT1_LEFT_VOLUME,
620 WM8915_OUTPUT1_RIGHT_VOLUME, 0, 12, 0, out_tlv),
621SOC_DOUBLE_R("Output 1 ZC Switch", WM8915_OUTPUT1_LEFT_VOLUME,
622 WM8915_OUTPUT1_RIGHT_VOLUME, 7, 1, 0),
623
624SOC_DOUBLE_R_TLV("Output 2 Volume", WM8915_OUTPUT2_LEFT_VOLUME,
625 WM8915_OUTPUT2_RIGHT_VOLUME, 0, 12, 0, out_tlv),
626SOC_DOUBLE_R("Output 2 ZC Switch", WM8915_OUTPUT2_LEFT_VOLUME,
627 WM8915_OUTPUT2_RIGHT_VOLUME, 7, 1, 0),
628
629SOC_DOUBLE_TLV("Speaker Volume", WM8915_PDM_SPEAKER_VOLUME, 0, 4, 8, 0,
630 spk_tlv),
631SOC_DOUBLE_R("Speaker Switch", WM8915_LEFT_PDM_SPEAKER,
632 WM8915_RIGHT_PDM_SPEAKER, 3, 1, 1),
633SOC_DOUBLE_R("Speaker ZC Switch", WM8915_LEFT_PDM_SPEAKER,
634 WM8915_RIGHT_PDM_SPEAKER, 2, 1, 0),
635
636SOC_SINGLE("DSP1 EQ Switch", WM8915_DSP1_RX_EQ_GAINS_1, 0, 1, 0),
637SOC_SINGLE("DSP2 EQ Switch", WM8915_DSP2_RX_EQ_GAINS_1, 0, 1, 0),
638};
639
640static const struct snd_kcontrol_new wm8915_eq_controls[] = {
641SOC_SINGLE_TLV("DSP1 EQ B1 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 11, 31, 0,
642 eq_tlv),
643SOC_SINGLE_TLV("DSP1 EQ B2 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 6, 31, 0,
644 eq_tlv),
645SOC_SINGLE_TLV("DSP1 EQ B3 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 1, 31, 0,
646 eq_tlv),
647SOC_SINGLE_TLV("DSP1 EQ B4 Volume", WM8915_DSP1_RX_EQ_GAINS_2, 11, 31, 0,
648 eq_tlv),
649SOC_SINGLE_TLV("DSP1 EQ B5 Volume", WM8915_DSP1_RX_EQ_GAINS_2, 6, 31, 0,
650 eq_tlv),
651
652SOC_SINGLE_TLV("DSP2 EQ B1 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 11, 31, 0,
653 eq_tlv),
654SOC_SINGLE_TLV("DSP2 EQ B2 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 6, 31, 0,
655 eq_tlv),
656SOC_SINGLE_TLV("DSP2 EQ B3 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 1, 31, 0,
657 eq_tlv),
658SOC_SINGLE_TLV("DSP2 EQ B4 Volume", WM8915_DSP2_RX_EQ_GAINS_2, 11, 31, 0,
659 eq_tlv),
660SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8915_DSP2_RX_EQ_GAINS_2, 6, 31, 0,
661 eq_tlv),
662};
663
664static int cp_event(struct snd_soc_dapm_widget *w,
665 struct snd_kcontrol *kcontrol, int event)
666{
667 switch (event) {
668 case SND_SOC_DAPM_POST_PMU:
669 msleep(5);
670 break;
671 default:
672 BUG();
673 return -EINVAL;
674 }
675
676 return 0;
677}
678
679static int rmv_short_event(struct snd_soc_dapm_widget *w,
680 struct snd_kcontrol *kcontrol, int event)
681{
682 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(w->codec);
683
684 /* Record which outputs we enabled */
685 switch (event) {
686 case SND_SOC_DAPM_PRE_PMD:
687 wm8915->hpout_pending &= ~w->shift;
688 break;
689 case SND_SOC_DAPM_PRE_PMU:
690 wm8915->hpout_pending |= w->shift;
691 break;
692 default:
693 BUG();
694 return -EINVAL;
695 }
696
697 return 0;
698}
699
700static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
701{
702 struct i2c_client *i2c = to_i2c_client(codec->dev);
703 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
704 int i, ret;
705 unsigned long timeout = 200;
706
707 snd_soc_write(codec, WM8915_DC_SERVO_2, mask);
708
709 /* Use the interrupt if possible */
710 do {
711 if (i2c->irq) {
712 timeout = wait_for_completion_timeout(&wm8915->dcs_done,
713 msecs_to_jiffies(200));
714 if (timeout == 0)
715 dev_err(codec->dev, "DC servo timed out\n");
716
717 } else {
718 msleep(1);
719 if (--i) {
720 timeout = 0;
721 break;
722 }
723 }
724
725 ret = snd_soc_read(codec, WM8915_DC_SERVO_2);
726 dev_dbg(codec->dev, "DC servo state: %x\n", ret);
727 } while (ret & mask);
728
729 if (timeout == 0)
730 dev_err(codec->dev, "DC servo timed out for %x\n", mask);
731 else
732 dev_dbg(codec->dev, "DC servo complete for %x\n", mask);
733}
734
735static void wm8915_seq_notifier(struct snd_soc_dapm_context *dapm,
736 enum snd_soc_dapm_type event, int subseq)
737{
738 struct snd_soc_codec *codec = container_of(dapm,
739 struct snd_soc_codec, dapm);
740 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
741 u16 val, mask;
742
743 /* Complete any pending DC servo starts */
744 if (wm8915->dcs_pending) {
745 dev_dbg(codec->dev, "Starting DC servo for %x\n",
746 wm8915->dcs_pending);
747
748 /* Trigger a startup sequence */
749 wait_for_dc_servo(codec, wm8915->dcs_pending
750 << WM8915_DCS_TRIG_STARTUP_0_SHIFT);
751
752 wm8915->dcs_pending = 0;
753 }
754
755 if (wm8915->hpout_pending != wm8915->hpout_ena) {
756 dev_dbg(codec->dev, "Applying RMV_SHORTs %x->%x\n",
757 wm8915->hpout_ena, wm8915->hpout_pending);
758
759 val = 0;
760 mask = 0;
761 if (wm8915->hpout_pending & HPOUT1L) {
762 val |= WM8915_HPOUT1L_RMV_SHORT;
763 mask |= WM8915_HPOUT1L_RMV_SHORT;
764 } else {
765 mask |= WM8915_HPOUT1L_RMV_SHORT |
766 WM8915_HPOUT1L_OUTP |
767 WM8915_HPOUT1L_DLY;
768 }
769
770 if (wm8915->hpout_pending & HPOUT1R) {
771 val |= WM8915_HPOUT1R_RMV_SHORT;
772 mask |= WM8915_HPOUT1R_RMV_SHORT;
773 } else {
774 mask |= WM8915_HPOUT1R_RMV_SHORT |
775 WM8915_HPOUT1R_OUTP |
776 WM8915_HPOUT1R_DLY;
777 }
778
779 snd_soc_update_bits(codec, WM8915_ANALOGUE_HP_1, mask, val);
780
781 val = 0;
782 mask = 0;
783 if (wm8915->hpout_pending & HPOUT2L) {
784 val |= WM8915_HPOUT2L_RMV_SHORT;
785 mask |= WM8915_HPOUT2L_RMV_SHORT;
786 } else {
787 mask |= WM8915_HPOUT2L_RMV_SHORT |
788 WM8915_HPOUT2L_OUTP |
789 WM8915_HPOUT2L_DLY;
790 }
791
792 if (wm8915->hpout_pending & HPOUT2R) {
793 val |= WM8915_HPOUT2R_RMV_SHORT;
794 mask |= WM8915_HPOUT2R_RMV_SHORT;
795 } else {
796 mask |= WM8915_HPOUT2R_RMV_SHORT |
797 WM8915_HPOUT2R_OUTP |
798 WM8915_HPOUT2R_DLY;
799 }
800
801 snd_soc_update_bits(codec, WM8915_ANALOGUE_HP_2, mask, val);
802
803 wm8915->hpout_ena = wm8915->hpout_pending;
804 }
805}
806
807static int dcs_start(struct snd_soc_dapm_widget *w,
808 struct snd_kcontrol *kcontrol, int event)
809{
810 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(w->codec);
811
812 switch (event) {
813 case SND_SOC_DAPM_POST_PMU:
814 wm8915->dcs_pending |= 1 << w->shift;
815 break;
816 default:
817 BUG();
818 return -EINVAL;
819 }
820
821 return 0;
822}
823
824static const char *sidetone_text[] = {
825 "IN1", "IN2",
826};
827
828static const struct soc_enum left_sidetone_enum =
829 SOC_ENUM_SINGLE(WM8915_SIDETONE, 0, 2, sidetone_text);
830
831static const struct snd_kcontrol_new left_sidetone =
832 SOC_DAPM_ENUM("Left Sidetone", left_sidetone_enum);
833
834static const struct soc_enum right_sidetone_enum =
835 SOC_ENUM_SINGLE(WM8915_SIDETONE, 1, 2, sidetone_text);
836
837static const struct snd_kcontrol_new right_sidetone =
838 SOC_DAPM_ENUM("Right Sidetone", right_sidetone_enum);
839
840static const char *spk_text[] = {
841 "DAC1L", "DAC1R", "DAC2L", "DAC2R"
842};
843
844static const struct soc_enum spkl_enum =
845 SOC_ENUM_SINGLE(WM8915_LEFT_PDM_SPEAKER, 0, 4, spk_text);
846
847static const struct snd_kcontrol_new spkl_mux =
848 SOC_DAPM_ENUM("SPKL", spkl_enum);
849
850static const struct soc_enum spkr_enum =
851 SOC_ENUM_SINGLE(WM8915_RIGHT_PDM_SPEAKER, 0, 4, spk_text);
852
853static const struct snd_kcontrol_new spkr_mux =
854 SOC_DAPM_ENUM("SPKR", spkr_enum);
855
856static const char *dsp1rx_text[] = {
857 "AIF1", "AIF2"
858};
859
860static const struct soc_enum dsp1rx_enum =
861 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 0, 2, dsp1rx_text);
862
863static const struct snd_kcontrol_new dsp1rx =
864 SOC_DAPM_ENUM("DSP1RX", dsp1rx_enum);
865
866static const char *dsp2rx_text[] = {
867 "AIF2", "AIF1"
868};
869
870static const struct soc_enum dsp2rx_enum =
871 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 4, 2, dsp2rx_text);
872
873static const struct snd_kcontrol_new dsp2rx =
874 SOC_DAPM_ENUM("DSP2RX", dsp2rx_enum);
875
876static const char *aif2tx_text[] = {
877 "DSP2", "DSP1", "AIF1"
878};
879
880static const struct soc_enum aif2tx_enum =
881 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 6, 3, aif2tx_text);
882
883static const struct snd_kcontrol_new aif2tx =
884 SOC_DAPM_ENUM("AIF2TX", aif2tx_enum);
885
886static const char *inmux_text[] = {
887 "ADC", "DMIC1", "DMIC2"
888};
889
890static const struct soc_enum in1_enum =
891 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_7, 0, 3, inmux_text);
892
893static const struct snd_kcontrol_new in1_mux =
894 SOC_DAPM_ENUM("IN1 Mux", in1_enum);
895
896static const struct soc_enum in2_enum =
897 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_7, 4, 3, inmux_text);
898
899static const struct snd_kcontrol_new in2_mux =
900 SOC_DAPM_ENUM("IN2 Mux", in2_enum);
901
902static const struct snd_kcontrol_new dac2r_mix[] = {
903SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING,
904 5, 1, 0),
905SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING,
906 4, 1, 0),
907SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, 1, 1, 0),
908SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, 0, 1, 0),
909};
910
911static const struct snd_kcontrol_new dac2l_mix[] = {
912SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC2_LEFT_MIXER_ROUTING,
913 5, 1, 0),
914SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC2_LEFT_MIXER_ROUTING,
915 4, 1, 0),
916SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, 1, 1, 0),
917SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, 0, 1, 0),
918};
919
920static const struct snd_kcontrol_new dac1r_mix[] = {
921SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING,
922 5, 1, 0),
923SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING,
924 4, 1, 0),
925SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, 1, 1, 0),
926SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, 0, 1, 0),
927};
928
929static const struct snd_kcontrol_new dac1l_mix[] = {
930SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC1_LEFT_MIXER_ROUTING,
931 5, 1, 0),
932SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC1_LEFT_MIXER_ROUTING,
933 4, 1, 0),
934SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, 1, 1, 0),
935SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, 0, 1, 0),
936};
937
938static const struct snd_kcontrol_new dsp1txl[] = {
939SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP1_TX_LEFT_MIXER_ROUTING,
940 1, 1, 0),
941SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP1_TX_LEFT_MIXER_ROUTING,
942 0, 1, 0),
943};
944
945static const struct snd_kcontrol_new dsp1txr[] = {
946SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP1_TX_RIGHT_MIXER_ROUTING,
947 1, 1, 0),
948SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP1_TX_RIGHT_MIXER_ROUTING,
949 0, 1, 0),
950};
951
952static const struct snd_kcontrol_new dsp2txl[] = {
953SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP2_TX_LEFT_MIXER_ROUTING,
954 1, 1, 0),
955SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP2_TX_LEFT_MIXER_ROUTING,
956 0, 1, 0),
957};
958
959static const struct snd_kcontrol_new dsp2txr[] = {
960SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP2_TX_RIGHT_MIXER_ROUTING,
961 1, 1, 0),
962SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP2_TX_RIGHT_MIXER_ROUTING,
963 0, 1, 0),
964};
965
966
967static const struct snd_soc_dapm_widget wm8915_dapm_widgets[] = {
968SND_SOC_DAPM_INPUT("IN1LN"),
969SND_SOC_DAPM_INPUT("IN1LP"),
970SND_SOC_DAPM_INPUT("IN1RN"),
971SND_SOC_DAPM_INPUT("IN1RP"),
972
973SND_SOC_DAPM_INPUT("IN2LN"),
974SND_SOC_DAPM_INPUT("IN2LP"),
975SND_SOC_DAPM_INPUT("IN2RN"),
976SND_SOC_DAPM_INPUT("IN2RP"),
977
978SND_SOC_DAPM_INPUT("DMIC1DAT"),
979SND_SOC_DAPM_INPUT("DMIC2DAT"),
980
981SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8915_AIF_CLOCKING_1, 0, 0, NULL, 0),
982SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8915_CLOCKING_1, 1, 0, NULL, 0),
983SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8915_CLOCKING_1, 2, 0, NULL, 0),
984SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8915_CHARGE_PUMP_1, 15, 0, cp_event,
985 SND_SOC_DAPM_POST_PMU),
986
987SND_SOC_DAPM_SUPPLY("LDO2", WM8915_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
988SND_SOC_DAPM_MICBIAS("MICB2", WM8915_POWER_MANAGEMENT_1, 9, 0),
989SND_SOC_DAPM_MICBIAS("MICB1", WM8915_POWER_MANAGEMENT_1, 8, 0),
990
991SND_SOC_DAPM_PGA("IN1L PGA", WM8915_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
992SND_SOC_DAPM_PGA("IN1R PGA", WM8915_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
993
994SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &in1_mux),
995SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &in1_mux),
996SND_SOC_DAPM_MUX("IN2L Mux", SND_SOC_NOPM, 0, 0, &in2_mux),
997SND_SOC_DAPM_MUX("IN2R Mux", SND_SOC_NOPM, 0, 0, &in2_mux),
998
999SND_SOC_DAPM_PGA("IN1L", WM8915_POWER_MANAGEMENT_7, 2, 0, NULL, 0),
1000SND_SOC_DAPM_PGA("IN1R", WM8915_POWER_MANAGEMENT_7, 3, 0, NULL, 0),
1001SND_SOC_DAPM_PGA("IN2L", WM8915_POWER_MANAGEMENT_7, 6, 0, NULL, 0),
1002SND_SOC_DAPM_PGA("IN2R", WM8915_POWER_MANAGEMENT_7, 7, 0, NULL, 0),
1003
1004SND_SOC_DAPM_SUPPLY("DMIC2", WM8915_POWER_MANAGEMENT_7, 9, 0, NULL, 0),
1005SND_SOC_DAPM_SUPPLY("DMIC1", WM8915_POWER_MANAGEMENT_7, 8, 0, NULL, 0),
1006
1007SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8915_POWER_MANAGEMENT_3, 5, 0),
1008SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8915_POWER_MANAGEMENT_3, 4, 0),
1009SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8915_POWER_MANAGEMENT_3, 3, 0),
1010SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8915_POWER_MANAGEMENT_3, 2, 0),
1011
1012SND_SOC_DAPM_ADC("ADCL", NULL, WM8915_POWER_MANAGEMENT_3, 1, 0),
1013SND_SOC_DAPM_ADC("ADCR", NULL, WM8915_POWER_MANAGEMENT_3, 0, 0),
1014
1015SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &left_sidetone),
1016SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &right_sidetone),
1017
1018SND_SOC_DAPM_AIF_IN("DSP2RXL", NULL, 0, WM8915_POWER_MANAGEMENT_3, 11, 0),
1019SND_SOC_DAPM_AIF_IN("DSP2RXR", NULL, 1, WM8915_POWER_MANAGEMENT_3, 10, 0),
1020SND_SOC_DAPM_AIF_IN("DSP1RXL", NULL, 0, WM8915_POWER_MANAGEMENT_3, 9, 0),
1021SND_SOC_DAPM_AIF_IN("DSP1RXR", NULL, 1, WM8915_POWER_MANAGEMENT_3, 8, 0),
1022
1023SND_SOC_DAPM_MIXER("DSP2TXL", WM8915_POWER_MANAGEMENT_5, 11, 0,
1024 dsp2txl, ARRAY_SIZE(dsp2txl)),
1025SND_SOC_DAPM_MIXER("DSP2TXR", WM8915_POWER_MANAGEMENT_5, 10, 0,
1026 dsp2txr, ARRAY_SIZE(dsp2txr)),
1027SND_SOC_DAPM_MIXER("DSP1TXL", WM8915_POWER_MANAGEMENT_5, 9, 0,
1028 dsp1txl, ARRAY_SIZE(dsp1txl)),
1029SND_SOC_DAPM_MIXER("DSP1TXR", WM8915_POWER_MANAGEMENT_5, 8, 0,
1030 dsp1txr, ARRAY_SIZE(dsp1txr)),
1031
1032SND_SOC_DAPM_MIXER("DAC2L Mixer", SND_SOC_NOPM, 0, 0,
1033 dac2l_mix, ARRAY_SIZE(dac2l_mix)),
1034SND_SOC_DAPM_MIXER("DAC2R Mixer", SND_SOC_NOPM, 0, 0,
1035 dac2r_mix, ARRAY_SIZE(dac2r_mix)),
1036SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0,
1037 dac1l_mix, ARRAY_SIZE(dac1l_mix)),
1038SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,
1039 dac1r_mix, ARRAY_SIZE(dac1r_mix)),
1040
1041SND_SOC_DAPM_DAC("DAC2L", NULL, WM8915_POWER_MANAGEMENT_5, 3, 0),
1042SND_SOC_DAPM_DAC("DAC2R", NULL, WM8915_POWER_MANAGEMENT_5, 2, 0),
1043SND_SOC_DAPM_DAC("DAC1L", NULL, WM8915_POWER_MANAGEMENT_5, 1, 0),
1044SND_SOC_DAPM_DAC("DAC1R", NULL, WM8915_POWER_MANAGEMENT_5, 0, 0),
1045
1046SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 1,
1047 WM8915_POWER_MANAGEMENT_4, 9, 0),
1048SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 2,
1049 WM8915_POWER_MANAGEMENT_4, 8, 0),
1050
1051SND_SOC_DAPM_AIF_IN("AIF2TX1", "AIF2 Capture", 1,
1052 WM8915_POWER_MANAGEMENT_6, 9, 0),
1053SND_SOC_DAPM_AIF_IN("AIF2TX0", "AIF2 Capture", 2,
1054 WM8915_POWER_MANAGEMENT_6, 8, 0),
1055
1056SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5,
1057 WM8915_POWER_MANAGEMENT_4, 5, 0),
1058SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 4,
1059 WM8915_POWER_MANAGEMENT_4, 4, 0),
1060SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 3,
1061 WM8915_POWER_MANAGEMENT_4, 3, 0),
1062SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 2,
1063 WM8915_POWER_MANAGEMENT_4, 2, 0),
1064SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 1,
1065 WM8915_POWER_MANAGEMENT_4, 1, 0),
1066SND_SOC_DAPM_AIF_IN("AIF1RX0", "AIF1 Playback", 0,
1067 WM8915_POWER_MANAGEMENT_4, 0, 0),
1068
1069SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 5,
1070 WM8915_POWER_MANAGEMENT_6, 5, 0),
1071SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 4,
1072 WM8915_POWER_MANAGEMENT_6, 4, 0),
1073SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 3,
1074 WM8915_POWER_MANAGEMENT_6, 3, 0),
1075SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 2,
1076 WM8915_POWER_MANAGEMENT_6, 2, 0),
1077SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 1,
1078 WM8915_POWER_MANAGEMENT_6, 1, 0),
1079SND_SOC_DAPM_AIF_OUT("AIF1TX0", "AIF1 Capture", 0,
1080 WM8915_POWER_MANAGEMENT_6, 0, 0),
1081
1082/* We route as stereo pairs so define some dummy widgets to squash
1083 * things down for now. RXA = 0,1, RXB = 2,3 and so on */
1084SND_SOC_DAPM_PGA("AIF1RXA", SND_SOC_NOPM, 0, 0, NULL, 0),
1085SND_SOC_DAPM_PGA("AIF1RXB", SND_SOC_NOPM, 0, 0, NULL, 0),
1086SND_SOC_DAPM_PGA("AIF1RXC", SND_SOC_NOPM, 0, 0, NULL, 0),
1087SND_SOC_DAPM_PGA("AIF2RX", SND_SOC_NOPM, 0, 0, NULL, 0),
1088SND_SOC_DAPM_PGA("DSP2TX", SND_SOC_NOPM, 0, 0, NULL, 0),
1089
1090SND_SOC_DAPM_MUX("DSP1RX", SND_SOC_NOPM, 0, 0, &dsp1rx),
1091SND_SOC_DAPM_MUX("DSP2RX", SND_SOC_NOPM, 0, 0, &dsp2rx),
1092SND_SOC_DAPM_MUX("AIF2TX", SND_SOC_NOPM, 0, 0, &aif2tx),
1093
1094SND_SOC_DAPM_MUX("SPKL", SND_SOC_NOPM, 0, 0, &spkl_mux),
1095SND_SOC_DAPM_MUX("SPKR", SND_SOC_NOPM, 0, 0, &spkr_mux),
1096SND_SOC_DAPM_PGA("SPKL PGA", WM8915_LEFT_PDM_SPEAKER, 4, 0, NULL, 0),
1097SND_SOC_DAPM_PGA("SPKR PGA", WM8915_RIGHT_PDM_SPEAKER, 4, 0, NULL, 0),
1098
1099SND_SOC_DAPM_PGA_S("HPOUT2L PGA", 0, WM8915_POWER_MANAGEMENT_1, 7, 0, NULL, 0),
1100SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8915_ANALOGUE_HP_2, 5, 0, NULL, 0),
1101SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8915_DC_SERVO_1, 2, 0, dcs_start,
1102 SND_SOC_DAPM_POST_PMU),
1103SND_SOC_DAPM_PGA_S("HPOUT2L_OUTP", 3, WM8915_ANALOGUE_HP_2, 6, 0, NULL, 0),
1104SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0,
1105 rmv_short_event,
1106 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1107
1108SND_SOC_DAPM_PGA_S("HPOUT2R PGA", 0, WM8915_POWER_MANAGEMENT_1, 6, 0,NULL, 0),
1109SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8915_ANALOGUE_HP_2, 1, 0, NULL, 0),
1110SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8915_DC_SERVO_1, 3, 0, dcs_start,
1111 SND_SOC_DAPM_POST_PMU),
1112SND_SOC_DAPM_PGA_S("HPOUT2R_OUTP", 3, WM8915_ANALOGUE_HP_2, 2, 0, NULL, 0),
1113SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0,
1114 rmv_short_event,
1115 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1116
1117SND_SOC_DAPM_PGA_S("HPOUT1L PGA", 0, WM8915_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
1118SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8915_ANALOGUE_HP_1, 5, 0, NULL, 0),
1119SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8915_DC_SERVO_1, 0, 0, dcs_start,
1120 SND_SOC_DAPM_POST_PMU),
1121SND_SOC_DAPM_PGA_S("HPOUT1L_OUTP", 3, WM8915_ANALOGUE_HP_1, 6, 0, NULL, 0),
1122SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0,
1123 rmv_short_event,
1124 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1125
1126SND_SOC_DAPM_PGA_S("HPOUT1R PGA", 0, WM8915_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
1127SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8915_ANALOGUE_HP_1, 1, 0, NULL, 0),
1128SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8915_DC_SERVO_1, 1, 0, dcs_start,
1129 SND_SOC_DAPM_POST_PMU),
1130SND_SOC_DAPM_PGA_S("HPOUT1R_OUTP", 3, WM8915_ANALOGUE_HP_1, 2, 0, NULL, 0),
1131SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0,
1132 rmv_short_event,
1133 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1134
1135SND_SOC_DAPM_OUTPUT("HPOUT1L"),
1136SND_SOC_DAPM_OUTPUT("HPOUT1R"),
1137SND_SOC_DAPM_OUTPUT("HPOUT2L"),
1138SND_SOC_DAPM_OUTPUT("HPOUT2R"),
1139SND_SOC_DAPM_OUTPUT("SPKDAT"),
1140};
1141
1142static const struct snd_soc_dapm_route wm8915_dapm_routes[] = {
1143 { "AIFCLK", NULL, "SYSCLK" },
1144 { "SYSDSPCLK", NULL, "SYSCLK" },
1145 { "Charge Pump", NULL, "SYSCLK" },
1146
1147 { "MICB1", NULL, "LDO2" },
1148 { "MICB2", NULL, "LDO2" },
1149
1150 { "IN1L PGA", NULL, "IN2LN" },
1151 { "IN1L PGA", NULL, "IN2LP" },
1152 { "IN1L PGA", NULL, "IN1LN" },
1153 { "IN1L PGA", NULL, "IN1LP" },
1154
1155 { "IN1R PGA", NULL, "IN2RN" },
1156 { "IN1R PGA", NULL, "IN2RP" },
1157 { "IN1R PGA", NULL, "IN1RN" },
1158 { "IN1R PGA", NULL, "IN1RP" },
1159
1160 { "ADCL", NULL, "IN1L PGA" },
1161
1162 { "ADCR", NULL, "IN1R PGA" },
1163
1164 { "DMIC1L", NULL, "DMIC1DAT" },
1165 { "DMIC1R", NULL, "DMIC1DAT" },
1166 { "DMIC2L", NULL, "DMIC2DAT" },
1167 { "DMIC2R", NULL, "DMIC2DAT" },
1168
1169 { "DMIC2L", NULL, "DMIC2" },
1170 { "DMIC2R", NULL, "DMIC2" },
1171 { "DMIC1L", NULL, "DMIC1" },
1172 { "DMIC1R", NULL, "DMIC1" },
1173
1174 { "IN1L Mux", "ADC", "ADCL" },
1175 { "IN1L Mux", "DMIC1", "DMIC1L" },
1176 { "IN1L Mux", "DMIC2", "DMIC2L" },
1177
1178 { "IN1R Mux", "ADC", "ADCR" },
1179 { "IN1R Mux", "DMIC1", "DMIC1R" },
1180 { "IN1R Mux", "DMIC2", "DMIC2R" },
1181
1182 { "IN2L Mux", "ADC", "ADCL" },
1183 { "IN2L Mux", "DMIC1", "DMIC1L" },
1184 { "IN2L Mux", "DMIC2", "DMIC2L" },
1185
1186 { "IN2R Mux", "ADC", "ADCR" },
1187 { "IN2R Mux", "DMIC1", "DMIC1R" },
1188 { "IN2R Mux", "DMIC2", "DMIC2R" },
1189
1190 { "Left Sidetone", "IN1", "IN1L Mux" },
1191 { "Left Sidetone", "IN2", "IN2L Mux" },
1192
1193 { "Right Sidetone", "IN1", "IN1R Mux" },
1194 { "Right Sidetone", "IN2", "IN2R Mux" },
1195
1196 { "DSP1TXL", "IN1 Switch", "IN1L Mux" },
1197 { "DSP1TXR", "IN1 Switch", "IN1R Mux" },
1198
1199 { "DSP2TXL", "IN1 Switch", "IN2L Mux" },
1200 { "DSP2TXR", "IN1 Switch", "IN2R Mux" },
1201
1202 { "AIF1TX0", NULL, "DSP1TXL" },
1203 { "AIF1TX1", NULL, "DSP1TXR" },
1204 { "AIF1TX2", NULL, "DSP2TXL" },
1205 { "AIF1TX3", NULL, "DSP2TXR" },
1206 { "AIF1TX4", NULL, "AIF2RX0" },
1207 { "AIF1TX5", NULL, "AIF2RX1" },
1208
1209 { "AIF1RX0", NULL, "AIFCLK" },
1210 { "AIF1RX1", NULL, "AIFCLK" },
1211 { "AIF1RX2", NULL, "AIFCLK" },
1212 { "AIF1RX3", NULL, "AIFCLK" },
1213 { "AIF1RX4", NULL, "AIFCLK" },
1214 { "AIF1RX5", NULL, "AIFCLK" },
1215
1216 { "AIF2RX0", NULL, "AIFCLK" },
1217 { "AIF2RX1", NULL, "AIFCLK" },
1218
1219 { "DSP1RXL", NULL, "SYSDSPCLK" },
1220 { "DSP1RXR", NULL, "SYSDSPCLK" },
1221 { "DSP2RXL", NULL, "SYSDSPCLK" },
1222 { "DSP2RXR", NULL, "SYSDSPCLK" },
1223 { "DSP1TXL", NULL, "SYSDSPCLK" },
1224 { "DSP1TXR", NULL, "SYSDSPCLK" },
1225 { "DSP2TXL", NULL, "SYSDSPCLK" },
1226 { "DSP2TXR", NULL, "SYSDSPCLK" },
1227
1228 { "AIF1RXA", NULL, "AIF1RX0" },
1229 { "AIF1RXA", NULL, "AIF1RX1" },
1230 { "AIF1RXB", NULL, "AIF1RX2" },
1231 { "AIF1RXB", NULL, "AIF1RX3" },
1232 { "AIF1RXC", NULL, "AIF1RX4" },
1233 { "AIF1RXC", NULL, "AIF1RX5" },
1234
1235 { "AIF2RX", NULL, "AIF2RX0" },
1236 { "AIF2RX", NULL, "AIF2RX1" },
1237
1238 { "AIF2TX", "DSP2", "DSP2TX" },
1239 { "AIF2TX", "DSP1", "DSP1RX" },
1240 { "AIF2TX", "AIF1", "AIF1RXC" },
1241
1242 { "DSP1RXL", NULL, "DSP1RX" },
1243 { "DSP1RXR", NULL, "DSP1RX" },
1244 { "DSP2RXL", NULL, "DSP2RX" },
1245 { "DSP2RXR", NULL, "DSP2RX" },
1246
1247 { "DSP2TX", NULL, "DSP2TXL" },
1248 { "DSP2TX", NULL, "DSP2TXR" },
1249
1250 { "DSP1RX", "AIF1", "AIF1RXA" },
1251 { "DSP1RX", "AIF2", "AIF2RX" },
1252
1253 { "DSP2RX", "AIF1", "AIF1RXB" },
1254 { "DSP2RX", "AIF2", "AIF2RX" },
1255
1256 { "DAC2L Mixer", "DSP2 Switch", "DSP2RXL" },
1257 { "DAC2L Mixer", "DSP1 Switch", "DSP1RXL" },
1258 { "DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
1259 { "DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },
1260
1261 { "DAC2R Mixer", "DSP2 Switch", "DSP2RXR" },
1262 { "DAC2R Mixer", "DSP1 Switch", "DSP1RXR" },
1263 { "DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
1264 { "DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
1265
1266 { "DAC1L Mixer", "DSP2 Switch", "DSP2RXL" },
1267 { "DAC1L Mixer", "DSP1 Switch", "DSP1RXL" },
1268 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
1269 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
1270
1271 { "DAC1R Mixer", "DSP2 Switch", "DSP2RXR" },
1272 { "DAC1R Mixer", "DSP1 Switch", "DSP1RXR" },
1273 { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
1274 { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
1275
1276 { "DAC1L", NULL, "DAC1L Mixer" },
1277 { "DAC1R", NULL, "DAC1R Mixer" },
1278 { "DAC2L", NULL, "DAC2L Mixer" },
1279 { "DAC2R", NULL, "DAC2R Mixer" },
1280
1281 { "HPOUT2L PGA", NULL, "Charge Pump" },
1282 { "HPOUT2L PGA", NULL, "DAC2L" },
1283 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" },
1284 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" },
1285 { "HPOUT2L_OUTP", NULL, "HPOUT2L_DCS" },
1286 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" },
1287
1288 { "HPOUT2R PGA", NULL, "Charge Pump" },
1289 { "HPOUT2R PGA", NULL, "DAC2R" },
1290 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" },
1291 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" },
1292 { "HPOUT2R_OUTP", NULL, "HPOUT2R_DCS" },
1293 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" },
1294
1295 { "HPOUT1L PGA", NULL, "Charge Pump" },
1296 { "HPOUT1L PGA", NULL, "DAC1L" },
1297 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" },
1298 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" },
1299 { "HPOUT1L_OUTP", NULL, "HPOUT1L_DCS" },
1300 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" },
1301
1302 { "HPOUT1R PGA", NULL, "Charge Pump" },
1303 { "HPOUT1R PGA", NULL, "DAC1R" },
1304 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" },
1305 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" },
1306 { "HPOUT1R_OUTP", NULL, "HPOUT1R_DCS" },
1307 { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_OUTP" },
1308
1309 { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" },
1310 { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" },
1311 { "HPOUT1L", NULL, "HPOUT1L_RMV_SHORT" },
1312 { "HPOUT1R", NULL, "HPOUT1R_RMV_SHORT" },
1313
1314 { "SPKL", "DAC1L", "DAC1L" },
1315 { "SPKL", "DAC1R", "DAC1R" },
1316 { "SPKL", "DAC2L", "DAC2L" },
1317 { "SPKL", "DAC2R", "DAC2R" },
1318
1319 { "SPKR", "DAC1L", "DAC1L" },
1320 { "SPKR", "DAC1R", "DAC1R" },
1321 { "SPKR", "DAC2L", "DAC2L" },
1322 { "SPKR", "DAC2R", "DAC2R" },
1323
1324 { "SPKL PGA", NULL, "SPKL" },
1325 { "SPKR PGA", NULL, "SPKR" },
1326
1327 { "SPKDAT", NULL, "SPKL PGA" },
1328 { "SPKDAT", NULL, "SPKR PGA" },
1329};
1330
1331static int wm8915_readable_register(struct snd_soc_codec *codec,
1332 unsigned int reg)
1333{
1334 /* Due to the sparseness of the register map the compiler
1335 * output from an explicit switch statement ends up being much
1336 * more efficient than a table.
1337 */
1338 switch (reg) {
1339 case WM8915_SOFTWARE_RESET:
1340 case WM8915_POWER_MANAGEMENT_1:
1341 case WM8915_POWER_MANAGEMENT_2:
1342 case WM8915_POWER_MANAGEMENT_3:
1343 case WM8915_POWER_MANAGEMENT_4:
1344 case WM8915_POWER_MANAGEMENT_5:
1345 case WM8915_POWER_MANAGEMENT_6:
1346 case WM8915_POWER_MANAGEMENT_7:
1347 case WM8915_POWER_MANAGEMENT_8:
1348 case WM8915_LEFT_LINE_INPUT_VOLUME:
1349 case WM8915_RIGHT_LINE_INPUT_VOLUME:
1350 case WM8915_LINE_INPUT_CONTROL:
1351 case WM8915_DAC1_HPOUT1_VOLUME:
1352 case WM8915_DAC2_HPOUT2_VOLUME:
1353 case WM8915_DAC1_LEFT_VOLUME:
1354 case WM8915_DAC1_RIGHT_VOLUME:
1355 case WM8915_DAC2_LEFT_VOLUME:
1356 case WM8915_DAC2_RIGHT_VOLUME:
1357 case WM8915_OUTPUT1_LEFT_VOLUME:
1358 case WM8915_OUTPUT1_RIGHT_VOLUME:
1359 case WM8915_OUTPUT2_LEFT_VOLUME:
1360 case WM8915_OUTPUT2_RIGHT_VOLUME:
1361 case WM8915_MICBIAS_1:
1362 case WM8915_MICBIAS_2:
1363 case WM8915_LDO_1:
1364 case WM8915_LDO_2:
1365 case WM8915_ACCESSORY_DETECT_MODE_1:
1366 case WM8915_ACCESSORY_DETECT_MODE_2:
1367 case WM8915_HEADPHONE_DETECT_1:
1368 case WM8915_HEADPHONE_DETECT_2:
1369 case WM8915_MIC_DETECT_1:
1370 case WM8915_MIC_DETECT_2:
1371 case WM8915_MIC_DETECT_3:
1372 case WM8915_CHARGE_PUMP_1:
1373 case WM8915_CHARGE_PUMP_2:
1374 case WM8915_DC_SERVO_1:
1375 case WM8915_DC_SERVO_2:
1376 case WM8915_DC_SERVO_3:
1377 case WM8915_DC_SERVO_5:
1378 case WM8915_DC_SERVO_6:
1379 case WM8915_DC_SERVO_7:
1380 case WM8915_DC_SERVO_READBACK_0:
1381 case WM8915_ANALOGUE_HP_1:
1382 case WM8915_ANALOGUE_HP_2:
1383 case WM8915_CHIP_REVISION:
1384 case WM8915_CONTROL_INTERFACE_1:
1385 case WM8915_WRITE_SEQUENCER_CTRL_1:
1386 case WM8915_WRITE_SEQUENCER_CTRL_2:
1387 case WM8915_AIF_CLOCKING_1:
1388 case WM8915_AIF_CLOCKING_2:
1389 case WM8915_CLOCKING_1:
1390 case WM8915_CLOCKING_2:
1391 case WM8915_AIF_RATE:
1392 case WM8915_FLL_CONTROL_1:
1393 case WM8915_FLL_CONTROL_2:
1394 case WM8915_FLL_CONTROL_3:
1395 case WM8915_FLL_CONTROL_4:
1396 case WM8915_FLL_CONTROL_5:
1397 case WM8915_FLL_CONTROL_6:
1398 case WM8915_FLL_EFS_1:
1399 case WM8915_FLL_EFS_2:
1400 case WM8915_AIF1_CONTROL:
1401 case WM8915_AIF1_BCLK:
1402 case WM8915_AIF1_TX_LRCLK_1:
1403 case WM8915_AIF1_TX_LRCLK_2:
1404 case WM8915_AIF1_RX_LRCLK_1:
1405 case WM8915_AIF1_RX_LRCLK_2:
1406 case WM8915_AIF1TX_DATA_CONFIGURATION_1:
1407 case WM8915_AIF1TX_DATA_CONFIGURATION_2:
1408 case WM8915_AIF1RX_DATA_CONFIGURATION:
1409 case WM8915_AIF1TX_CHANNEL_0_CONFIGURATION:
1410 case WM8915_AIF1TX_CHANNEL_1_CONFIGURATION:
1411 case WM8915_AIF1TX_CHANNEL_2_CONFIGURATION:
1412 case WM8915_AIF1TX_CHANNEL_3_CONFIGURATION:
1413 case WM8915_AIF1TX_CHANNEL_4_CONFIGURATION:
1414 case WM8915_AIF1TX_CHANNEL_5_CONFIGURATION:
1415 case WM8915_AIF1RX_CHANNEL_0_CONFIGURATION:
1416 case WM8915_AIF1RX_CHANNEL_1_CONFIGURATION:
1417 case WM8915_AIF1RX_CHANNEL_2_CONFIGURATION:
1418 case WM8915_AIF1RX_CHANNEL_3_CONFIGURATION:
1419 case WM8915_AIF1RX_CHANNEL_4_CONFIGURATION:
1420 case WM8915_AIF1RX_CHANNEL_5_CONFIGURATION:
1421 case WM8915_AIF1RX_MONO_CONFIGURATION:
1422 case WM8915_AIF1TX_TEST:
1423 case WM8915_AIF2_CONTROL:
1424 case WM8915_AIF2_BCLK:
1425 case WM8915_AIF2_TX_LRCLK_1:
1426 case WM8915_AIF2_TX_LRCLK_2:
1427 case WM8915_AIF2_RX_LRCLK_1:
1428 case WM8915_AIF2_RX_LRCLK_2:
1429 case WM8915_AIF2TX_DATA_CONFIGURATION_1:
1430 case WM8915_AIF2TX_DATA_CONFIGURATION_2:
1431 case WM8915_AIF2RX_DATA_CONFIGURATION:
1432 case WM8915_AIF2TX_CHANNEL_0_CONFIGURATION:
1433 case WM8915_AIF2TX_CHANNEL_1_CONFIGURATION:
1434 case WM8915_AIF2RX_CHANNEL_0_CONFIGURATION:
1435 case WM8915_AIF2RX_CHANNEL_1_CONFIGURATION:
1436 case WM8915_AIF2RX_MONO_CONFIGURATION:
1437 case WM8915_AIF2TX_TEST:
1438 case WM8915_DSP1_TX_LEFT_VOLUME:
1439 case WM8915_DSP1_TX_RIGHT_VOLUME:
1440 case WM8915_DSP1_RX_LEFT_VOLUME:
1441 case WM8915_DSP1_RX_RIGHT_VOLUME:
1442 case WM8915_DSP1_TX_FILTERS:
1443 case WM8915_DSP1_RX_FILTERS_1:
1444 case WM8915_DSP1_RX_FILTERS_2:
1445 case WM8915_DSP1_DRC_1:
1446 case WM8915_DSP1_DRC_2:
1447 case WM8915_DSP1_DRC_3:
1448 case WM8915_DSP1_DRC_4:
1449 case WM8915_DSP1_DRC_5:
1450 case WM8915_DSP1_RX_EQ_GAINS_1:
1451 case WM8915_DSP1_RX_EQ_GAINS_2:
1452 case WM8915_DSP1_RX_EQ_BAND_1_A:
1453 case WM8915_DSP1_RX_EQ_BAND_1_B:
1454 case WM8915_DSP1_RX_EQ_BAND_1_PG:
1455 case WM8915_DSP1_RX_EQ_BAND_2_A:
1456 case WM8915_DSP1_RX_EQ_BAND_2_B:
1457 case WM8915_DSP1_RX_EQ_BAND_2_C:
1458 case WM8915_DSP1_RX_EQ_BAND_2_PG:
1459 case WM8915_DSP1_RX_EQ_BAND_3_A:
1460 case WM8915_DSP1_RX_EQ_BAND_3_B:
1461 case WM8915_DSP1_RX_EQ_BAND_3_C:
1462 case WM8915_DSP1_RX_EQ_BAND_3_PG:
1463 case WM8915_DSP1_RX_EQ_BAND_4_A:
1464 case WM8915_DSP1_RX_EQ_BAND_4_B:
1465 case WM8915_DSP1_RX_EQ_BAND_4_C:
1466 case WM8915_DSP1_RX_EQ_BAND_4_PG:
1467 case WM8915_DSP1_RX_EQ_BAND_5_A:
1468 case WM8915_DSP1_RX_EQ_BAND_5_B:
1469 case WM8915_DSP1_RX_EQ_BAND_5_PG:
1470 case WM8915_DSP2_TX_LEFT_VOLUME:
1471 case WM8915_DSP2_TX_RIGHT_VOLUME:
1472 case WM8915_DSP2_RX_LEFT_VOLUME:
1473 case WM8915_DSP2_RX_RIGHT_VOLUME:
1474 case WM8915_DSP2_TX_FILTERS:
1475 case WM8915_DSP2_RX_FILTERS_1:
1476 case WM8915_DSP2_RX_FILTERS_2:
1477 case WM8915_DSP2_DRC_1:
1478 case WM8915_DSP2_DRC_2:
1479 case WM8915_DSP2_DRC_3:
1480 case WM8915_DSP2_DRC_4:
1481 case WM8915_DSP2_DRC_5:
1482 case WM8915_DSP2_RX_EQ_GAINS_1:
1483 case WM8915_DSP2_RX_EQ_GAINS_2:
1484 case WM8915_DSP2_RX_EQ_BAND_1_A:
1485 case WM8915_DSP2_RX_EQ_BAND_1_B:
1486 case WM8915_DSP2_RX_EQ_BAND_1_PG:
1487 case WM8915_DSP2_RX_EQ_BAND_2_A:
1488 case WM8915_DSP2_RX_EQ_BAND_2_B:
1489 case WM8915_DSP2_RX_EQ_BAND_2_C:
1490 case WM8915_DSP2_RX_EQ_BAND_2_PG:
1491 case WM8915_DSP2_RX_EQ_BAND_3_A:
1492 case WM8915_DSP2_RX_EQ_BAND_3_B:
1493 case WM8915_DSP2_RX_EQ_BAND_3_C:
1494 case WM8915_DSP2_RX_EQ_BAND_3_PG:
1495 case WM8915_DSP2_RX_EQ_BAND_4_A:
1496 case WM8915_DSP2_RX_EQ_BAND_4_B:
1497 case WM8915_DSP2_RX_EQ_BAND_4_C:
1498 case WM8915_DSP2_RX_EQ_BAND_4_PG:
1499 case WM8915_DSP2_RX_EQ_BAND_5_A:
1500 case WM8915_DSP2_RX_EQ_BAND_5_B:
1501 case WM8915_DSP2_RX_EQ_BAND_5_PG:
1502 case WM8915_DAC1_MIXER_VOLUMES:
1503 case WM8915_DAC1_LEFT_MIXER_ROUTING:
1504 case WM8915_DAC1_RIGHT_MIXER_ROUTING:
1505 case WM8915_DAC2_MIXER_VOLUMES:
1506 case WM8915_DAC2_LEFT_MIXER_ROUTING:
1507 case WM8915_DAC2_RIGHT_MIXER_ROUTING:
1508 case WM8915_DSP1_TX_LEFT_MIXER_ROUTING:
1509 case WM8915_DSP1_TX_RIGHT_MIXER_ROUTING:
1510 case WM8915_DSP2_TX_LEFT_MIXER_ROUTING:
1511 case WM8915_DSP2_TX_RIGHT_MIXER_ROUTING:
1512 case WM8915_DSP_TX_MIXER_SELECT:
1513 case WM8915_DAC_SOFTMUTE:
1514 case WM8915_OVERSAMPLING:
1515 case WM8915_SIDETONE:
1516 case WM8915_GPIO_1:
1517 case WM8915_GPIO_2:
1518 case WM8915_GPIO_3:
1519 case WM8915_GPIO_4:
1520 case WM8915_GPIO_5:
1521 case WM8915_PULL_CONTROL_1:
1522 case WM8915_PULL_CONTROL_2:
1523 case WM8915_INTERRUPT_STATUS_1:
1524 case WM8915_INTERRUPT_STATUS_2:
1525 case WM8915_INTERRUPT_RAW_STATUS_2:
1526 case WM8915_INTERRUPT_STATUS_1_MASK:
1527 case WM8915_INTERRUPT_STATUS_2_MASK:
1528 case WM8915_INTERRUPT_CONTROL:
1529 case WM8915_LEFT_PDM_SPEAKER:
1530 case WM8915_RIGHT_PDM_SPEAKER:
1531 case WM8915_PDM_SPEAKER_MUTE_SEQUENCE:
1532 case WM8915_PDM_SPEAKER_VOLUME:
1533 return 1;
1534 default:
1535 return 0;
1536 }
1537}
1538
1539static int wm8915_volatile_register(struct snd_soc_codec *codec,
1540 unsigned int reg)
1541{
1542 switch (reg) {
1543 case WM8915_SOFTWARE_RESET:
1544 case WM8915_CHIP_REVISION:
1545 case WM8915_LDO_1:
1546 case WM8915_LDO_2:
1547 case WM8915_INTERRUPT_STATUS_1:
1548 case WM8915_INTERRUPT_STATUS_2:
1549 case WM8915_INTERRUPT_RAW_STATUS_2:
1550 case WM8915_DC_SERVO_READBACK_0:
1551 case WM8915_DC_SERVO_2:
1552 case WM8915_DC_SERVO_6:
1553 case WM8915_DC_SERVO_7:
1554 case WM8915_FLL_CONTROL_6:
1555 case WM8915_MIC_DETECT_3:
1556 case WM8915_HEADPHONE_DETECT_1:
1557 case WM8915_HEADPHONE_DETECT_2:
1558 return 1;
1559 default:
1560 return 0;
1561 }
1562}
1563
1564static int wm8915_reset(struct snd_soc_codec *codec)
1565{
1566 return snd_soc_write(codec, WM8915_SOFTWARE_RESET, 0x8915);
1567}
1568
1569static int wm8915_set_bias_level(struct snd_soc_codec *codec,
1570 enum snd_soc_bias_level level)
1571{
1572 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
1573 int ret;
1574
1575 switch (level) {
1576 case SND_SOC_BIAS_ON:
1577 break;
1578
1579 case SND_SOC_BIAS_PREPARE:
1580 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
1581 snd_soc_update_bits(codec, WM8915_POWER_MANAGEMENT_1,
1582 WM8915_BG_ENA, WM8915_BG_ENA);
1583 msleep(2);
1584 }
1585 break;
1586
1587 case SND_SOC_BIAS_STANDBY:
1588 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1589 ret = regulator_bulk_enable(ARRAY_SIZE(wm8915->supplies),
1590 wm8915->supplies);
1591 if (ret != 0) {
1592 dev_err(codec->dev,
1593 "Failed to enable supplies: %d\n",
1594 ret);
1595 return ret;
1596 }
1597
1598 if (wm8915->pdata.ldo_ena >= 0) {
1599 gpio_set_value_cansleep(wm8915->pdata.ldo_ena,
1600 1);
1601 msleep(5);
1602 }
1603
1604 codec->cache_only = false;
1605 snd_soc_cache_sync(codec);
1606 }
1607
1608 snd_soc_update_bits(codec, WM8915_POWER_MANAGEMENT_1,
1609 WM8915_BG_ENA, 0);
1610 break;
1611
1612 case SND_SOC_BIAS_OFF:
1613 codec->cache_only = true;
1614 if (wm8915->pdata.ldo_ena >= 0)
1615 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0);
1616 regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies),
1617 wm8915->supplies);
1618 break;
1619 }
1620
1621 codec->dapm.bias_level = level;
1622
1623 return 0;
1624}
1625
1626static int wm8915_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1627{
1628 struct snd_soc_codec *codec = dai->codec;
1629 int aifctrl = 0;
1630 int bclk = 0;
1631 int lrclk_tx = 0;
1632 int lrclk_rx = 0;
1633 int aifctrl_reg, bclk_reg, lrclk_tx_reg, lrclk_rx_reg;
1634
1635 switch (dai->id) {
1636 case 0:
1637 aifctrl_reg = WM8915_AIF1_CONTROL;
1638 bclk_reg = WM8915_AIF1_BCLK;
1639 lrclk_tx_reg = WM8915_AIF1_TX_LRCLK_2;
1640 lrclk_rx_reg = WM8915_AIF1_RX_LRCLK_2;
1641 break;
1642 case 1:
1643 aifctrl_reg = WM8915_AIF2_CONTROL;
1644 bclk_reg = WM8915_AIF2_BCLK;
1645 lrclk_tx_reg = WM8915_AIF2_TX_LRCLK_2;
1646 lrclk_rx_reg = WM8915_AIF2_RX_LRCLK_2;
1647 break;
1648 default:
1649 BUG();
1650 return -EINVAL;
1651 }
1652
1653 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1654 case SND_SOC_DAIFMT_NB_NF:
1655 break;
1656 case SND_SOC_DAIFMT_IB_NF:
1657 bclk |= WM8915_AIF1_BCLK_INV;
1658 break;
1659 case SND_SOC_DAIFMT_NB_IF:
1660 lrclk_tx |= WM8915_AIF1TX_LRCLK_INV;
1661 lrclk_rx |= WM8915_AIF1RX_LRCLK_INV;
1662 break;
1663 case SND_SOC_DAIFMT_IB_IF:
1664 bclk |= WM8915_AIF1_BCLK_INV;
1665 lrclk_tx |= WM8915_AIF1TX_LRCLK_INV;
1666 lrclk_rx |= WM8915_AIF1RX_LRCLK_INV;
1667 break;
1668 }
1669
1670 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1671 case SND_SOC_DAIFMT_CBS_CFS:
1672 break;
1673 case SND_SOC_DAIFMT_CBS_CFM:
1674 lrclk_tx |= WM8915_AIF1TX_LRCLK_MSTR;
1675 lrclk_rx |= WM8915_AIF1RX_LRCLK_MSTR;
1676 break;
1677 case SND_SOC_DAIFMT_CBM_CFS:
1678 bclk |= WM8915_AIF1_BCLK_MSTR;
1679 break;
1680 case SND_SOC_DAIFMT_CBM_CFM:
1681 bclk |= WM8915_AIF1_BCLK_MSTR;
1682 lrclk_tx |= WM8915_AIF1TX_LRCLK_MSTR;
1683 lrclk_rx |= WM8915_AIF1RX_LRCLK_MSTR;
1684 break;
1685 default:
1686 return -EINVAL;
1687 }
1688
1689 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1690 case SND_SOC_DAIFMT_DSP_A:
1691 break;
1692 case SND_SOC_DAIFMT_DSP_B:
1693 aifctrl |= 1;
1694 break;
1695 case SND_SOC_DAIFMT_I2S:
1696 aifctrl |= 2;
1697 break;
1698 case SND_SOC_DAIFMT_LEFT_J:
1699 aifctrl |= 3;
1700 break;
1701 default:
1702 return -EINVAL;
1703 }
1704
1705 snd_soc_update_bits(codec, aifctrl_reg, WM8915_AIF1_FMT_MASK, aifctrl);
1706 snd_soc_update_bits(codec, bclk_reg,
1707 WM8915_AIF1_BCLK_INV | WM8915_AIF1_BCLK_MSTR,
1708 bclk);
1709 snd_soc_update_bits(codec, lrclk_tx_reg,
1710 WM8915_AIF1TX_LRCLK_INV |
1711 WM8915_AIF1TX_LRCLK_MSTR,
1712 lrclk_tx);
1713 snd_soc_update_bits(codec, lrclk_rx_reg,
1714 WM8915_AIF1RX_LRCLK_INV |
1715 WM8915_AIF1RX_LRCLK_MSTR,
1716 lrclk_rx);
1717
1718 return 0;
1719}
1720
1721static const int bclk_divs[] = {
1722 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
1723};
1724
1725static const int dsp_divs[] = {
1726 48000, 32000, 16000, 8000
1727};
1728
1729static int wm8915_hw_params(struct snd_pcm_substream *substream,
1730 struct snd_pcm_hw_params *params,
1731 struct snd_soc_dai *dai)
1732{
1733 struct snd_soc_codec *codec = dai->codec;
1734 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
1735 int bits, i, bclk_rate, best, cur_val;
1736 int aifdata = 0;
1737 int bclk = 0;
1738 int lrclk = 0;
1739 int dsp = 0;
1740 int aifdata_reg, bclk_reg, lrclk_reg, dsp_shift;
1741
1742 if (!wm8915->sysclk) {
1743 dev_err(codec->dev, "SYSCLK not configured\n");
1744 return -EINVAL;
1745 }
1746
1747 switch (dai->id) {
1748 case 0:
1749 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1750 (snd_soc_read(codec, WM8915_GPIO_1)) & WM8915_GP1_FN_MASK) {
1751 aifdata_reg = WM8915_AIF1RX_DATA_CONFIGURATION;
1752 lrclk_reg = WM8915_AIF1_RX_LRCLK_1;
1753 } else {
1754 aifdata_reg = WM8915_AIF1TX_DATA_CONFIGURATION_1;
1755 lrclk_reg = WM8915_AIF1_TX_LRCLK_1;
1756 }
1757 bclk_reg = WM8915_AIF1_BCLK;
1758 dsp_shift = 0;
1759 break;
1760 case 1:
1761 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1762 (snd_soc_read(codec, WM8915_GPIO_2)) & WM8915_GP2_FN_MASK) {
1763 aifdata_reg = WM8915_AIF2RX_DATA_CONFIGURATION;
1764 lrclk_reg = WM8915_AIF2_RX_LRCLK_1;
1765 } else {
1766 aifdata_reg = WM8915_AIF2TX_DATA_CONFIGURATION_1;
1767 lrclk_reg = WM8915_AIF2_TX_LRCLK_1;
1768 }
1769 bclk_reg = WM8915_AIF2_BCLK;
1770 dsp_shift = WM8915_DSP2_DIV_SHIFT;
1771 break;
1772 default:
1773 BUG();
1774 return -EINVAL;
1775 }
1776
1777 bclk_rate = snd_soc_params_to_bclk(params);
1778 if (bclk_rate < 0) {
1779 dev_err(codec->dev, "Unsupported BCLK rate: %d\n", bclk_rate);
1780 return bclk_rate;
1781 }
1782
1783 /* Needs looking at for TDM */
1784 bits = snd_pcm_format_width(params_format(params));
1785 if (bits < 0)
1786 return bits;
1787 aifdata |= (bits << WM8915_AIF1TX_WL_SHIFT) | bits;
1788
1789 for (i = 0; i < ARRAY_SIZE(dsp_divs); i++) {
1790 if (dsp_divs[i] == params_rate(params))
1791 break;
1792 }
1793 if (i == ARRAY_SIZE(dsp_divs)) {
1794 dev_err(codec->dev, "Unsupported sample rate %dHz\n",
1795 params_rate(params));
1796 return -EINVAL;
1797 }
1798 dsp |= i << dsp_shift;
1799
1800 /* Pick a divisor for BCLK as close as we can get to ideal */
1801 best = 0;
1802 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1803 cur_val = (wm8915->sysclk / bclk_divs[i]) - bclk_rate;
1804 if (cur_val < 0) /* BCLK table is sorted */
1805 break;
1806 best = i;
1807 }
1808 bclk_rate = wm8915->sysclk / bclk_divs[best];
1809 dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
1810 bclk_divs[best], bclk_rate);
1811 bclk |= best;
1812
1813 lrclk = bclk_rate / params_rate(params);
1814 dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
1815 lrclk, bclk_rate / lrclk);
1816
1817 snd_soc_update_bits(codec, aifdata_reg,
1818 WM8915_AIF1TX_WL_MASK |
1819 WM8915_AIF1TX_SLOT_LEN_MASK,
1820 aifdata);
1821 snd_soc_update_bits(codec, bclk_reg, WM8915_AIF1_BCLK_DIV_MASK, bclk);
1822 snd_soc_update_bits(codec, lrclk_reg, WM8915_AIF1RX_RATE_MASK,
1823 lrclk);
1824 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_2,
1825 WM8915_DSP1_DIV_SHIFT << dsp_shift, dsp);
1826
1827 wm8915->rx_rate[dai->id] = params_rate(params);
1828
1829 return 0;
1830}
1831
1832static int wm8915_set_sysclk(struct snd_soc_dai *dai,
1833 int clk_id, unsigned int freq, int dir)
1834{
1835 struct snd_soc_codec *codec = dai->codec;
1836 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
1837 int lfclk = 0;
1838 int ratediv = 0;
1839 int src;
1840 int old;
1841
1842 /* Disable SYSCLK while we reconfigure */
1843 old = snd_soc_read(codec, WM8915_AIF_CLOCKING_1);
1844 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
1845 WM8915_SYSCLK_ENA, 0);
1846
1847 switch (clk_id) {
1848 case WM8915_SYSCLK_MCLK1:
1849 wm8915->sysclk = freq;
1850 src = 0;
1851 break;
1852 case WM8915_SYSCLK_MCLK2:
1853 wm8915->sysclk = freq;
1854 src = 1;
1855 break;
1856 case WM8915_SYSCLK_FLL:
1857 wm8915->sysclk = freq;
1858 src = 2;
1859 break;
1860 default:
1861 dev_err(codec->dev, "Unsupported clock source %d\n", clk_id);
1862 return -EINVAL;
1863 }
1864
1865 switch (wm8915->sysclk) {
1866 case 6144000:
1867 snd_soc_update_bits(codec, WM8915_AIF_RATE,
1868 WM8915_SYSCLK_RATE, 0);
1869 break;
1870 case 24576000:
1871 ratediv = WM8915_SYSCLK_DIV;
1872 case 12288000:
1873 snd_soc_update_bits(codec, WM8915_AIF_RATE,
1874 WM8915_SYSCLK_RATE, WM8915_SYSCLK_RATE);
1875 break;
1876 case 32000:
1877 case 32768:
1878 lfclk = WM8915_LFCLK_ENA;
1879 break;
1880 default:
1881 dev_warn(codec->dev, "Unsupported clock rate %dHz\n",
1882 wm8915->sysclk);
1883 return -EINVAL;
1884 }
1885
1886 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
1887 WM8915_SYSCLK_SRC_MASK | WM8915_SYSCLK_DIV_MASK,
1888 src << WM8915_SYSCLK_SRC_SHIFT | ratediv);
1889 snd_soc_update_bits(codec, WM8915_CLOCKING_1, WM8915_LFCLK_ENA, lfclk);
1890 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
1891 WM8915_SYSCLK_ENA, old);
1892
1893 return 0;
1894}
1895
1896struct _fll_div {
1897 u16 fll_fratio;
1898 u16 fll_outdiv;
1899 u16 fll_refclk_div;
1900 u16 fll_loop_gain;
1901 u16 fll_ref_freq;
1902 u16 n;
1903 u16 theta;
1904 u16 lambda;
1905};
1906
1907static struct {
1908 unsigned int min;
1909 unsigned int max;
1910 u16 fll_fratio;
1911 int ratio;
1912} fll_fratios[] = {
1913 { 0, 64000, 4, 16 },
1914 { 64000, 128000, 3, 8 },
1915 { 128000, 256000, 2, 4 },
1916 { 256000, 1000000, 1, 2 },
1917 { 1000000, 13500000, 0, 1 },
1918};
1919
1920static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1921 unsigned int Fout)
1922{
1923 unsigned int target;
1924 unsigned int div;
1925 unsigned int fratio, gcd_fll;
1926 int i;
1927
1928 /* Fref must be <=13.5MHz */
1929 div = 1;
1930 fll_div->fll_refclk_div = 0;
1931 while ((Fref / div) > 13500000) {
1932 div *= 2;
1933 fll_div->fll_refclk_div++;
1934
1935 if (div > 8) {
1936 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1937 Fref);
1938 return -EINVAL;
1939 }
1940 }
1941
1942 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
1943
1944 /* Apply the division for our remaining calculations */
1945 Fref /= div;
1946
1947 if (Fref >= 3000000)
1948 fll_div->fll_loop_gain = 5;
1949 else
1950 fll_div->fll_loop_gain = 0;
1951
1952 if (Fref >= 48000)
1953 fll_div->fll_ref_freq = 0;
1954 else
1955 fll_div->fll_ref_freq = 1;
1956
1957 /* Fvco should be 90-100MHz; don't check the upper bound */
1958 div = 2;
1959 while (Fout * div < 90000000) {
1960 div++;
1961 if (div > 64) {
1962 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1963 Fout);
1964 return -EINVAL;
1965 }
1966 }
1967 target = Fout * div;
1968 fll_div->fll_outdiv = div - 1;
1969
1970 pr_debug("FLL Fvco=%dHz\n", target);
1971
1972 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1973 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1974 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1975 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1976 fratio = fll_fratios[i].ratio;
1977 break;
1978 }
1979 }
1980 if (i == ARRAY_SIZE(fll_fratios)) {
1981 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1982 return -EINVAL;
1983 }
1984
1985 fll_div->n = target / (fratio * Fref);
1986
1987 if (target % Fref == 0) {
1988 fll_div->theta = 0;
1989 fll_div->lambda = 0;
1990 } else {
1991 gcd_fll = gcd(target, fratio * Fref);
1992
1993 fll_div->theta = (target - (fll_div->n * fratio * Fref))
1994 / gcd_fll;
1995 fll_div->lambda = (fratio * Fref) / gcd_fll;
1996 }
1997
1998 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
1999 fll_div->n, fll_div->theta, fll_div->lambda);
2000 pr_debug("FLL_FRATIO=%x FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
2001 fll_div->fll_fratio, fll_div->fll_outdiv,
2002 fll_div->fll_refclk_div);
2003
2004 return 0;
2005}
2006
2007static int wm8915_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2008 unsigned int Fref, unsigned int Fout)
2009{
2010 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2011 struct _fll_div fll_div;
2012 unsigned long timeout;
2013 int ret, reg;
2014
2015 /* Any change? */
2016 if (source == wm8915->fll_src && Fref == wm8915->fll_fref &&
2017 Fout == wm8915->fll_fout)
2018 return 0;
2019
2020 if (Fout == 0) {
2021 dev_dbg(codec->dev, "FLL disabled\n");
2022
2023 wm8915->fll_fref = 0;
2024 wm8915->fll_fout = 0;
2025
2026 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_1,
2027 WM8915_FLL_ENA, 0);
2028
2029 return 0;
2030 }
2031
2032 ret = fll_factors(&fll_div, Fref, Fout);
2033 if (ret != 0)
2034 return ret;
2035
2036 switch (source) {
2037 case WM8915_FLL_MCLK1:
2038 reg = 0;
2039 break;
2040 case WM8915_FLL_MCLK2:
2041 reg = 1;
2042 case WM8915_FLL_DACLRCLK1:
2043 reg = 2;
2044 break;
2045 case WM8915_FLL_BCLK1:
2046 reg = 3;
2047 break;
2048 default:
2049 dev_err(codec->dev, "Unknown FLL source %d\n", ret);
2050 return -EINVAL;
2051 }
2052
2053 reg |= fll_div.fll_refclk_div << WM8915_FLL_REFCLK_DIV_SHIFT;
2054 reg |= fll_div.fll_ref_freq << WM8915_FLL_REF_FREQ_SHIFT;
2055
2056 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_5,
2057 WM8915_FLL_REFCLK_DIV_MASK | WM8915_FLL_REF_FREQ |
2058 WM8915_FLL_REFCLK_SRC_MASK, reg);
2059
2060 reg = 0;
2061 if (fll_div.theta || fll_div.lambda)
2062 reg |= WM8915_FLL_EFS_ENA | (3 << WM8915_FLL_LFSR_SEL_SHIFT);
2063 else
2064 reg |= 1 << WM8915_FLL_LFSR_SEL_SHIFT;
2065 snd_soc_write(codec, WM8915_FLL_EFS_2, reg);
2066
2067 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_2,
2068 WM8915_FLL_OUTDIV_MASK |
2069 WM8915_FLL_FRATIO_MASK,
2070 (fll_div.fll_outdiv << WM8915_FLL_OUTDIV_SHIFT) |
2071 (fll_div.fll_fratio));
2072
2073 snd_soc_write(codec, WM8915_FLL_CONTROL_3, fll_div.theta);
2074
2075 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_4,
2076 WM8915_FLL_N_MASK | WM8915_FLL_LOOP_GAIN_MASK,
2077 (fll_div.n << WM8915_FLL_N_SHIFT) |
2078 fll_div.fll_loop_gain);
2079
2080 snd_soc_write(codec, WM8915_FLL_EFS_1, fll_div.lambda);
2081
2082 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_1,
2083 WM8915_FLL_ENA, WM8915_FLL_ENA);
2084
2085 /* The FLL supports live reconfiguration - kick that in case we were
2086 * already enabled.
2087 */
2088 snd_soc_write(codec, WM8915_FLL_CONTROL_6, WM8915_FLL_SWITCH_CLK);
2089
2090 /* Wait for the FLL to lock, using the interrupt if possible */
2091 if (Fref > 1000000)
2092 timeout = usecs_to_jiffies(300);
2093 else
2094 timeout = msecs_to_jiffies(2);
2095
2096 wait_for_completion_timeout(&wm8915->fll_lock, timeout);
2097
2098 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
2099
2100 wm8915->fll_fref = Fref;
2101 wm8915->fll_fout = Fout;
2102 wm8915->fll_src = source;
2103
2104 return 0;
2105}
2106
2107#ifdef CONFIG_GPIOLIB
2108static inline struct wm8915_priv *gpio_to_wm8915(struct gpio_chip *chip)
2109{
2110 return container_of(chip, struct wm8915_priv, gpio_chip);
2111}
2112
2113static void wm8915_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
2114{
2115 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2116 struct snd_soc_codec *codec = wm8915->codec;
2117
2118 snd_soc_update_bits(codec, WM8915_GPIO_1 + offset,
2119 WM8915_GP1_LVL, !!value << WM8915_GP1_LVL_SHIFT);
2120}
2121
2122static int wm8915_gpio_direction_out(struct gpio_chip *chip,
2123 unsigned offset, int value)
2124{
2125 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2126 struct snd_soc_codec *codec = wm8915->codec;
2127 int val;
2128
2129 val = (1 << WM8915_GP1_FN_SHIFT) | (!!value << WM8915_GP1_LVL_SHIFT);
2130
2131 return snd_soc_update_bits(codec, WM8915_GPIO_1 + offset,
2132 WM8915_GP1_FN_MASK | WM8915_GP1_DIR |
2133 WM8915_GP1_LVL, val);
2134}
2135
2136static int wm8915_gpio_get(struct gpio_chip *chip, unsigned offset)
2137{
2138 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2139 struct snd_soc_codec *codec = wm8915->codec;
2140 int ret;
2141
2142 ret = snd_soc_read(codec, WM8915_GPIO_1 + offset);
2143 if (ret < 0)
2144 return ret;
2145
2146 return (ret & WM8915_GP1_LVL) != 0;
2147}
2148
2149static int wm8915_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
2150{
2151 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2152 struct snd_soc_codec *codec = wm8915->codec;
2153
2154 return snd_soc_update_bits(codec, WM8915_GPIO_1 + offset,
2155 WM8915_GP1_FN_MASK | WM8915_GP1_DIR,
2156 (1 << WM8915_GP1_FN_SHIFT) |
2157 (1 << WM8915_GP1_DIR_SHIFT));
2158}
2159
2160static struct gpio_chip wm8915_template_chip = {
2161 .label = "wm8915",
2162 .owner = THIS_MODULE,
2163 .direction_output = wm8915_gpio_direction_out,
2164 .set = wm8915_gpio_set,
2165 .direction_input = wm8915_gpio_direction_in,
2166 .get = wm8915_gpio_get,
2167 .can_sleep = 1,
2168};
2169
2170static void wm8915_init_gpio(struct snd_soc_codec *codec)
2171{
2172 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2173 int ret;
2174
2175 wm8915->gpio_chip = wm8915_template_chip;
2176 wm8915->gpio_chip.ngpio = 5;
2177 wm8915->gpio_chip.dev = codec->dev;
2178
2179 if (wm8915->pdata.gpio_base)
2180 wm8915->gpio_chip.base = wm8915->pdata.gpio_base;
2181 else
2182 wm8915->gpio_chip.base = -1;
2183
2184 ret = gpiochip_add(&wm8915->gpio_chip);
2185 if (ret != 0)
2186 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
2187}
2188
2189static void wm8915_free_gpio(struct snd_soc_codec *codec)
2190{
2191 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2192 int ret;
2193
2194 ret = gpiochip_remove(&wm8915->gpio_chip);
2195 if (ret != 0)
2196 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
2197}
2198#else
2199static void wm8915_init_gpio(struct snd_soc_codec *codec)
2200{
2201}
2202
2203static void wm8915_free_gpio(struct snd_soc_codec *codec)
2204{
2205}
2206#endif
2207
2208/**
2209 * wm8915_detect - Enable default WM8915 jack detection
2210 *
2211 * The WM8915 has advanced accessory detection support for headsets.
2212 * This function provides a default implementation which integrates
2213 * the majority of this functionality with minimal user configuration.
2214 *
2215 * This will detect headset, headphone and short circuit button and
2216 * will also detect inverted microphone ground connections and update
2217 * the polarity of the connections.
2218 */
2219int wm8915_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2220 wm8915_polarity_fn polarity_cb)
2221{
2222 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2223
2224 wm8915->jack = jack;
2225 wm8915->detecting = true;
2226 wm8915->polarity_cb = polarity_cb;
2227
2228 if (wm8915->polarity_cb)
2229 wm8915->polarity_cb(codec, 0);
2230
2231 /* Clear discarge to avoid noise during detection */
2232 snd_soc_update_bits(codec, WM8915_MICBIAS_1,
2233 WM8915_MICB1_DISCH, 0);
2234 snd_soc_update_bits(codec, WM8915_MICBIAS_2,
2235 WM8915_MICB2_DISCH, 0);
2236
2237 /* LDO2 powers the microphones, SYSCLK clocks detection */
2238 snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2");
2239 snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK");
2240
2241 /* We start off just enabling microphone detection - even a
2242 * plain headphone will trigger detection.
2243 */
2244 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2245 WM8915_MICD_ENA, WM8915_MICD_ENA);
2246
2247 /* Slowest detection rate, gives debounce for initial detection */
2248 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2249 WM8915_MICD_RATE_MASK,
2250 WM8915_MICD_RATE_MASK);
2251
2252 /* Enable interrupts and we're off */
2253 snd_soc_update_bits(codec, WM8915_INTERRUPT_STATUS_2_MASK,
2254 WM8915_IM_MICD_EINT, 0);
2255
2256 return 0;
2257}
2258EXPORT_SYMBOL_GPL(wm8915_detect);
2259
2260static void wm8915_micd(struct snd_soc_codec *codec)
2261{
2262 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2263 int val, reg;
2264
2265 val = snd_soc_read(codec, WM8915_MIC_DETECT_3);
2266
2267 dev_dbg(codec->dev, "Microphone event: %x\n", val);
2268
2269 if (!(val & WM8915_MICD_VALID)) {
2270 dev_warn(codec->dev, "Microphone detection state invalid\n");
2271 return;
2272 }
2273
2274 /* No accessory, reset everything and report removal */
2275 if (!(val & WM8915_MICD_STS)) {
2276 dev_dbg(codec->dev, "Jack removal detected\n");
2277 wm8915->jack_mic = false;
2278 wm8915->detecting = true;
2279 snd_soc_jack_report(wm8915->jack, 0,
2280 SND_JACK_HEADSET | SND_JACK_BTN_0);
2281 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2282 WM8915_MICD_RATE_MASK,
2283 WM8915_MICD_RATE_MASK);
2284 return;
2285 }
2286
2287 /* If the measurement is very high we've got a microphone but
2288 * do a little debounce to account for mechanical issues.
2289 */
2290 if (val & 0x400) {
2291 dev_dbg(codec->dev, "Microphone detected\n");
2292 snd_soc_jack_report(wm8915->jack, SND_JACK_HEADSET,
2293 SND_JACK_HEADSET | SND_JACK_BTN_0);
2294 wm8915->jack_mic = true;
2295 wm8915->detecting = false;
2296 }
2297
2298 /* If we detected a lower impedence during initial startup
2299 * then we probably have the wrong polarity, flip it. Don't
2300 * do this for the lowest impedences to speed up detection of
2301 * plain headphones.
2302 */
2303 if (wm8915->detecting && (val & 0x3f0)) {
2304 reg = snd_soc_read(codec, WM8915_ACCESSORY_DETECT_MODE_2);
2305 reg ^= WM8915_HPOUT1FB_SRC | WM8915_MICD_SRC |
2306 WM8915_MICD_BIAS_SRC;
2307 snd_soc_update_bits(codec, WM8915_ACCESSORY_DETECT_MODE_2,
2308 WM8915_HPOUT1FB_SRC | WM8915_MICD_SRC |
2309 WM8915_MICD_BIAS_SRC, reg);
2310
2311 if (wm8915->polarity_cb)
2312 wm8915->polarity_cb(codec,
2313 (reg & WM8915_MICD_SRC) != 0);
2314
2315 dev_dbg(codec->dev, "Set microphone polarity to %d\n",
2316 (reg & WM8915_MICD_SRC) != 0);
2317
2318 return;
2319 }
2320
2321 /* Don't distinguish between buttons, just report any low
2322 * impedence as BTN_0.
2323 */
2324 if (val & 0x3fc) {
2325 if (wm8915->jack_mic) {
2326 dev_dbg(codec->dev, "Mic button detected\n");
2327 snd_soc_jack_report(wm8915->jack,
2328 SND_JACK_HEADSET | SND_JACK_BTN_0,
2329 SND_JACK_HEADSET | SND_JACK_BTN_0);
2330 } else {
2331 dev_dbg(codec->dev, "Headphone detected\n");
2332 snd_soc_jack_report(wm8915->jack,
2333 SND_JACK_HEADPHONE,
2334 SND_JACK_HEADSET |
2335 SND_JACK_BTN_0);
2336 wm8915->detecting = false;
2337 }
2338 }
2339
2340 /* Increase poll rate to give better responsiveness for buttons */
2341 if (!wm8915->detecting)
2342 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2343 WM8915_MICD_RATE_MASK,
2344 5 << WM8915_MICD_RATE_SHIFT);
2345}
2346
2347static irqreturn_t wm8915_irq(int irq, void *data)
2348{
2349 struct snd_soc_codec *codec = data;
2350 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2351 int irq_val;
2352
2353 irq_val = snd_soc_read(codec, WM8915_INTERRUPT_STATUS_2);
2354 if (irq_val < 0) {
2355 dev_err(codec->dev, "Failed to read IRQ status: %d\n",
2356 irq_val);
2357 return IRQ_NONE;
2358 }
2359 irq_val &= ~snd_soc_read(codec, WM8915_INTERRUPT_STATUS_2_MASK);
2360
2361 if (irq_val & (WM8915_DCS_DONE_01_EINT | WM8915_DCS_DONE_23_EINT)) {
2362 dev_dbg(codec->dev, "DC servo IRQ\n");
2363 complete(&wm8915->dcs_done);
2364 }
2365
2366 if (irq_val & WM8915_FIFOS_ERR_EINT)
2367 dev_err(codec->dev, "Digital core FIFO error\n");
2368
2369 if (irq_val & WM8915_FLL_LOCK_EINT) {
2370 dev_dbg(codec->dev, "FLL locked\n");
2371 complete(&wm8915->fll_lock);
2372 }
2373
2374 if (irq_val & WM8915_MICD_EINT)
2375 wm8915_micd(codec);
2376
2377 if (irq_val) {
2378 snd_soc_write(codec, WM8915_INTERRUPT_STATUS_2, irq_val);
2379
2380 return IRQ_HANDLED;
2381 } else {
2382 return IRQ_NONE;
2383 }
2384}
2385
2386static void wm8915_retune_mobile_pdata(struct snd_soc_codec *codec)
2387{
2388 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2389 struct wm8915_pdata *pdata = &wm8915->pdata;
2390
2391 struct snd_kcontrol_new controls[] = {
2392 SOC_ENUM_EXT("DSP1 EQ Mode",
2393 wm8915->retune_mobile_enum,
2394 wm8915_get_retune_mobile_enum,
2395 wm8915_put_retune_mobile_enum),
2396 SOC_ENUM_EXT("DSP2 EQ Mode",
2397 wm8915->retune_mobile_enum,
2398 wm8915_get_retune_mobile_enum,
2399 wm8915_put_retune_mobile_enum),
2400 };
2401 int ret, i, j;
2402 const char **t;
2403
2404 /* We need an array of texts for the enum API but the number
2405 * of texts is likely to be less than the number of
2406 * configurations due to the sample rate dependency of the
2407 * configurations. */
2408 wm8915->num_retune_mobile_texts = 0;
2409 wm8915->retune_mobile_texts = NULL;
2410 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
2411 for (j = 0; j < wm8915->num_retune_mobile_texts; j++) {
2412 if (strcmp(pdata->retune_mobile_cfgs[i].name,
2413 wm8915->retune_mobile_texts[j]) == 0)
2414 break;
2415 }
2416
2417 if (j != wm8915->num_retune_mobile_texts)
2418 continue;
2419
2420 /* Expand the array... */
2421 t = krealloc(wm8915->retune_mobile_texts,
2422 sizeof(char *) *
2423 (wm8915->num_retune_mobile_texts + 1),
2424 GFP_KERNEL);
2425 if (t == NULL)
2426 continue;
2427
2428 /* ...store the new entry... */
2429 t[wm8915->num_retune_mobile_texts] =
2430 pdata->retune_mobile_cfgs[i].name;
2431
2432 /* ...and remember the new version. */
2433 wm8915->num_retune_mobile_texts++;
2434 wm8915->retune_mobile_texts = t;
2435 }
2436
2437 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
2438 wm8915->num_retune_mobile_texts);
2439
2440 wm8915->retune_mobile_enum.max = wm8915->num_retune_mobile_texts;
2441 wm8915->retune_mobile_enum.texts = wm8915->retune_mobile_texts;
2442
2443 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
2444 if (ret != 0)
2445 dev_err(codec->dev,
2446 "Failed to add ReTune Mobile controls: %d\n", ret);
2447}
2448
2449static int wm8915_probe(struct snd_soc_codec *codec)
2450{
2451 int ret;
2452 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2453 struct i2c_client *i2c = to_i2c_client(codec->dev);
2454 struct snd_soc_dapm_context *dapm = &codec->dapm;
2455 int i, irq_flags;
2456
2457 wm8915->codec = codec;
2458
2459 init_completion(&wm8915->dcs_done);
2460 init_completion(&wm8915->fll_lock);
2461
2462 dapm->idle_bias_off = true;
2463 dapm->bias_level = SND_SOC_BIAS_OFF;
2464
2465 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
2466 if (ret != 0) {
2467 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2468 goto err;
2469 }
2470
2471 for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++)
2472 wm8915->supplies[i].supply = wm8915_supply_names[i];
2473
2474 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8915->supplies),
2475 wm8915->supplies);
2476 if (ret != 0) {
2477 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
2478 goto err;
2479 }
2480
2481 wm8915->disable_nb[0].notifier_call = wm8915_regulator_event_0;
2482 wm8915->disable_nb[1].notifier_call = wm8915_regulator_event_1;
2483 wm8915->disable_nb[2].notifier_call = wm8915_regulator_event_2;
2484 wm8915->disable_nb[3].notifier_call = wm8915_regulator_event_3;
2485 wm8915->disable_nb[4].notifier_call = wm8915_regulator_event_4;
2486 wm8915->disable_nb[5].notifier_call = wm8915_regulator_event_5;
2487
2488 /* This should really be moved into the regulator core */
2489 for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++) {
2490 ret = regulator_register_notifier(wm8915->supplies[i].consumer,
2491 &wm8915->disable_nb[i]);
2492 if (ret != 0) {
2493 dev_err(codec->dev,
2494 "Failed to register regulator notifier: %d\n",
2495 ret);
2496 }
2497 }
2498
2499 ret = regulator_bulk_enable(ARRAY_SIZE(wm8915->supplies),
2500 wm8915->supplies);
2501 if (ret != 0) {
2502 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2503 goto err_get;
2504 }
2505
2506 if (wm8915->pdata.ldo_ena >= 0) {
2507 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 1);
2508 msleep(5);
2509 }
2510
2511 ret = snd_soc_read(codec, WM8915_SOFTWARE_RESET);
2512 if (ret < 0) {
2513 dev_err(codec->dev, "Failed to read ID register: %d\n", ret);
2514 goto err_enable;
2515 }
2516 if (ret != 0x8915) {
2517 dev_err(codec->dev, "Device is not a WM8915, ID %x\n", ret);
2518 ret = -EINVAL;
2519 goto err_enable;
2520 }
2521
2522 ret = snd_soc_read(codec, WM8915_CHIP_REVISION);
2523 if (ret < 0) {
2524 dev_err(codec->dev, "Failed to read device revision: %d\n",
2525 ret);
2526 goto err_enable;
2527 }
2528
2529 dev_info(codec->dev, "revision %c\n",
2530 (ret & WM8915_CHIP_REV_MASK) + 'A');
2531
2532 if (wm8915->pdata.ldo_ena >= 0) {
2533 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0);
2534 } else {
2535 ret = wm8915_reset(codec);
2536 if (ret < 0) {
2537 dev_err(codec->dev, "Failed to issue reset\n");
2538 goto err_enable;
2539 }
2540 }
2541
2542 codec->cache_only = true;
2543
2544 /* Apply platform data settings */
2545 snd_soc_update_bits(codec, WM8915_LINE_INPUT_CONTROL,
2546 WM8915_INL_MODE_MASK | WM8915_INR_MODE_MASK,
2547 wm8915->pdata.inl_mode << WM8915_INL_MODE_SHIFT |
2548 wm8915->pdata.inr_mode);
2549
2550 for (i = 0; i < ARRAY_SIZE(wm8915->pdata.gpio_default); i++) {
2551 if (!wm8915->pdata.gpio_default[i])
2552 continue;
2553
2554 snd_soc_write(codec, WM8915_GPIO_1 + i,
2555 wm8915->pdata.gpio_default[i] & 0xffff);
2556 }
2557
2558 if (wm8915->pdata.spkmute_seq)
2559 snd_soc_update_bits(codec, WM8915_PDM_SPEAKER_MUTE_SEQUENCE,
2560 WM8915_SPK_MUTE_ENDIAN |
2561 WM8915_SPK_MUTE_SEQ1_MASK,
2562 wm8915->pdata.spkmute_seq);
2563
2564 snd_soc_update_bits(codec, WM8915_ACCESSORY_DETECT_MODE_2,
2565 WM8915_MICD_BIAS_SRC | WM8915_HPOUT1FB_SRC |
2566 WM8915_MICD_SRC, wm8915->pdata.micdet_def);
2567
2568 /* Latch volume update bits */
2569 snd_soc_update_bits(codec, WM8915_LEFT_LINE_INPUT_VOLUME,
2570 WM8915_IN1_VU, WM8915_IN1_VU);
2571 snd_soc_update_bits(codec, WM8915_RIGHT_LINE_INPUT_VOLUME,
2572 WM8915_IN1_VU, WM8915_IN1_VU);
2573
2574 snd_soc_update_bits(codec, WM8915_DAC1_LEFT_VOLUME,
2575 WM8915_DAC1_VU, WM8915_DAC1_VU);
2576 snd_soc_update_bits(codec, WM8915_DAC1_RIGHT_VOLUME,
2577 WM8915_DAC1_VU, WM8915_DAC1_VU);
2578 snd_soc_update_bits(codec, WM8915_DAC2_LEFT_VOLUME,
2579 WM8915_DAC2_VU, WM8915_DAC2_VU);
2580 snd_soc_update_bits(codec, WM8915_DAC2_RIGHT_VOLUME,
2581 WM8915_DAC2_VU, WM8915_DAC2_VU);
2582
2583 snd_soc_update_bits(codec, WM8915_OUTPUT1_LEFT_VOLUME,
2584 WM8915_DAC1_VU, WM8915_DAC1_VU);
2585 snd_soc_update_bits(codec, WM8915_OUTPUT1_RIGHT_VOLUME,
2586 WM8915_DAC1_VU, WM8915_DAC1_VU);
2587 snd_soc_update_bits(codec, WM8915_OUTPUT2_LEFT_VOLUME,
2588 WM8915_DAC2_VU, WM8915_DAC2_VU);
2589 snd_soc_update_bits(codec, WM8915_OUTPUT2_RIGHT_VOLUME,
2590 WM8915_DAC2_VU, WM8915_DAC2_VU);
2591
2592 snd_soc_update_bits(codec, WM8915_DSP1_TX_LEFT_VOLUME,
2593 WM8915_DSP1TX_VU, WM8915_DSP1TX_VU);
2594 snd_soc_update_bits(codec, WM8915_DSP1_TX_RIGHT_VOLUME,
2595 WM8915_DSP1TX_VU, WM8915_DSP1TX_VU);
2596 snd_soc_update_bits(codec, WM8915_DSP2_TX_LEFT_VOLUME,
2597 WM8915_DSP2TX_VU, WM8915_DSP2TX_VU);
2598 snd_soc_update_bits(codec, WM8915_DSP2_TX_RIGHT_VOLUME,
2599 WM8915_DSP2TX_VU, WM8915_DSP2TX_VU);
2600
2601 snd_soc_update_bits(codec, WM8915_DSP1_RX_LEFT_VOLUME,
2602 WM8915_DSP1RX_VU, WM8915_DSP1RX_VU);
2603 snd_soc_update_bits(codec, WM8915_DSP1_RX_RIGHT_VOLUME,
2604 WM8915_DSP1RX_VU, WM8915_DSP1RX_VU);
2605 snd_soc_update_bits(codec, WM8915_DSP2_RX_LEFT_VOLUME,
2606 WM8915_DSP2RX_VU, WM8915_DSP2RX_VU);
2607 snd_soc_update_bits(codec, WM8915_DSP2_RX_RIGHT_VOLUME,
2608 WM8915_DSP2RX_VU, WM8915_DSP2RX_VU);
2609
2610 /* No support currently for the underclocked TDM modes and
2611 * pick a default TDM layout with each channel pair working with
2612 * slots 0 and 1. */
2613 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_0_CONFIGURATION,
2614 WM8915_AIF1RX_CHAN0_SLOTS_MASK |
2615 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2616 1 << WM8915_AIF1RX_CHAN0_SLOTS_SHIFT | 0);
2617 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_1_CONFIGURATION,
2618 WM8915_AIF1RX_CHAN1_SLOTS_MASK |
2619 WM8915_AIF1RX_CHAN1_START_SLOT_MASK,
2620 1 << WM8915_AIF1RX_CHAN1_SLOTS_SHIFT | 1);
2621 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_2_CONFIGURATION,
2622 WM8915_AIF1RX_CHAN2_SLOTS_MASK |
2623 WM8915_AIF1RX_CHAN2_START_SLOT_MASK,
2624 1 << WM8915_AIF1RX_CHAN2_SLOTS_SHIFT | 0);
2625 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_3_CONFIGURATION,
2626 WM8915_AIF1RX_CHAN3_SLOTS_MASK |
2627 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2628 1 << WM8915_AIF1RX_CHAN3_SLOTS_SHIFT | 1);
2629 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_4_CONFIGURATION,
2630 WM8915_AIF1RX_CHAN4_SLOTS_MASK |
2631 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2632 1 << WM8915_AIF1RX_CHAN4_SLOTS_SHIFT | 0);
2633 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_5_CONFIGURATION,
2634 WM8915_AIF1RX_CHAN5_SLOTS_MASK |
2635 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2636 1 << WM8915_AIF1RX_CHAN5_SLOTS_SHIFT | 1);
2637
2638 snd_soc_update_bits(codec, WM8915_AIF2RX_CHANNEL_0_CONFIGURATION,
2639 WM8915_AIF2RX_CHAN0_SLOTS_MASK |
2640 WM8915_AIF2RX_CHAN0_START_SLOT_MASK,
2641 1 << WM8915_AIF2RX_CHAN0_SLOTS_SHIFT | 0);
2642 snd_soc_update_bits(codec, WM8915_AIF2RX_CHANNEL_1_CONFIGURATION,
2643 WM8915_AIF2RX_CHAN1_SLOTS_MASK |
2644 WM8915_AIF2RX_CHAN1_START_SLOT_MASK,
2645 1 << WM8915_AIF2RX_CHAN1_SLOTS_SHIFT | 1);
2646
2647 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_0_CONFIGURATION,
2648 WM8915_AIF1TX_CHAN0_SLOTS_MASK |
2649 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2650 1 << WM8915_AIF1TX_CHAN0_SLOTS_SHIFT | 0);
2651 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_1_CONFIGURATION,
2652 WM8915_AIF1TX_CHAN1_SLOTS_MASK |
2653 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2654 1 << WM8915_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2655 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_2_CONFIGURATION,
2656 WM8915_AIF1TX_CHAN2_SLOTS_MASK |
2657 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2658 1 << WM8915_AIF1TX_CHAN2_SLOTS_SHIFT | 0);
2659 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_3_CONFIGURATION,
2660 WM8915_AIF1TX_CHAN3_SLOTS_MASK |
2661 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2662 1 << WM8915_AIF1TX_CHAN3_SLOTS_SHIFT | 1);
2663 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_4_CONFIGURATION,
2664 WM8915_AIF1TX_CHAN4_SLOTS_MASK |
2665 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2666 1 << WM8915_AIF1TX_CHAN4_SLOTS_SHIFT | 0);
2667 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_5_CONFIGURATION,
2668 WM8915_AIF1TX_CHAN5_SLOTS_MASK |
2669 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2670 1 << WM8915_AIF1TX_CHAN5_SLOTS_SHIFT | 1);
2671
2672 snd_soc_update_bits(codec, WM8915_AIF2TX_CHANNEL_0_CONFIGURATION,
2673 WM8915_AIF2TX_CHAN0_SLOTS_MASK |
2674 WM8915_AIF2TX_CHAN0_START_SLOT_MASK,
2675 1 << WM8915_AIF2TX_CHAN0_SLOTS_SHIFT | 0);
2676 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_1_CONFIGURATION,
2677 WM8915_AIF2TX_CHAN1_SLOTS_MASK |
2678 WM8915_AIF2TX_CHAN1_START_SLOT_MASK,
2679 1 << WM8915_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2680
2681 if (wm8915->pdata.num_retune_mobile_cfgs)
2682 wm8915_retune_mobile_pdata(codec);
2683 else
2684 snd_soc_add_controls(codec, wm8915_eq_controls,
2685 ARRAY_SIZE(wm8915_eq_controls));
2686
2687 /* If the TX LRCLK pins are not in LRCLK mode configure the
2688 * AIFs to source their clocks from the RX LRCLKs.
2689 */
2690 if ((snd_soc_read(codec, WM8915_GPIO_1)))
2691 snd_soc_update_bits(codec, WM8915_AIF1_TX_LRCLK_2,
2692 WM8915_AIF1TX_LRCLK_MODE,
2693 WM8915_AIF1TX_LRCLK_MODE);
2694
2695 if ((snd_soc_read(codec, WM8915_GPIO_2)))
2696 snd_soc_update_bits(codec, WM8915_AIF2_TX_LRCLK_2,
2697 WM8915_AIF2TX_LRCLK_MODE,
2698 WM8915_AIF2TX_LRCLK_MODE);
2699
2700 regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2701
2702 wm8915_init_gpio(codec);
2703
2704 if (i2c->irq) {
2705 if (wm8915->pdata.irq_flags)
2706 irq_flags = wm8915->pdata.irq_flags;
2707 else
2708 irq_flags = IRQF_TRIGGER_LOW;
2709
2710 irq_flags |= IRQF_ONESHOT;
2711
2712 ret = request_threaded_irq(i2c->irq, NULL, wm8915_irq,
2713 irq_flags, "wm8915", codec);
2714 if (ret == 0) {
2715 /* Unmask the interrupt */
2716 snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL,
2717 WM8915_IM_IRQ, 0);
2718
2719 /* Enable error reporting and DC servo status */
2720 snd_soc_update_bits(codec,
2721 WM8915_INTERRUPT_STATUS_2_MASK,
2722 WM8915_IM_DCS_DONE_23_EINT |
2723 WM8915_IM_DCS_DONE_01_EINT |
2724 WM8915_IM_FLL_LOCK_EINT |
2725 WM8915_IM_FIFOS_ERR_EINT,
2726 0);
2727 } else {
2728 dev_err(codec->dev, "Failed to request IRQ: %d\n",
2729 ret);
2730 }
2731 }
2732
2733 return 0;
2734
2735err_enable:
2736 if (wm8915->pdata.ldo_ena >= 0)
2737 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0);
2738
2739 regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2740err_get:
2741 regulator_bulk_free(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2742err:
2743 return ret;
2744}
2745
2746static int wm8915_remove(struct snd_soc_codec *codec)
2747{
2748 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2749 struct i2c_client *i2c = to_i2c_client(codec->dev);
2750 int i;
2751
2752 snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL,
2753 WM8915_IM_IRQ, WM8915_IM_IRQ);
2754
2755 if (i2c->irq)
2756 free_irq(i2c->irq, codec);
2757
2758 wm8915_free_gpio(codec);
2759
2760 for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++)
2761 regulator_unregister_notifier(wm8915->supplies[i].consumer,
2762 &wm8915->disable_nb[i]);
2763 regulator_bulk_free(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2764
2765 return 0;
2766}
2767
2768static struct snd_soc_codec_driver soc_codec_dev_wm8915 = {
2769 .probe = wm8915_probe,
2770 .remove = wm8915_remove,
2771 .set_bias_level = wm8915_set_bias_level,
2772 .seq_notifier = wm8915_seq_notifier,
2773 .reg_cache_size = WM8915_MAX_REGISTER + 1,
2774 .reg_word_size = sizeof(u16),
2775 .reg_cache_default = wm8915_reg,
2776 .volatile_register = wm8915_volatile_register,
2777 .readable_register = wm8915_readable_register,
2778 .compress_type = SND_SOC_RBTREE_COMPRESSION,
2779 .controls = wm8915_snd_controls,
2780 .num_controls = ARRAY_SIZE(wm8915_snd_controls),
2781 .dapm_widgets = wm8915_dapm_widgets,
2782 .num_dapm_widgets = ARRAY_SIZE(wm8915_dapm_widgets),
2783 .dapm_routes = wm8915_dapm_routes,
2784 .num_dapm_routes = ARRAY_SIZE(wm8915_dapm_routes),
2785 .set_pll = wm8915_set_fll,
2786};
2787
2788#define WM8915_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
2789 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000)
2790#define WM8915_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
2791 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\
2792 SNDRV_PCM_FMTBIT_S32_LE)
2793
2794static struct snd_soc_dai_ops wm8915_dai_ops = {
2795 .set_fmt = wm8915_set_fmt,
2796 .hw_params = wm8915_hw_params,
2797 .set_sysclk = wm8915_set_sysclk,
2798};
2799
2800static struct snd_soc_dai_driver wm8915_dai[] = {
2801 {
2802 .name = "wm8915-aif1",
2803 .playback = {
2804 .stream_name = "AIF1 Playback",
2805 .channels_min = 1,
2806 .channels_max = 6,
2807 .rates = WM8915_RATES,
2808 .formats = WM8915_FORMATS,
2809 },
2810 .capture = {
2811 .stream_name = "AIF1 Capture",
2812 .channels_min = 1,
2813 .channels_max = 6,
2814 .rates = WM8915_RATES,
2815 .formats = WM8915_FORMATS,
2816 },
2817 .ops = &wm8915_dai_ops,
2818 },
2819 {
2820 .name = "wm8915-aif2",
2821 .playback = {
2822 .stream_name = "AIF2 Playback",
2823 .channels_min = 1,
2824 .channels_max = 2,
2825 .rates = WM8915_RATES,
2826 .formats = WM8915_FORMATS,
2827 },
2828 .capture = {
2829 .stream_name = "AIF2 Capture",
2830 .channels_min = 1,
2831 .channels_max = 2,
2832 .rates = WM8915_RATES,
2833 .formats = WM8915_FORMATS,
2834 },
2835 .ops = &wm8915_dai_ops,
2836 },
2837};
2838
2839static __devinit int wm8915_i2c_probe(struct i2c_client *i2c,
2840 const struct i2c_device_id *id)
2841{
2842 struct wm8915_priv *wm8915;
2843 int ret;
2844
2845 wm8915 = kzalloc(sizeof(struct wm8915_priv), GFP_KERNEL);
2846 if (wm8915 == NULL)
2847 return -ENOMEM;
2848
2849 i2c_set_clientdata(i2c, wm8915);
2850
2851 if (dev_get_platdata(&i2c->dev))
2852 memcpy(&wm8915->pdata, dev_get_platdata(&i2c->dev),
2853 sizeof(wm8915->pdata));
2854
2855 if (wm8915->pdata.ldo_ena > 0) {
2856 ret = gpio_request_one(wm8915->pdata.ldo_ena,
2857 GPIOF_OUT_INIT_LOW, "WM8915 ENA");
2858 if (ret < 0) {
2859 dev_err(&i2c->dev, "Failed to request GPIO %d: %d\n",
2860 wm8915->pdata.ldo_ena, ret);
2861 goto err;
2862 }
2863 }
2864
2865 ret = snd_soc_register_codec(&i2c->dev,
2866 &soc_codec_dev_wm8915, wm8915_dai,
2867 ARRAY_SIZE(wm8915_dai));
2868 if (ret < 0)
2869 goto err_gpio;
2870
2871 return ret;
2872
2873err_gpio:
2874 if (wm8915->pdata.ldo_ena > 0)
2875 gpio_free(wm8915->pdata.ldo_ena);
2876err:
2877 kfree(wm8915);
2878
2879 return ret;
2880}
2881
2882static __devexit int wm8915_i2c_remove(struct i2c_client *client)
2883{
2884 struct wm8915_priv *wm8915 = i2c_get_clientdata(client);
2885
2886 snd_soc_unregister_codec(&client->dev);
2887 if (wm8915->pdata.ldo_ena > 0)
2888 gpio_free(wm8915->pdata.ldo_ena);
2889 kfree(i2c_get_clientdata(client));
2890 return 0;
2891}
2892
2893static const struct i2c_device_id wm8915_i2c_id[] = {
2894 { "wm8915", 0 },
2895 { }
2896};
2897MODULE_DEVICE_TABLE(i2c, wm8915_i2c_id);
2898
2899static struct i2c_driver wm8915_i2c_driver = {
2900 .driver = {
2901 .name = "wm8915",
2902 .owner = THIS_MODULE,
2903 },
2904 .probe = wm8915_i2c_probe,
2905 .remove = __devexit_p(wm8915_i2c_remove),
2906 .id_table = wm8915_i2c_id,
2907};
2908
2909static int __init wm8915_modinit(void)
2910{
2911 int ret;
2912
2913 ret = i2c_add_driver(&wm8915_i2c_driver);
2914 if (ret != 0) {
2915 printk(KERN_ERR "Failed to register WM8915 I2C driver: %d\n",
2916 ret);
2917 }
2918
2919 return ret;
2920}
2921module_init(wm8915_modinit);
2922
2923static void __exit wm8915_exit(void)
2924{
2925 i2c_del_driver(&wm8915_i2c_driver);
2926}
2927module_exit(wm8915_exit);
2928
2929MODULE_DESCRIPTION("ASoC WM8915 driver");
2930MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2931MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8915.h b/sound/soc/codecs/wm8915.h
new file mode 100644
index 000000000000..200ffd7bf953
--- /dev/null
+++ b/sound/soc/codecs/wm8915.h
@@ -0,0 +1,3717 @@
1/*
2 * wm8915.h - WM8915 audio codec interface
3 *
4 * Copyright 2011 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef _WM8915_H
14#define _WM8915_H
15
16#define WM8915_SYSCLK_MCLK1 1
17#define WM8915_SYSCLK_MCLK2 2
18#define WM8915_SYSCLK_FLL 3
19
20#define WM8915_FLL_MCLK1 1
21#define WM8915_FLL_MCLK2 2
22#define WM8915_FLL_DACLRCLK1 3
23#define WM8915_FLL_BCLK1 4
24
25typedef void (*wm8915_polarity_fn)(struct snd_soc_codec *codec, int polarity);
26
27int wm8915_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
28 wm8915_polarity_fn polarity_cb);
29
30/*
31 * Register values.
32 */
33#define WM8915_SOFTWARE_RESET 0x00
34#define WM8915_POWER_MANAGEMENT_1 0x01
35#define WM8915_POWER_MANAGEMENT_2 0x02
36#define WM8915_POWER_MANAGEMENT_3 0x03
37#define WM8915_POWER_MANAGEMENT_4 0x04
38#define WM8915_POWER_MANAGEMENT_5 0x05
39#define WM8915_POWER_MANAGEMENT_6 0x06
40#define WM8915_POWER_MANAGEMENT_7 0x07
41#define WM8915_POWER_MANAGEMENT_8 0x08
42#define WM8915_LEFT_LINE_INPUT_VOLUME 0x10
43#define WM8915_RIGHT_LINE_INPUT_VOLUME 0x11
44#define WM8915_LINE_INPUT_CONTROL 0x12
45#define WM8915_DAC1_HPOUT1_VOLUME 0x15
46#define WM8915_DAC2_HPOUT2_VOLUME 0x16
47#define WM8915_DAC1_LEFT_VOLUME 0x18
48#define WM8915_DAC1_RIGHT_VOLUME 0x19
49#define WM8915_DAC2_LEFT_VOLUME 0x1A
50#define WM8915_DAC2_RIGHT_VOLUME 0x1B
51#define WM8915_OUTPUT1_LEFT_VOLUME 0x1C
52#define WM8915_OUTPUT1_RIGHT_VOLUME 0x1D
53#define WM8915_OUTPUT2_LEFT_VOLUME 0x1E
54#define WM8915_OUTPUT2_RIGHT_VOLUME 0x1F
55#define WM8915_MICBIAS_1 0x20
56#define WM8915_MICBIAS_2 0x21
57#define WM8915_LDO_1 0x28
58#define WM8915_LDO_2 0x29
59#define WM8915_ACCESSORY_DETECT_MODE_1 0x30
60#define WM8915_ACCESSORY_DETECT_MODE_2 0x31
61#define WM8915_HEADPHONE_DETECT_1 0x34
62#define WM8915_HEADPHONE_DETECT_2 0x35
63#define WM8915_MIC_DETECT_1 0x38
64#define WM8915_MIC_DETECT_2 0x39
65#define WM8915_MIC_DETECT_3 0x3A
66#define WM8915_CHARGE_PUMP_1 0x40
67#define WM8915_CHARGE_PUMP_2 0x41
68#define WM8915_DC_SERVO_1 0x50
69#define WM8915_DC_SERVO_2 0x51
70#define WM8915_DC_SERVO_3 0x52
71#define WM8915_DC_SERVO_5 0x54
72#define WM8915_DC_SERVO_6 0x55
73#define WM8915_DC_SERVO_7 0x56
74#define WM8915_DC_SERVO_READBACK_0 0x57
75#define WM8915_ANALOGUE_HP_1 0x60
76#define WM8915_ANALOGUE_HP_2 0x61
77#define WM8915_CHIP_REVISION 0x100
78#define WM8915_CONTROL_INTERFACE_1 0x101
79#define WM8915_WRITE_SEQUENCER_CTRL_1 0x110
80#define WM8915_WRITE_SEQUENCER_CTRL_2 0x111
81#define WM8915_AIF_CLOCKING_1 0x200
82#define WM8915_AIF_CLOCKING_2 0x201
83#define WM8915_CLOCKING_1 0x208
84#define WM8915_CLOCKING_2 0x209
85#define WM8915_AIF_RATE 0x210
86#define WM8915_FLL_CONTROL_1 0x220
87#define WM8915_FLL_CONTROL_2 0x221
88#define WM8915_FLL_CONTROL_3 0x222
89#define WM8915_FLL_CONTROL_4 0x223
90#define WM8915_FLL_CONTROL_5 0x224
91#define WM8915_FLL_CONTROL_6 0x225
92#define WM8915_FLL_EFS_1 0x226
93#define WM8915_FLL_EFS_2 0x227
94#define WM8915_AIF1_CONTROL 0x300
95#define WM8915_AIF1_BCLK 0x301
96#define WM8915_AIF1_TX_LRCLK_1 0x302
97#define WM8915_AIF1_TX_LRCLK_2 0x303
98#define WM8915_AIF1_RX_LRCLK_1 0x304
99#define WM8915_AIF1_RX_LRCLK_2 0x305
100#define WM8915_AIF1TX_DATA_CONFIGURATION_1 0x306
101#define WM8915_AIF1TX_DATA_CONFIGURATION_2 0x307
102#define WM8915_AIF1RX_DATA_CONFIGURATION 0x308
103#define WM8915_AIF1TX_CHANNEL_0_CONFIGURATION 0x309
104#define WM8915_AIF1TX_CHANNEL_1_CONFIGURATION 0x30A
105#define WM8915_AIF1TX_CHANNEL_2_CONFIGURATION 0x30B
106#define WM8915_AIF1TX_CHANNEL_3_CONFIGURATION 0x30C
107#define WM8915_AIF1TX_CHANNEL_4_CONFIGURATION 0x30D
108#define WM8915_AIF1TX_CHANNEL_5_CONFIGURATION 0x30E
109#define WM8915_AIF1RX_CHANNEL_0_CONFIGURATION 0x30F
110#define WM8915_AIF1RX_CHANNEL_1_CONFIGURATION 0x310
111#define WM8915_AIF1RX_CHANNEL_2_CONFIGURATION 0x311
112#define WM8915_AIF1RX_CHANNEL_3_CONFIGURATION 0x312
113#define WM8915_AIF1RX_CHANNEL_4_CONFIGURATION 0x313
114#define WM8915_AIF1RX_CHANNEL_5_CONFIGURATION 0x314
115#define WM8915_AIF1RX_MONO_CONFIGURATION 0x315
116#define WM8915_AIF1TX_TEST 0x31A
117#define WM8915_AIF2_CONTROL 0x320
118#define WM8915_AIF2_BCLK 0x321
119#define WM8915_AIF2_TX_LRCLK_1 0x322
120#define WM8915_AIF2_TX_LRCLK_2 0x323
121#define WM8915_AIF2_RX_LRCLK_1 0x324
122#define WM8915_AIF2_RX_LRCLK_2 0x325
123#define WM8915_AIF2TX_DATA_CONFIGURATION_1 0x326
124#define WM8915_AIF2TX_DATA_CONFIGURATION_2 0x327
125#define WM8915_AIF2RX_DATA_CONFIGURATION 0x328
126#define WM8915_AIF2TX_CHANNEL_0_CONFIGURATION 0x329
127#define WM8915_AIF2TX_CHANNEL_1_CONFIGURATION 0x32A
128#define WM8915_AIF2RX_CHANNEL_0_CONFIGURATION 0x32B
129#define WM8915_AIF2RX_CHANNEL_1_CONFIGURATION 0x32C
130#define WM8915_AIF2RX_MONO_CONFIGURATION 0x32D
131#define WM8915_AIF2TX_TEST 0x32F
132#define WM8915_DSP1_TX_LEFT_VOLUME 0x400
133#define WM8915_DSP1_TX_RIGHT_VOLUME 0x401
134#define WM8915_DSP1_RX_LEFT_VOLUME 0x402
135#define WM8915_DSP1_RX_RIGHT_VOLUME 0x403
136#define WM8915_DSP1_TX_FILTERS 0x410
137#define WM8915_DSP1_RX_FILTERS_1 0x420
138#define WM8915_DSP1_RX_FILTERS_2 0x421
139#define WM8915_DSP1_DRC_1 0x440
140#define WM8915_DSP1_DRC_2 0x441
141#define WM8915_DSP1_DRC_3 0x442
142#define WM8915_DSP1_DRC_4 0x443
143#define WM8915_DSP1_DRC_5 0x444
144#define WM8915_DSP1_RX_EQ_GAINS_1 0x480
145#define WM8915_DSP1_RX_EQ_GAINS_2 0x481
146#define WM8915_DSP1_RX_EQ_BAND_1_A 0x482
147#define WM8915_DSP1_RX_EQ_BAND_1_B 0x483
148#define WM8915_DSP1_RX_EQ_BAND_1_PG 0x484
149#define WM8915_DSP1_RX_EQ_BAND_2_A 0x485
150#define WM8915_DSP1_RX_EQ_BAND_2_B 0x486
151#define WM8915_DSP1_RX_EQ_BAND_2_C 0x487
152#define WM8915_DSP1_RX_EQ_BAND_2_PG 0x488
153#define WM8915_DSP1_RX_EQ_BAND_3_A 0x489
154#define WM8915_DSP1_RX_EQ_BAND_3_B 0x48A
155#define WM8915_DSP1_RX_EQ_BAND_3_C 0x48B
156#define WM8915_DSP1_RX_EQ_BAND_3_PG 0x48C
157#define WM8915_DSP1_RX_EQ_BAND_4_A 0x48D
158#define WM8915_DSP1_RX_EQ_BAND_4_B 0x48E
159#define WM8915_DSP1_RX_EQ_BAND_4_C 0x48F
160#define WM8915_DSP1_RX_EQ_BAND_4_PG 0x490
161#define WM8915_DSP1_RX_EQ_BAND_5_A 0x491
162#define WM8915_DSP1_RX_EQ_BAND_5_B 0x492
163#define WM8915_DSP1_RX_EQ_BAND_5_PG 0x493
164#define WM8915_DSP2_TX_LEFT_VOLUME 0x500
165#define WM8915_DSP2_TX_RIGHT_VOLUME 0x501
166#define WM8915_DSP2_RX_LEFT_VOLUME 0x502
167#define WM8915_DSP2_RX_RIGHT_VOLUME 0x503
168#define WM8915_DSP2_TX_FILTERS 0x510
169#define WM8915_DSP2_RX_FILTERS_1 0x520
170#define WM8915_DSP2_RX_FILTERS_2 0x521
171#define WM8915_DSP2_DRC_1 0x540
172#define WM8915_DSP2_DRC_2 0x541
173#define WM8915_DSP2_DRC_3 0x542
174#define WM8915_DSP2_DRC_4 0x543
175#define WM8915_DSP2_DRC_5 0x544
176#define WM8915_DSP2_RX_EQ_GAINS_1 0x580
177#define WM8915_DSP2_RX_EQ_GAINS_2 0x581
178#define WM8915_DSP2_RX_EQ_BAND_1_A 0x582
179#define WM8915_DSP2_RX_EQ_BAND_1_B 0x583
180#define WM8915_DSP2_RX_EQ_BAND_1_PG 0x584
181#define WM8915_DSP2_RX_EQ_BAND_2_A 0x585
182#define WM8915_DSP2_RX_EQ_BAND_2_B 0x586
183#define WM8915_DSP2_RX_EQ_BAND_2_C 0x587
184#define WM8915_DSP2_RX_EQ_BAND_2_PG 0x588
185#define WM8915_DSP2_RX_EQ_BAND_3_A 0x589
186#define WM8915_DSP2_RX_EQ_BAND_3_B 0x58A
187#define WM8915_DSP2_RX_EQ_BAND_3_C 0x58B
188#define WM8915_DSP2_RX_EQ_BAND_3_PG 0x58C
189#define WM8915_DSP2_RX_EQ_BAND_4_A 0x58D
190#define WM8915_DSP2_RX_EQ_BAND_4_B 0x58E
191#define WM8915_DSP2_RX_EQ_BAND_4_C 0x58F
192#define WM8915_DSP2_RX_EQ_BAND_4_PG 0x590
193#define WM8915_DSP2_RX_EQ_BAND_5_A 0x591
194#define WM8915_DSP2_RX_EQ_BAND_5_B 0x592
195#define WM8915_DSP2_RX_EQ_BAND_5_PG 0x593
196#define WM8915_DAC1_MIXER_VOLUMES 0x600
197#define WM8915_DAC1_LEFT_MIXER_ROUTING 0x601
198#define WM8915_DAC1_RIGHT_MIXER_ROUTING 0x602
199#define WM8915_DAC2_MIXER_VOLUMES 0x603
200#define WM8915_DAC2_LEFT_MIXER_ROUTING 0x604
201#define WM8915_DAC2_RIGHT_MIXER_ROUTING 0x605
202#define WM8915_DSP1_TX_LEFT_MIXER_ROUTING 0x606
203#define WM8915_DSP1_TX_RIGHT_MIXER_ROUTING 0x607
204#define WM8915_DSP2_TX_LEFT_MIXER_ROUTING 0x608
205#define WM8915_DSP2_TX_RIGHT_MIXER_ROUTING 0x609
206#define WM8915_DSP_TX_MIXER_SELECT 0x60A
207#define WM8915_DAC_SOFTMUTE 0x610
208#define WM8915_OVERSAMPLING 0x620
209#define WM8915_SIDETONE 0x621
210#define WM8915_GPIO_1 0x700
211#define WM8915_GPIO_2 0x701
212#define WM8915_GPIO_3 0x702
213#define WM8915_GPIO_4 0x703
214#define WM8915_GPIO_5 0x704
215#define WM8915_PULL_CONTROL_1 0x720
216#define WM8915_PULL_CONTROL_2 0x721
217#define WM8915_INTERRUPT_STATUS_1 0x730
218#define WM8915_INTERRUPT_STATUS_2 0x731
219#define WM8915_INTERRUPT_RAW_STATUS_2 0x732
220#define WM8915_INTERRUPT_STATUS_1_MASK 0x738
221#define WM8915_INTERRUPT_STATUS_2_MASK 0x739
222#define WM8915_INTERRUPT_CONTROL 0x740
223#define WM8915_LEFT_PDM_SPEAKER 0x800
224#define WM8915_RIGHT_PDM_SPEAKER 0x801
225#define WM8915_PDM_SPEAKER_MUTE_SEQUENCE 0x802
226#define WM8915_PDM_SPEAKER_VOLUME 0x803
227#define WM8915_WRITE_SEQUENCER_0 0x3000
228#define WM8915_WRITE_SEQUENCER_1 0x3001
229#define WM8915_WRITE_SEQUENCER_2 0x3002
230#define WM8915_WRITE_SEQUENCER_3 0x3003
231#define WM8915_WRITE_SEQUENCER_4 0x3004
232#define WM8915_WRITE_SEQUENCER_5 0x3005
233#define WM8915_WRITE_SEQUENCER_6 0x3006
234#define WM8915_WRITE_SEQUENCER_7 0x3007
235#define WM8915_WRITE_SEQUENCER_8 0x3008
236#define WM8915_WRITE_SEQUENCER_9 0x3009
237#define WM8915_WRITE_SEQUENCER_10 0x300A
238#define WM8915_WRITE_SEQUENCER_11 0x300B
239#define WM8915_WRITE_SEQUENCER_12 0x300C
240#define WM8915_WRITE_SEQUENCER_13 0x300D
241#define WM8915_WRITE_SEQUENCER_14 0x300E
242#define WM8915_WRITE_SEQUENCER_15 0x300F
243#define WM8915_WRITE_SEQUENCER_16 0x3010
244#define WM8915_WRITE_SEQUENCER_17 0x3011
245#define WM8915_WRITE_SEQUENCER_18 0x3012
246#define WM8915_WRITE_SEQUENCER_19 0x3013
247#define WM8915_WRITE_SEQUENCER_20 0x3014
248#define WM8915_WRITE_SEQUENCER_21 0x3015
249#define WM8915_WRITE_SEQUENCER_22 0x3016
250#define WM8915_WRITE_SEQUENCER_23 0x3017
251#define WM8915_WRITE_SEQUENCER_24 0x3018
252#define WM8915_WRITE_SEQUENCER_25 0x3019
253#define WM8915_WRITE_SEQUENCER_26 0x301A
254#define WM8915_WRITE_SEQUENCER_27 0x301B
255#define WM8915_WRITE_SEQUENCER_28 0x301C
256#define WM8915_WRITE_SEQUENCER_29 0x301D
257#define WM8915_WRITE_SEQUENCER_30 0x301E
258#define WM8915_WRITE_SEQUENCER_31 0x301F
259#define WM8915_WRITE_SEQUENCER_32 0x3020
260#define WM8915_WRITE_SEQUENCER_33 0x3021
261#define WM8915_WRITE_SEQUENCER_34 0x3022
262#define WM8915_WRITE_SEQUENCER_35 0x3023
263#define WM8915_WRITE_SEQUENCER_36 0x3024
264#define WM8915_WRITE_SEQUENCER_37 0x3025
265#define WM8915_WRITE_SEQUENCER_38 0x3026
266#define WM8915_WRITE_SEQUENCER_39 0x3027
267#define WM8915_WRITE_SEQUENCER_40 0x3028
268#define WM8915_WRITE_SEQUENCER_41 0x3029
269#define WM8915_WRITE_SEQUENCER_42 0x302A
270#define WM8915_WRITE_SEQUENCER_43 0x302B
271#define WM8915_WRITE_SEQUENCER_44 0x302C
272#define WM8915_WRITE_SEQUENCER_45 0x302D
273#define WM8915_WRITE_SEQUENCER_46 0x302E
274#define WM8915_WRITE_SEQUENCER_47 0x302F
275#define WM8915_WRITE_SEQUENCER_48 0x3030
276#define WM8915_WRITE_SEQUENCER_49 0x3031
277#define WM8915_WRITE_SEQUENCER_50 0x3032
278#define WM8915_WRITE_SEQUENCER_51 0x3033
279#define WM8915_WRITE_SEQUENCER_52 0x3034
280#define WM8915_WRITE_SEQUENCER_53 0x3035
281#define WM8915_WRITE_SEQUENCER_54 0x3036
282#define WM8915_WRITE_SEQUENCER_55 0x3037
283#define WM8915_WRITE_SEQUENCER_56 0x3038
284#define WM8915_WRITE_SEQUENCER_57 0x3039
285#define WM8915_WRITE_SEQUENCER_58 0x303A
286#define WM8915_WRITE_SEQUENCER_59 0x303B
287#define WM8915_WRITE_SEQUENCER_60 0x303C
288#define WM8915_WRITE_SEQUENCER_61 0x303D
289#define WM8915_WRITE_SEQUENCER_62 0x303E
290#define WM8915_WRITE_SEQUENCER_63 0x303F
291#define WM8915_WRITE_SEQUENCER_64 0x3040
292#define WM8915_WRITE_SEQUENCER_65 0x3041
293#define WM8915_WRITE_SEQUENCER_66 0x3042
294#define WM8915_WRITE_SEQUENCER_67 0x3043
295#define WM8915_WRITE_SEQUENCER_68 0x3044
296#define WM8915_WRITE_SEQUENCER_69 0x3045
297#define WM8915_WRITE_SEQUENCER_70 0x3046
298#define WM8915_WRITE_SEQUENCER_71 0x3047
299#define WM8915_WRITE_SEQUENCER_72 0x3048
300#define WM8915_WRITE_SEQUENCER_73 0x3049
301#define WM8915_WRITE_SEQUENCER_74 0x304A
302#define WM8915_WRITE_SEQUENCER_75 0x304B
303#define WM8915_WRITE_SEQUENCER_76 0x304C
304#define WM8915_WRITE_SEQUENCER_77 0x304D
305#define WM8915_WRITE_SEQUENCER_78 0x304E
306#define WM8915_WRITE_SEQUENCER_79 0x304F
307#define WM8915_WRITE_SEQUENCER_80 0x3050
308#define WM8915_WRITE_SEQUENCER_81 0x3051
309#define WM8915_WRITE_SEQUENCER_82 0x3052
310#define WM8915_WRITE_SEQUENCER_83 0x3053
311#define WM8915_WRITE_SEQUENCER_84 0x3054
312#define WM8915_WRITE_SEQUENCER_85 0x3055
313#define WM8915_WRITE_SEQUENCER_86 0x3056
314#define WM8915_WRITE_SEQUENCER_87 0x3057
315#define WM8915_WRITE_SEQUENCER_88 0x3058
316#define WM8915_WRITE_SEQUENCER_89 0x3059
317#define WM8915_WRITE_SEQUENCER_90 0x305A
318#define WM8915_WRITE_SEQUENCER_91 0x305B
319#define WM8915_WRITE_SEQUENCER_92 0x305C
320#define WM8915_WRITE_SEQUENCER_93 0x305D
321#define WM8915_WRITE_SEQUENCER_94 0x305E
322#define WM8915_WRITE_SEQUENCER_95 0x305F
323#define WM8915_WRITE_SEQUENCER_96 0x3060
324#define WM8915_WRITE_SEQUENCER_97 0x3061
325#define WM8915_WRITE_SEQUENCER_98 0x3062
326#define WM8915_WRITE_SEQUENCER_99 0x3063
327#define WM8915_WRITE_SEQUENCER_100 0x3064
328#define WM8915_WRITE_SEQUENCER_101 0x3065
329#define WM8915_WRITE_SEQUENCER_102 0x3066
330#define WM8915_WRITE_SEQUENCER_103 0x3067
331#define WM8915_WRITE_SEQUENCER_104 0x3068
332#define WM8915_WRITE_SEQUENCER_105 0x3069
333#define WM8915_WRITE_SEQUENCER_106 0x306A
334#define WM8915_WRITE_SEQUENCER_107 0x306B
335#define WM8915_WRITE_SEQUENCER_108 0x306C
336#define WM8915_WRITE_SEQUENCER_109 0x306D
337#define WM8915_WRITE_SEQUENCER_110 0x306E
338#define WM8915_WRITE_SEQUENCER_111 0x306F
339#define WM8915_WRITE_SEQUENCER_112 0x3070
340#define WM8915_WRITE_SEQUENCER_113 0x3071
341#define WM8915_WRITE_SEQUENCER_114 0x3072
342#define WM8915_WRITE_SEQUENCER_115 0x3073
343#define WM8915_WRITE_SEQUENCER_116 0x3074
344#define WM8915_WRITE_SEQUENCER_117 0x3075
345#define WM8915_WRITE_SEQUENCER_118 0x3076
346#define WM8915_WRITE_SEQUENCER_119 0x3077
347#define WM8915_WRITE_SEQUENCER_120 0x3078
348#define WM8915_WRITE_SEQUENCER_121 0x3079
349#define WM8915_WRITE_SEQUENCER_122 0x307A
350#define WM8915_WRITE_SEQUENCER_123 0x307B
351#define WM8915_WRITE_SEQUENCER_124 0x307C
352#define WM8915_WRITE_SEQUENCER_125 0x307D
353#define WM8915_WRITE_SEQUENCER_126 0x307E
354#define WM8915_WRITE_SEQUENCER_127 0x307F
355#define WM8915_WRITE_SEQUENCER_128 0x3080
356#define WM8915_WRITE_SEQUENCER_129 0x3081
357#define WM8915_WRITE_SEQUENCER_130 0x3082
358#define WM8915_WRITE_SEQUENCER_131 0x3083
359#define WM8915_WRITE_SEQUENCER_132 0x3084
360#define WM8915_WRITE_SEQUENCER_133 0x3085
361#define WM8915_WRITE_SEQUENCER_134 0x3086
362#define WM8915_WRITE_SEQUENCER_135 0x3087
363#define WM8915_WRITE_SEQUENCER_136 0x3088
364#define WM8915_WRITE_SEQUENCER_137 0x3089
365#define WM8915_WRITE_SEQUENCER_138 0x308A
366#define WM8915_WRITE_SEQUENCER_139 0x308B
367#define WM8915_WRITE_SEQUENCER_140 0x308C
368#define WM8915_WRITE_SEQUENCER_141 0x308D
369#define WM8915_WRITE_SEQUENCER_142 0x308E
370#define WM8915_WRITE_SEQUENCER_143 0x308F
371#define WM8915_WRITE_SEQUENCER_144 0x3090
372#define WM8915_WRITE_SEQUENCER_145 0x3091
373#define WM8915_WRITE_SEQUENCER_146 0x3092
374#define WM8915_WRITE_SEQUENCER_147 0x3093
375#define WM8915_WRITE_SEQUENCER_148 0x3094
376#define WM8915_WRITE_SEQUENCER_149 0x3095
377#define WM8915_WRITE_SEQUENCER_150 0x3096
378#define WM8915_WRITE_SEQUENCER_151 0x3097
379#define WM8915_WRITE_SEQUENCER_152 0x3098
380#define WM8915_WRITE_SEQUENCER_153 0x3099
381#define WM8915_WRITE_SEQUENCER_154 0x309A
382#define WM8915_WRITE_SEQUENCER_155 0x309B
383#define WM8915_WRITE_SEQUENCER_156 0x309C
384#define WM8915_WRITE_SEQUENCER_157 0x309D
385#define WM8915_WRITE_SEQUENCER_158 0x309E
386#define WM8915_WRITE_SEQUENCER_159 0x309F
387#define WM8915_WRITE_SEQUENCER_160 0x30A0
388#define WM8915_WRITE_SEQUENCER_161 0x30A1
389#define WM8915_WRITE_SEQUENCER_162 0x30A2
390#define WM8915_WRITE_SEQUENCER_163 0x30A3
391#define WM8915_WRITE_SEQUENCER_164 0x30A4
392#define WM8915_WRITE_SEQUENCER_165 0x30A5
393#define WM8915_WRITE_SEQUENCER_166 0x30A6
394#define WM8915_WRITE_SEQUENCER_167 0x30A7
395#define WM8915_WRITE_SEQUENCER_168 0x30A8
396#define WM8915_WRITE_SEQUENCER_169 0x30A9
397#define WM8915_WRITE_SEQUENCER_170 0x30AA
398#define WM8915_WRITE_SEQUENCER_171 0x30AB
399#define WM8915_WRITE_SEQUENCER_172 0x30AC
400#define WM8915_WRITE_SEQUENCER_173 0x30AD
401#define WM8915_WRITE_SEQUENCER_174 0x30AE
402#define WM8915_WRITE_SEQUENCER_175 0x30AF
403#define WM8915_WRITE_SEQUENCER_176 0x30B0
404#define WM8915_WRITE_SEQUENCER_177 0x30B1
405#define WM8915_WRITE_SEQUENCER_178 0x30B2
406#define WM8915_WRITE_SEQUENCER_179 0x30B3
407#define WM8915_WRITE_SEQUENCER_180 0x30B4
408#define WM8915_WRITE_SEQUENCER_181 0x30B5
409#define WM8915_WRITE_SEQUENCER_182 0x30B6
410#define WM8915_WRITE_SEQUENCER_183 0x30B7
411#define WM8915_WRITE_SEQUENCER_184 0x30B8
412#define WM8915_WRITE_SEQUENCER_185 0x30B9
413#define WM8915_WRITE_SEQUENCER_186 0x30BA
414#define WM8915_WRITE_SEQUENCER_187 0x30BB
415#define WM8915_WRITE_SEQUENCER_188 0x30BC
416#define WM8915_WRITE_SEQUENCER_189 0x30BD
417#define WM8915_WRITE_SEQUENCER_190 0x30BE
418#define WM8915_WRITE_SEQUENCER_191 0x30BF
419#define WM8915_WRITE_SEQUENCER_192 0x30C0
420#define WM8915_WRITE_SEQUENCER_193 0x30C1
421#define WM8915_WRITE_SEQUENCER_194 0x30C2
422#define WM8915_WRITE_SEQUENCER_195 0x30C3
423#define WM8915_WRITE_SEQUENCER_196 0x30C4
424#define WM8915_WRITE_SEQUENCER_197 0x30C5
425#define WM8915_WRITE_SEQUENCER_198 0x30C6
426#define WM8915_WRITE_SEQUENCER_199 0x30C7
427#define WM8915_WRITE_SEQUENCER_200 0x30C8
428#define WM8915_WRITE_SEQUENCER_201 0x30C9
429#define WM8915_WRITE_SEQUENCER_202 0x30CA
430#define WM8915_WRITE_SEQUENCER_203 0x30CB
431#define WM8915_WRITE_SEQUENCER_204 0x30CC
432#define WM8915_WRITE_SEQUENCER_205 0x30CD
433#define WM8915_WRITE_SEQUENCER_206 0x30CE
434#define WM8915_WRITE_SEQUENCER_207 0x30CF
435#define WM8915_WRITE_SEQUENCER_208 0x30D0
436#define WM8915_WRITE_SEQUENCER_209 0x30D1
437#define WM8915_WRITE_SEQUENCER_210 0x30D2
438#define WM8915_WRITE_SEQUENCER_211 0x30D3
439#define WM8915_WRITE_SEQUENCER_212 0x30D4
440#define WM8915_WRITE_SEQUENCER_213 0x30D5
441#define WM8915_WRITE_SEQUENCER_214 0x30D6
442#define WM8915_WRITE_SEQUENCER_215 0x30D7
443#define WM8915_WRITE_SEQUENCER_216 0x30D8
444#define WM8915_WRITE_SEQUENCER_217 0x30D9
445#define WM8915_WRITE_SEQUENCER_218 0x30DA
446#define WM8915_WRITE_SEQUENCER_219 0x30DB
447#define WM8915_WRITE_SEQUENCER_220 0x30DC
448#define WM8915_WRITE_SEQUENCER_221 0x30DD
449#define WM8915_WRITE_SEQUENCER_222 0x30DE
450#define WM8915_WRITE_SEQUENCER_223 0x30DF
451#define WM8915_WRITE_SEQUENCER_224 0x30E0
452#define WM8915_WRITE_SEQUENCER_225 0x30E1
453#define WM8915_WRITE_SEQUENCER_226 0x30E2
454#define WM8915_WRITE_SEQUENCER_227 0x30E3
455#define WM8915_WRITE_SEQUENCER_228 0x30E4
456#define WM8915_WRITE_SEQUENCER_229 0x30E5
457#define WM8915_WRITE_SEQUENCER_230 0x30E6
458#define WM8915_WRITE_SEQUENCER_231 0x30E7
459#define WM8915_WRITE_SEQUENCER_232 0x30E8
460#define WM8915_WRITE_SEQUENCER_233 0x30E9
461#define WM8915_WRITE_SEQUENCER_234 0x30EA
462#define WM8915_WRITE_SEQUENCER_235 0x30EB
463#define WM8915_WRITE_SEQUENCER_236 0x30EC
464#define WM8915_WRITE_SEQUENCER_237 0x30ED
465#define WM8915_WRITE_SEQUENCER_238 0x30EE
466#define WM8915_WRITE_SEQUENCER_239 0x30EF
467#define WM8915_WRITE_SEQUENCER_240 0x30F0
468#define WM8915_WRITE_SEQUENCER_241 0x30F1
469#define WM8915_WRITE_SEQUENCER_242 0x30F2
470#define WM8915_WRITE_SEQUENCER_243 0x30F3
471#define WM8915_WRITE_SEQUENCER_244 0x30F4
472#define WM8915_WRITE_SEQUENCER_245 0x30F5
473#define WM8915_WRITE_SEQUENCER_246 0x30F6
474#define WM8915_WRITE_SEQUENCER_247 0x30F7
475#define WM8915_WRITE_SEQUENCER_248 0x30F8
476#define WM8915_WRITE_SEQUENCER_249 0x30F9
477#define WM8915_WRITE_SEQUENCER_250 0x30FA
478#define WM8915_WRITE_SEQUENCER_251 0x30FB
479#define WM8915_WRITE_SEQUENCER_252 0x30FC
480#define WM8915_WRITE_SEQUENCER_253 0x30FD
481#define WM8915_WRITE_SEQUENCER_254 0x30FE
482#define WM8915_WRITE_SEQUENCER_255 0x30FF
483#define WM8915_WRITE_SEQUENCER_256 0x3100
484#define WM8915_WRITE_SEQUENCER_257 0x3101
485#define WM8915_WRITE_SEQUENCER_258 0x3102
486#define WM8915_WRITE_SEQUENCER_259 0x3103
487#define WM8915_WRITE_SEQUENCER_260 0x3104
488#define WM8915_WRITE_SEQUENCER_261 0x3105
489#define WM8915_WRITE_SEQUENCER_262 0x3106
490#define WM8915_WRITE_SEQUENCER_263 0x3107
491#define WM8915_WRITE_SEQUENCER_264 0x3108
492#define WM8915_WRITE_SEQUENCER_265 0x3109
493#define WM8915_WRITE_SEQUENCER_266 0x310A
494#define WM8915_WRITE_SEQUENCER_267 0x310B
495#define WM8915_WRITE_SEQUENCER_268 0x310C
496#define WM8915_WRITE_SEQUENCER_269 0x310D
497#define WM8915_WRITE_SEQUENCER_270 0x310E
498#define WM8915_WRITE_SEQUENCER_271 0x310F
499#define WM8915_WRITE_SEQUENCER_272 0x3110
500#define WM8915_WRITE_SEQUENCER_273 0x3111
501#define WM8915_WRITE_SEQUENCER_274 0x3112
502#define WM8915_WRITE_SEQUENCER_275 0x3113
503#define WM8915_WRITE_SEQUENCER_276 0x3114
504#define WM8915_WRITE_SEQUENCER_277 0x3115
505#define WM8915_WRITE_SEQUENCER_278 0x3116
506#define WM8915_WRITE_SEQUENCER_279 0x3117
507#define WM8915_WRITE_SEQUENCER_280 0x3118
508#define WM8915_WRITE_SEQUENCER_281 0x3119
509#define WM8915_WRITE_SEQUENCER_282 0x311A
510#define WM8915_WRITE_SEQUENCER_283 0x311B
511#define WM8915_WRITE_SEQUENCER_284 0x311C
512#define WM8915_WRITE_SEQUENCER_285 0x311D
513#define WM8915_WRITE_SEQUENCER_286 0x311E
514#define WM8915_WRITE_SEQUENCER_287 0x311F
515#define WM8915_WRITE_SEQUENCER_288 0x3120
516#define WM8915_WRITE_SEQUENCER_289 0x3121
517#define WM8915_WRITE_SEQUENCER_290 0x3122
518#define WM8915_WRITE_SEQUENCER_291 0x3123
519#define WM8915_WRITE_SEQUENCER_292 0x3124
520#define WM8915_WRITE_SEQUENCER_293 0x3125
521#define WM8915_WRITE_SEQUENCER_294 0x3126
522#define WM8915_WRITE_SEQUENCER_295 0x3127
523#define WM8915_WRITE_SEQUENCER_296 0x3128
524#define WM8915_WRITE_SEQUENCER_297 0x3129
525#define WM8915_WRITE_SEQUENCER_298 0x312A
526#define WM8915_WRITE_SEQUENCER_299 0x312B
527#define WM8915_WRITE_SEQUENCER_300 0x312C
528#define WM8915_WRITE_SEQUENCER_301 0x312D
529#define WM8915_WRITE_SEQUENCER_302 0x312E
530#define WM8915_WRITE_SEQUENCER_303 0x312F
531#define WM8915_WRITE_SEQUENCER_304 0x3130
532#define WM8915_WRITE_SEQUENCER_305 0x3131
533#define WM8915_WRITE_SEQUENCER_306 0x3132
534#define WM8915_WRITE_SEQUENCER_307 0x3133
535#define WM8915_WRITE_SEQUENCER_308 0x3134
536#define WM8915_WRITE_SEQUENCER_309 0x3135
537#define WM8915_WRITE_SEQUENCER_310 0x3136
538#define WM8915_WRITE_SEQUENCER_311 0x3137
539#define WM8915_WRITE_SEQUENCER_312 0x3138
540#define WM8915_WRITE_SEQUENCER_313 0x3139
541#define WM8915_WRITE_SEQUENCER_314 0x313A
542#define WM8915_WRITE_SEQUENCER_315 0x313B
543#define WM8915_WRITE_SEQUENCER_316 0x313C
544#define WM8915_WRITE_SEQUENCER_317 0x313D
545#define WM8915_WRITE_SEQUENCER_318 0x313E
546#define WM8915_WRITE_SEQUENCER_319 0x313F
547#define WM8915_WRITE_SEQUENCER_320 0x3140
548#define WM8915_WRITE_SEQUENCER_321 0x3141
549#define WM8915_WRITE_SEQUENCER_322 0x3142
550#define WM8915_WRITE_SEQUENCER_323 0x3143
551#define WM8915_WRITE_SEQUENCER_324 0x3144
552#define WM8915_WRITE_SEQUENCER_325 0x3145
553#define WM8915_WRITE_SEQUENCER_326 0x3146
554#define WM8915_WRITE_SEQUENCER_327 0x3147
555#define WM8915_WRITE_SEQUENCER_328 0x3148
556#define WM8915_WRITE_SEQUENCER_329 0x3149
557#define WM8915_WRITE_SEQUENCER_330 0x314A
558#define WM8915_WRITE_SEQUENCER_331 0x314B
559#define WM8915_WRITE_SEQUENCER_332 0x314C
560#define WM8915_WRITE_SEQUENCER_333 0x314D
561#define WM8915_WRITE_SEQUENCER_334 0x314E
562#define WM8915_WRITE_SEQUENCER_335 0x314F
563#define WM8915_WRITE_SEQUENCER_336 0x3150
564#define WM8915_WRITE_SEQUENCER_337 0x3151
565#define WM8915_WRITE_SEQUENCER_338 0x3152
566#define WM8915_WRITE_SEQUENCER_339 0x3153
567#define WM8915_WRITE_SEQUENCER_340 0x3154
568#define WM8915_WRITE_SEQUENCER_341 0x3155
569#define WM8915_WRITE_SEQUENCER_342 0x3156
570#define WM8915_WRITE_SEQUENCER_343 0x3157
571#define WM8915_WRITE_SEQUENCER_344 0x3158
572#define WM8915_WRITE_SEQUENCER_345 0x3159
573#define WM8915_WRITE_SEQUENCER_346 0x315A
574#define WM8915_WRITE_SEQUENCER_347 0x315B
575#define WM8915_WRITE_SEQUENCER_348 0x315C
576#define WM8915_WRITE_SEQUENCER_349 0x315D
577#define WM8915_WRITE_SEQUENCER_350 0x315E
578#define WM8915_WRITE_SEQUENCER_351 0x315F
579#define WM8915_WRITE_SEQUENCER_352 0x3160
580#define WM8915_WRITE_SEQUENCER_353 0x3161
581#define WM8915_WRITE_SEQUENCER_354 0x3162
582#define WM8915_WRITE_SEQUENCER_355 0x3163
583#define WM8915_WRITE_SEQUENCER_356 0x3164
584#define WM8915_WRITE_SEQUENCER_357 0x3165
585#define WM8915_WRITE_SEQUENCER_358 0x3166
586#define WM8915_WRITE_SEQUENCER_359 0x3167
587#define WM8915_WRITE_SEQUENCER_360 0x3168
588#define WM8915_WRITE_SEQUENCER_361 0x3169
589#define WM8915_WRITE_SEQUENCER_362 0x316A
590#define WM8915_WRITE_SEQUENCER_363 0x316B
591#define WM8915_WRITE_SEQUENCER_364 0x316C
592#define WM8915_WRITE_SEQUENCER_365 0x316D
593#define WM8915_WRITE_SEQUENCER_366 0x316E
594#define WM8915_WRITE_SEQUENCER_367 0x316F
595#define WM8915_WRITE_SEQUENCER_368 0x3170
596#define WM8915_WRITE_SEQUENCER_369 0x3171
597#define WM8915_WRITE_SEQUENCER_370 0x3172
598#define WM8915_WRITE_SEQUENCER_371 0x3173
599#define WM8915_WRITE_SEQUENCER_372 0x3174
600#define WM8915_WRITE_SEQUENCER_373 0x3175
601#define WM8915_WRITE_SEQUENCER_374 0x3176
602#define WM8915_WRITE_SEQUENCER_375 0x3177
603#define WM8915_WRITE_SEQUENCER_376 0x3178
604#define WM8915_WRITE_SEQUENCER_377 0x3179
605#define WM8915_WRITE_SEQUENCER_378 0x317A
606#define WM8915_WRITE_SEQUENCER_379 0x317B
607#define WM8915_WRITE_SEQUENCER_380 0x317C
608#define WM8915_WRITE_SEQUENCER_381 0x317D
609#define WM8915_WRITE_SEQUENCER_382 0x317E
610#define WM8915_WRITE_SEQUENCER_383 0x317F
611#define WM8915_WRITE_SEQUENCER_384 0x3180
612#define WM8915_WRITE_SEQUENCER_385 0x3181
613#define WM8915_WRITE_SEQUENCER_386 0x3182
614#define WM8915_WRITE_SEQUENCER_387 0x3183
615#define WM8915_WRITE_SEQUENCER_388 0x3184
616#define WM8915_WRITE_SEQUENCER_389 0x3185
617#define WM8915_WRITE_SEQUENCER_390 0x3186
618#define WM8915_WRITE_SEQUENCER_391 0x3187
619#define WM8915_WRITE_SEQUENCER_392 0x3188
620#define WM8915_WRITE_SEQUENCER_393 0x3189
621#define WM8915_WRITE_SEQUENCER_394 0x318A
622#define WM8915_WRITE_SEQUENCER_395 0x318B
623#define WM8915_WRITE_SEQUENCER_396 0x318C
624#define WM8915_WRITE_SEQUENCER_397 0x318D
625#define WM8915_WRITE_SEQUENCER_398 0x318E
626#define WM8915_WRITE_SEQUENCER_399 0x318F
627#define WM8915_WRITE_SEQUENCER_400 0x3190
628#define WM8915_WRITE_SEQUENCER_401 0x3191
629#define WM8915_WRITE_SEQUENCER_402 0x3192
630#define WM8915_WRITE_SEQUENCER_403 0x3193
631#define WM8915_WRITE_SEQUENCER_404 0x3194
632#define WM8915_WRITE_SEQUENCER_405 0x3195
633#define WM8915_WRITE_SEQUENCER_406 0x3196
634#define WM8915_WRITE_SEQUENCER_407 0x3197
635#define WM8915_WRITE_SEQUENCER_408 0x3198
636#define WM8915_WRITE_SEQUENCER_409 0x3199
637#define WM8915_WRITE_SEQUENCER_410 0x319A
638#define WM8915_WRITE_SEQUENCER_411 0x319B
639#define WM8915_WRITE_SEQUENCER_412 0x319C
640#define WM8915_WRITE_SEQUENCER_413 0x319D
641#define WM8915_WRITE_SEQUENCER_414 0x319E
642#define WM8915_WRITE_SEQUENCER_415 0x319F
643#define WM8915_WRITE_SEQUENCER_416 0x31A0
644#define WM8915_WRITE_SEQUENCER_417 0x31A1
645#define WM8915_WRITE_SEQUENCER_418 0x31A2
646#define WM8915_WRITE_SEQUENCER_419 0x31A3
647#define WM8915_WRITE_SEQUENCER_420 0x31A4
648#define WM8915_WRITE_SEQUENCER_421 0x31A5
649#define WM8915_WRITE_SEQUENCER_422 0x31A6
650#define WM8915_WRITE_SEQUENCER_423 0x31A7
651#define WM8915_WRITE_SEQUENCER_424 0x31A8
652#define WM8915_WRITE_SEQUENCER_425 0x31A9
653#define WM8915_WRITE_SEQUENCER_426 0x31AA
654#define WM8915_WRITE_SEQUENCER_427 0x31AB
655#define WM8915_WRITE_SEQUENCER_428 0x31AC
656#define WM8915_WRITE_SEQUENCER_429 0x31AD
657#define WM8915_WRITE_SEQUENCER_430 0x31AE
658#define WM8915_WRITE_SEQUENCER_431 0x31AF
659#define WM8915_WRITE_SEQUENCER_432 0x31B0
660#define WM8915_WRITE_SEQUENCER_433 0x31B1
661#define WM8915_WRITE_SEQUENCER_434 0x31B2
662#define WM8915_WRITE_SEQUENCER_435 0x31B3
663#define WM8915_WRITE_SEQUENCER_436 0x31B4
664#define WM8915_WRITE_SEQUENCER_437 0x31B5
665#define WM8915_WRITE_SEQUENCER_438 0x31B6
666#define WM8915_WRITE_SEQUENCER_439 0x31B7
667#define WM8915_WRITE_SEQUENCER_440 0x31B8
668#define WM8915_WRITE_SEQUENCER_441 0x31B9
669#define WM8915_WRITE_SEQUENCER_442 0x31BA
670#define WM8915_WRITE_SEQUENCER_443 0x31BB
671#define WM8915_WRITE_SEQUENCER_444 0x31BC
672#define WM8915_WRITE_SEQUENCER_445 0x31BD
673#define WM8915_WRITE_SEQUENCER_446 0x31BE
674#define WM8915_WRITE_SEQUENCER_447 0x31BF
675#define WM8915_WRITE_SEQUENCER_448 0x31C0
676#define WM8915_WRITE_SEQUENCER_449 0x31C1
677#define WM8915_WRITE_SEQUENCER_450 0x31C2
678#define WM8915_WRITE_SEQUENCER_451 0x31C3
679#define WM8915_WRITE_SEQUENCER_452 0x31C4
680#define WM8915_WRITE_SEQUENCER_453 0x31C5
681#define WM8915_WRITE_SEQUENCER_454 0x31C6
682#define WM8915_WRITE_SEQUENCER_455 0x31C7
683#define WM8915_WRITE_SEQUENCER_456 0x31C8
684#define WM8915_WRITE_SEQUENCER_457 0x31C9
685#define WM8915_WRITE_SEQUENCER_458 0x31CA
686#define WM8915_WRITE_SEQUENCER_459 0x31CB
687#define WM8915_WRITE_SEQUENCER_460 0x31CC
688#define WM8915_WRITE_SEQUENCER_461 0x31CD
689#define WM8915_WRITE_SEQUENCER_462 0x31CE
690#define WM8915_WRITE_SEQUENCER_463 0x31CF
691#define WM8915_WRITE_SEQUENCER_464 0x31D0
692#define WM8915_WRITE_SEQUENCER_465 0x31D1
693#define WM8915_WRITE_SEQUENCER_466 0x31D2
694#define WM8915_WRITE_SEQUENCER_467 0x31D3
695#define WM8915_WRITE_SEQUENCER_468 0x31D4
696#define WM8915_WRITE_SEQUENCER_469 0x31D5
697#define WM8915_WRITE_SEQUENCER_470 0x31D6
698#define WM8915_WRITE_SEQUENCER_471 0x31D7
699#define WM8915_WRITE_SEQUENCER_472 0x31D8
700#define WM8915_WRITE_SEQUENCER_473 0x31D9
701#define WM8915_WRITE_SEQUENCER_474 0x31DA
702#define WM8915_WRITE_SEQUENCER_475 0x31DB
703#define WM8915_WRITE_SEQUENCER_476 0x31DC
704#define WM8915_WRITE_SEQUENCER_477 0x31DD
705#define WM8915_WRITE_SEQUENCER_478 0x31DE
706#define WM8915_WRITE_SEQUENCER_479 0x31DF
707#define WM8915_WRITE_SEQUENCER_480 0x31E0
708#define WM8915_WRITE_SEQUENCER_481 0x31E1
709#define WM8915_WRITE_SEQUENCER_482 0x31E2
710#define WM8915_WRITE_SEQUENCER_483 0x31E3
711#define WM8915_WRITE_SEQUENCER_484 0x31E4
712#define WM8915_WRITE_SEQUENCER_485 0x31E5
713#define WM8915_WRITE_SEQUENCER_486 0x31E6
714#define WM8915_WRITE_SEQUENCER_487 0x31E7
715#define WM8915_WRITE_SEQUENCER_488 0x31E8
716#define WM8915_WRITE_SEQUENCER_489 0x31E9
717#define WM8915_WRITE_SEQUENCER_490 0x31EA
718#define WM8915_WRITE_SEQUENCER_491 0x31EB
719#define WM8915_WRITE_SEQUENCER_492 0x31EC
720#define WM8915_WRITE_SEQUENCER_493 0x31ED
721#define WM8915_WRITE_SEQUENCER_494 0x31EE
722#define WM8915_WRITE_SEQUENCER_495 0x31EF
723#define WM8915_WRITE_SEQUENCER_496 0x31F0
724#define WM8915_WRITE_SEQUENCER_497 0x31F1
725#define WM8915_WRITE_SEQUENCER_498 0x31F2
726#define WM8915_WRITE_SEQUENCER_499 0x31F3
727#define WM8915_WRITE_SEQUENCER_500 0x31F4
728#define WM8915_WRITE_SEQUENCER_501 0x31F5
729#define WM8915_WRITE_SEQUENCER_502 0x31F6
730#define WM8915_WRITE_SEQUENCER_503 0x31F7
731#define WM8915_WRITE_SEQUENCER_504 0x31F8
732#define WM8915_WRITE_SEQUENCER_505 0x31F9
733#define WM8915_WRITE_SEQUENCER_506 0x31FA
734#define WM8915_WRITE_SEQUENCER_507 0x31FB
735#define WM8915_WRITE_SEQUENCER_508 0x31FC
736#define WM8915_WRITE_SEQUENCER_509 0x31FD
737#define WM8915_WRITE_SEQUENCER_510 0x31FE
738#define WM8915_WRITE_SEQUENCER_511 0x31FF
739
740#define WM8915_REGISTER_COUNT 706
741#define WM8915_MAX_REGISTER 0x31FF
742
743/*
744 * Field Definitions.
745 */
746
747/*
748 * R0 (0x00) - Software Reset
749 */
750#define WM8915_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
751#define WM8915_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
752#define WM8915_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
753
754/*
755 * R1 (0x01) - Power Management (1)
756 */
757#define WM8915_MICB2_ENA 0x0200 /* MICB2_ENA */
758#define WM8915_MICB2_ENA_MASK 0x0200 /* MICB2_ENA */
759#define WM8915_MICB2_ENA_SHIFT 9 /* MICB2_ENA */
760#define WM8915_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
761#define WM8915_MICB1_ENA 0x0100 /* MICB1_ENA */
762#define WM8915_MICB1_ENA_MASK 0x0100 /* MICB1_ENA */
763#define WM8915_MICB1_ENA_SHIFT 8 /* MICB1_ENA */
764#define WM8915_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
765#define WM8915_HPOUT2L_ENA 0x0080 /* HPOUT2L_ENA */
766#define WM8915_HPOUT2L_ENA_MASK 0x0080 /* HPOUT2L_ENA */
767#define WM8915_HPOUT2L_ENA_SHIFT 7 /* HPOUT2L_ENA */
768#define WM8915_HPOUT2L_ENA_WIDTH 1 /* HPOUT2L_ENA */
769#define WM8915_HPOUT2R_ENA 0x0040 /* HPOUT2R_ENA */
770#define WM8915_HPOUT2R_ENA_MASK 0x0040 /* HPOUT2R_ENA */
771#define WM8915_HPOUT2R_ENA_SHIFT 6 /* HPOUT2R_ENA */
772#define WM8915_HPOUT2R_ENA_WIDTH 1 /* HPOUT2R_ENA */
773#define WM8915_HPOUT1L_ENA 0x0020 /* HPOUT1L_ENA */
774#define WM8915_HPOUT1L_ENA_MASK 0x0020 /* HPOUT1L_ENA */
775#define WM8915_HPOUT1L_ENA_SHIFT 5 /* HPOUT1L_ENA */
776#define WM8915_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
777#define WM8915_HPOUT1R_ENA 0x0010 /* HPOUT1R_ENA */
778#define WM8915_HPOUT1R_ENA_MASK 0x0010 /* HPOUT1R_ENA */
779#define WM8915_HPOUT1R_ENA_SHIFT 4 /* HPOUT1R_ENA */
780#define WM8915_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
781#define WM8915_BG_ENA 0x0001 /* BG_ENA */
782#define WM8915_BG_ENA_MASK 0x0001 /* BG_ENA */
783#define WM8915_BG_ENA_SHIFT 0 /* BG_ENA */
784#define WM8915_BG_ENA_WIDTH 1 /* BG_ENA */
785
786/*
787 * R2 (0x02) - Power Management (2)
788 */
789#define WM8915_OPCLK_ENA 0x0800 /* OPCLK_ENA */
790#define WM8915_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
791#define WM8915_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
792#define WM8915_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
793#define WM8915_INL_ENA 0x0020 /* INL_ENA */
794#define WM8915_INL_ENA_MASK 0x0020 /* INL_ENA */
795#define WM8915_INL_ENA_SHIFT 5 /* INL_ENA */
796#define WM8915_INL_ENA_WIDTH 1 /* INL_ENA */
797#define WM8915_INR_ENA 0x0010 /* INR_ENA */
798#define WM8915_INR_ENA_MASK 0x0010 /* INR_ENA */
799#define WM8915_INR_ENA_SHIFT 4 /* INR_ENA */
800#define WM8915_INR_ENA_WIDTH 1 /* INR_ENA */
801#define WM8915_LDO2_ENA 0x0002 /* LDO2_ENA */
802#define WM8915_LDO2_ENA_MASK 0x0002 /* LDO2_ENA */
803#define WM8915_LDO2_ENA_SHIFT 1 /* LDO2_ENA */
804#define WM8915_LDO2_ENA_WIDTH 1 /* LDO2_ENA */
805
806/*
807 * R3 (0x03) - Power Management (3)
808 */
809#define WM8915_DSP2RXL_ENA 0x0800 /* DSP2RXL_ENA */
810#define WM8915_DSP2RXL_ENA_MASK 0x0800 /* DSP2RXL_ENA */
811#define WM8915_DSP2RXL_ENA_SHIFT 11 /* DSP2RXL_ENA */
812#define WM8915_DSP2RXL_ENA_WIDTH 1 /* DSP2RXL_ENA */
813#define WM8915_DSP2RXR_ENA 0x0400 /* DSP2RXR_ENA */
814#define WM8915_DSP2RXR_ENA_MASK 0x0400 /* DSP2RXR_ENA */
815#define WM8915_DSP2RXR_ENA_SHIFT 10 /* DSP2RXR_ENA */
816#define WM8915_DSP2RXR_ENA_WIDTH 1 /* DSP2RXR_ENA */
817#define WM8915_DSP1RXL_ENA 0x0200 /* DSP1RXL_ENA */
818#define WM8915_DSP1RXL_ENA_MASK 0x0200 /* DSP1RXL_ENA */
819#define WM8915_DSP1RXL_ENA_SHIFT 9 /* DSP1RXL_ENA */
820#define WM8915_DSP1RXL_ENA_WIDTH 1 /* DSP1RXL_ENA */
821#define WM8915_DSP1RXR_ENA 0x0100 /* DSP1RXR_ENA */
822#define WM8915_DSP1RXR_ENA_MASK 0x0100 /* DSP1RXR_ENA */
823#define WM8915_DSP1RXR_ENA_SHIFT 8 /* DSP1RXR_ENA */
824#define WM8915_DSP1RXR_ENA_WIDTH 1 /* DSP1RXR_ENA */
825#define WM8915_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */
826#define WM8915_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */
827#define WM8915_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */
828#define WM8915_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */
829#define WM8915_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */
830#define WM8915_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */
831#define WM8915_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */
832#define WM8915_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */
833#define WM8915_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */
834#define WM8915_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */
835#define WM8915_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */
836#define WM8915_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */
837#define WM8915_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */
838#define WM8915_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */
839#define WM8915_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */
840#define WM8915_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */
841#define WM8915_ADCL_ENA 0x0002 /* ADCL_ENA */
842#define WM8915_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
843#define WM8915_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
844#define WM8915_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
845#define WM8915_ADCR_ENA 0x0001 /* ADCR_ENA */
846#define WM8915_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
847#define WM8915_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
848#define WM8915_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
849
850/*
851 * R4 (0x04) - Power Management (4)
852 */
853#define WM8915_AIF2RX_CHAN1_ENA 0x0200 /* AIF2RX_CHAN1_ENA */
854#define WM8915_AIF2RX_CHAN1_ENA_MASK 0x0200 /* AIF2RX_CHAN1_ENA */
855#define WM8915_AIF2RX_CHAN1_ENA_SHIFT 9 /* AIF2RX_CHAN1_ENA */
856#define WM8915_AIF2RX_CHAN1_ENA_WIDTH 1 /* AIF2RX_CHAN1_ENA */
857#define WM8915_AIF2RX_CHAN0_ENA 0x0100 /* AIF2RX_CHAN0_ENA */
858#define WM8915_AIF2RX_CHAN0_ENA_MASK 0x0100 /* AIF2RX_CHAN0_ENA */
859#define WM8915_AIF2RX_CHAN0_ENA_SHIFT 8 /* AIF2RX_CHAN0_ENA */
860#define WM8915_AIF2RX_CHAN0_ENA_WIDTH 1 /* AIF2RX_CHAN0_ENA */
861#define WM8915_AIF1RX_CHAN5_ENA 0x0020 /* AIF1RX_CHAN5_ENA */
862#define WM8915_AIF1RX_CHAN5_ENA_MASK 0x0020 /* AIF1RX_CHAN5_ENA */
863#define WM8915_AIF1RX_CHAN5_ENA_SHIFT 5 /* AIF1RX_CHAN5_ENA */
864#define WM8915_AIF1RX_CHAN5_ENA_WIDTH 1 /* AIF1RX_CHAN5_ENA */
865#define WM8915_AIF1RX_CHAN4_ENA 0x0010 /* AIF1RX_CHAN4_ENA */
866#define WM8915_AIF1RX_CHAN4_ENA_MASK 0x0010 /* AIF1RX_CHAN4_ENA */
867#define WM8915_AIF1RX_CHAN4_ENA_SHIFT 4 /* AIF1RX_CHAN4_ENA */
868#define WM8915_AIF1RX_CHAN4_ENA_WIDTH 1 /* AIF1RX_CHAN4_ENA */
869#define WM8915_AIF1RX_CHAN3_ENA 0x0008 /* AIF1RX_CHAN3_ENA */
870#define WM8915_AIF1RX_CHAN3_ENA_MASK 0x0008 /* AIF1RX_CHAN3_ENA */
871#define WM8915_AIF1RX_CHAN3_ENA_SHIFT 3 /* AIF1RX_CHAN3_ENA */
872#define WM8915_AIF1RX_CHAN3_ENA_WIDTH 1 /* AIF1RX_CHAN3_ENA */
873#define WM8915_AIF1RX_CHAN2_ENA 0x0004 /* AIF1RX_CHAN2_ENA */
874#define WM8915_AIF1RX_CHAN2_ENA_MASK 0x0004 /* AIF1RX_CHAN2_ENA */
875#define WM8915_AIF1RX_CHAN2_ENA_SHIFT 2 /* AIF1RX_CHAN2_ENA */
876#define WM8915_AIF1RX_CHAN2_ENA_WIDTH 1 /* AIF1RX_CHAN2_ENA */
877#define WM8915_AIF1RX_CHAN1_ENA 0x0002 /* AIF1RX_CHAN1_ENA */
878#define WM8915_AIF1RX_CHAN1_ENA_MASK 0x0002 /* AIF1RX_CHAN1_ENA */
879#define WM8915_AIF1RX_CHAN1_ENA_SHIFT 1 /* AIF1RX_CHAN1_ENA */
880#define WM8915_AIF1RX_CHAN1_ENA_WIDTH 1 /* AIF1RX_CHAN1_ENA */
881#define WM8915_AIF1RX_CHAN0_ENA 0x0001 /* AIF1RX_CHAN0_ENA */
882#define WM8915_AIF1RX_CHAN0_ENA_MASK 0x0001 /* AIF1RX_CHAN0_ENA */
883#define WM8915_AIF1RX_CHAN0_ENA_SHIFT 0 /* AIF1RX_CHAN0_ENA */
884#define WM8915_AIF1RX_CHAN0_ENA_WIDTH 1 /* AIF1RX_CHAN0_ENA */
885
886/*
887 * R5 (0x05) - Power Management (5)
888 */
889#define WM8915_DSP2TXL_ENA 0x0800 /* DSP2TXL_ENA */
890#define WM8915_DSP2TXL_ENA_MASK 0x0800 /* DSP2TXL_ENA */
891#define WM8915_DSP2TXL_ENA_SHIFT 11 /* DSP2TXL_ENA */
892#define WM8915_DSP2TXL_ENA_WIDTH 1 /* DSP2TXL_ENA */
893#define WM8915_DSP2TXR_ENA 0x0400 /* DSP2TXR_ENA */
894#define WM8915_DSP2TXR_ENA_MASK 0x0400 /* DSP2TXR_ENA */
895#define WM8915_DSP2TXR_ENA_SHIFT 10 /* DSP2TXR_ENA */
896#define WM8915_DSP2TXR_ENA_WIDTH 1 /* DSP2TXR_ENA */
897#define WM8915_DSP1TXL_ENA 0x0200 /* DSP1TXL_ENA */
898#define WM8915_DSP1TXL_ENA_MASK 0x0200 /* DSP1TXL_ENA */
899#define WM8915_DSP1TXL_ENA_SHIFT 9 /* DSP1TXL_ENA */
900#define WM8915_DSP1TXL_ENA_WIDTH 1 /* DSP1TXL_ENA */
901#define WM8915_DSP1TXR_ENA 0x0100 /* DSP1TXR_ENA */
902#define WM8915_DSP1TXR_ENA_MASK 0x0100 /* DSP1TXR_ENA */
903#define WM8915_DSP1TXR_ENA_SHIFT 8 /* DSP1TXR_ENA */
904#define WM8915_DSP1TXR_ENA_WIDTH 1 /* DSP1TXR_ENA */
905#define WM8915_DAC2L_ENA 0x0008 /* DAC2L_ENA */
906#define WM8915_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */
907#define WM8915_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */
908#define WM8915_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */
909#define WM8915_DAC2R_ENA 0x0004 /* DAC2R_ENA */
910#define WM8915_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */
911#define WM8915_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */
912#define WM8915_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */
913#define WM8915_DAC1L_ENA 0x0002 /* DAC1L_ENA */
914#define WM8915_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */
915#define WM8915_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */
916#define WM8915_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */
917#define WM8915_DAC1R_ENA 0x0001 /* DAC1R_ENA */
918#define WM8915_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */
919#define WM8915_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */
920#define WM8915_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */
921
922/*
923 * R6 (0x06) - Power Management (6)
924 */
925#define WM8915_AIF2TX_CHAN1_ENA 0x0200 /* AIF2TX_CHAN1_ENA */
926#define WM8915_AIF2TX_CHAN1_ENA_MASK 0x0200 /* AIF2TX_CHAN1_ENA */
927#define WM8915_AIF2TX_CHAN1_ENA_SHIFT 9 /* AIF2TX_CHAN1_ENA */
928#define WM8915_AIF2TX_CHAN1_ENA_WIDTH 1 /* AIF2TX_CHAN1_ENA */
929#define WM8915_AIF2TX_CHAN0_ENA 0x0100 /* AIF2TX_CHAN0_ENA */
930#define WM8915_AIF2TX_CHAN0_ENA_MASK 0x0100 /* AIF2TX_CHAN0_ENA */
931#define WM8915_AIF2TX_CHAN0_ENA_SHIFT 8 /* AIF2TX_CHAN0_ENA */
932#define WM8915_AIF2TX_CHAN0_ENA_WIDTH 1 /* AIF2TX_CHAN0_ENA */
933#define WM8915_AIF1TX_CHAN5_ENA 0x0020 /* AIF1TX_CHAN5_ENA */
934#define WM8915_AIF1TX_CHAN5_ENA_MASK 0x0020 /* AIF1TX_CHAN5_ENA */
935#define WM8915_AIF1TX_CHAN5_ENA_SHIFT 5 /* AIF1TX_CHAN5_ENA */
936#define WM8915_AIF1TX_CHAN5_ENA_WIDTH 1 /* AIF1TX_CHAN5_ENA */
937#define WM8915_AIF1TX_CHAN4_ENA 0x0010 /* AIF1TX_CHAN4_ENA */
938#define WM8915_AIF1TX_CHAN4_ENA_MASK 0x0010 /* AIF1TX_CHAN4_ENA */
939#define WM8915_AIF1TX_CHAN4_ENA_SHIFT 4 /* AIF1TX_CHAN4_ENA */
940#define WM8915_AIF1TX_CHAN4_ENA_WIDTH 1 /* AIF1TX_CHAN4_ENA */
941#define WM8915_AIF1TX_CHAN3_ENA 0x0008 /* AIF1TX_CHAN3_ENA */
942#define WM8915_AIF1TX_CHAN3_ENA_MASK 0x0008 /* AIF1TX_CHAN3_ENA */
943#define WM8915_AIF1TX_CHAN3_ENA_SHIFT 3 /* AIF1TX_CHAN3_ENA */
944#define WM8915_AIF1TX_CHAN3_ENA_WIDTH 1 /* AIF1TX_CHAN3_ENA */
945#define WM8915_AIF1TX_CHAN2_ENA 0x0004 /* AIF1TX_CHAN2_ENA */
946#define WM8915_AIF1TX_CHAN2_ENA_MASK 0x0004 /* AIF1TX_CHAN2_ENA */
947#define WM8915_AIF1TX_CHAN2_ENA_SHIFT 2 /* AIF1TX_CHAN2_ENA */
948#define WM8915_AIF1TX_CHAN2_ENA_WIDTH 1 /* AIF1TX_CHAN2_ENA */
949#define WM8915_AIF1TX_CHAN1_ENA 0x0002 /* AIF1TX_CHAN1_ENA */
950#define WM8915_AIF1TX_CHAN1_ENA_MASK 0x0002 /* AIF1TX_CHAN1_ENA */
951#define WM8915_AIF1TX_CHAN1_ENA_SHIFT 1 /* AIF1TX_CHAN1_ENA */
952#define WM8915_AIF1TX_CHAN1_ENA_WIDTH 1 /* AIF1TX_CHAN1_ENA */
953#define WM8915_AIF1TX_CHAN0_ENA 0x0001 /* AIF1TX_CHAN0_ENA */
954#define WM8915_AIF1TX_CHAN0_ENA_MASK 0x0001 /* AIF1TX_CHAN0_ENA */
955#define WM8915_AIF1TX_CHAN0_ENA_SHIFT 0 /* AIF1TX_CHAN0_ENA */
956#define WM8915_AIF1TX_CHAN0_ENA_WIDTH 1 /* AIF1TX_CHAN0_ENA */
957
958/*
959 * R7 (0x07) - Power Management (7)
960 */
961#define WM8915_DMIC2_FN 0x0200 /* DMIC2_FN */
962#define WM8915_DMIC2_FN_MASK 0x0200 /* DMIC2_FN */
963#define WM8915_DMIC2_FN_SHIFT 9 /* DMIC2_FN */
964#define WM8915_DMIC2_FN_WIDTH 1 /* DMIC2_FN */
965#define WM8915_DMIC1_FN 0x0100 /* DMIC1_FN */
966#define WM8915_DMIC1_FN_MASK 0x0100 /* DMIC1_FN */
967#define WM8915_DMIC1_FN_SHIFT 8 /* DMIC1_FN */
968#define WM8915_DMIC1_FN_WIDTH 1 /* DMIC1_FN */
969#define WM8915_ADC_DMIC_DSP2R_ENA 0x0080 /* ADC_DMIC_DSP2R_ENA */
970#define WM8915_ADC_DMIC_DSP2R_ENA_MASK 0x0080 /* ADC_DMIC_DSP2R_ENA */
971#define WM8915_ADC_DMIC_DSP2R_ENA_SHIFT 7 /* ADC_DMIC_DSP2R_ENA */
972#define WM8915_ADC_DMIC_DSP2R_ENA_WIDTH 1 /* ADC_DMIC_DSP2R_ENA */
973#define WM8915_ADC_DMIC_DSP2L_ENA 0x0040 /* ADC_DMIC_DSP2L_ENA */
974#define WM8915_ADC_DMIC_DSP2L_ENA_MASK 0x0040 /* ADC_DMIC_DSP2L_ENA */
975#define WM8915_ADC_DMIC_DSP2L_ENA_SHIFT 6 /* ADC_DMIC_DSP2L_ENA */
976#define WM8915_ADC_DMIC_DSP2L_ENA_WIDTH 1 /* ADC_DMIC_DSP2L_ENA */
977#define WM8915_ADC_DMIC_SRC2_MASK 0x0030 /* ADC_DMIC_SRC2 - [5:4] */
978#define WM8915_ADC_DMIC_SRC2_SHIFT 4 /* ADC_DMIC_SRC2 - [5:4] */
979#define WM8915_ADC_DMIC_SRC2_WIDTH 2 /* ADC_DMIC_SRC2 - [5:4] */
980#define WM8915_ADC_DMIC_DSP1R_ENA 0x0008 /* ADC_DMIC_DSP1R_ENA */
981#define WM8915_ADC_DMIC_DSP1R_ENA_MASK 0x0008 /* ADC_DMIC_DSP1R_ENA */
982#define WM8915_ADC_DMIC_DSP1R_ENA_SHIFT 3 /* ADC_DMIC_DSP1R_ENA */
983#define WM8915_ADC_DMIC_DSP1R_ENA_WIDTH 1 /* ADC_DMIC_DSP1R_ENA */
984#define WM8915_ADC_DMIC_DSP1L_ENA 0x0004 /* ADC_DMIC_DSP1L_ENA */
985#define WM8915_ADC_DMIC_DSP1L_ENA_MASK 0x0004 /* ADC_DMIC_DSP1L_ENA */
986#define WM8915_ADC_DMIC_DSP1L_ENA_SHIFT 2 /* ADC_DMIC_DSP1L_ENA */
987#define WM8915_ADC_DMIC_DSP1L_ENA_WIDTH 1 /* ADC_DMIC_DSP1L_ENA */
988#define WM8915_ADC_DMIC_SRC1_MASK 0x0003 /* ADC_DMIC_SRC1 - [1:0] */
989#define WM8915_ADC_DMIC_SRC1_SHIFT 0 /* ADC_DMIC_SRC1 - [1:0] */
990#define WM8915_ADC_DMIC_SRC1_WIDTH 2 /* ADC_DMIC_SRC1 - [1:0] */
991
992/*
993 * R8 (0x08) - Power Management (8)
994 */
995#define WM8915_AIF2TX_SRC_MASK 0x00C0 /* AIF2TX_SRC - [7:6] */
996#define WM8915_AIF2TX_SRC_SHIFT 6 /* AIF2TX_SRC - [7:6] */
997#define WM8915_AIF2TX_SRC_WIDTH 2 /* AIF2TX_SRC - [7:6] */
998#define WM8915_DSP2RX_SRC 0x0010 /* DSP2RX_SRC */
999#define WM8915_DSP2RX_SRC_MASK 0x0010 /* DSP2RX_SRC */
1000#define WM8915_DSP2RX_SRC_SHIFT 4 /* DSP2RX_SRC */
1001#define WM8915_DSP2RX_SRC_WIDTH 1 /* DSP2RX_SRC */
1002#define WM8915_DSP1RX_SRC 0x0001 /* DSP1RX_SRC */
1003#define WM8915_DSP1RX_SRC_MASK 0x0001 /* DSP1RX_SRC */
1004#define WM8915_DSP1RX_SRC_SHIFT 0 /* DSP1RX_SRC */
1005#define WM8915_DSP1RX_SRC_WIDTH 1 /* DSP1RX_SRC */
1006
1007/*
1008 * R16 (0x10) - Left Line Input Volume
1009 */
1010#define WM8915_IN1_VU 0x0080 /* IN1_VU */
1011#define WM8915_IN1_VU_MASK 0x0080 /* IN1_VU */
1012#define WM8915_IN1_VU_SHIFT 7 /* IN1_VU */
1013#define WM8915_IN1_VU_WIDTH 1 /* IN1_VU */
1014#define WM8915_IN1L_ZC 0x0020 /* IN1L_ZC */
1015#define WM8915_IN1L_ZC_MASK 0x0020 /* IN1L_ZC */
1016#define WM8915_IN1L_ZC_SHIFT 5 /* IN1L_ZC */
1017#define WM8915_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
1018#define WM8915_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
1019#define WM8915_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
1020#define WM8915_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
1021
1022/*
1023 * R17 (0x11) - Right Line Input Volume
1024 */
1025#define WM8915_IN1_VU 0x0080 /* IN1_VU */
1026#define WM8915_IN1_VU_MASK 0x0080 /* IN1_VU */
1027#define WM8915_IN1_VU_SHIFT 7 /* IN1_VU */
1028#define WM8915_IN1_VU_WIDTH 1 /* IN1_VU */
1029#define WM8915_IN1R_ZC 0x0020 /* IN1R_ZC */
1030#define WM8915_IN1R_ZC_MASK 0x0020 /* IN1R_ZC */
1031#define WM8915_IN1R_ZC_SHIFT 5 /* IN1R_ZC */
1032#define WM8915_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
1033#define WM8915_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
1034#define WM8915_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
1035#define WM8915_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
1036
1037/*
1038 * R18 (0x12) - Line Input Control
1039 */
1040#define WM8915_INL_MODE_MASK 0x000C /* INL_MODE - [3:2] */
1041#define WM8915_INL_MODE_SHIFT 2 /* INL_MODE - [3:2] */
1042#define WM8915_INL_MODE_WIDTH 2 /* INL_MODE - [3:2] */
1043#define WM8915_INR_MODE_MASK 0x0003 /* INR_MODE - [1:0] */
1044#define WM8915_INR_MODE_SHIFT 0 /* INR_MODE - [1:0] */
1045#define WM8915_INR_MODE_WIDTH 2 /* INR_MODE - [1:0] */
1046
1047/*
1048 * R21 (0x15) - DAC1 HPOUT1 Volume
1049 */
1050#define WM8915_DAC1R_HPOUT1R_VOL_MASK 0x00F0 /* DAC1R_HPOUT1R_VOL - [7:4] */
1051#define WM8915_DAC1R_HPOUT1R_VOL_SHIFT 4 /* DAC1R_HPOUT1R_VOL - [7:4] */
1052#define WM8915_DAC1R_HPOUT1R_VOL_WIDTH 4 /* DAC1R_HPOUT1R_VOL - [7:4] */
1053#define WM8915_DAC1L_HPOUT1L_VOL_MASK 0x000F /* DAC1L_HPOUT1L_VOL - [3:0] */
1054#define WM8915_DAC1L_HPOUT1L_VOL_SHIFT 0 /* DAC1L_HPOUT1L_VOL - [3:0] */
1055#define WM8915_DAC1L_HPOUT1L_VOL_WIDTH 4 /* DAC1L_HPOUT1L_VOL - [3:0] */
1056
1057/*
1058 * R22 (0x16) - DAC2 HPOUT2 Volume
1059 */
1060#define WM8915_DAC2R_HPOUT2R_VOL_MASK 0x00F0 /* DAC2R_HPOUT2R_VOL - [7:4] */
1061#define WM8915_DAC2R_HPOUT2R_VOL_SHIFT 4 /* DAC2R_HPOUT2R_VOL - [7:4] */
1062#define WM8915_DAC2R_HPOUT2R_VOL_WIDTH 4 /* DAC2R_HPOUT2R_VOL - [7:4] */
1063#define WM8915_DAC2L_HPOUT2L_VOL_MASK 0x000F /* DAC2L_HPOUT2L_VOL - [3:0] */
1064#define WM8915_DAC2L_HPOUT2L_VOL_SHIFT 0 /* DAC2L_HPOUT2L_VOL - [3:0] */
1065#define WM8915_DAC2L_HPOUT2L_VOL_WIDTH 4 /* DAC2L_HPOUT2L_VOL - [3:0] */
1066
1067/*
1068 * R24 (0x18) - DAC1 Left Volume
1069 */
1070#define WM8915_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */
1071#define WM8915_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */
1072#define WM8915_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */
1073#define WM8915_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */
1074#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1075#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1076#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1077#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1078#define WM8915_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */
1079#define WM8915_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */
1080#define WM8915_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */
1081
1082/*
1083 * R25 (0x19) - DAC1 Right Volume
1084 */
1085#define WM8915_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */
1086#define WM8915_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */
1087#define WM8915_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */
1088#define WM8915_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */
1089#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1090#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1091#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1092#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1093#define WM8915_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */
1094#define WM8915_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */
1095#define WM8915_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */
1096
1097/*
1098 * R26 (0x1A) - DAC2 Left Volume
1099 */
1100#define WM8915_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */
1101#define WM8915_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */
1102#define WM8915_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */
1103#define WM8915_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */
1104#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1105#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1106#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1107#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1108#define WM8915_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */
1109#define WM8915_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */
1110#define WM8915_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */
1111
1112/*
1113 * R27 (0x1B) - DAC2 Right Volume
1114 */
1115#define WM8915_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */
1116#define WM8915_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */
1117#define WM8915_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */
1118#define WM8915_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */
1119#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1120#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1121#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1122#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1123#define WM8915_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */
1124#define WM8915_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */
1125#define WM8915_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */
1126
1127/*
1128 * R28 (0x1C) - Output1 Left Volume
1129 */
1130#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1131#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1132#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1133#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1134#define WM8915_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
1135#define WM8915_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
1136#define WM8915_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
1137#define WM8915_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
1138#define WM8915_HPOUT1L_VOL_MASK 0x000F /* HPOUT1L_VOL - [3:0] */
1139#define WM8915_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [3:0] */
1140#define WM8915_HPOUT1L_VOL_WIDTH 4 /* HPOUT1L_VOL - [3:0] */
1141
1142/*
1143 * R29 (0x1D) - Output1 Right Volume
1144 */
1145#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1146#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1147#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1148#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1149#define WM8915_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
1150#define WM8915_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
1151#define WM8915_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
1152#define WM8915_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
1153#define WM8915_HPOUT1R_VOL_MASK 0x000F /* HPOUT1R_VOL - [3:0] */
1154#define WM8915_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [3:0] */
1155#define WM8915_HPOUT1R_VOL_WIDTH 4 /* HPOUT1R_VOL - [3:0] */
1156
1157/*
1158 * R30 (0x1E) - Output2 Left Volume
1159 */
1160#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1161#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1162#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1163#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1164#define WM8915_HPOUT2L_ZC 0x0080 /* HPOUT2L_ZC */
1165#define WM8915_HPOUT2L_ZC_MASK 0x0080 /* HPOUT2L_ZC */
1166#define WM8915_HPOUT2L_ZC_SHIFT 7 /* HPOUT2L_ZC */
1167#define WM8915_HPOUT2L_ZC_WIDTH 1 /* HPOUT2L_ZC */
1168#define WM8915_HPOUT2L_VOL_MASK 0x000F /* HPOUT2L_VOL - [3:0] */
1169#define WM8915_HPOUT2L_VOL_SHIFT 0 /* HPOUT2L_VOL - [3:0] */
1170#define WM8915_HPOUT2L_VOL_WIDTH 4 /* HPOUT2L_VOL - [3:0] */
1171
1172/*
1173 * R31 (0x1F) - Output2 Right Volume
1174 */
1175#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1176#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1177#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1178#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1179#define WM8915_HPOUT2R_ZC 0x0080 /* HPOUT2R_ZC */
1180#define WM8915_HPOUT2R_ZC_MASK 0x0080 /* HPOUT2R_ZC */
1181#define WM8915_HPOUT2R_ZC_SHIFT 7 /* HPOUT2R_ZC */
1182#define WM8915_HPOUT2R_ZC_WIDTH 1 /* HPOUT2R_ZC */
1183#define WM8915_HPOUT2R_VOL_MASK 0x000F /* HPOUT2R_VOL - [3:0] */
1184#define WM8915_HPOUT2R_VOL_SHIFT 0 /* HPOUT2R_VOL - [3:0] */
1185#define WM8915_HPOUT2R_VOL_WIDTH 4 /* HPOUT2R_VOL - [3:0] */
1186
1187/*
1188 * R32 (0x20) - MICBIAS (1)
1189 */
1190#define WM8915_MICB1_RATE 0x0020 /* MICB1_RATE */
1191#define WM8915_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */
1192#define WM8915_MICB1_RATE_SHIFT 5 /* MICB1_RATE */
1193#define WM8915_MICB1_RATE_WIDTH 1 /* MICB1_RATE */
1194#define WM8915_MICB1_MODE 0x0010 /* MICB1_MODE */
1195#define WM8915_MICB1_MODE_MASK 0x0010 /* MICB1_MODE */
1196#define WM8915_MICB1_MODE_SHIFT 4 /* MICB1_MODE */
1197#define WM8915_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
1198#define WM8915_MICB1_LVL_MASK 0x000E /* MICB1_LVL - [3:1] */
1199#define WM8915_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [3:1] */
1200#define WM8915_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [3:1] */
1201#define WM8915_MICB1_DISCH 0x0001 /* MICB1_DISCH */
1202#define WM8915_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */
1203#define WM8915_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */
1204#define WM8915_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
1205
1206/*
1207 * R33 (0x21) - MICBIAS (2)
1208 */
1209#define WM8915_MICB2_RATE 0x0020 /* MICB2_RATE */
1210#define WM8915_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */
1211#define WM8915_MICB2_RATE_SHIFT 5 /* MICB2_RATE */
1212#define WM8915_MICB2_RATE_WIDTH 1 /* MICB2_RATE */
1213#define WM8915_MICB2_MODE 0x0010 /* MICB2_MODE */
1214#define WM8915_MICB2_MODE_MASK 0x0010 /* MICB2_MODE */
1215#define WM8915_MICB2_MODE_SHIFT 4 /* MICB2_MODE */
1216#define WM8915_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
1217#define WM8915_MICB2_LVL_MASK 0x000E /* MICB2_LVL - [3:1] */
1218#define WM8915_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [3:1] */
1219#define WM8915_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [3:1] */
1220#define WM8915_MICB2_DISCH 0x0001 /* MICB2_DISCH */
1221#define WM8915_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */
1222#define WM8915_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */
1223#define WM8915_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
1224
1225/*
1226 * R40 (0x28) - LDO 1
1227 */
1228#define WM8915_LDO1_MODE 0x0020 /* LDO1_MODE */
1229#define WM8915_LDO1_MODE_MASK 0x0020 /* LDO1_MODE */
1230#define WM8915_LDO1_MODE_SHIFT 5 /* LDO1_MODE */
1231#define WM8915_LDO1_MODE_WIDTH 1 /* LDO1_MODE */
1232#define WM8915_LDO1_VSEL_MASK 0x0006 /* LDO1_VSEL - [2:1] */
1233#define WM8915_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [2:1] */
1234#define WM8915_LDO1_VSEL_WIDTH 2 /* LDO1_VSEL - [2:1] */
1235#define WM8915_LDO1_DISCH 0x0001 /* LDO1_DISCH */
1236#define WM8915_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */
1237#define WM8915_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */
1238#define WM8915_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */
1239
1240/*
1241 * R41 (0x29) - LDO 2
1242 */
1243#define WM8915_LDO2_MODE 0x0020 /* LDO2_MODE */
1244#define WM8915_LDO2_MODE_MASK 0x0020 /* LDO2_MODE */
1245#define WM8915_LDO2_MODE_SHIFT 5 /* LDO2_MODE */
1246#define WM8915_LDO2_MODE_WIDTH 1 /* LDO2_MODE */
1247#define WM8915_LDO2_VSEL_MASK 0x001E /* LDO2_VSEL - [4:1] */
1248#define WM8915_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [4:1] */
1249#define WM8915_LDO2_VSEL_WIDTH 4 /* LDO2_VSEL - [4:1] */
1250#define WM8915_LDO2_DISCH 0x0001 /* LDO2_DISCH */
1251#define WM8915_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */
1252#define WM8915_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */
1253#define WM8915_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
1254
1255/*
1256 * R48 (0x30) - Accessory Detect Mode 1
1257 */
1258#define WM8915_JD_MODE_MASK 0x0003 /* JD_MODE - [1:0] */
1259#define WM8915_JD_MODE_SHIFT 0 /* JD_MODE - [1:0] */
1260#define WM8915_JD_MODE_WIDTH 2 /* JD_MODE - [1:0] */
1261
1262/*
1263 * R49 (0x31) - Accessory Detect Mode 2
1264 */
1265#define WM8915_HPOUT1FB_SRC 0x0004 /* HPOUT1FB_SRC */
1266#define WM8915_HPOUT1FB_SRC_MASK 0x0004 /* HPOUT1FB_SRC */
1267#define WM8915_HPOUT1FB_SRC_SHIFT 2 /* HPOUT1FB_SRC */
1268#define WM8915_HPOUT1FB_SRC_WIDTH 1 /* HPOUT1FB_SRC */
1269#define WM8915_MICD_SRC 0x0002 /* MICD_SRC */
1270#define WM8915_MICD_SRC_MASK 0x0002 /* MICD_SRC */
1271#define WM8915_MICD_SRC_SHIFT 1 /* MICD_SRC */
1272#define WM8915_MICD_SRC_WIDTH 1 /* MICD_SRC */
1273#define WM8915_MICD_BIAS_SRC 0x0001 /* MICD_BIAS_SRC */
1274#define WM8915_MICD_BIAS_SRC_MASK 0x0001 /* MICD_BIAS_SRC */
1275#define WM8915_MICD_BIAS_SRC_SHIFT 0 /* MICD_BIAS_SRC */
1276#define WM8915_MICD_BIAS_SRC_WIDTH 1 /* MICD_BIAS_SRC */
1277
1278/*
1279 * R52 (0x34) - Headphone Detect 1
1280 */
1281#define WM8915_HP_HOLDTIME_MASK 0x00E0 /* HP_HOLDTIME - [7:5] */
1282#define WM8915_HP_HOLDTIME_SHIFT 5 /* HP_HOLDTIME - [7:5] */
1283#define WM8915_HP_HOLDTIME_WIDTH 3 /* HP_HOLDTIME - [7:5] */
1284#define WM8915_HP_CLK_DIV_MASK 0x0018 /* HP_CLK_DIV - [4:3] */
1285#define WM8915_HP_CLK_DIV_SHIFT 3 /* HP_CLK_DIV - [4:3] */
1286#define WM8915_HP_CLK_DIV_WIDTH 2 /* HP_CLK_DIV - [4:3] */
1287#define WM8915_HP_STEP_SIZE 0x0002 /* HP_STEP_SIZE */
1288#define WM8915_HP_STEP_SIZE_MASK 0x0002 /* HP_STEP_SIZE */
1289#define WM8915_HP_STEP_SIZE_SHIFT 1 /* HP_STEP_SIZE */
1290#define WM8915_HP_STEP_SIZE_WIDTH 1 /* HP_STEP_SIZE */
1291#define WM8915_HP_POLL 0x0001 /* HP_POLL */
1292#define WM8915_HP_POLL_MASK 0x0001 /* HP_POLL */
1293#define WM8915_HP_POLL_SHIFT 0 /* HP_POLL */
1294#define WM8915_HP_POLL_WIDTH 1 /* HP_POLL */
1295
1296/*
1297 * R53 (0x35) - Headphone Detect 2
1298 */
1299#define WM8915_HP_DONE 0x0080 /* HP_DONE */
1300#define WM8915_HP_DONE_MASK 0x0080 /* HP_DONE */
1301#define WM8915_HP_DONE_SHIFT 7 /* HP_DONE */
1302#define WM8915_HP_DONE_WIDTH 1 /* HP_DONE */
1303#define WM8915_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */
1304#define WM8915_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
1305#define WM8915_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
1306
1307/*
1308 * R56 (0x38) - Mic Detect 1
1309 */
1310#define WM8915_MICD_BIAS_STARTTIME_MASK 0xF000 /* MICD_BIAS_STARTTIME - [15:12] */
1311#define WM8915_MICD_BIAS_STARTTIME_SHIFT 12 /* MICD_BIAS_STARTTIME - [15:12] */
1312#define WM8915_MICD_BIAS_STARTTIME_WIDTH 4 /* MICD_BIAS_STARTTIME - [15:12] */
1313#define WM8915_MICD_RATE_MASK 0x0F00 /* MICD_RATE - [11:8] */
1314#define WM8915_MICD_RATE_SHIFT 8 /* MICD_RATE - [11:8] */
1315#define WM8915_MICD_RATE_WIDTH 4 /* MICD_RATE - [11:8] */
1316#define WM8915_MICD_DBTIME 0x0002 /* MICD_DBTIME */
1317#define WM8915_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */
1318#define WM8915_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */
1319#define WM8915_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */
1320#define WM8915_MICD_ENA 0x0001 /* MICD_ENA */
1321#define WM8915_MICD_ENA_MASK 0x0001 /* MICD_ENA */
1322#define WM8915_MICD_ENA_SHIFT 0 /* MICD_ENA */
1323#define WM8915_MICD_ENA_WIDTH 1 /* MICD_ENA */
1324
1325/*
1326 * R57 (0x39) - Mic Detect 2
1327 */
1328#define WM8915_MICD_LVL_SEL_MASK 0x00FF /* MICD_LVL_SEL - [7:0] */
1329#define WM8915_MICD_LVL_SEL_SHIFT 0 /* MICD_LVL_SEL - [7:0] */
1330#define WM8915_MICD_LVL_SEL_WIDTH 8 /* MICD_LVL_SEL - [7:0] */
1331
1332/*
1333 * R58 (0x3A) - Mic Detect 3
1334 */
1335#define WM8915_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */
1336#define WM8915_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */
1337#define WM8915_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */
1338#define WM8915_MICD_VALID 0x0002 /* MICD_VALID */
1339#define WM8915_MICD_VALID_MASK 0x0002 /* MICD_VALID */
1340#define WM8915_MICD_VALID_SHIFT 1 /* MICD_VALID */
1341#define WM8915_MICD_VALID_WIDTH 1 /* MICD_VALID */
1342#define WM8915_MICD_STS 0x0001 /* MICD_STS */
1343#define WM8915_MICD_STS_MASK 0x0001 /* MICD_STS */
1344#define WM8915_MICD_STS_SHIFT 0 /* MICD_STS */
1345#define WM8915_MICD_STS_WIDTH 1 /* MICD_STS */
1346
1347/*
1348 * R64 (0x40) - Charge Pump (1)
1349 */
1350#define WM8915_CP_ENA 0x8000 /* CP_ENA */
1351#define WM8915_CP_ENA_MASK 0x8000 /* CP_ENA */
1352#define WM8915_CP_ENA_SHIFT 15 /* CP_ENA */
1353#define WM8915_CP_ENA_WIDTH 1 /* CP_ENA */
1354
1355/*
1356 * R65 (0x41) - Charge Pump (2)
1357 */
1358#define WM8915_CP_DISCH 0x8000 /* CP_DISCH */
1359#define WM8915_CP_DISCH_MASK 0x8000 /* CP_DISCH */
1360#define WM8915_CP_DISCH_SHIFT 15 /* CP_DISCH */
1361#define WM8915_CP_DISCH_WIDTH 1 /* CP_DISCH */
1362
1363/*
1364 * R80 (0x50) - DC Servo (1)
1365 */
1366#define WM8915_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
1367#define WM8915_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
1368#define WM8915_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
1369#define WM8915_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
1370#define WM8915_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
1371#define WM8915_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
1372#define WM8915_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
1373#define WM8915_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
1374#define WM8915_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
1375#define WM8915_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
1376#define WM8915_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
1377#define WM8915_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
1378#define WM8915_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
1379#define WM8915_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
1380#define WM8915_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
1381#define WM8915_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
1382
1383/*
1384 * R81 (0x51) - DC Servo (2)
1385 */
1386#define WM8915_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
1387#define WM8915_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
1388#define WM8915_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
1389#define WM8915_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
1390#define WM8915_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
1391#define WM8915_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
1392#define WM8915_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
1393#define WM8915_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
1394#define WM8915_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
1395#define WM8915_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
1396#define WM8915_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
1397#define WM8915_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
1398#define WM8915_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
1399#define WM8915_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
1400#define WM8915_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
1401#define WM8915_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
1402#define WM8915_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
1403#define WM8915_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
1404#define WM8915_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
1405#define WM8915_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
1406#define WM8915_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
1407#define WM8915_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
1408#define WM8915_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
1409#define WM8915_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
1410#define WM8915_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
1411#define WM8915_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
1412#define WM8915_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
1413#define WM8915_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
1414#define WM8915_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
1415#define WM8915_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
1416#define WM8915_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
1417#define WM8915_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
1418#define WM8915_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
1419#define WM8915_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
1420#define WM8915_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
1421#define WM8915_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
1422#define WM8915_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
1423#define WM8915_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
1424#define WM8915_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
1425#define WM8915_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
1426#define WM8915_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
1427#define WM8915_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
1428#define WM8915_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
1429#define WM8915_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
1430#define WM8915_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
1431#define WM8915_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
1432#define WM8915_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
1433#define WM8915_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
1434#define WM8915_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
1435#define WM8915_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
1436#define WM8915_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
1437#define WM8915_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
1438#define WM8915_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
1439#define WM8915_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
1440#define WM8915_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
1441#define WM8915_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
1442#define WM8915_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
1443#define WM8915_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
1444#define WM8915_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
1445#define WM8915_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
1446#define WM8915_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
1447#define WM8915_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
1448#define WM8915_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
1449#define WM8915_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
1450
1451/*
1452 * R82 (0x52) - DC Servo (3)
1453 */
1454#define WM8915_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
1455#define WM8915_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
1456#define WM8915_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
1457#define WM8915_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
1458#define WM8915_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
1459#define WM8915_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
1460
1461/*
1462 * R84 (0x54) - DC Servo (5)
1463 */
1464#define WM8915_DCS_SERIES_NO_23_MASK 0x7F00 /* DCS_SERIES_NO_23 - [14:8] */
1465#define WM8915_DCS_SERIES_NO_23_SHIFT 8 /* DCS_SERIES_NO_23 - [14:8] */
1466#define WM8915_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [14:8] */
1467#define WM8915_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
1468#define WM8915_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
1469#define WM8915_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
1470
1471/*
1472 * R85 (0x55) - DC Servo (6)
1473 */
1474#define WM8915_DCS_DAC_WR_VAL_3_MASK 0xFF00 /* DCS_DAC_WR_VAL_3 - [15:8] */
1475#define WM8915_DCS_DAC_WR_VAL_3_SHIFT 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
1476#define WM8915_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
1477#define WM8915_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
1478#define WM8915_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
1479#define WM8915_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
1480
1481/*
1482 * R86 (0x56) - DC Servo (7)
1483 */
1484#define WM8915_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
1485#define WM8915_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1486#define WM8915_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1487#define WM8915_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
1488#define WM8915_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
1489#define WM8915_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
1490
1491/*
1492 * R87 (0x57) - DC Servo Readback 0
1493 */
1494#define WM8915_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
1495#define WM8915_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
1496#define WM8915_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
1497#define WM8915_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
1498#define WM8915_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
1499#define WM8915_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
1500#define WM8915_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
1501#define WM8915_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
1502#define WM8915_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
1503
1504/*
1505 * R96 (0x60) - Analogue HP (1)
1506 */
1507#define WM8915_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
1508#define WM8915_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
1509#define WM8915_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
1510#define WM8915_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
1511#define WM8915_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
1512#define WM8915_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
1513#define WM8915_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
1514#define WM8915_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
1515#define WM8915_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
1516#define WM8915_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
1517#define WM8915_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
1518#define WM8915_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
1519#define WM8915_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
1520#define WM8915_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
1521#define WM8915_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
1522#define WM8915_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
1523#define WM8915_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
1524#define WM8915_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
1525#define WM8915_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
1526#define WM8915_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
1527#define WM8915_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
1528#define WM8915_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
1529#define WM8915_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
1530#define WM8915_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
1531
1532/*
1533 * R97 (0x61) - Analogue HP (2)
1534 */
1535#define WM8915_HPOUT2L_RMV_SHORT 0x0080 /* HPOUT2L_RMV_SHORT */
1536#define WM8915_HPOUT2L_RMV_SHORT_MASK 0x0080 /* HPOUT2L_RMV_SHORT */
1537#define WM8915_HPOUT2L_RMV_SHORT_SHIFT 7 /* HPOUT2L_RMV_SHORT */
1538#define WM8915_HPOUT2L_RMV_SHORT_WIDTH 1 /* HPOUT2L_RMV_SHORT */
1539#define WM8915_HPOUT2L_OUTP 0x0040 /* HPOUT2L_OUTP */
1540#define WM8915_HPOUT2L_OUTP_MASK 0x0040 /* HPOUT2L_OUTP */
1541#define WM8915_HPOUT2L_OUTP_SHIFT 6 /* HPOUT2L_OUTP */
1542#define WM8915_HPOUT2L_OUTP_WIDTH 1 /* HPOUT2L_OUTP */
1543#define WM8915_HPOUT2L_DLY 0x0020 /* HPOUT2L_DLY */
1544#define WM8915_HPOUT2L_DLY_MASK 0x0020 /* HPOUT2L_DLY */
1545#define WM8915_HPOUT2L_DLY_SHIFT 5 /* HPOUT2L_DLY */
1546#define WM8915_HPOUT2L_DLY_WIDTH 1 /* HPOUT2L_DLY */
1547#define WM8915_HPOUT2R_RMV_SHORT 0x0008 /* HPOUT2R_RMV_SHORT */
1548#define WM8915_HPOUT2R_RMV_SHORT_MASK 0x0008 /* HPOUT2R_RMV_SHORT */
1549#define WM8915_HPOUT2R_RMV_SHORT_SHIFT 3 /* HPOUT2R_RMV_SHORT */
1550#define WM8915_HPOUT2R_RMV_SHORT_WIDTH 1 /* HPOUT2R_RMV_SHORT */
1551#define WM8915_HPOUT2R_OUTP 0x0004 /* HPOUT2R_OUTP */
1552#define WM8915_HPOUT2R_OUTP_MASK 0x0004 /* HPOUT2R_OUTP */
1553#define WM8915_HPOUT2R_OUTP_SHIFT 2 /* HPOUT2R_OUTP */
1554#define WM8915_HPOUT2R_OUTP_WIDTH 1 /* HPOUT2R_OUTP */
1555#define WM8915_HPOUT2R_DLY 0x0002 /* HPOUT2R_DLY */
1556#define WM8915_HPOUT2R_DLY_MASK 0x0002 /* HPOUT2R_DLY */
1557#define WM8915_HPOUT2R_DLY_SHIFT 1 /* HPOUT2R_DLY */
1558#define WM8915_HPOUT2R_DLY_WIDTH 1 /* HPOUT2R_DLY */
1559
1560/*
1561 * R256 (0x100) - Chip Revision
1562 */
1563#define WM8915_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
1564#define WM8915_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
1565#define WM8915_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
1566
1567/*
1568 * R257 (0x101) - Control Interface (1)
1569 */
1570#define WM8915_AUTO_INC 0x0004 /* AUTO_INC */
1571#define WM8915_AUTO_INC_MASK 0x0004 /* AUTO_INC */
1572#define WM8915_AUTO_INC_SHIFT 2 /* AUTO_INC */
1573#define WM8915_AUTO_INC_WIDTH 1 /* AUTO_INC */
1574
1575/*
1576 * R272 (0x110) - Write Sequencer Ctrl (1)
1577 */
1578#define WM8915_WSEQ_ENA 0x8000 /* WSEQ_ENA */
1579#define WM8915_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */
1580#define WM8915_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */
1581#define WM8915_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1582#define WM8915_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1583#define WM8915_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1584#define WM8915_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1585#define WM8915_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1586#define WM8915_WSEQ_START 0x0100 /* WSEQ_START */
1587#define WM8915_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1588#define WM8915_WSEQ_START_SHIFT 8 /* WSEQ_START */
1589#define WM8915_WSEQ_START_WIDTH 1 /* WSEQ_START */
1590#define WM8915_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
1591#define WM8915_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
1592#define WM8915_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
1593
1594/*
1595 * R273 (0x111) - Write Sequencer Ctrl (2)
1596 */
1597#define WM8915_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */
1598#define WM8915_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */
1599#define WM8915_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */
1600#define WM8915_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
1601#define WM8915_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */
1602#define WM8915_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */
1603#define WM8915_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */
1604
1605/*
1606 * R512 (0x200) - AIF Clocking (1)
1607 */
1608#define WM8915_SYSCLK_SRC_MASK 0x0018 /* SYSCLK_SRC - [4:3] */
1609#define WM8915_SYSCLK_SRC_SHIFT 3 /* SYSCLK_SRC - [4:3] */
1610#define WM8915_SYSCLK_SRC_WIDTH 2 /* SYSCLK_SRC - [4:3] */
1611#define WM8915_SYSCLK_INV 0x0004 /* SYSCLK_INV */
1612#define WM8915_SYSCLK_INV_MASK 0x0004 /* SYSCLK_INV */
1613#define WM8915_SYSCLK_INV_SHIFT 2 /* SYSCLK_INV */
1614#define WM8915_SYSCLK_INV_WIDTH 1 /* SYSCLK_INV */
1615#define WM8915_SYSCLK_DIV 0x0002 /* SYSCLK_DIV */
1616#define WM8915_SYSCLK_DIV_MASK 0x0002 /* SYSCLK_DIV */
1617#define WM8915_SYSCLK_DIV_SHIFT 1 /* SYSCLK_DIV */
1618#define WM8915_SYSCLK_DIV_WIDTH 1 /* SYSCLK_DIV */
1619#define WM8915_SYSCLK_ENA 0x0001 /* SYSCLK_ENA */
1620#define WM8915_SYSCLK_ENA_MASK 0x0001 /* SYSCLK_ENA */
1621#define WM8915_SYSCLK_ENA_SHIFT 0 /* SYSCLK_ENA */
1622#define WM8915_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
1623
1624/*
1625 * R513 (0x201) - AIF Clocking (2)
1626 */
1627#define WM8915_DSP2_DIV_MASK 0x0018 /* DSP2_DIV - [4:3] */
1628#define WM8915_DSP2_DIV_SHIFT 3 /* DSP2_DIV - [4:3] */
1629#define WM8915_DSP2_DIV_WIDTH 2 /* DSP2_DIV - [4:3] */
1630#define WM8915_DSP1_DIV_MASK 0x0003 /* DSP1_DIV - [1:0] */
1631#define WM8915_DSP1_DIV_SHIFT 0 /* DSP1_DIV - [1:0] */
1632#define WM8915_DSP1_DIV_WIDTH 2 /* DSP1_DIV - [1:0] */
1633
1634/*
1635 * R520 (0x208) - Clocking (1)
1636 */
1637#define WM8915_LFCLK_ENA 0x0020 /* LFCLK_ENA */
1638#define WM8915_LFCLK_ENA_MASK 0x0020 /* LFCLK_ENA */
1639#define WM8915_LFCLK_ENA_SHIFT 5 /* LFCLK_ENA */
1640#define WM8915_LFCLK_ENA_WIDTH 1 /* LFCLK_ENA */
1641#define WM8915_TOCLK_ENA 0x0010 /* TOCLK_ENA */
1642#define WM8915_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
1643#define WM8915_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
1644#define WM8915_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
1645#define WM8915_AIFCLK_ENA 0x0004 /* AIFCLK_ENA */
1646#define WM8915_AIFCLK_ENA_MASK 0x0004 /* AIFCLK_ENA */
1647#define WM8915_AIFCLK_ENA_SHIFT 2 /* AIFCLK_ENA */
1648#define WM8915_AIFCLK_ENA_WIDTH 1 /* AIFCLK_ENA */
1649#define WM8915_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */
1650#define WM8915_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */
1651#define WM8915_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */
1652#define WM8915_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */
1653
1654/*
1655 * R521 (0x209) - Clocking (2)
1656 */
1657#define WM8915_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */
1658#define WM8915_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */
1659#define WM8915_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */
1660#define WM8915_DBCLK_DIV_MASK 0x00F0 /* DBCLK_DIV - [7:4] */
1661#define WM8915_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [7:4] */
1662#define WM8915_DBCLK_DIV_WIDTH 4 /* DBCLK_DIV - [7:4] */
1663#define WM8915_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */
1664#define WM8915_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */
1665#define WM8915_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */
1666
1667/*
1668 * R528 (0x210) - AIF Rate
1669 */
1670#define WM8915_SYSCLK_RATE 0x0001 /* SYSCLK_RATE */
1671#define WM8915_SYSCLK_RATE_MASK 0x0001 /* SYSCLK_RATE */
1672#define WM8915_SYSCLK_RATE_SHIFT 0 /* SYSCLK_RATE */
1673#define WM8915_SYSCLK_RATE_WIDTH 1 /* SYSCLK_RATE */
1674
1675/*
1676 * R544 (0x220) - FLL Control (1)
1677 */
1678#define WM8915_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
1679#define WM8915_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
1680#define WM8915_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
1681#define WM8915_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
1682#define WM8915_FLL_ENA 0x0001 /* FLL_ENA */
1683#define WM8915_FLL_ENA_MASK 0x0001 /* FLL_ENA */
1684#define WM8915_FLL_ENA_SHIFT 0 /* FLL_ENA */
1685#define WM8915_FLL_ENA_WIDTH 1 /* FLL_ENA */
1686
1687/*
1688 * R545 (0x221) - FLL Control (2)
1689 */
1690#define WM8915_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */
1691#define WM8915_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */
1692#define WM8915_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */
1693#define WM8915_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
1694#define WM8915_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
1695#define WM8915_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
1696
1697/*
1698 * R546 (0x222) - FLL Control (3)
1699 */
1700#define WM8915_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */
1701#define WM8915_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */
1702#define WM8915_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */
1703
1704/*
1705 * R547 (0x223) - FLL Control (4)
1706 */
1707#define WM8915_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
1708#define WM8915_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
1709#define WM8915_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
1710#define WM8915_FLL_LOOP_GAIN_MASK 0x000F /* FLL_LOOP_GAIN - [3:0] */
1711#define WM8915_FLL_LOOP_GAIN_SHIFT 0 /* FLL_LOOP_GAIN - [3:0] */
1712#define WM8915_FLL_LOOP_GAIN_WIDTH 4 /* FLL_LOOP_GAIN - [3:0] */
1713
1714/*
1715 * R548 (0x224) - FLL Control (5)
1716 */
1717#define WM8915_FLL_FRC_NCO_VAL_MASK 0x1F80 /* FLL_FRC_NCO_VAL - [12:7] */
1718#define WM8915_FLL_FRC_NCO_VAL_SHIFT 7 /* FLL_FRC_NCO_VAL - [12:7] */
1719#define WM8915_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [12:7] */
1720#define WM8915_FLL_FRC_NCO 0x0040 /* FLL_FRC_NCO */
1721#define WM8915_FLL_FRC_NCO_MASK 0x0040 /* FLL_FRC_NCO */
1722#define WM8915_FLL_FRC_NCO_SHIFT 6 /* FLL_FRC_NCO */
1723#define WM8915_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
1724#define WM8915_FLL_REFCLK_DIV_MASK 0x0018 /* FLL_REFCLK_DIV - [4:3] */
1725#define WM8915_FLL_REFCLK_DIV_SHIFT 3 /* FLL_REFCLK_DIV - [4:3] */
1726#define WM8915_FLL_REFCLK_DIV_WIDTH 2 /* FLL_REFCLK_DIV - [4:3] */
1727#define WM8915_FLL_REF_FREQ 0x0004 /* FLL_REF_FREQ */
1728#define WM8915_FLL_REF_FREQ_MASK 0x0004 /* FLL_REF_FREQ */
1729#define WM8915_FLL_REF_FREQ_SHIFT 2 /* FLL_REF_FREQ */
1730#define WM8915_FLL_REF_FREQ_WIDTH 1 /* FLL_REF_FREQ */
1731#define WM8915_FLL_REFCLK_SRC_MASK 0x0003 /* FLL_REFCLK_SRC - [1:0] */
1732#define WM8915_FLL_REFCLK_SRC_SHIFT 0 /* FLL_REFCLK_SRC - [1:0] */
1733#define WM8915_FLL_REFCLK_SRC_WIDTH 2 /* FLL_REFCLK_SRC - [1:0] */
1734
1735/*
1736 * R549 (0x225) - FLL Control (6)
1737 */
1738#define WM8915_FLL_REFCLK_SRC_STS_MASK 0x000C /* FLL_REFCLK_SRC_STS - [3:2] */
1739#define WM8915_FLL_REFCLK_SRC_STS_SHIFT 2 /* FLL_REFCLK_SRC_STS - [3:2] */
1740#define WM8915_FLL_REFCLK_SRC_STS_WIDTH 2 /* FLL_REFCLK_SRC_STS - [3:2] */
1741#define WM8915_FLL_SWITCH_CLK 0x0001 /* FLL_SWITCH_CLK */
1742#define WM8915_FLL_SWITCH_CLK_MASK 0x0001 /* FLL_SWITCH_CLK */
1743#define WM8915_FLL_SWITCH_CLK_SHIFT 0 /* FLL_SWITCH_CLK */
1744#define WM8915_FLL_SWITCH_CLK_WIDTH 1 /* FLL_SWITCH_CLK */
1745
1746/*
1747 * R550 (0x226) - FLL EFS 1
1748 */
1749#define WM8915_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */
1750#define WM8915_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */
1751#define WM8915_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */
1752
1753/*
1754 * R551 (0x227) - FLL EFS 2
1755 */
1756#define WM8915_FLL_LFSR_SEL_MASK 0x0006 /* FLL_LFSR_SEL - [2:1] */
1757#define WM8915_FLL_LFSR_SEL_SHIFT 1 /* FLL_LFSR_SEL - [2:1] */
1758#define WM8915_FLL_LFSR_SEL_WIDTH 2 /* FLL_LFSR_SEL - [2:1] */
1759#define WM8915_FLL_EFS_ENA 0x0001 /* FLL_EFS_ENA */
1760#define WM8915_FLL_EFS_ENA_MASK 0x0001 /* FLL_EFS_ENA */
1761#define WM8915_FLL_EFS_ENA_SHIFT 0 /* FLL_EFS_ENA */
1762#define WM8915_FLL_EFS_ENA_WIDTH 1 /* FLL_EFS_ENA */
1763
1764/*
1765 * R768 (0x300) - AIF1 Control
1766 */
1767#define WM8915_AIF1_TRI 0x0004 /* AIF1_TRI */
1768#define WM8915_AIF1_TRI_MASK 0x0004 /* AIF1_TRI */
1769#define WM8915_AIF1_TRI_SHIFT 2 /* AIF1_TRI */
1770#define WM8915_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
1771#define WM8915_AIF1_FMT_MASK 0x0003 /* AIF1_FMT - [1:0] */
1772#define WM8915_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [1:0] */
1773#define WM8915_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [1:0] */
1774
1775/*
1776 * R769 (0x301) - AIF1 BCLK
1777 */
1778#define WM8915_AIF1_BCLK_INV 0x0400 /* AIF1_BCLK_INV */
1779#define WM8915_AIF1_BCLK_INV_MASK 0x0400 /* AIF1_BCLK_INV */
1780#define WM8915_AIF1_BCLK_INV_SHIFT 10 /* AIF1_BCLK_INV */
1781#define WM8915_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
1782#define WM8915_AIF1_BCLK_FRC 0x0200 /* AIF1_BCLK_FRC */
1783#define WM8915_AIF1_BCLK_FRC_MASK 0x0200 /* AIF1_BCLK_FRC */
1784#define WM8915_AIF1_BCLK_FRC_SHIFT 9 /* AIF1_BCLK_FRC */
1785#define WM8915_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */
1786#define WM8915_AIF1_BCLK_MSTR 0x0100 /* AIF1_BCLK_MSTR */
1787#define WM8915_AIF1_BCLK_MSTR_MASK 0x0100 /* AIF1_BCLK_MSTR */
1788#define WM8915_AIF1_BCLK_MSTR_SHIFT 8 /* AIF1_BCLK_MSTR */
1789#define WM8915_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */
1790#define WM8915_AIF1_BCLK_DIV_MASK 0x000F /* AIF1_BCLK_DIV - [3:0] */
1791#define WM8915_AIF1_BCLK_DIV_SHIFT 0 /* AIF1_BCLK_DIV - [3:0] */
1792#define WM8915_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [3:0] */
1793
1794/*
1795 * R770 (0x302) - AIF1 TX LRCLK(1)
1796 */
1797#define WM8915_AIF1TX_RATE_MASK 0x07FF /* AIF1TX_RATE - [10:0] */
1798#define WM8915_AIF1TX_RATE_SHIFT 0 /* AIF1TX_RATE - [10:0] */
1799#define WM8915_AIF1TX_RATE_WIDTH 11 /* AIF1TX_RATE - [10:0] */
1800
1801/*
1802 * R771 (0x303) - AIF1 TX LRCLK(2)
1803 */
1804#define WM8915_AIF1TX_LRCLK_MODE 0x0008 /* AIF1TX_LRCLK_MODE */
1805#define WM8915_AIF1TX_LRCLK_MODE_MASK 0x0008 /* AIF1TX_LRCLK_MODE */
1806#define WM8915_AIF1TX_LRCLK_MODE_SHIFT 3 /* AIF1TX_LRCLK_MODE */
1807#define WM8915_AIF1TX_LRCLK_MODE_WIDTH 1 /* AIF1TX_LRCLK_MODE */
1808#define WM8915_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */
1809#define WM8915_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */
1810#define WM8915_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */
1811#define WM8915_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */
1812#define WM8915_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */
1813#define WM8915_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */
1814#define WM8915_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */
1815#define WM8915_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */
1816#define WM8915_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */
1817#define WM8915_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */
1818#define WM8915_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */
1819#define WM8915_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */
1820
1821/*
1822 * R772 (0x304) - AIF1 RX LRCLK(1)
1823 */
1824#define WM8915_AIF1RX_RATE_MASK 0x07FF /* AIF1RX_RATE - [10:0] */
1825#define WM8915_AIF1RX_RATE_SHIFT 0 /* AIF1RX_RATE - [10:0] */
1826#define WM8915_AIF1RX_RATE_WIDTH 11 /* AIF1RX_RATE - [10:0] */
1827
1828/*
1829 * R773 (0x305) - AIF1 RX LRCLK(2)
1830 */
1831#define WM8915_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */
1832#define WM8915_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */
1833#define WM8915_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */
1834#define WM8915_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */
1835#define WM8915_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */
1836#define WM8915_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */
1837#define WM8915_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */
1838#define WM8915_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */
1839#define WM8915_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */
1840#define WM8915_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */
1841#define WM8915_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */
1842#define WM8915_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */
1843
1844/*
1845 * R774 (0x306) - AIF1TX Data Configuration (1)
1846 */
1847#define WM8915_AIF1TX_WL_MASK 0xFF00 /* AIF1TX_WL - [15:8] */
1848#define WM8915_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [15:8] */
1849#define WM8915_AIF1TX_WL_WIDTH 8 /* AIF1TX_WL - [15:8] */
1850#define WM8915_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */
1851#define WM8915_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */
1852#define WM8915_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */
1853
1854/*
1855 * R775 (0x307) - AIF1TX Data Configuration (2)
1856 */
1857#define WM8915_AIF1TX_DAT_TRI 0x0001 /* AIF1TX_DAT_TRI */
1858#define WM8915_AIF1TX_DAT_TRI_MASK 0x0001 /* AIF1TX_DAT_TRI */
1859#define WM8915_AIF1TX_DAT_TRI_SHIFT 0 /* AIF1TX_DAT_TRI */
1860#define WM8915_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */
1861
1862/*
1863 * R776 (0x308) - AIF1RX Data Configuration
1864 */
1865#define WM8915_AIF1RX_WL_MASK 0xFF00 /* AIF1RX_WL - [15:8] */
1866#define WM8915_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [15:8] */
1867#define WM8915_AIF1RX_WL_WIDTH 8 /* AIF1RX_WL - [15:8] */
1868#define WM8915_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */
1869#define WM8915_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */
1870#define WM8915_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */
1871
1872/*
1873 * R777 (0x309) - AIF1TX Channel 0 Configuration
1874 */
1875#define WM8915_AIF1TX_CHAN0_DAT_INV 0x8000 /* AIF1TX_CHAN0_DAT_INV */
1876#define WM8915_AIF1TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN0_DAT_INV */
1877#define WM8915_AIF1TX_CHAN0_DAT_INV_SHIFT 15 /* AIF1TX_CHAN0_DAT_INV */
1878#define WM8915_AIF1TX_CHAN0_DAT_INV_WIDTH 1 /* AIF1TX_CHAN0_DAT_INV */
1879#define WM8915_AIF1TX_CHAN0_SPACING_MASK 0x7E00 /* AIF1TX_CHAN0_SPACING - [14:9] */
1880#define WM8915_AIF1TX_CHAN0_SPACING_SHIFT 9 /* AIF1TX_CHAN0_SPACING - [14:9] */
1881#define WM8915_AIF1TX_CHAN0_SPACING_WIDTH 6 /* AIF1TX_CHAN0_SPACING - [14:9] */
1882#define WM8915_AIF1TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN0_SLOTS - [8:6] */
1883#define WM8915_AIF1TX_CHAN0_SLOTS_SHIFT 6 /* AIF1TX_CHAN0_SLOTS - [8:6] */
1884#define WM8915_AIF1TX_CHAN0_SLOTS_WIDTH 3 /* AIF1TX_CHAN0_SLOTS - [8:6] */
1885#define WM8915_AIF1TX_CHAN0_START_SLOT_MASK 0x003F /* AIF1TX_CHAN0_START_SLOT - [5:0] */
1886#define WM8915_AIF1TX_CHAN0_START_SLOT_SHIFT 0 /* AIF1TX_CHAN0_START_SLOT - [5:0] */
1887#define WM8915_AIF1TX_CHAN0_START_SLOT_WIDTH 6 /* AIF1TX_CHAN0_START_SLOT - [5:0] */
1888
1889/*
1890 * R778 (0x30A) - AIF1TX Channel 1 Configuration
1891 */
1892#define WM8915_AIF1TX_CHAN1_DAT_INV 0x8000 /* AIF1TX_CHAN1_DAT_INV */
1893#define WM8915_AIF1TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN1_DAT_INV */
1894#define WM8915_AIF1TX_CHAN1_DAT_INV_SHIFT 15 /* AIF1TX_CHAN1_DAT_INV */
1895#define WM8915_AIF1TX_CHAN1_DAT_INV_WIDTH 1 /* AIF1TX_CHAN1_DAT_INV */
1896#define WM8915_AIF1TX_CHAN1_SPACING_MASK 0x7E00 /* AIF1TX_CHAN1_SPACING - [14:9] */
1897#define WM8915_AIF1TX_CHAN1_SPACING_SHIFT 9 /* AIF1TX_CHAN1_SPACING - [14:9] */
1898#define WM8915_AIF1TX_CHAN1_SPACING_WIDTH 6 /* AIF1TX_CHAN1_SPACING - [14:9] */
1899#define WM8915_AIF1TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN1_SLOTS - [8:6] */
1900#define WM8915_AIF1TX_CHAN1_SLOTS_SHIFT 6 /* AIF1TX_CHAN1_SLOTS - [8:6] */
1901#define WM8915_AIF1TX_CHAN1_SLOTS_WIDTH 3 /* AIF1TX_CHAN1_SLOTS - [8:6] */
1902#define WM8915_AIF1TX_CHAN1_START_SLOT_MASK 0x003F /* AIF1TX_CHAN1_START_SLOT - [5:0] */
1903#define WM8915_AIF1TX_CHAN1_START_SLOT_SHIFT 0 /* AIF1TX_CHAN1_START_SLOT - [5:0] */
1904#define WM8915_AIF1TX_CHAN1_START_SLOT_WIDTH 6 /* AIF1TX_CHAN1_START_SLOT - [5:0] */
1905
1906/*
1907 * R779 (0x30B) - AIF1TX Channel 2 Configuration
1908 */
1909#define WM8915_AIF1TX_CHAN2_DAT_INV 0x8000 /* AIF1TX_CHAN2_DAT_INV */
1910#define WM8915_AIF1TX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN2_DAT_INV */
1911#define WM8915_AIF1TX_CHAN2_DAT_INV_SHIFT 15 /* AIF1TX_CHAN2_DAT_INV */
1912#define WM8915_AIF1TX_CHAN2_DAT_INV_WIDTH 1 /* AIF1TX_CHAN2_DAT_INV */
1913#define WM8915_AIF1TX_CHAN2_SPACING_MASK 0x7E00 /* AIF1TX_CHAN2_SPACING - [14:9] */
1914#define WM8915_AIF1TX_CHAN2_SPACING_SHIFT 9 /* AIF1TX_CHAN2_SPACING - [14:9] */
1915#define WM8915_AIF1TX_CHAN2_SPACING_WIDTH 6 /* AIF1TX_CHAN2_SPACING - [14:9] */
1916#define WM8915_AIF1TX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN2_SLOTS - [8:6] */
1917#define WM8915_AIF1TX_CHAN2_SLOTS_SHIFT 6 /* AIF1TX_CHAN2_SLOTS - [8:6] */
1918#define WM8915_AIF1TX_CHAN2_SLOTS_WIDTH 3 /* AIF1TX_CHAN2_SLOTS - [8:6] */
1919#define WM8915_AIF1TX_CHAN2_START_SLOT_MASK 0x003F /* AIF1TX_CHAN2_START_SLOT - [5:0] */
1920#define WM8915_AIF1TX_CHAN2_START_SLOT_SHIFT 0 /* AIF1TX_CHAN2_START_SLOT - [5:0] */
1921#define WM8915_AIF1TX_CHAN2_START_SLOT_WIDTH 6 /* AIF1TX_CHAN2_START_SLOT - [5:0] */
1922
1923/*
1924 * R780 (0x30C) - AIF1TX Channel 3 Configuration
1925 */
1926#define WM8915_AIF1TX_CHAN3_DAT_INV 0x8000 /* AIF1TX_CHAN3_DAT_INV */
1927#define WM8915_AIF1TX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN3_DAT_INV */
1928#define WM8915_AIF1TX_CHAN3_DAT_INV_SHIFT 15 /* AIF1TX_CHAN3_DAT_INV */
1929#define WM8915_AIF1TX_CHAN3_DAT_INV_WIDTH 1 /* AIF1TX_CHAN3_DAT_INV */
1930#define WM8915_AIF1TX_CHAN3_SPACING_MASK 0x7E00 /* AIF1TX_CHAN3_SPACING - [14:9] */
1931#define WM8915_AIF1TX_CHAN3_SPACING_SHIFT 9 /* AIF1TX_CHAN3_SPACING - [14:9] */
1932#define WM8915_AIF1TX_CHAN3_SPACING_WIDTH 6 /* AIF1TX_CHAN3_SPACING - [14:9] */
1933#define WM8915_AIF1TX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN3_SLOTS - [8:6] */
1934#define WM8915_AIF1TX_CHAN3_SLOTS_SHIFT 6 /* AIF1TX_CHAN3_SLOTS - [8:6] */
1935#define WM8915_AIF1TX_CHAN3_SLOTS_WIDTH 3 /* AIF1TX_CHAN3_SLOTS - [8:6] */
1936#define WM8915_AIF1TX_CHAN3_START_SLOT_MASK 0x003F /* AIF1TX_CHAN3_START_SLOT - [5:0] */
1937#define WM8915_AIF1TX_CHAN3_START_SLOT_SHIFT 0 /* AIF1TX_CHAN3_START_SLOT - [5:0] */
1938#define WM8915_AIF1TX_CHAN3_START_SLOT_WIDTH 6 /* AIF1TX_CHAN3_START_SLOT - [5:0] */
1939
1940/*
1941 * R781 (0x30D) - AIF1TX Channel 4 Configuration
1942 */
1943#define WM8915_AIF1TX_CHAN4_DAT_INV 0x8000 /* AIF1TX_CHAN4_DAT_INV */
1944#define WM8915_AIF1TX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN4_DAT_INV */
1945#define WM8915_AIF1TX_CHAN4_DAT_INV_SHIFT 15 /* AIF1TX_CHAN4_DAT_INV */
1946#define WM8915_AIF1TX_CHAN4_DAT_INV_WIDTH 1 /* AIF1TX_CHAN4_DAT_INV */
1947#define WM8915_AIF1TX_CHAN4_SPACING_MASK 0x7E00 /* AIF1TX_CHAN4_SPACING - [14:9] */
1948#define WM8915_AIF1TX_CHAN4_SPACING_SHIFT 9 /* AIF1TX_CHAN4_SPACING - [14:9] */
1949#define WM8915_AIF1TX_CHAN4_SPACING_WIDTH 6 /* AIF1TX_CHAN4_SPACING - [14:9] */
1950#define WM8915_AIF1TX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN4_SLOTS - [8:6] */
1951#define WM8915_AIF1TX_CHAN4_SLOTS_SHIFT 6 /* AIF1TX_CHAN4_SLOTS - [8:6] */
1952#define WM8915_AIF1TX_CHAN4_SLOTS_WIDTH 3 /* AIF1TX_CHAN4_SLOTS - [8:6] */
1953#define WM8915_AIF1TX_CHAN4_START_SLOT_MASK 0x003F /* AIF1TX_CHAN4_START_SLOT - [5:0] */
1954#define WM8915_AIF1TX_CHAN4_START_SLOT_SHIFT 0 /* AIF1TX_CHAN4_START_SLOT - [5:0] */
1955#define WM8915_AIF1TX_CHAN4_START_SLOT_WIDTH 6 /* AIF1TX_CHAN4_START_SLOT - [5:0] */
1956
1957/*
1958 * R782 (0x30E) - AIF1TX Channel 5 Configuration
1959 */
1960#define WM8915_AIF1TX_CHAN5_DAT_INV 0x8000 /* AIF1TX_CHAN5_DAT_INV */
1961#define WM8915_AIF1TX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN5_DAT_INV */
1962#define WM8915_AIF1TX_CHAN5_DAT_INV_SHIFT 15 /* AIF1TX_CHAN5_DAT_INV */
1963#define WM8915_AIF1TX_CHAN5_DAT_INV_WIDTH 1 /* AIF1TX_CHAN5_DAT_INV */
1964#define WM8915_AIF1TX_CHAN5_SPACING_MASK 0x7E00 /* AIF1TX_CHAN5_SPACING - [14:9] */
1965#define WM8915_AIF1TX_CHAN5_SPACING_SHIFT 9 /* AIF1TX_CHAN5_SPACING - [14:9] */
1966#define WM8915_AIF1TX_CHAN5_SPACING_WIDTH 6 /* AIF1TX_CHAN5_SPACING - [14:9] */
1967#define WM8915_AIF1TX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN5_SLOTS - [8:6] */
1968#define WM8915_AIF1TX_CHAN5_SLOTS_SHIFT 6 /* AIF1TX_CHAN5_SLOTS - [8:6] */
1969#define WM8915_AIF1TX_CHAN5_SLOTS_WIDTH 3 /* AIF1TX_CHAN5_SLOTS - [8:6] */
1970#define WM8915_AIF1TX_CHAN5_START_SLOT_MASK 0x003F /* AIF1TX_CHAN5_START_SLOT - [5:0] */
1971#define WM8915_AIF1TX_CHAN5_START_SLOT_SHIFT 0 /* AIF1TX_CHAN5_START_SLOT - [5:0] */
1972#define WM8915_AIF1TX_CHAN5_START_SLOT_WIDTH 6 /* AIF1TX_CHAN5_START_SLOT - [5:0] */
1973
1974/*
1975 * R783 (0x30F) - AIF1RX Channel 0 Configuration
1976 */
1977#define WM8915_AIF1RX_CHAN0_DAT_INV 0x8000 /* AIF1RX_CHAN0_DAT_INV */
1978#define WM8915_AIF1RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN0_DAT_INV */
1979#define WM8915_AIF1RX_CHAN0_DAT_INV_SHIFT 15 /* AIF1RX_CHAN0_DAT_INV */
1980#define WM8915_AIF1RX_CHAN0_DAT_INV_WIDTH 1 /* AIF1RX_CHAN0_DAT_INV */
1981#define WM8915_AIF1RX_CHAN0_SPACING_MASK 0x7E00 /* AIF1RX_CHAN0_SPACING - [14:9] */
1982#define WM8915_AIF1RX_CHAN0_SPACING_SHIFT 9 /* AIF1RX_CHAN0_SPACING - [14:9] */
1983#define WM8915_AIF1RX_CHAN0_SPACING_WIDTH 6 /* AIF1RX_CHAN0_SPACING - [14:9] */
1984#define WM8915_AIF1RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN0_SLOTS - [8:6] */
1985#define WM8915_AIF1RX_CHAN0_SLOTS_SHIFT 6 /* AIF1RX_CHAN0_SLOTS - [8:6] */
1986#define WM8915_AIF1RX_CHAN0_SLOTS_WIDTH 3 /* AIF1RX_CHAN0_SLOTS - [8:6] */
1987#define WM8915_AIF1RX_CHAN0_START_SLOT_MASK 0x003F /* AIF1RX_CHAN0_START_SLOT - [5:0] */
1988#define WM8915_AIF1RX_CHAN0_START_SLOT_SHIFT 0 /* AIF1RX_CHAN0_START_SLOT - [5:0] */
1989#define WM8915_AIF1RX_CHAN0_START_SLOT_WIDTH 6 /* AIF1RX_CHAN0_START_SLOT - [5:0] */
1990
1991/*
1992 * R784 (0x310) - AIF1RX Channel 1 Configuration
1993 */
1994#define WM8915_AIF1RX_CHAN1_DAT_INV 0x8000 /* AIF1RX_CHAN1_DAT_INV */
1995#define WM8915_AIF1RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN1_DAT_INV */
1996#define WM8915_AIF1RX_CHAN1_DAT_INV_SHIFT 15 /* AIF1RX_CHAN1_DAT_INV */
1997#define WM8915_AIF1RX_CHAN1_DAT_INV_WIDTH 1 /* AIF1RX_CHAN1_DAT_INV */
1998#define WM8915_AIF1RX_CHAN1_SPACING_MASK 0x7E00 /* AIF1RX_CHAN1_SPACING - [14:9] */
1999#define WM8915_AIF1RX_CHAN1_SPACING_SHIFT 9 /* AIF1RX_CHAN1_SPACING - [14:9] */
2000#define WM8915_AIF1RX_CHAN1_SPACING_WIDTH 6 /* AIF1RX_CHAN1_SPACING - [14:9] */
2001#define WM8915_AIF1RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN1_SLOTS - [8:6] */
2002#define WM8915_AIF1RX_CHAN1_SLOTS_SHIFT 6 /* AIF1RX_CHAN1_SLOTS - [8:6] */
2003#define WM8915_AIF1RX_CHAN1_SLOTS_WIDTH 3 /* AIF1RX_CHAN1_SLOTS - [8:6] */
2004#define WM8915_AIF1RX_CHAN1_START_SLOT_MASK 0x003F /* AIF1RX_CHAN1_START_SLOT - [5:0] */
2005#define WM8915_AIF1RX_CHAN1_START_SLOT_SHIFT 0 /* AIF1RX_CHAN1_START_SLOT - [5:0] */
2006#define WM8915_AIF1RX_CHAN1_START_SLOT_WIDTH 6 /* AIF1RX_CHAN1_START_SLOT - [5:0] */
2007
2008/*
2009 * R785 (0x311) - AIF1RX Channel 2 Configuration
2010 */
2011#define WM8915_AIF1RX_CHAN2_DAT_INV 0x8000 /* AIF1RX_CHAN2_DAT_INV */
2012#define WM8915_AIF1RX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN2_DAT_INV */
2013#define WM8915_AIF1RX_CHAN2_DAT_INV_SHIFT 15 /* AIF1RX_CHAN2_DAT_INV */
2014#define WM8915_AIF1RX_CHAN2_DAT_INV_WIDTH 1 /* AIF1RX_CHAN2_DAT_INV */
2015#define WM8915_AIF1RX_CHAN2_SPACING_MASK 0x7E00 /* AIF1RX_CHAN2_SPACING - [14:9] */
2016#define WM8915_AIF1RX_CHAN2_SPACING_SHIFT 9 /* AIF1RX_CHAN2_SPACING - [14:9] */
2017#define WM8915_AIF1RX_CHAN2_SPACING_WIDTH 6 /* AIF1RX_CHAN2_SPACING - [14:9] */
2018#define WM8915_AIF1RX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN2_SLOTS - [8:6] */
2019#define WM8915_AIF1RX_CHAN2_SLOTS_SHIFT 6 /* AIF1RX_CHAN2_SLOTS - [8:6] */
2020#define WM8915_AIF1RX_CHAN2_SLOTS_WIDTH 3 /* AIF1RX_CHAN2_SLOTS - [8:6] */
2021#define WM8915_AIF1RX_CHAN2_START_SLOT_MASK 0x003F /* AIF1RX_CHAN2_START_SLOT - [5:0] */
2022#define WM8915_AIF1RX_CHAN2_START_SLOT_SHIFT 0 /* AIF1RX_CHAN2_START_SLOT - [5:0] */
2023#define WM8915_AIF1RX_CHAN2_START_SLOT_WIDTH 6 /* AIF1RX_CHAN2_START_SLOT - [5:0] */
2024
2025/*
2026 * R786 (0x312) - AIF1RX Channel 3 Configuration
2027 */
2028#define WM8915_AIF1RX_CHAN3_DAT_INV 0x8000 /* AIF1RX_CHAN3_DAT_INV */
2029#define WM8915_AIF1RX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN3_DAT_INV */
2030#define WM8915_AIF1RX_CHAN3_DAT_INV_SHIFT 15 /* AIF1RX_CHAN3_DAT_INV */
2031#define WM8915_AIF1RX_CHAN3_DAT_INV_WIDTH 1 /* AIF1RX_CHAN3_DAT_INV */
2032#define WM8915_AIF1RX_CHAN3_SPACING_MASK 0x7E00 /* AIF1RX_CHAN3_SPACING - [14:9] */
2033#define WM8915_AIF1RX_CHAN3_SPACING_SHIFT 9 /* AIF1RX_CHAN3_SPACING - [14:9] */
2034#define WM8915_AIF1RX_CHAN3_SPACING_WIDTH 6 /* AIF1RX_CHAN3_SPACING - [14:9] */
2035#define WM8915_AIF1RX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN3_SLOTS - [8:6] */
2036#define WM8915_AIF1RX_CHAN3_SLOTS_SHIFT 6 /* AIF1RX_CHAN3_SLOTS - [8:6] */
2037#define WM8915_AIF1RX_CHAN3_SLOTS_WIDTH 3 /* AIF1RX_CHAN3_SLOTS - [8:6] */
2038#define WM8915_AIF1RX_CHAN3_START_SLOT_MASK 0x003F /* AIF1RX_CHAN3_START_SLOT - [5:0] */
2039#define WM8915_AIF1RX_CHAN3_START_SLOT_SHIFT 0 /* AIF1RX_CHAN3_START_SLOT - [5:0] */
2040#define WM8915_AIF1RX_CHAN3_START_SLOT_WIDTH 6 /* AIF1RX_CHAN3_START_SLOT - [5:0] */
2041
2042/*
2043 * R787 (0x313) - AIF1RX Channel 4 Configuration
2044 */
2045#define WM8915_AIF1RX_CHAN4_DAT_INV 0x8000 /* AIF1RX_CHAN4_DAT_INV */
2046#define WM8915_AIF1RX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN4_DAT_INV */
2047#define WM8915_AIF1RX_CHAN4_DAT_INV_SHIFT 15 /* AIF1RX_CHAN4_DAT_INV */
2048#define WM8915_AIF1RX_CHAN4_DAT_INV_WIDTH 1 /* AIF1RX_CHAN4_DAT_INV */
2049#define WM8915_AIF1RX_CHAN4_SPACING_MASK 0x7E00 /* AIF1RX_CHAN4_SPACING - [14:9] */
2050#define WM8915_AIF1RX_CHAN4_SPACING_SHIFT 9 /* AIF1RX_CHAN4_SPACING - [14:9] */
2051#define WM8915_AIF1RX_CHAN4_SPACING_WIDTH 6 /* AIF1RX_CHAN4_SPACING - [14:9] */
2052#define WM8915_AIF1RX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN4_SLOTS - [8:6] */
2053#define WM8915_AIF1RX_CHAN4_SLOTS_SHIFT 6 /* AIF1RX_CHAN4_SLOTS - [8:6] */
2054#define WM8915_AIF1RX_CHAN4_SLOTS_WIDTH 3 /* AIF1RX_CHAN4_SLOTS - [8:6] */
2055#define WM8915_AIF1RX_CHAN4_START_SLOT_MASK 0x003F /* AIF1RX_CHAN4_START_SLOT - [5:0] */
2056#define WM8915_AIF1RX_CHAN4_START_SLOT_SHIFT 0 /* AIF1RX_CHAN4_START_SLOT - [5:0] */
2057#define WM8915_AIF1RX_CHAN4_START_SLOT_WIDTH 6 /* AIF1RX_CHAN4_START_SLOT - [5:0] */
2058
2059/*
2060 * R788 (0x314) - AIF1RX Channel 5 Configuration
2061 */
2062#define WM8915_AIF1RX_CHAN5_DAT_INV 0x8000 /* AIF1RX_CHAN5_DAT_INV */
2063#define WM8915_AIF1RX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN5_DAT_INV */
2064#define WM8915_AIF1RX_CHAN5_DAT_INV_SHIFT 15 /* AIF1RX_CHAN5_DAT_INV */
2065#define WM8915_AIF1RX_CHAN5_DAT_INV_WIDTH 1 /* AIF1RX_CHAN5_DAT_INV */
2066#define WM8915_AIF1RX_CHAN5_SPACING_MASK 0x7E00 /* AIF1RX_CHAN5_SPACING - [14:9] */
2067#define WM8915_AIF1RX_CHAN5_SPACING_SHIFT 9 /* AIF1RX_CHAN5_SPACING - [14:9] */
2068#define WM8915_AIF1RX_CHAN5_SPACING_WIDTH 6 /* AIF1RX_CHAN5_SPACING - [14:9] */
2069#define WM8915_AIF1RX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN5_SLOTS - [8:6] */
2070#define WM8915_AIF1RX_CHAN5_SLOTS_SHIFT 6 /* AIF1RX_CHAN5_SLOTS - [8:6] */
2071#define WM8915_AIF1RX_CHAN5_SLOTS_WIDTH 3 /* AIF1RX_CHAN5_SLOTS - [8:6] */
2072#define WM8915_AIF1RX_CHAN5_START_SLOT_MASK 0x003F /* AIF1RX_CHAN5_START_SLOT - [5:0] */
2073#define WM8915_AIF1RX_CHAN5_START_SLOT_SHIFT 0 /* AIF1RX_CHAN5_START_SLOT - [5:0] */
2074#define WM8915_AIF1RX_CHAN5_START_SLOT_WIDTH 6 /* AIF1RX_CHAN5_START_SLOT - [5:0] */
2075
2076/*
2077 * R789 (0x315) - AIF1RX Mono Configuration
2078 */
2079#define WM8915_AIF1RX_CHAN4_MONO_MODE 0x0004 /* AIF1RX_CHAN4_MONO_MODE */
2080#define WM8915_AIF1RX_CHAN4_MONO_MODE_MASK 0x0004 /* AIF1RX_CHAN4_MONO_MODE */
2081#define WM8915_AIF1RX_CHAN4_MONO_MODE_SHIFT 2 /* AIF1RX_CHAN4_MONO_MODE */
2082#define WM8915_AIF1RX_CHAN4_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN4_MONO_MODE */
2083#define WM8915_AIF1RX_CHAN2_MONO_MODE 0x0002 /* AIF1RX_CHAN2_MONO_MODE */
2084#define WM8915_AIF1RX_CHAN2_MONO_MODE_MASK 0x0002 /* AIF1RX_CHAN2_MONO_MODE */
2085#define WM8915_AIF1RX_CHAN2_MONO_MODE_SHIFT 1 /* AIF1RX_CHAN2_MONO_MODE */
2086#define WM8915_AIF1RX_CHAN2_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN2_MONO_MODE */
2087#define WM8915_AIF1RX_CHAN0_MONO_MODE 0x0001 /* AIF1RX_CHAN0_MONO_MODE */
2088#define WM8915_AIF1RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF1RX_CHAN0_MONO_MODE */
2089#define WM8915_AIF1RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF1RX_CHAN0_MONO_MODE */
2090#define WM8915_AIF1RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN0_MONO_MODE */
2091
2092/*
2093 * R794 (0x31A) - AIF1TX Test
2094 */
2095#define WM8915_AIF1TX45_DITHER_ENA 0x0004 /* AIF1TX45_DITHER_ENA */
2096#define WM8915_AIF1TX45_DITHER_ENA_MASK 0x0004 /* AIF1TX45_DITHER_ENA */
2097#define WM8915_AIF1TX45_DITHER_ENA_SHIFT 2 /* AIF1TX45_DITHER_ENA */
2098#define WM8915_AIF1TX45_DITHER_ENA_WIDTH 1 /* AIF1TX45_DITHER_ENA */
2099#define WM8915_AIF1TX23_DITHER_ENA 0x0002 /* AIF1TX23_DITHER_ENA */
2100#define WM8915_AIF1TX23_DITHER_ENA_MASK 0x0002 /* AIF1TX23_DITHER_ENA */
2101#define WM8915_AIF1TX23_DITHER_ENA_SHIFT 1 /* AIF1TX23_DITHER_ENA */
2102#define WM8915_AIF1TX23_DITHER_ENA_WIDTH 1 /* AIF1TX23_DITHER_ENA */
2103#define WM8915_AIF1TX01_DITHER_ENA 0x0001 /* AIF1TX01_DITHER_ENA */
2104#define WM8915_AIF1TX01_DITHER_ENA_MASK 0x0001 /* AIF1TX01_DITHER_ENA */
2105#define WM8915_AIF1TX01_DITHER_ENA_SHIFT 0 /* AIF1TX01_DITHER_ENA */
2106#define WM8915_AIF1TX01_DITHER_ENA_WIDTH 1 /* AIF1TX01_DITHER_ENA */
2107
2108/*
2109 * R800 (0x320) - AIF2 Control
2110 */
2111#define WM8915_AIF2_TRI 0x0004 /* AIF2_TRI */
2112#define WM8915_AIF2_TRI_MASK 0x0004 /* AIF2_TRI */
2113#define WM8915_AIF2_TRI_SHIFT 2 /* AIF2_TRI */
2114#define WM8915_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
2115#define WM8915_AIF2_FMT_MASK 0x0003 /* AIF2_FMT - [1:0] */
2116#define WM8915_AIF2_FMT_SHIFT 0 /* AIF2_FMT - [1:0] */
2117#define WM8915_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [1:0] */
2118
2119/*
2120 * R801 (0x321) - AIF2 BCLK
2121 */
2122#define WM8915_AIF2_BCLK_INV 0x0400 /* AIF2_BCLK_INV */
2123#define WM8915_AIF2_BCLK_INV_MASK 0x0400 /* AIF2_BCLK_INV */
2124#define WM8915_AIF2_BCLK_INV_SHIFT 10 /* AIF2_BCLK_INV */
2125#define WM8915_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
2126#define WM8915_AIF2_BCLK_FRC 0x0200 /* AIF2_BCLK_FRC */
2127#define WM8915_AIF2_BCLK_FRC_MASK 0x0200 /* AIF2_BCLK_FRC */
2128#define WM8915_AIF2_BCLK_FRC_SHIFT 9 /* AIF2_BCLK_FRC */
2129#define WM8915_AIF2_BCLK_FRC_WIDTH 1 /* AIF2_BCLK_FRC */
2130#define WM8915_AIF2_BCLK_MSTR 0x0100 /* AIF2_BCLK_MSTR */
2131#define WM8915_AIF2_BCLK_MSTR_MASK 0x0100 /* AIF2_BCLK_MSTR */
2132#define WM8915_AIF2_BCLK_MSTR_SHIFT 8 /* AIF2_BCLK_MSTR */
2133#define WM8915_AIF2_BCLK_MSTR_WIDTH 1 /* AIF2_BCLK_MSTR */
2134#define WM8915_AIF2_BCLK_DIV_MASK 0x000F /* AIF2_BCLK_DIV - [3:0] */
2135#define WM8915_AIF2_BCLK_DIV_SHIFT 0 /* AIF2_BCLK_DIV - [3:0] */
2136#define WM8915_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [3:0] */
2137
2138/*
2139 * R802 (0x322) - AIF2 TX LRCLK(1)
2140 */
2141#define WM8915_AIF2TX_RATE_MASK 0x07FF /* AIF2TX_RATE - [10:0] */
2142#define WM8915_AIF2TX_RATE_SHIFT 0 /* AIF2TX_RATE - [10:0] */
2143#define WM8915_AIF2TX_RATE_WIDTH 11 /* AIF2TX_RATE - [10:0] */
2144
2145/*
2146 * R803 (0x323) - AIF2 TX LRCLK(2)
2147 */
2148#define WM8915_AIF2TX_LRCLK_MODE 0x0008 /* AIF2TX_LRCLK_MODE */
2149#define WM8915_AIF2TX_LRCLK_MODE_MASK 0x0008 /* AIF2TX_LRCLK_MODE */
2150#define WM8915_AIF2TX_LRCLK_MODE_SHIFT 3 /* AIF2TX_LRCLK_MODE */
2151#define WM8915_AIF2TX_LRCLK_MODE_WIDTH 1 /* AIF2TX_LRCLK_MODE */
2152#define WM8915_AIF2TX_LRCLK_INV 0x0004 /* AIF2TX_LRCLK_INV */
2153#define WM8915_AIF2TX_LRCLK_INV_MASK 0x0004 /* AIF2TX_LRCLK_INV */
2154#define WM8915_AIF2TX_LRCLK_INV_SHIFT 2 /* AIF2TX_LRCLK_INV */
2155#define WM8915_AIF2TX_LRCLK_INV_WIDTH 1 /* AIF2TX_LRCLK_INV */
2156#define WM8915_AIF2TX_LRCLK_FRC 0x0002 /* AIF2TX_LRCLK_FRC */
2157#define WM8915_AIF2TX_LRCLK_FRC_MASK 0x0002 /* AIF2TX_LRCLK_FRC */
2158#define WM8915_AIF2TX_LRCLK_FRC_SHIFT 1 /* AIF2TX_LRCLK_FRC */
2159#define WM8915_AIF2TX_LRCLK_FRC_WIDTH 1 /* AIF2TX_LRCLK_FRC */
2160#define WM8915_AIF2TX_LRCLK_MSTR 0x0001 /* AIF2TX_LRCLK_MSTR */
2161#define WM8915_AIF2TX_LRCLK_MSTR_MASK 0x0001 /* AIF2TX_LRCLK_MSTR */
2162#define WM8915_AIF2TX_LRCLK_MSTR_SHIFT 0 /* AIF2TX_LRCLK_MSTR */
2163#define WM8915_AIF2TX_LRCLK_MSTR_WIDTH 1 /* AIF2TX_LRCLK_MSTR */
2164
2165/*
2166 * R804 (0x324) - AIF2 RX LRCLK(1)
2167 */
2168#define WM8915_AIF2RX_RATE_MASK 0x07FF /* AIF2RX_RATE - [10:0] */
2169#define WM8915_AIF2RX_RATE_SHIFT 0 /* AIF2RX_RATE - [10:0] */
2170#define WM8915_AIF2RX_RATE_WIDTH 11 /* AIF2RX_RATE - [10:0] */
2171
2172/*
2173 * R805 (0x325) - AIF2 RX LRCLK(2)
2174 */
2175#define WM8915_AIF2RX_LRCLK_INV 0x0004 /* AIF2RX_LRCLK_INV */
2176#define WM8915_AIF2RX_LRCLK_INV_MASK 0x0004 /* AIF2RX_LRCLK_INV */
2177#define WM8915_AIF2RX_LRCLK_INV_SHIFT 2 /* AIF2RX_LRCLK_INV */
2178#define WM8915_AIF2RX_LRCLK_INV_WIDTH 1 /* AIF2RX_LRCLK_INV */
2179#define WM8915_AIF2RX_LRCLK_FRC 0x0002 /* AIF2RX_LRCLK_FRC */
2180#define WM8915_AIF2RX_LRCLK_FRC_MASK 0x0002 /* AIF2RX_LRCLK_FRC */
2181#define WM8915_AIF2RX_LRCLK_FRC_SHIFT 1 /* AIF2RX_LRCLK_FRC */
2182#define WM8915_AIF2RX_LRCLK_FRC_WIDTH 1 /* AIF2RX_LRCLK_FRC */
2183#define WM8915_AIF2RX_LRCLK_MSTR 0x0001 /* AIF2RX_LRCLK_MSTR */
2184#define WM8915_AIF2RX_LRCLK_MSTR_MASK 0x0001 /* AIF2RX_LRCLK_MSTR */
2185#define WM8915_AIF2RX_LRCLK_MSTR_SHIFT 0 /* AIF2RX_LRCLK_MSTR */
2186#define WM8915_AIF2RX_LRCLK_MSTR_WIDTH 1 /* AIF2RX_LRCLK_MSTR */
2187
2188/*
2189 * R806 (0x326) - AIF2TX Data Configuration (1)
2190 */
2191#define WM8915_AIF2TX_WL_MASK 0xFF00 /* AIF2TX_WL - [15:8] */
2192#define WM8915_AIF2TX_WL_SHIFT 8 /* AIF2TX_WL - [15:8] */
2193#define WM8915_AIF2TX_WL_WIDTH 8 /* AIF2TX_WL - [15:8] */
2194#define WM8915_AIF2TX_SLOT_LEN_MASK 0x00FF /* AIF2TX_SLOT_LEN - [7:0] */
2195#define WM8915_AIF2TX_SLOT_LEN_SHIFT 0 /* AIF2TX_SLOT_LEN - [7:0] */
2196#define WM8915_AIF2TX_SLOT_LEN_WIDTH 8 /* AIF2TX_SLOT_LEN - [7:0] */
2197
2198/*
2199 * R807 (0x327) - AIF2TX Data Configuration (2)
2200 */
2201#define WM8915_AIF2TX_DAT_TRI 0x0001 /* AIF2TX_DAT_TRI */
2202#define WM8915_AIF2TX_DAT_TRI_MASK 0x0001 /* AIF2TX_DAT_TRI */
2203#define WM8915_AIF2TX_DAT_TRI_SHIFT 0 /* AIF2TX_DAT_TRI */
2204#define WM8915_AIF2TX_DAT_TRI_WIDTH 1 /* AIF2TX_DAT_TRI */
2205
2206/*
2207 * R808 (0x328) - AIF2RX Data Configuration
2208 */
2209#define WM8915_AIF2RX_WL_MASK 0xFF00 /* AIF2RX_WL - [15:8] */
2210#define WM8915_AIF2RX_WL_SHIFT 8 /* AIF2RX_WL - [15:8] */
2211#define WM8915_AIF2RX_WL_WIDTH 8 /* AIF2RX_WL - [15:8] */
2212#define WM8915_AIF2RX_SLOT_LEN_MASK 0x00FF /* AIF2RX_SLOT_LEN - [7:0] */
2213#define WM8915_AIF2RX_SLOT_LEN_SHIFT 0 /* AIF2RX_SLOT_LEN - [7:0] */
2214#define WM8915_AIF2RX_SLOT_LEN_WIDTH 8 /* AIF2RX_SLOT_LEN - [7:0] */
2215
2216/*
2217 * R809 (0x329) - AIF2TX Channel 0 Configuration
2218 */
2219#define WM8915_AIF2TX_CHAN0_DAT_INV 0x8000 /* AIF2TX_CHAN0_DAT_INV */
2220#define WM8915_AIF2TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN0_DAT_INV */
2221#define WM8915_AIF2TX_CHAN0_DAT_INV_SHIFT 15 /* AIF2TX_CHAN0_DAT_INV */
2222#define WM8915_AIF2TX_CHAN0_DAT_INV_WIDTH 1 /* AIF2TX_CHAN0_DAT_INV */
2223#define WM8915_AIF2TX_CHAN0_SPACING_MASK 0x7E00 /* AIF2TX_CHAN0_SPACING - [14:9] */
2224#define WM8915_AIF2TX_CHAN0_SPACING_SHIFT 9 /* AIF2TX_CHAN0_SPACING - [14:9] */
2225#define WM8915_AIF2TX_CHAN0_SPACING_WIDTH 6 /* AIF2TX_CHAN0_SPACING - [14:9] */
2226#define WM8915_AIF2TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN0_SLOTS - [8:6] */
2227#define WM8915_AIF2TX_CHAN0_SLOTS_SHIFT 6 /* AIF2TX_CHAN0_SLOTS - [8:6] */
2228#define WM8915_AIF2TX_CHAN0_SLOTS_WIDTH 3 /* AIF2TX_CHAN0_SLOTS - [8:6] */
2229#define WM8915_AIF2TX_CHAN0_START_SLOT_MASK 0x003F /* AIF2TX_CHAN0_START_SLOT - [5:0] */
2230#define WM8915_AIF2TX_CHAN0_START_SLOT_SHIFT 0 /* AIF2TX_CHAN0_START_SLOT - [5:0] */
2231#define WM8915_AIF2TX_CHAN0_START_SLOT_WIDTH 6 /* AIF2TX_CHAN0_START_SLOT - [5:0] */
2232
2233/*
2234 * R810 (0x32A) - AIF2TX Channel 1 Configuration
2235 */
2236#define WM8915_AIF2TX_CHAN1_DAT_INV 0x8000 /* AIF2TX_CHAN1_DAT_INV */
2237#define WM8915_AIF2TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN1_DAT_INV */
2238#define WM8915_AIF2TX_CHAN1_DAT_INV_SHIFT 15 /* AIF2TX_CHAN1_DAT_INV */
2239#define WM8915_AIF2TX_CHAN1_DAT_INV_WIDTH 1 /* AIF2TX_CHAN1_DAT_INV */
2240#define WM8915_AIF2TX_CHAN1_SPACING_MASK 0x7E00 /* AIF2TX_CHAN1_SPACING - [14:9] */
2241#define WM8915_AIF2TX_CHAN1_SPACING_SHIFT 9 /* AIF2TX_CHAN1_SPACING - [14:9] */
2242#define WM8915_AIF2TX_CHAN1_SPACING_WIDTH 6 /* AIF2TX_CHAN1_SPACING - [14:9] */
2243#define WM8915_AIF2TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN1_SLOTS - [8:6] */
2244#define WM8915_AIF2TX_CHAN1_SLOTS_SHIFT 6 /* AIF2TX_CHAN1_SLOTS - [8:6] */
2245#define WM8915_AIF2TX_CHAN1_SLOTS_WIDTH 3 /* AIF2TX_CHAN1_SLOTS - [8:6] */
2246#define WM8915_AIF2TX_CHAN1_START_SLOT_MASK 0x003F /* AIF2TX_CHAN1_START_SLOT - [5:0] */
2247#define WM8915_AIF2TX_CHAN1_START_SLOT_SHIFT 0 /* AIF2TX_CHAN1_START_SLOT - [5:0] */
2248#define WM8915_AIF2TX_CHAN1_START_SLOT_WIDTH 6 /* AIF2TX_CHAN1_START_SLOT - [5:0] */
2249
2250/*
2251 * R811 (0x32B) - AIF2RX Channel 0 Configuration
2252 */
2253#define WM8915_AIF2RX_CHAN0_DAT_INV 0x8000 /* AIF2RX_CHAN0_DAT_INV */
2254#define WM8915_AIF2RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN0_DAT_INV */
2255#define WM8915_AIF2RX_CHAN0_DAT_INV_SHIFT 15 /* AIF2RX_CHAN0_DAT_INV */
2256#define WM8915_AIF2RX_CHAN0_DAT_INV_WIDTH 1 /* AIF2RX_CHAN0_DAT_INV */
2257#define WM8915_AIF2RX_CHAN0_SPACING_MASK 0x7E00 /* AIF2RX_CHAN0_SPACING - [14:9] */
2258#define WM8915_AIF2RX_CHAN0_SPACING_SHIFT 9 /* AIF2RX_CHAN0_SPACING - [14:9] */
2259#define WM8915_AIF2RX_CHAN0_SPACING_WIDTH 6 /* AIF2RX_CHAN0_SPACING - [14:9] */
2260#define WM8915_AIF2RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN0_SLOTS - [8:6] */
2261#define WM8915_AIF2RX_CHAN0_SLOTS_SHIFT 6 /* AIF2RX_CHAN0_SLOTS - [8:6] */
2262#define WM8915_AIF2RX_CHAN0_SLOTS_WIDTH 3 /* AIF2RX_CHAN0_SLOTS - [8:6] */
2263#define WM8915_AIF2RX_CHAN0_START_SLOT_MASK 0x003F /* AIF2RX_CHAN0_START_SLOT - [5:0] */
2264#define WM8915_AIF2RX_CHAN0_START_SLOT_SHIFT 0 /* AIF2RX_CHAN0_START_SLOT - [5:0] */
2265#define WM8915_AIF2RX_CHAN0_START_SLOT_WIDTH 6 /* AIF2RX_CHAN0_START_SLOT - [5:0] */
2266
2267/*
2268 * R812 (0x32C) - AIF2RX Channel 1 Configuration
2269 */
2270#define WM8915_AIF2RX_CHAN1_DAT_INV 0x8000 /* AIF2RX_CHAN1_DAT_INV */
2271#define WM8915_AIF2RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN1_DAT_INV */
2272#define WM8915_AIF2RX_CHAN1_DAT_INV_SHIFT 15 /* AIF2RX_CHAN1_DAT_INV */
2273#define WM8915_AIF2RX_CHAN1_DAT_INV_WIDTH 1 /* AIF2RX_CHAN1_DAT_INV */
2274#define WM8915_AIF2RX_CHAN1_SPACING_MASK 0x7E00 /* AIF2RX_CHAN1_SPACING - [14:9] */
2275#define WM8915_AIF2RX_CHAN1_SPACING_SHIFT 9 /* AIF2RX_CHAN1_SPACING - [14:9] */
2276#define WM8915_AIF2RX_CHAN1_SPACING_WIDTH 6 /* AIF2RX_CHAN1_SPACING - [14:9] */
2277#define WM8915_AIF2RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN1_SLOTS - [8:6] */
2278#define WM8915_AIF2RX_CHAN1_SLOTS_SHIFT 6 /* AIF2RX_CHAN1_SLOTS - [8:6] */
2279#define WM8915_AIF2RX_CHAN1_SLOTS_WIDTH 3 /* AIF2RX_CHAN1_SLOTS - [8:6] */
2280#define WM8915_AIF2RX_CHAN1_START_SLOT_MASK 0x003F /* AIF2RX_CHAN1_START_SLOT - [5:0] */
2281#define WM8915_AIF2RX_CHAN1_START_SLOT_SHIFT 0 /* AIF2RX_CHAN1_START_SLOT - [5:0] */
2282#define WM8915_AIF2RX_CHAN1_START_SLOT_WIDTH 6 /* AIF2RX_CHAN1_START_SLOT - [5:0] */
2283
2284/*
2285 * R813 (0x32D) - AIF2RX Mono Configuration
2286 */
2287#define WM8915_AIF2RX_CHAN0_MONO_MODE 0x0001 /* AIF2RX_CHAN0_MONO_MODE */
2288#define WM8915_AIF2RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF2RX_CHAN0_MONO_MODE */
2289#define WM8915_AIF2RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF2RX_CHAN0_MONO_MODE */
2290#define WM8915_AIF2RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF2RX_CHAN0_MONO_MODE */
2291
2292/*
2293 * R815 (0x32F) - AIF2TX Test
2294 */
2295#define WM8915_AIF2TX_DITHER_ENA 0x0001 /* AIF2TX_DITHER_ENA */
2296#define WM8915_AIF2TX_DITHER_ENA_MASK 0x0001 /* AIF2TX_DITHER_ENA */
2297#define WM8915_AIF2TX_DITHER_ENA_SHIFT 0 /* AIF2TX_DITHER_ENA */
2298#define WM8915_AIF2TX_DITHER_ENA_WIDTH 1 /* AIF2TX_DITHER_ENA */
2299
2300/*
2301 * R1024 (0x400) - DSP1 TX Left Volume
2302 */
2303#define WM8915_DSP1TX_VU 0x0100 /* DSP1TX_VU */
2304#define WM8915_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */
2305#define WM8915_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */
2306#define WM8915_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */
2307#define WM8915_DSP1TXL_VOL_MASK 0x00FF /* DSP1TXL_VOL - [7:0] */
2308#define WM8915_DSP1TXL_VOL_SHIFT 0 /* DSP1TXL_VOL - [7:0] */
2309#define WM8915_DSP1TXL_VOL_WIDTH 8 /* DSP1TXL_VOL - [7:0] */
2310
2311/*
2312 * R1025 (0x401) - DSP1 TX Right Volume
2313 */
2314#define WM8915_DSP1TX_VU 0x0100 /* DSP1TX_VU */
2315#define WM8915_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */
2316#define WM8915_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */
2317#define WM8915_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */
2318#define WM8915_DSP1TXR_VOL_MASK 0x00FF /* DSP1TXR_VOL - [7:0] */
2319#define WM8915_DSP1TXR_VOL_SHIFT 0 /* DSP1TXR_VOL - [7:0] */
2320#define WM8915_DSP1TXR_VOL_WIDTH 8 /* DSP1TXR_VOL - [7:0] */
2321
2322/*
2323 * R1026 (0x402) - DSP1 RX Left Volume
2324 */
2325#define WM8915_DSP1RX_VU 0x0100 /* DSP1RX_VU */
2326#define WM8915_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */
2327#define WM8915_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */
2328#define WM8915_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */
2329#define WM8915_DSP1RXL_VOL_MASK 0x00FF /* DSP1RXL_VOL - [7:0] */
2330#define WM8915_DSP1RXL_VOL_SHIFT 0 /* DSP1RXL_VOL - [7:0] */
2331#define WM8915_DSP1RXL_VOL_WIDTH 8 /* DSP1RXL_VOL - [7:0] */
2332
2333/*
2334 * R1027 (0x403) - DSP1 RX Right Volume
2335 */
2336#define WM8915_DSP1RX_VU 0x0100 /* DSP1RX_VU */
2337#define WM8915_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */
2338#define WM8915_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */
2339#define WM8915_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */
2340#define WM8915_DSP1RXR_VOL_MASK 0x00FF /* DSP1RXR_VOL - [7:0] */
2341#define WM8915_DSP1RXR_VOL_SHIFT 0 /* DSP1RXR_VOL - [7:0] */
2342#define WM8915_DSP1RXR_VOL_WIDTH 8 /* DSP1RXR_VOL - [7:0] */
2343
2344/*
2345 * R1040 (0x410) - DSP1 TX Filters
2346 */
2347#define WM8915_DSP1TX_NF 0x2000 /* DSP1TX_NF */
2348#define WM8915_DSP1TX_NF_MASK 0x2000 /* DSP1TX_NF */
2349#define WM8915_DSP1TX_NF_SHIFT 13 /* DSP1TX_NF */
2350#define WM8915_DSP1TX_NF_WIDTH 1 /* DSP1TX_NF */
2351#define WM8915_DSP1TXL_HPF 0x1000 /* DSP1TXL_HPF */
2352#define WM8915_DSP1TXL_HPF_MASK 0x1000 /* DSP1TXL_HPF */
2353#define WM8915_DSP1TXL_HPF_SHIFT 12 /* DSP1TXL_HPF */
2354#define WM8915_DSP1TXL_HPF_WIDTH 1 /* DSP1TXL_HPF */
2355#define WM8915_DSP1TXR_HPF 0x0800 /* DSP1TXR_HPF */
2356#define WM8915_DSP1TXR_HPF_MASK 0x0800 /* DSP1TXR_HPF */
2357#define WM8915_DSP1TXR_HPF_SHIFT 11 /* DSP1TXR_HPF */
2358#define WM8915_DSP1TXR_HPF_WIDTH 1 /* DSP1TXR_HPF */
2359#define WM8915_DSP1TX_HPF_MODE_MASK 0x0018 /* DSP1TX_HPF_MODE - [4:3] */
2360#define WM8915_DSP1TX_HPF_MODE_SHIFT 3 /* DSP1TX_HPF_MODE - [4:3] */
2361#define WM8915_DSP1TX_HPF_MODE_WIDTH 2 /* DSP1TX_HPF_MODE - [4:3] */
2362#define WM8915_DSP1TX_HPF_CUT_MASK 0x0007 /* DSP1TX_HPF_CUT - [2:0] */
2363#define WM8915_DSP1TX_HPF_CUT_SHIFT 0 /* DSP1TX_HPF_CUT - [2:0] */
2364#define WM8915_DSP1TX_HPF_CUT_WIDTH 3 /* DSP1TX_HPF_CUT - [2:0] */
2365
2366/*
2367 * R1056 (0x420) - DSP1 RX Filters (1)
2368 */
2369#define WM8915_DSP1RX_MUTE 0x0200 /* DSP1RX_MUTE */
2370#define WM8915_DSP1RX_MUTE_MASK 0x0200 /* DSP1RX_MUTE */
2371#define WM8915_DSP1RX_MUTE_SHIFT 9 /* DSP1RX_MUTE */
2372#define WM8915_DSP1RX_MUTE_WIDTH 1 /* DSP1RX_MUTE */
2373#define WM8915_DSP1RX_MONO 0x0080 /* DSP1RX_MONO */
2374#define WM8915_DSP1RX_MONO_MASK 0x0080 /* DSP1RX_MONO */
2375#define WM8915_DSP1RX_MONO_SHIFT 7 /* DSP1RX_MONO */
2376#define WM8915_DSP1RX_MONO_WIDTH 1 /* DSP1RX_MONO */
2377#define WM8915_DSP1RX_MUTERATE 0x0020 /* DSP1RX_MUTERATE */
2378#define WM8915_DSP1RX_MUTERATE_MASK 0x0020 /* DSP1RX_MUTERATE */
2379#define WM8915_DSP1RX_MUTERATE_SHIFT 5 /* DSP1RX_MUTERATE */
2380#define WM8915_DSP1RX_MUTERATE_WIDTH 1 /* DSP1RX_MUTERATE */
2381#define WM8915_DSP1RX_UNMUTE_RAMP 0x0010 /* DSP1RX_UNMUTE_RAMP */
2382#define WM8915_DSP1RX_UNMUTE_RAMP_MASK 0x0010 /* DSP1RX_UNMUTE_RAMP */
2383#define WM8915_DSP1RX_UNMUTE_RAMP_SHIFT 4 /* DSP1RX_UNMUTE_RAMP */
2384#define WM8915_DSP1RX_UNMUTE_RAMP_WIDTH 1 /* DSP1RX_UNMUTE_RAMP */
2385
2386/*
2387 * R1057 (0x421) - DSP1 RX Filters (2)
2388 */
2389#define WM8915_DSP1RX_3D_GAIN_MASK 0x3E00 /* DSP1RX_3D_GAIN - [13:9] */
2390#define WM8915_DSP1RX_3D_GAIN_SHIFT 9 /* DSP1RX_3D_GAIN - [13:9] */
2391#define WM8915_DSP1RX_3D_GAIN_WIDTH 5 /* DSP1RX_3D_GAIN - [13:9] */
2392#define WM8915_DSP1RX_3D_ENA 0x0100 /* DSP1RX_3D_ENA */
2393#define WM8915_DSP1RX_3D_ENA_MASK 0x0100 /* DSP1RX_3D_ENA */
2394#define WM8915_DSP1RX_3D_ENA_SHIFT 8 /* DSP1RX_3D_ENA */
2395#define WM8915_DSP1RX_3D_ENA_WIDTH 1 /* DSP1RX_3D_ENA */
2396
2397/*
2398 * R1088 (0x440) - DSP1 DRC (1)
2399 */
2400#define WM8915_DSP1DRC_SIG_DET_RMS_MASK 0xF800 /* DSP1DRC_SIG_DET_RMS - [15:11] */
2401#define WM8915_DSP1DRC_SIG_DET_RMS_SHIFT 11 /* DSP1DRC_SIG_DET_RMS - [15:11] */
2402#define WM8915_DSP1DRC_SIG_DET_RMS_WIDTH 5 /* DSP1DRC_SIG_DET_RMS - [15:11] */
2403#define WM8915_DSP1DRC_SIG_DET_PK_MASK 0x0600 /* DSP1DRC_SIG_DET_PK - [10:9] */
2404#define WM8915_DSP1DRC_SIG_DET_PK_SHIFT 9 /* DSP1DRC_SIG_DET_PK - [10:9] */
2405#define WM8915_DSP1DRC_SIG_DET_PK_WIDTH 2 /* DSP1DRC_SIG_DET_PK - [10:9] */
2406#define WM8915_DSP1DRC_NG_ENA 0x0100 /* DSP1DRC_NG_ENA */
2407#define WM8915_DSP1DRC_NG_ENA_MASK 0x0100 /* DSP1DRC_NG_ENA */
2408#define WM8915_DSP1DRC_NG_ENA_SHIFT 8 /* DSP1DRC_NG_ENA */
2409#define WM8915_DSP1DRC_NG_ENA_WIDTH 1 /* DSP1DRC_NG_ENA */
2410#define WM8915_DSP1DRC_SIG_DET_MODE 0x0080 /* DSP1DRC_SIG_DET_MODE */
2411#define WM8915_DSP1DRC_SIG_DET_MODE_MASK 0x0080 /* DSP1DRC_SIG_DET_MODE */
2412#define WM8915_DSP1DRC_SIG_DET_MODE_SHIFT 7 /* DSP1DRC_SIG_DET_MODE */
2413#define WM8915_DSP1DRC_SIG_DET_MODE_WIDTH 1 /* DSP1DRC_SIG_DET_MODE */
2414#define WM8915_DSP1DRC_SIG_DET 0x0040 /* DSP1DRC_SIG_DET */
2415#define WM8915_DSP1DRC_SIG_DET_MASK 0x0040 /* DSP1DRC_SIG_DET */
2416#define WM8915_DSP1DRC_SIG_DET_SHIFT 6 /* DSP1DRC_SIG_DET */
2417#define WM8915_DSP1DRC_SIG_DET_WIDTH 1 /* DSP1DRC_SIG_DET */
2418#define WM8915_DSP1DRC_KNEE2_OP_ENA 0x0020 /* DSP1DRC_KNEE2_OP_ENA */
2419#define WM8915_DSP1DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP1DRC_KNEE2_OP_ENA */
2420#define WM8915_DSP1DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP1DRC_KNEE2_OP_ENA */
2421#define WM8915_DSP1DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP1DRC_KNEE2_OP_ENA */
2422#define WM8915_DSP1DRC_QR 0x0010 /* DSP1DRC_QR */
2423#define WM8915_DSP1DRC_QR_MASK 0x0010 /* DSP1DRC_QR */
2424#define WM8915_DSP1DRC_QR_SHIFT 4 /* DSP1DRC_QR */
2425#define WM8915_DSP1DRC_QR_WIDTH 1 /* DSP1DRC_QR */
2426#define WM8915_DSP1DRC_ANTICLIP 0x0008 /* DSP1DRC_ANTICLIP */
2427#define WM8915_DSP1DRC_ANTICLIP_MASK 0x0008 /* DSP1DRC_ANTICLIP */
2428#define WM8915_DSP1DRC_ANTICLIP_SHIFT 3 /* DSP1DRC_ANTICLIP */
2429#define WM8915_DSP1DRC_ANTICLIP_WIDTH 1 /* DSP1DRC_ANTICLIP */
2430#define WM8915_DSP1RX_DRC_ENA 0x0004 /* DSP1RX_DRC_ENA */
2431#define WM8915_DSP1RX_DRC_ENA_MASK 0x0004 /* DSP1RX_DRC_ENA */
2432#define WM8915_DSP1RX_DRC_ENA_SHIFT 2 /* DSP1RX_DRC_ENA */
2433#define WM8915_DSP1RX_DRC_ENA_WIDTH 1 /* DSP1RX_DRC_ENA */
2434#define WM8915_DSP1TXL_DRC_ENA 0x0002 /* DSP1TXL_DRC_ENA */
2435#define WM8915_DSP1TXL_DRC_ENA_MASK 0x0002 /* DSP1TXL_DRC_ENA */
2436#define WM8915_DSP1TXL_DRC_ENA_SHIFT 1 /* DSP1TXL_DRC_ENA */
2437#define WM8915_DSP1TXL_DRC_ENA_WIDTH 1 /* DSP1TXL_DRC_ENA */
2438#define WM8915_DSP1TXR_DRC_ENA 0x0001 /* DSP1TXR_DRC_ENA */
2439#define WM8915_DSP1TXR_DRC_ENA_MASK 0x0001 /* DSP1TXR_DRC_ENA */
2440#define WM8915_DSP1TXR_DRC_ENA_SHIFT 0 /* DSP1TXR_DRC_ENA */
2441#define WM8915_DSP1TXR_DRC_ENA_WIDTH 1 /* DSP1TXR_DRC_ENA */
2442
2443/*
2444 * R1089 (0x441) - DSP1 DRC (2)
2445 */
2446#define WM8915_DSP1DRC_ATK_MASK 0x1E00 /* DSP1DRC_ATK - [12:9] */
2447#define WM8915_DSP1DRC_ATK_SHIFT 9 /* DSP1DRC_ATK - [12:9] */
2448#define WM8915_DSP1DRC_ATK_WIDTH 4 /* DSP1DRC_ATK - [12:9] */
2449#define WM8915_DSP1DRC_DCY_MASK 0x01E0 /* DSP1DRC_DCY - [8:5] */
2450#define WM8915_DSP1DRC_DCY_SHIFT 5 /* DSP1DRC_DCY - [8:5] */
2451#define WM8915_DSP1DRC_DCY_WIDTH 4 /* DSP1DRC_DCY - [8:5] */
2452#define WM8915_DSP1DRC_MINGAIN_MASK 0x001C /* DSP1DRC_MINGAIN - [4:2] */
2453#define WM8915_DSP1DRC_MINGAIN_SHIFT 2 /* DSP1DRC_MINGAIN - [4:2] */
2454#define WM8915_DSP1DRC_MINGAIN_WIDTH 3 /* DSP1DRC_MINGAIN - [4:2] */
2455#define WM8915_DSP1DRC_MAXGAIN_MASK 0x0003 /* DSP1DRC_MAXGAIN - [1:0] */
2456#define WM8915_DSP1DRC_MAXGAIN_SHIFT 0 /* DSP1DRC_MAXGAIN - [1:0] */
2457#define WM8915_DSP1DRC_MAXGAIN_WIDTH 2 /* DSP1DRC_MAXGAIN - [1:0] */
2458
2459/*
2460 * R1090 (0x442) - DSP1 DRC (3)
2461 */
2462#define WM8915_DSP1DRC_NG_MINGAIN_MASK 0xF000 /* DSP1DRC_NG_MINGAIN - [15:12] */
2463#define WM8915_DSP1DRC_NG_MINGAIN_SHIFT 12 /* DSP1DRC_NG_MINGAIN - [15:12] */
2464#define WM8915_DSP1DRC_NG_MINGAIN_WIDTH 4 /* DSP1DRC_NG_MINGAIN - [15:12] */
2465#define WM8915_DSP1DRC_NG_EXP_MASK 0x0C00 /* DSP1DRC_NG_EXP - [11:10] */
2466#define WM8915_DSP1DRC_NG_EXP_SHIFT 10 /* DSP1DRC_NG_EXP - [11:10] */
2467#define WM8915_DSP1DRC_NG_EXP_WIDTH 2 /* DSP1DRC_NG_EXP - [11:10] */
2468#define WM8915_DSP1DRC_QR_THR_MASK 0x0300 /* DSP1DRC_QR_THR - [9:8] */
2469#define WM8915_DSP1DRC_QR_THR_SHIFT 8 /* DSP1DRC_QR_THR - [9:8] */
2470#define WM8915_DSP1DRC_QR_THR_WIDTH 2 /* DSP1DRC_QR_THR - [9:8] */
2471#define WM8915_DSP1DRC_QR_DCY_MASK 0x00C0 /* DSP1DRC_QR_DCY - [7:6] */
2472#define WM8915_DSP1DRC_QR_DCY_SHIFT 6 /* DSP1DRC_QR_DCY - [7:6] */
2473#define WM8915_DSP1DRC_QR_DCY_WIDTH 2 /* DSP1DRC_QR_DCY - [7:6] */
2474#define WM8915_DSP1DRC_HI_COMP_MASK 0x0038 /* DSP1DRC_HI_COMP - [5:3] */
2475#define WM8915_DSP1DRC_HI_COMP_SHIFT 3 /* DSP1DRC_HI_COMP - [5:3] */
2476#define WM8915_DSP1DRC_HI_COMP_WIDTH 3 /* DSP1DRC_HI_COMP - [5:3] */
2477#define WM8915_DSP1DRC_LO_COMP_MASK 0x0007 /* DSP1DRC_LO_COMP - [2:0] */
2478#define WM8915_DSP1DRC_LO_COMP_SHIFT 0 /* DSP1DRC_LO_COMP - [2:0] */
2479#define WM8915_DSP1DRC_LO_COMP_WIDTH 3 /* DSP1DRC_LO_COMP - [2:0] */
2480
2481/*
2482 * R1091 (0x443) - DSP1 DRC (4)
2483 */
2484#define WM8915_DSP1DRC_KNEE_IP_MASK 0x07E0 /* DSP1DRC_KNEE_IP - [10:5] */
2485#define WM8915_DSP1DRC_KNEE_IP_SHIFT 5 /* DSP1DRC_KNEE_IP - [10:5] */
2486#define WM8915_DSP1DRC_KNEE_IP_WIDTH 6 /* DSP1DRC_KNEE_IP - [10:5] */
2487#define WM8915_DSP1DRC_KNEE_OP_MASK 0x001F /* DSP1DRC_KNEE_OP - [4:0] */
2488#define WM8915_DSP1DRC_KNEE_OP_SHIFT 0 /* DSP1DRC_KNEE_OP - [4:0] */
2489#define WM8915_DSP1DRC_KNEE_OP_WIDTH 5 /* DSP1DRC_KNEE_OP - [4:0] */
2490
2491/*
2492 * R1092 (0x444) - DSP1 DRC (5)
2493 */
2494#define WM8915_DSP1DRC_KNEE2_IP_MASK 0x03E0 /* DSP1DRC_KNEE2_IP - [9:5] */
2495#define WM8915_DSP1DRC_KNEE2_IP_SHIFT 5 /* DSP1DRC_KNEE2_IP - [9:5] */
2496#define WM8915_DSP1DRC_KNEE2_IP_WIDTH 5 /* DSP1DRC_KNEE2_IP - [9:5] */
2497#define WM8915_DSP1DRC_KNEE2_OP_MASK 0x001F /* DSP1DRC_KNEE2_OP - [4:0] */
2498#define WM8915_DSP1DRC_KNEE2_OP_SHIFT 0 /* DSP1DRC_KNEE2_OP - [4:0] */
2499#define WM8915_DSP1DRC_KNEE2_OP_WIDTH 5 /* DSP1DRC_KNEE2_OP - [4:0] */
2500
2501/*
2502 * R1152 (0x480) - DSP1 RX EQ Gains (1)
2503 */
2504#define WM8915_DSP1RX_EQ_B1_GAIN_MASK 0xF800 /* DSP1RX_EQ_B1_GAIN - [15:11] */
2505#define WM8915_DSP1RX_EQ_B1_GAIN_SHIFT 11 /* DSP1RX_EQ_B1_GAIN - [15:11] */
2506#define WM8915_DSP1RX_EQ_B1_GAIN_WIDTH 5 /* DSP1RX_EQ_B1_GAIN - [15:11] */
2507#define WM8915_DSP1RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B2_GAIN - [10:6] */
2508#define WM8915_DSP1RX_EQ_B2_GAIN_SHIFT 6 /* DSP1RX_EQ_B2_GAIN - [10:6] */
2509#define WM8915_DSP1RX_EQ_B2_GAIN_WIDTH 5 /* DSP1RX_EQ_B2_GAIN - [10:6] */
2510#define WM8915_DSP1RX_EQ_B3_GAIN_MASK 0x003E /* DSP1RX_EQ_B3_GAIN - [5:1] */
2511#define WM8915_DSP1RX_EQ_B3_GAIN_SHIFT 1 /* DSP1RX_EQ_B3_GAIN - [5:1] */
2512#define WM8915_DSP1RX_EQ_B3_GAIN_WIDTH 5 /* DSP1RX_EQ_B3_GAIN - [5:1] */
2513#define WM8915_DSP1RX_EQ_ENA 0x0001 /* DSP1RX_EQ_ENA */
2514#define WM8915_DSP1RX_EQ_ENA_MASK 0x0001 /* DSP1RX_EQ_ENA */
2515#define WM8915_DSP1RX_EQ_ENA_SHIFT 0 /* DSP1RX_EQ_ENA */
2516#define WM8915_DSP1RX_EQ_ENA_WIDTH 1 /* DSP1RX_EQ_ENA */
2517
2518/*
2519 * R1153 (0x481) - DSP1 RX EQ Gains (2)
2520 */
2521#define WM8915_DSP1RX_EQ_B4_GAIN_MASK 0xF800 /* DSP1RX_EQ_B4_GAIN - [15:11] */
2522#define WM8915_DSP1RX_EQ_B4_GAIN_SHIFT 11 /* DSP1RX_EQ_B4_GAIN - [15:11] */
2523#define WM8915_DSP1RX_EQ_B4_GAIN_WIDTH 5 /* DSP1RX_EQ_B4_GAIN - [15:11] */
2524#define WM8915_DSP1RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B5_GAIN - [10:6] */
2525#define WM8915_DSP1RX_EQ_B5_GAIN_SHIFT 6 /* DSP1RX_EQ_B5_GAIN - [10:6] */
2526#define WM8915_DSP1RX_EQ_B5_GAIN_WIDTH 5 /* DSP1RX_EQ_B5_GAIN - [10:6] */
2527
2528/*
2529 * R1154 (0x482) - DSP1 RX EQ Band 1 A
2530 */
2531#define WM8915_DSP1RX_EQ_B1_A_MASK 0xFFFF /* DSP1RX_EQ_B1_A - [15:0] */
2532#define WM8915_DSP1RX_EQ_B1_A_SHIFT 0 /* DSP1RX_EQ_B1_A - [15:0] */
2533#define WM8915_DSP1RX_EQ_B1_A_WIDTH 16 /* DSP1RX_EQ_B1_A - [15:0] */
2534
2535/*
2536 * R1155 (0x483) - DSP1 RX EQ Band 1 B
2537 */
2538#define WM8915_DSP1RX_EQ_B1_B_MASK 0xFFFF /* DSP1RX_EQ_B1_B - [15:0] */
2539#define WM8915_DSP1RX_EQ_B1_B_SHIFT 0 /* DSP1RX_EQ_B1_B - [15:0] */
2540#define WM8915_DSP1RX_EQ_B1_B_WIDTH 16 /* DSP1RX_EQ_B1_B - [15:0] */
2541
2542/*
2543 * R1156 (0x484) - DSP1 RX EQ Band 1 PG
2544 */
2545#define WM8915_DSP1RX_EQ_B1_PG_MASK 0xFFFF /* DSP1RX_EQ_B1_PG - [15:0] */
2546#define WM8915_DSP1RX_EQ_B1_PG_SHIFT 0 /* DSP1RX_EQ_B1_PG - [15:0] */
2547#define WM8915_DSP1RX_EQ_B1_PG_WIDTH 16 /* DSP1RX_EQ_B1_PG - [15:0] */
2548
2549/*
2550 * R1157 (0x485) - DSP1 RX EQ Band 2 A
2551 */
2552#define WM8915_DSP1RX_EQ_B2_A_MASK 0xFFFF /* DSP1RX_EQ_B2_A - [15:0] */
2553#define WM8915_DSP1RX_EQ_B2_A_SHIFT 0 /* DSP1RX_EQ_B2_A - [15:0] */
2554#define WM8915_DSP1RX_EQ_B2_A_WIDTH 16 /* DSP1RX_EQ_B2_A - [15:0] */
2555
2556/*
2557 * R1158 (0x486) - DSP1 RX EQ Band 2 B
2558 */
2559#define WM8915_DSP1RX_EQ_B2_B_MASK 0xFFFF /* DSP1RX_EQ_B2_B - [15:0] */
2560#define WM8915_DSP1RX_EQ_B2_B_SHIFT 0 /* DSP1RX_EQ_B2_B - [15:0] */
2561#define WM8915_DSP1RX_EQ_B2_B_WIDTH 16 /* DSP1RX_EQ_B2_B - [15:0] */
2562
2563/*
2564 * R1159 (0x487) - DSP1 RX EQ Band 2 C
2565 */
2566#define WM8915_DSP1RX_EQ_B2_C_MASK 0xFFFF /* DSP1RX_EQ_B2_C - [15:0] */
2567#define WM8915_DSP1RX_EQ_B2_C_SHIFT 0 /* DSP1RX_EQ_B2_C - [15:0] */
2568#define WM8915_DSP1RX_EQ_B2_C_WIDTH 16 /* DSP1RX_EQ_B2_C - [15:0] */
2569
2570/*
2571 * R1160 (0x488) - DSP1 RX EQ Band 2 PG
2572 */
2573#define WM8915_DSP1RX_EQ_B2_PG_MASK 0xFFFF /* DSP1RX_EQ_B2_PG - [15:0] */
2574#define WM8915_DSP1RX_EQ_B2_PG_SHIFT 0 /* DSP1RX_EQ_B2_PG - [15:0] */
2575#define WM8915_DSP1RX_EQ_B2_PG_WIDTH 16 /* DSP1RX_EQ_B2_PG - [15:0] */
2576
2577/*
2578 * R1161 (0x489) - DSP1 RX EQ Band 3 A
2579 */
2580#define WM8915_DSP1RX_EQ_B3_A_MASK 0xFFFF /* DSP1RX_EQ_B3_A - [15:0] */
2581#define WM8915_DSP1RX_EQ_B3_A_SHIFT 0 /* DSP1RX_EQ_B3_A - [15:0] */
2582#define WM8915_DSP1RX_EQ_B3_A_WIDTH 16 /* DSP1RX_EQ_B3_A - [15:0] */
2583
2584/*
2585 * R1162 (0x48A) - DSP1 RX EQ Band 3 B
2586 */
2587#define WM8915_DSP1RX_EQ_B3_B_MASK 0xFFFF /* DSP1RX_EQ_B3_B - [15:0] */
2588#define WM8915_DSP1RX_EQ_B3_B_SHIFT 0 /* DSP1RX_EQ_B3_B - [15:0] */
2589#define WM8915_DSP1RX_EQ_B3_B_WIDTH 16 /* DSP1RX_EQ_B3_B - [15:0] */
2590
2591/*
2592 * R1163 (0x48B) - DSP1 RX EQ Band 3 C
2593 */
2594#define WM8915_DSP1RX_EQ_B3_C_MASK 0xFFFF /* DSP1RX_EQ_B3_C - [15:0] */
2595#define WM8915_DSP1RX_EQ_B3_C_SHIFT 0 /* DSP1RX_EQ_B3_C - [15:0] */
2596#define WM8915_DSP1RX_EQ_B3_C_WIDTH 16 /* DSP1RX_EQ_B3_C - [15:0] */
2597
2598/*
2599 * R1164 (0x48C) - DSP1 RX EQ Band 3 PG
2600 */
2601#define WM8915_DSP1RX_EQ_B3_PG_MASK 0xFFFF /* DSP1RX_EQ_B3_PG - [15:0] */
2602#define WM8915_DSP1RX_EQ_B3_PG_SHIFT 0 /* DSP1RX_EQ_B3_PG - [15:0] */
2603#define WM8915_DSP1RX_EQ_B3_PG_WIDTH 16 /* DSP1RX_EQ_B3_PG - [15:0] */
2604
2605/*
2606 * R1165 (0x48D) - DSP1 RX EQ Band 4 A
2607 */
2608#define WM8915_DSP1RX_EQ_B4_A_MASK 0xFFFF /* DSP1RX_EQ_B4_A - [15:0] */
2609#define WM8915_DSP1RX_EQ_B4_A_SHIFT 0 /* DSP1RX_EQ_B4_A - [15:0] */
2610#define WM8915_DSP1RX_EQ_B4_A_WIDTH 16 /* DSP1RX_EQ_B4_A - [15:0] */
2611
2612/*
2613 * R1166 (0x48E) - DSP1 RX EQ Band 4 B
2614 */
2615#define WM8915_DSP1RX_EQ_B4_B_MASK 0xFFFF /* DSP1RX_EQ_B4_B - [15:0] */
2616#define WM8915_DSP1RX_EQ_B4_B_SHIFT 0 /* DSP1RX_EQ_B4_B - [15:0] */
2617#define WM8915_DSP1RX_EQ_B4_B_WIDTH 16 /* DSP1RX_EQ_B4_B - [15:0] */
2618
2619/*
2620 * R1167 (0x48F) - DSP1 RX EQ Band 4 C
2621 */
2622#define WM8915_DSP1RX_EQ_B4_C_MASK 0xFFFF /* DSP1RX_EQ_B4_C - [15:0] */
2623#define WM8915_DSP1RX_EQ_B4_C_SHIFT 0 /* DSP1RX_EQ_B4_C - [15:0] */
2624#define WM8915_DSP1RX_EQ_B4_C_WIDTH 16 /* DSP1RX_EQ_B4_C - [15:0] */
2625
2626/*
2627 * R1168 (0x490) - DSP1 RX EQ Band 4 PG
2628 */
2629#define WM8915_DSP1RX_EQ_B4_PG_MASK 0xFFFF /* DSP1RX_EQ_B4_PG - [15:0] */
2630#define WM8915_DSP1RX_EQ_B4_PG_SHIFT 0 /* DSP1RX_EQ_B4_PG - [15:0] */
2631#define WM8915_DSP1RX_EQ_B4_PG_WIDTH 16 /* DSP1RX_EQ_B4_PG - [15:0] */
2632
2633/*
2634 * R1169 (0x491) - DSP1 RX EQ Band 5 A
2635 */
2636#define WM8915_DSP1RX_EQ_B5_A_MASK 0xFFFF /* DSP1RX_EQ_B5_A - [15:0] */
2637#define WM8915_DSP1RX_EQ_B5_A_SHIFT 0 /* DSP1RX_EQ_B5_A - [15:0] */
2638#define WM8915_DSP1RX_EQ_B5_A_WIDTH 16 /* DSP1RX_EQ_B5_A - [15:0] */
2639
2640/*
2641 * R1170 (0x492) - DSP1 RX EQ Band 5 B
2642 */
2643#define WM8915_DSP1RX_EQ_B5_B_MASK 0xFFFF /* DSP1RX_EQ_B5_B - [15:0] */
2644#define WM8915_DSP1RX_EQ_B5_B_SHIFT 0 /* DSP1RX_EQ_B5_B - [15:0] */
2645#define WM8915_DSP1RX_EQ_B5_B_WIDTH 16 /* DSP1RX_EQ_B5_B - [15:0] */
2646
2647/*
2648 * R1171 (0x493) - DSP1 RX EQ Band 5 PG
2649 */
2650#define WM8915_DSP1RX_EQ_B5_PG_MASK 0xFFFF /* DSP1RX_EQ_B5_PG - [15:0] */
2651#define WM8915_DSP1RX_EQ_B5_PG_SHIFT 0 /* DSP1RX_EQ_B5_PG - [15:0] */
2652#define WM8915_DSP1RX_EQ_B5_PG_WIDTH 16 /* DSP1RX_EQ_B5_PG - [15:0] */
2653
2654/*
2655 * R1280 (0x500) - DSP2 TX Left Volume
2656 */
2657#define WM8915_DSP2TX_VU 0x0100 /* DSP2TX_VU */
2658#define WM8915_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */
2659#define WM8915_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */
2660#define WM8915_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */
2661#define WM8915_DSP2TXL_VOL_MASK 0x00FF /* DSP2TXL_VOL - [7:0] */
2662#define WM8915_DSP2TXL_VOL_SHIFT 0 /* DSP2TXL_VOL - [7:0] */
2663#define WM8915_DSP2TXL_VOL_WIDTH 8 /* DSP2TXL_VOL - [7:0] */
2664
2665/*
2666 * R1281 (0x501) - DSP2 TX Right Volume
2667 */
2668#define WM8915_DSP2TX_VU 0x0100 /* DSP2TX_VU */
2669#define WM8915_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */
2670#define WM8915_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */
2671#define WM8915_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */
2672#define WM8915_DSP2TXR_VOL_MASK 0x00FF /* DSP2TXR_VOL - [7:0] */
2673#define WM8915_DSP2TXR_VOL_SHIFT 0 /* DSP2TXR_VOL - [7:0] */
2674#define WM8915_DSP2TXR_VOL_WIDTH 8 /* DSP2TXR_VOL - [7:0] */
2675
2676/*
2677 * R1282 (0x502) - DSP2 RX Left Volume
2678 */
2679#define WM8915_DSP2RX_VU 0x0100 /* DSP2RX_VU */
2680#define WM8915_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */
2681#define WM8915_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */
2682#define WM8915_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */
2683#define WM8915_DSP2RXL_VOL_MASK 0x00FF /* DSP2RXL_VOL - [7:0] */
2684#define WM8915_DSP2RXL_VOL_SHIFT 0 /* DSP2RXL_VOL - [7:0] */
2685#define WM8915_DSP2RXL_VOL_WIDTH 8 /* DSP2RXL_VOL - [7:0] */
2686
2687/*
2688 * R1283 (0x503) - DSP2 RX Right Volume
2689 */
2690#define WM8915_DSP2RX_VU 0x0100 /* DSP2RX_VU */
2691#define WM8915_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */
2692#define WM8915_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */
2693#define WM8915_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */
2694#define WM8915_DSP2RXR_VOL_MASK 0x00FF /* DSP2RXR_VOL - [7:0] */
2695#define WM8915_DSP2RXR_VOL_SHIFT 0 /* DSP2RXR_VOL - [7:0] */
2696#define WM8915_DSP2RXR_VOL_WIDTH 8 /* DSP2RXR_VOL - [7:0] */
2697
2698/*
2699 * R1296 (0x510) - DSP2 TX Filters
2700 */
2701#define WM8915_DSP2TX_NF 0x2000 /* DSP2TX_NF */
2702#define WM8915_DSP2TX_NF_MASK 0x2000 /* DSP2TX_NF */
2703#define WM8915_DSP2TX_NF_SHIFT 13 /* DSP2TX_NF */
2704#define WM8915_DSP2TX_NF_WIDTH 1 /* DSP2TX_NF */
2705#define WM8915_DSP2TXL_HPF 0x1000 /* DSP2TXL_HPF */
2706#define WM8915_DSP2TXL_HPF_MASK 0x1000 /* DSP2TXL_HPF */
2707#define WM8915_DSP2TXL_HPF_SHIFT 12 /* DSP2TXL_HPF */
2708#define WM8915_DSP2TXL_HPF_WIDTH 1 /* DSP2TXL_HPF */
2709#define WM8915_DSP2TXR_HPF 0x0800 /* DSP2TXR_HPF */
2710#define WM8915_DSP2TXR_HPF_MASK 0x0800 /* DSP2TXR_HPF */
2711#define WM8915_DSP2TXR_HPF_SHIFT 11 /* DSP2TXR_HPF */
2712#define WM8915_DSP2TXR_HPF_WIDTH 1 /* DSP2TXR_HPF */
2713#define WM8915_DSP2TX_HPF_MODE_MASK 0x0018 /* DSP2TX_HPF_MODE - [4:3] */
2714#define WM8915_DSP2TX_HPF_MODE_SHIFT 3 /* DSP2TX_HPF_MODE - [4:3] */
2715#define WM8915_DSP2TX_HPF_MODE_WIDTH 2 /* DSP2TX_HPF_MODE - [4:3] */
2716#define WM8915_DSP2TX_HPF_CUT_MASK 0x0007 /* DSP2TX_HPF_CUT - [2:0] */
2717#define WM8915_DSP2TX_HPF_CUT_SHIFT 0 /* DSP2TX_HPF_CUT - [2:0] */
2718#define WM8915_DSP2TX_HPF_CUT_WIDTH 3 /* DSP2TX_HPF_CUT - [2:0] */
2719
2720/*
2721 * R1312 (0x520) - DSP2 RX Filters (1)
2722 */
2723#define WM8915_DSP2RX_MUTE 0x0200 /* DSP2RX_MUTE */
2724#define WM8915_DSP2RX_MUTE_MASK 0x0200 /* DSP2RX_MUTE */
2725#define WM8915_DSP2RX_MUTE_SHIFT 9 /* DSP2RX_MUTE */
2726#define WM8915_DSP2RX_MUTE_WIDTH 1 /* DSP2RX_MUTE */
2727#define WM8915_DSP2RX_MONO 0x0080 /* DSP2RX_MONO */
2728#define WM8915_DSP2RX_MONO_MASK 0x0080 /* DSP2RX_MONO */
2729#define WM8915_DSP2RX_MONO_SHIFT 7 /* DSP2RX_MONO */
2730#define WM8915_DSP2RX_MONO_WIDTH 1 /* DSP2RX_MONO */
2731#define WM8915_DSP2RX_MUTERATE 0x0020 /* DSP2RX_MUTERATE */
2732#define WM8915_DSP2RX_MUTERATE_MASK 0x0020 /* DSP2RX_MUTERATE */
2733#define WM8915_DSP2RX_MUTERATE_SHIFT 5 /* DSP2RX_MUTERATE */
2734#define WM8915_DSP2RX_MUTERATE_WIDTH 1 /* DSP2RX_MUTERATE */
2735#define WM8915_DSP2RX_UNMUTE_RAMP 0x0010 /* DSP2RX_UNMUTE_RAMP */
2736#define WM8915_DSP2RX_UNMUTE_RAMP_MASK 0x0010 /* DSP2RX_UNMUTE_RAMP */
2737#define WM8915_DSP2RX_UNMUTE_RAMP_SHIFT 4 /* DSP2RX_UNMUTE_RAMP */
2738#define WM8915_DSP2RX_UNMUTE_RAMP_WIDTH 1 /* DSP2RX_UNMUTE_RAMP */
2739
2740/*
2741 * R1313 (0x521) - DSP2 RX Filters (2)
2742 */
2743#define WM8915_DSP2RX_3D_GAIN_MASK 0x3E00 /* DSP2RX_3D_GAIN - [13:9] */
2744#define WM8915_DSP2RX_3D_GAIN_SHIFT 9 /* DSP2RX_3D_GAIN - [13:9] */
2745#define WM8915_DSP2RX_3D_GAIN_WIDTH 5 /* DSP2RX_3D_GAIN - [13:9] */
2746#define WM8915_DSP2RX_3D_ENA 0x0100 /* DSP2RX_3D_ENA */
2747#define WM8915_DSP2RX_3D_ENA_MASK 0x0100 /* DSP2RX_3D_ENA */
2748#define WM8915_DSP2RX_3D_ENA_SHIFT 8 /* DSP2RX_3D_ENA */
2749#define WM8915_DSP2RX_3D_ENA_WIDTH 1 /* DSP2RX_3D_ENA */
2750
2751/*
2752 * R1344 (0x540) - DSP2 DRC (1)
2753 */
2754#define WM8915_DSP2DRC_SIG_DET_RMS_MASK 0xF800 /* DSP2DRC_SIG_DET_RMS - [15:11] */
2755#define WM8915_DSP2DRC_SIG_DET_RMS_SHIFT 11 /* DSP2DRC_SIG_DET_RMS - [15:11] */
2756#define WM8915_DSP2DRC_SIG_DET_RMS_WIDTH 5 /* DSP2DRC_SIG_DET_RMS - [15:11] */
2757#define WM8915_DSP2DRC_SIG_DET_PK_MASK 0x0600 /* DSP2DRC_SIG_DET_PK - [10:9] */
2758#define WM8915_DSP2DRC_SIG_DET_PK_SHIFT 9 /* DSP2DRC_SIG_DET_PK - [10:9] */
2759#define WM8915_DSP2DRC_SIG_DET_PK_WIDTH 2 /* DSP2DRC_SIG_DET_PK - [10:9] */
2760#define WM8915_DSP2DRC_NG_ENA 0x0100 /* DSP2DRC_NG_ENA */
2761#define WM8915_DSP2DRC_NG_ENA_MASK 0x0100 /* DSP2DRC_NG_ENA */
2762#define WM8915_DSP2DRC_NG_ENA_SHIFT 8 /* DSP2DRC_NG_ENA */
2763#define WM8915_DSP2DRC_NG_ENA_WIDTH 1 /* DSP2DRC_NG_ENA */
2764#define WM8915_DSP2DRC_SIG_DET_MODE 0x0080 /* DSP2DRC_SIG_DET_MODE */
2765#define WM8915_DSP2DRC_SIG_DET_MODE_MASK 0x0080 /* DSP2DRC_SIG_DET_MODE */
2766#define WM8915_DSP2DRC_SIG_DET_MODE_SHIFT 7 /* DSP2DRC_SIG_DET_MODE */
2767#define WM8915_DSP2DRC_SIG_DET_MODE_WIDTH 1 /* DSP2DRC_SIG_DET_MODE */
2768#define WM8915_DSP2DRC_SIG_DET 0x0040 /* DSP2DRC_SIG_DET */
2769#define WM8915_DSP2DRC_SIG_DET_MASK 0x0040 /* DSP2DRC_SIG_DET */
2770#define WM8915_DSP2DRC_SIG_DET_SHIFT 6 /* DSP2DRC_SIG_DET */
2771#define WM8915_DSP2DRC_SIG_DET_WIDTH 1 /* DSP2DRC_SIG_DET */
2772#define WM8915_DSP2DRC_KNEE2_OP_ENA 0x0020 /* DSP2DRC_KNEE2_OP_ENA */
2773#define WM8915_DSP2DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP2DRC_KNEE2_OP_ENA */
2774#define WM8915_DSP2DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP2DRC_KNEE2_OP_ENA */
2775#define WM8915_DSP2DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP2DRC_KNEE2_OP_ENA */
2776#define WM8915_DSP2DRC_QR 0x0010 /* DSP2DRC_QR */
2777#define WM8915_DSP2DRC_QR_MASK 0x0010 /* DSP2DRC_QR */
2778#define WM8915_DSP2DRC_QR_SHIFT 4 /* DSP2DRC_QR */
2779#define WM8915_DSP2DRC_QR_WIDTH 1 /* DSP2DRC_QR */
2780#define WM8915_DSP2DRC_ANTICLIP 0x0008 /* DSP2DRC_ANTICLIP */
2781#define WM8915_DSP2DRC_ANTICLIP_MASK 0x0008 /* DSP2DRC_ANTICLIP */
2782#define WM8915_DSP2DRC_ANTICLIP_SHIFT 3 /* DSP2DRC_ANTICLIP */
2783#define WM8915_DSP2DRC_ANTICLIP_WIDTH 1 /* DSP2DRC_ANTICLIP */
2784#define WM8915_DSP2RX_DRC_ENA 0x0004 /* DSP2RX_DRC_ENA */
2785#define WM8915_DSP2RX_DRC_ENA_MASK 0x0004 /* DSP2RX_DRC_ENA */
2786#define WM8915_DSP2RX_DRC_ENA_SHIFT 2 /* DSP2RX_DRC_ENA */
2787#define WM8915_DSP2RX_DRC_ENA_WIDTH 1 /* DSP2RX_DRC_ENA */
2788#define WM8915_DSP2TXL_DRC_ENA 0x0002 /* DSP2TXL_DRC_ENA */
2789#define WM8915_DSP2TXL_DRC_ENA_MASK 0x0002 /* DSP2TXL_DRC_ENA */
2790#define WM8915_DSP2TXL_DRC_ENA_SHIFT 1 /* DSP2TXL_DRC_ENA */
2791#define WM8915_DSP2TXL_DRC_ENA_WIDTH 1 /* DSP2TXL_DRC_ENA */
2792#define WM8915_DSP2TXR_DRC_ENA 0x0001 /* DSP2TXR_DRC_ENA */
2793#define WM8915_DSP2TXR_DRC_ENA_MASK 0x0001 /* DSP2TXR_DRC_ENA */
2794#define WM8915_DSP2TXR_DRC_ENA_SHIFT 0 /* DSP2TXR_DRC_ENA */
2795#define WM8915_DSP2TXR_DRC_ENA_WIDTH 1 /* DSP2TXR_DRC_ENA */
2796
2797/*
2798 * R1345 (0x541) - DSP2 DRC (2)
2799 */
2800#define WM8915_DSP2DRC_ATK_MASK 0x1E00 /* DSP2DRC_ATK - [12:9] */
2801#define WM8915_DSP2DRC_ATK_SHIFT 9 /* DSP2DRC_ATK - [12:9] */
2802#define WM8915_DSP2DRC_ATK_WIDTH 4 /* DSP2DRC_ATK - [12:9] */
2803#define WM8915_DSP2DRC_DCY_MASK 0x01E0 /* DSP2DRC_DCY - [8:5] */
2804#define WM8915_DSP2DRC_DCY_SHIFT 5 /* DSP2DRC_DCY - [8:5] */
2805#define WM8915_DSP2DRC_DCY_WIDTH 4 /* DSP2DRC_DCY - [8:5] */
2806#define WM8915_DSP2DRC_MINGAIN_MASK 0x001C /* DSP2DRC_MINGAIN - [4:2] */
2807#define WM8915_DSP2DRC_MINGAIN_SHIFT 2 /* DSP2DRC_MINGAIN - [4:2] */
2808#define WM8915_DSP2DRC_MINGAIN_WIDTH 3 /* DSP2DRC_MINGAIN - [4:2] */
2809#define WM8915_DSP2DRC_MAXGAIN_MASK 0x0003 /* DSP2DRC_MAXGAIN - [1:0] */
2810#define WM8915_DSP2DRC_MAXGAIN_SHIFT 0 /* DSP2DRC_MAXGAIN - [1:0] */
2811#define WM8915_DSP2DRC_MAXGAIN_WIDTH 2 /* DSP2DRC_MAXGAIN - [1:0] */
2812
2813/*
2814 * R1346 (0x542) - DSP2 DRC (3)
2815 */
2816#define WM8915_DSP2DRC_NG_MINGAIN_MASK 0xF000 /* DSP2DRC_NG_MINGAIN - [15:12] */
2817#define WM8915_DSP2DRC_NG_MINGAIN_SHIFT 12 /* DSP2DRC_NG_MINGAIN - [15:12] */
2818#define WM8915_DSP2DRC_NG_MINGAIN_WIDTH 4 /* DSP2DRC_NG_MINGAIN - [15:12] */
2819#define WM8915_DSP2DRC_NG_EXP_MASK 0x0C00 /* DSP2DRC_NG_EXP - [11:10] */
2820#define WM8915_DSP2DRC_NG_EXP_SHIFT 10 /* DSP2DRC_NG_EXP - [11:10] */
2821#define WM8915_DSP2DRC_NG_EXP_WIDTH 2 /* DSP2DRC_NG_EXP - [11:10] */
2822#define WM8915_DSP2DRC_QR_THR_MASK 0x0300 /* DSP2DRC_QR_THR - [9:8] */
2823#define WM8915_DSP2DRC_QR_THR_SHIFT 8 /* DSP2DRC_QR_THR - [9:8] */
2824#define WM8915_DSP2DRC_QR_THR_WIDTH 2 /* DSP2DRC_QR_THR - [9:8] */
2825#define WM8915_DSP2DRC_QR_DCY_MASK 0x00C0 /* DSP2DRC_QR_DCY - [7:6] */
2826#define WM8915_DSP2DRC_QR_DCY_SHIFT 6 /* DSP2DRC_QR_DCY - [7:6] */
2827#define WM8915_DSP2DRC_QR_DCY_WIDTH 2 /* DSP2DRC_QR_DCY - [7:6] */
2828#define WM8915_DSP2DRC_HI_COMP_MASK 0x0038 /* DSP2DRC_HI_COMP - [5:3] */
2829#define WM8915_DSP2DRC_HI_COMP_SHIFT 3 /* DSP2DRC_HI_COMP - [5:3] */
2830#define WM8915_DSP2DRC_HI_COMP_WIDTH 3 /* DSP2DRC_HI_COMP - [5:3] */
2831#define WM8915_DSP2DRC_LO_COMP_MASK 0x0007 /* DSP2DRC_LO_COMP - [2:0] */
2832#define WM8915_DSP2DRC_LO_COMP_SHIFT 0 /* DSP2DRC_LO_COMP - [2:0] */
2833#define WM8915_DSP2DRC_LO_COMP_WIDTH 3 /* DSP2DRC_LO_COMP - [2:0] */
2834
2835/*
2836 * R1347 (0x543) - DSP2 DRC (4)
2837 */
2838#define WM8915_DSP2DRC_KNEE_IP_MASK 0x07E0 /* DSP2DRC_KNEE_IP - [10:5] */
2839#define WM8915_DSP2DRC_KNEE_IP_SHIFT 5 /* DSP2DRC_KNEE_IP - [10:5] */
2840#define WM8915_DSP2DRC_KNEE_IP_WIDTH 6 /* DSP2DRC_KNEE_IP - [10:5] */
2841#define WM8915_DSP2DRC_KNEE_OP_MASK 0x001F /* DSP2DRC_KNEE_OP - [4:0] */
2842#define WM8915_DSP2DRC_KNEE_OP_SHIFT 0 /* DSP2DRC_KNEE_OP - [4:0] */
2843#define WM8915_DSP2DRC_KNEE_OP_WIDTH 5 /* DSP2DRC_KNEE_OP - [4:0] */
2844
2845/*
2846 * R1348 (0x544) - DSP2 DRC (5)
2847 */
2848#define WM8915_DSP2DRC_KNEE2_IP_MASK 0x03E0 /* DSP2DRC_KNEE2_IP - [9:5] */
2849#define WM8915_DSP2DRC_KNEE2_IP_SHIFT 5 /* DSP2DRC_KNEE2_IP - [9:5] */
2850#define WM8915_DSP2DRC_KNEE2_IP_WIDTH 5 /* DSP2DRC_KNEE2_IP - [9:5] */
2851#define WM8915_DSP2DRC_KNEE2_OP_MASK 0x001F /* DSP2DRC_KNEE2_OP - [4:0] */
2852#define WM8915_DSP2DRC_KNEE2_OP_SHIFT 0 /* DSP2DRC_KNEE2_OP - [4:0] */
2853#define WM8915_DSP2DRC_KNEE2_OP_WIDTH 5 /* DSP2DRC_KNEE2_OP - [4:0] */
2854
2855/*
2856 * R1408 (0x580) - DSP2 RX EQ Gains (1)
2857 */
2858#define WM8915_DSP2RX_EQ_B1_GAIN_MASK 0xF800 /* DSP2RX_EQ_B1_GAIN - [15:11] */
2859#define WM8915_DSP2RX_EQ_B1_GAIN_SHIFT 11 /* DSP2RX_EQ_B1_GAIN - [15:11] */
2860#define WM8915_DSP2RX_EQ_B1_GAIN_WIDTH 5 /* DSP2RX_EQ_B1_GAIN - [15:11] */
2861#define WM8915_DSP2RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B2_GAIN - [10:6] */
2862#define WM8915_DSP2RX_EQ_B2_GAIN_SHIFT 6 /* DSP2RX_EQ_B2_GAIN - [10:6] */
2863#define WM8915_DSP2RX_EQ_B2_GAIN_WIDTH 5 /* DSP2RX_EQ_B2_GAIN - [10:6] */
2864#define WM8915_DSP2RX_EQ_B3_GAIN_MASK 0x003E /* DSP2RX_EQ_B3_GAIN - [5:1] */
2865#define WM8915_DSP2RX_EQ_B3_GAIN_SHIFT 1 /* DSP2RX_EQ_B3_GAIN - [5:1] */
2866#define WM8915_DSP2RX_EQ_B3_GAIN_WIDTH 5 /* DSP2RX_EQ_B3_GAIN - [5:1] */
2867#define WM8915_DSP2RX_EQ_ENA 0x0001 /* DSP2RX_EQ_ENA */
2868#define WM8915_DSP2RX_EQ_ENA_MASK 0x0001 /* DSP2RX_EQ_ENA */
2869#define WM8915_DSP2RX_EQ_ENA_SHIFT 0 /* DSP2RX_EQ_ENA */
2870#define WM8915_DSP2RX_EQ_ENA_WIDTH 1 /* DSP2RX_EQ_ENA */
2871
2872/*
2873 * R1409 (0x581) - DSP2 RX EQ Gains (2)
2874 */
2875#define WM8915_DSP2RX_EQ_B4_GAIN_MASK 0xF800 /* DSP2RX_EQ_B4_GAIN - [15:11] */
2876#define WM8915_DSP2RX_EQ_B4_GAIN_SHIFT 11 /* DSP2RX_EQ_B4_GAIN - [15:11] */
2877#define WM8915_DSP2RX_EQ_B4_GAIN_WIDTH 5 /* DSP2RX_EQ_B4_GAIN - [15:11] */
2878#define WM8915_DSP2RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B5_GAIN - [10:6] */
2879#define WM8915_DSP2RX_EQ_B5_GAIN_SHIFT 6 /* DSP2RX_EQ_B5_GAIN - [10:6] */
2880#define WM8915_DSP2RX_EQ_B5_GAIN_WIDTH 5 /* DSP2RX_EQ_B5_GAIN - [10:6] */
2881
2882/*
2883 * R1410 (0x582) - DSP2 RX EQ Band 1 A
2884 */
2885#define WM8915_DSP2RX_EQ_B1_A_MASK 0xFFFF /* DSP2RX_EQ_B1_A - [15:0] */
2886#define WM8915_DSP2RX_EQ_B1_A_SHIFT 0 /* DSP2RX_EQ_B1_A - [15:0] */
2887#define WM8915_DSP2RX_EQ_B1_A_WIDTH 16 /* DSP2RX_EQ_B1_A - [15:0] */
2888
2889/*
2890 * R1411 (0x583) - DSP2 RX EQ Band 1 B
2891 */
2892#define WM8915_DSP2RX_EQ_B1_B_MASK 0xFFFF /* DSP2RX_EQ_B1_B - [15:0] */
2893#define WM8915_DSP2RX_EQ_B1_B_SHIFT 0 /* DSP2RX_EQ_B1_B - [15:0] */
2894#define WM8915_DSP2RX_EQ_B1_B_WIDTH 16 /* DSP2RX_EQ_B1_B - [15:0] */
2895
2896/*
2897 * R1412 (0x584) - DSP2 RX EQ Band 1 PG
2898 */
2899#define WM8915_DSP2RX_EQ_B1_PG_MASK 0xFFFF /* DSP2RX_EQ_B1_PG - [15:0] */
2900#define WM8915_DSP2RX_EQ_B1_PG_SHIFT 0 /* DSP2RX_EQ_B1_PG - [15:0] */
2901#define WM8915_DSP2RX_EQ_B1_PG_WIDTH 16 /* DSP2RX_EQ_B1_PG - [15:0] */
2902
2903/*
2904 * R1413 (0x585) - DSP2 RX EQ Band 2 A
2905 */
2906#define WM8915_DSP2RX_EQ_B2_A_MASK 0xFFFF /* DSP2RX_EQ_B2_A - [15:0] */
2907#define WM8915_DSP2RX_EQ_B2_A_SHIFT 0 /* DSP2RX_EQ_B2_A - [15:0] */
2908#define WM8915_DSP2RX_EQ_B2_A_WIDTH 16 /* DSP2RX_EQ_B2_A - [15:0] */
2909
2910/*
2911 * R1414 (0x586) - DSP2 RX EQ Band 2 B
2912 */
2913#define WM8915_DSP2RX_EQ_B2_B_MASK 0xFFFF /* DSP2RX_EQ_B2_B - [15:0] */
2914#define WM8915_DSP2RX_EQ_B2_B_SHIFT 0 /* DSP2RX_EQ_B2_B - [15:0] */
2915#define WM8915_DSP2RX_EQ_B2_B_WIDTH 16 /* DSP2RX_EQ_B2_B - [15:0] */
2916
2917/*
2918 * R1415 (0x587) - DSP2 RX EQ Band 2 C
2919 */
2920#define WM8915_DSP2RX_EQ_B2_C_MASK 0xFFFF /* DSP2RX_EQ_B2_C - [15:0] */
2921#define WM8915_DSP2RX_EQ_B2_C_SHIFT 0 /* DSP2RX_EQ_B2_C - [15:0] */
2922#define WM8915_DSP2RX_EQ_B2_C_WIDTH 16 /* DSP2RX_EQ_B2_C - [15:0] */
2923
2924/*
2925 * R1416 (0x588) - DSP2 RX EQ Band 2 PG
2926 */
2927#define WM8915_DSP2RX_EQ_B2_PG_MASK 0xFFFF /* DSP2RX_EQ_B2_PG - [15:0] */
2928#define WM8915_DSP2RX_EQ_B2_PG_SHIFT 0 /* DSP2RX_EQ_B2_PG - [15:0] */
2929#define WM8915_DSP2RX_EQ_B2_PG_WIDTH 16 /* DSP2RX_EQ_B2_PG - [15:0] */
2930
2931/*
2932 * R1417 (0x589) - DSP2 RX EQ Band 3 A
2933 */
2934#define WM8915_DSP2RX_EQ_B3_A_MASK 0xFFFF /* DSP2RX_EQ_B3_A - [15:0] */
2935#define WM8915_DSP2RX_EQ_B3_A_SHIFT 0 /* DSP2RX_EQ_B3_A - [15:0] */
2936#define WM8915_DSP2RX_EQ_B3_A_WIDTH 16 /* DSP2RX_EQ_B3_A - [15:0] */
2937
2938/*
2939 * R1418 (0x58A) - DSP2 RX EQ Band 3 B
2940 */
2941#define WM8915_DSP2RX_EQ_B3_B_MASK 0xFFFF /* DSP2RX_EQ_B3_B - [15:0] */
2942#define WM8915_DSP2RX_EQ_B3_B_SHIFT 0 /* DSP2RX_EQ_B3_B - [15:0] */
2943#define WM8915_DSP2RX_EQ_B3_B_WIDTH 16 /* DSP2RX_EQ_B3_B - [15:0] */
2944
2945/*
2946 * R1419 (0x58B) - DSP2 RX EQ Band 3 C
2947 */
2948#define WM8915_DSP2RX_EQ_B3_C_MASK 0xFFFF /* DSP2RX_EQ_B3_C - [15:0] */
2949#define WM8915_DSP2RX_EQ_B3_C_SHIFT 0 /* DSP2RX_EQ_B3_C - [15:0] */
2950#define WM8915_DSP2RX_EQ_B3_C_WIDTH 16 /* DSP2RX_EQ_B3_C - [15:0] */
2951
2952/*
2953 * R1420 (0x58C) - DSP2 RX EQ Band 3 PG
2954 */
2955#define WM8915_DSP2RX_EQ_B3_PG_MASK 0xFFFF /* DSP2RX_EQ_B3_PG - [15:0] */
2956#define WM8915_DSP2RX_EQ_B3_PG_SHIFT 0 /* DSP2RX_EQ_B3_PG - [15:0] */
2957#define WM8915_DSP2RX_EQ_B3_PG_WIDTH 16 /* DSP2RX_EQ_B3_PG - [15:0] */
2958
2959/*
2960 * R1421 (0x58D) - DSP2 RX EQ Band 4 A
2961 */
2962#define WM8915_DSP2RX_EQ_B4_A_MASK 0xFFFF /* DSP2RX_EQ_B4_A - [15:0] */
2963#define WM8915_DSP2RX_EQ_B4_A_SHIFT 0 /* DSP2RX_EQ_B4_A - [15:0] */
2964#define WM8915_DSP2RX_EQ_B4_A_WIDTH 16 /* DSP2RX_EQ_B4_A - [15:0] */
2965
2966/*
2967 * R1422 (0x58E) - DSP2 RX EQ Band 4 B
2968 */
2969#define WM8915_DSP2RX_EQ_B4_B_MASK 0xFFFF /* DSP2RX_EQ_B4_B - [15:0] */
2970#define WM8915_DSP2RX_EQ_B4_B_SHIFT 0 /* DSP2RX_EQ_B4_B - [15:0] */
2971#define WM8915_DSP2RX_EQ_B4_B_WIDTH 16 /* DSP2RX_EQ_B4_B - [15:0] */
2972
2973/*
2974 * R1423 (0x58F) - DSP2 RX EQ Band 4 C
2975 */
2976#define WM8915_DSP2RX_EQ_B4_C_MASK 0xFFFF /* DSP2RX_EQ_B4_C - [15:0] */
2977#define WM8915_DSP2RX_EQ_B4_C_SHIFT 0 /* DSP2RX_EQ_B4_C - [15:0] */
2978#define WM8915_DSP2RX_EQ_B4_C_WIDTH 16 /* DSP2RX_EQ_B4_C - [15:0] */
2979
2980/*
2981 * R1424 (0x590) - DSP2 RX EQ Band 4 PG
2982 */
2983#define WM8915_DSP2RX_EQ_B4_PG_MASK 0xFFFF /* DSP2RX_EQ_B4_PG - [15:0] */
2984#define WM8915_DSP2RX_EQ_B4_PG_SHIFT 0 /* DSP2RX_EQ_B4_PG - [15:0] */
2985#define WM8915_DSP2RX_EQ_B4_PG_WIDTH 16 /* DSP2RX_EQ_B4_PG - [15:0] */
2986
2987/*
2988 * R1425 (0x591) - DSP2 RX EQ Band 5 A
2989 */
2990#define WM8915_DSP2RX_EQ_B5_A_MASK 0xFFFF /* DSP2RX_EQ_B5_A - [15:0] */
2991#define WM8915_DSP2RX_EQ_B5_A_SHIFT 0 /* DSP2RX_EQ_B5_A - [15:0] */
2992#define WM8915_DSP2RX_EQ_B5_A_WIDTH 16 /* DSP2RX_EQ_B5_A - [15:0] */
2993
2994/*
2995 * R1426 (0x592) - DSP2 RX EQ Band 5 B
2996 */
2997#define WM8915_DSP2RX_EQ_B5_B_MASK 0xFFFF /* DSP2RX_EQ_B5_B - [15:0] */
2998#define WM8915_DSP2RX_EQ_B5_B_SHIFT 0 /* DSP2RX_EQ_B5_B - [15:0] */
2999#define WM8915_DSP2RX_EQ_B5_B_WIDTH 16 /* DSP2RX_EQ_B5_B - [15:0] */
3000
3001/*
3002 * R1427 (0x593) - DSP2 RX EQ Band 5 PG
3003 */
3004#define WM8915_DSP2RX_EQ_B5_PG_MASK 0xFFFF /* DSP2RX_EQ_B5_PG - [15:0] */
3005#define WM8915_DSP2RX_EQ_B5_PG_SHIFT 0 /* DSP2RX_EQ_B5_PG - [15:0] */
3006#define WM8915_DSP2RX_EQ_B5_PG_WIDTH 16 /* DSP2RX_EQ_B5_PG - [15:0] */
3007
3008/*
3009 * R1536 (0x600) - DAC1 Mixer Volumes
3010 */
3011#define WM8915_ADCR_DAC1_VOL_MASK 0x03E0 /* ADCR_DAC1_VOL - [9:5] */
3012#define WM8915_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [9:5] */
3013#define WM8915_ADCR_DAC1_VOL_WIDTH 5 /* ADCR_DAC1_VOL - [9:5] */
3014#define WM8915_ADCL_DAC1_VOL_MASK 0x001F /* ADCL_DAC1_VOL - [4:0] */
3015#define WM8915_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [4:0] */
3016#define WM8915_ADCL_DAC1_VOL_WIDTH 5 /* ADCL_DAC1_VOL - [4:0] */
3017
3018/*
3019 * R1537 (0x601) - DAC1 Left Mixer Routing
3020 */
3021#define WM8915_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */
3022#define WM8915_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */
3023#define WM8915_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */
3024#define WM8915_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */
3025#define WM8915_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */
3026#define WM8915_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */
3027#define WM8915_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */
3028#define WM8915_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */
3029#define WM8915_DSP2RXL_TO_DAC1L 0x0002 /* DSP2RXL_TO_DAC1L */
3030#define WM8915_DSP2RXL_TO_DAC1L_MASK 0x0002 /* DSP2RXL_TO_DAC1L */
3031#define WM8915_DSP2RXL_TO_DAC1L_SHIFT 1 /* DSP2RXL_TO_DAC1L */
3032#define WM8915_DSP2RXL_TO_DAC1L_WIDTH 1 /* DSP2RXL_TO_DAC1L */
3033#define WM8915_DSP1RXL_TO_DAC1L 0x0001 /* DSP1RXL_TO_DAC1L */
3034#define WM8915_DSP1RXL_TO_DAC1L_MASK 0x0001 /* DSP1RXL_TO_DAC1L */
3035#define WM8915_DSP1RXL_TO_DAC1L_SHIFT 0 /* DSP1RXL_TO_DAC1L */
3036#define WM8915_DSP1RXL_TO_DAC1L_WIDTH 1 /* DSP1RXL_TO_DAC1L */
3037
3038/*
3039 * R1538 (0x602) - DAC1 Right Mixer Routing
3040 */
3041#define WM8915_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */
3042#define WM8915_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */
3043#define WM8915_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */
3044#define WM8915_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */
3045#define WM8915_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */
3046#define WM8915_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */
3047#define WM8915_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */
3048#define WM8915_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */
3049#define WM8915_DSP2RXR_TO_DAC1R 0x0002 /* DSP2RXR_TO_DAC1R */
3050#define WM8915_DSP2RXR_TO_DAC1R_MASK 0x0002 /* DSP2RXR_TO_DAC1R */
3051#define WM8915_DSP2RXR_TO_DAC1R_SHIFT 1 /* DSP2RXR_TO_DAC1R */
3052#define WM8915_DSP2RXR_TO_DAC1R_WIDTH 1 /* DSP2RXR_TO_DAC1R */
3053#define WM8915_DSP1RXR_TO_DAC1R 0x0001 /* DSP1RXR_TO_DAC1R */
3054#define WM8915_DSP1RXR_TO_DAC1R_MASK 0x0001 /* DSP1RXR_TO_DAC1R */
3055#define WM8915_DSP1RXR_TO_DAC1R_SHIFT 0 /* DSP1RXR_TO_DAC1R */
3056#define WM8915_DSP1RXR_TO_DAC1R_WIDTH 1 /* DSP1RXR_TO_DAC1R */
3057
3058/*
3059 * R1539 (0x603) - DAC2 Mixer Volumes
3060 */
3061#define WM8915_ADCR_DAC2_VOL_MASK 0x03E0 /* ADCR_DAC2_VOL - [9:5] */
3062#define WM8915_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [9:5] */
3063#define WM8915_ADCR_DAC2_VOL_WIDTH 5 /* ADCR_DAC2_VOL - [9:5] */
3064#define WM8915_ADCL_DAC2_VOL_MASK 0x001F /* ADCL_DAC2_VOL - [4:0] */
3065#define WM8915_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [4:0] */
3066#define WM8915_ADCL_DAC2_VOL_WIDTH 5 /* ADCL_DAC2_VOL - [4:0] */
3067
3068/*
3069 * R1540 (0x604) - DAC2 Left Mixer Routing
3070 */
3071#define WM8915_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */
3072#define WM8915_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */
3073#define WM8915_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */
3074#define WM8915_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */
3075#define WM8915_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */
3076#define WM8915_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */
3077#define WM8915_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */
3078#define WM8915_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */
3079#define WM8915_DSP2RXL_TO_DAC2L 0x0002 /* DSP2RXL_TO_DAC2L */
3080#define WM8915_DSP2RXL_TO_DAC2L_MASK 0x0002 /* DSP2RXL_TO_DAC2L */
3081#define WM8915_DSP2RXL_TO_DAC2L_SHIFT 1 /* DSP2RXL_TO_DAC2L */
3082#define WM8915_DSP2RXL_TO_DAC2L_WIDTH 1 /* DSP2RXL_TO_DAC2L */
3083#define WM8915_DSP1RXL_TO_DAC2L 0x0001 /* DSP1RXL_TO_DAC2L */
3084#define WM8915_DSP1RXL_TO_DAC2L_MASK 0x0001 /* DSP1RXL_TO_DAC2L */
3085#define WM8915_DSP1RXL_TO_DAC2L_SHIFT 0 /* DSP1RXL_TO_DAC2L */
3086#define WM8915_DSP1RXL_TO_DAC2L_WIDTH 1 /* DSP1RXL_TO_DAC2L */
3087
3088/*
3089 * R1541 (0x605) - DAC2 Right Mixer Routing
3090 */
3091#define WM8915_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */
3092#define WM8915_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */
3093#define WM8915_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */
3094#define WM8915_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */
3095#define WM8915_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */
3096#define WM8915_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */
3097#define WM8915_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */
3098#define WM8915_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */
3099#define WM8915_DSP2RXR_TO_DAC2R 0x0002 /* DSP2RXR_TO_DAC2R */
3100#define WM8915_DSP2RXR_TO_DAC2R_MASK 0x0002 /* DSP2RXR_TO_DAC2R */
3101#define WM8915_DSP2RXR_TO_DAC2R_SHIFT 1 /* DSP2RXR_TO_DAC2R */
3102#define WM8915_DSP2RXR_TO_DAC2R_WIDTH 1 /* DSP2RXR_TO_DAC2R */
3103#define WM8915_DSP1RXR_TO_DAC2R 0x0001 /* DSP1RXR_TO_DAC2R */
3104#define WM8915_DSP1RXR_TO_DAC2R_MASK 0x0001 /* DSP1RXR_TO_DAC2R */
3105#define WM8915_DSP1RXR_TO_DAC2R_SHIFT 0 /* DSP1RXR_TO_DAC2R */
3106#define WM8915_DSP1RXR_TO_DAC2R_WIDTH 1 /* DSP1RXR_TO_DAC2R */
3107
3108/*
3109 * R1542 (0x606) - DSP1 TX Left Mixer Routing
3110 */
3111#define WM8915_ADC1L_TO_DSP1TXL 0x0002 /* ADC1L_TO_DSP1TXL */
3112#define WM8915_ADC1L_TO_DSP1TXL_MASK 0x0002 /* ADC1L_TO_DSP1TXL */
3113#define WM8915_ADC1L_TO_DSP1TXL_SHIFT 1 /* ADC1L_TO_DSP1TXL */
3114#define WM8915_ADC1L_TO_DSP1TXL_WIDTH 1 /* ADC1L_TO_DSP1TXL */
3115#define WM8915_DACL_TO_DSP1TXL 0x0001 /* DACL_TO_DSP1TXL */
3116#define WM8915_DACL_TO_DSP1TXL_MASK 0x0001 /* DACL_TO_DSP1TXL */
3117#define WM8915_DACL_TO_DSP1TXL_SHIFT 0 /* DACL_TO_DSP1TXL */
3118#define WM8915_DACL_TO_DSP1TXL_WIDTH 1 /* DACL_TO_DSP1TXL */
3119
3120/*
3121 * R1543 (0x607) - DSP1 TX Right Mixer Routing
3122 */
3123#define WM8915_ADC1R_TO_DSP1TXR 0x0002 /* ADC1R_TO_DSP1TXR */
3124#define WM8915_ADC1R_TO_DSP1TXR_MASK 0x0002 /* ADC1R_TO_DSP1TXR */
3125#define WM8915_ADC1R_TO_DSP1TXR_SHIFT 1 /* ADC1R_TO_DSP1TXR */
3126#define WM8915_ADC1R_TO_DSP1TXR_WIDTH 1 /* ADC1R_TO_DSP1TXR */
3127#define WM8915_DACR_TO_DSP1TXR 0x0001 /* DACR_TO_DSP1TXR */
3128#define WM8915_DACR_TO_DSP1TXR_MASK 0x0001 /* DACR_TO_DSP1TXR */
3129#define WM8915_DACR_TO_DSP1TXR_SHIFT 0 /* DACR_TO_DSP1TXR */
3130#define WM8915_DACR_TO_DSP1TXR_WIDTH 1 /* DACR_TO_DSP1TXR */
3131
3132/*
3133 * R1544 (0x608) - DSP2 TX Left Mixer Routing
3134 */
3135#define WM8915_ADC2L_TO_DSP2TXL 0x0002 /* ADC2L_TO_DSP2TXL */
3136#define WM8915_ADC2L_TO_DSP2TXL_MASK 0x0002 /* ADC2L_TO_DSP2TXL */
3137#define WM8915_ADC2L_TO_DSP2TXL_SHIFT 1 /* ADC2L_TO_DSP2TXL */
3138#define WM8915_ADC2L_TO_DSP2TXL_WIDTH 1 /* ADC2L_TO_DSP2TXL */
3139#define WM8915_DACL_TO_DSP2TXL 0x0001 /* DACL_TO_DSP2TXL */
3140#define WM8915_DACL_TO_DSP2TXL_MASK 0x0001 /* DACL_TO_DSP2TXL */
3141#define WM8915_DACL_TO_DSP2TXL_SHIFT 0 /* DACL_TO_DSP2TXL */
3142#define WM8915_DACL_TO_DSP2TXL_WIDTH 1 /* DACL_TO_DSP2TXL */
3143
3144/*
3145 * R1545 (0x609) - DSP2 TX Right Mixer Routing
3146 */
3147#define WM8915_ADC2R_TO_DSP2TXR 0x0002 /* ADC2R_TO_DSP2TXR */
3148#define WM8915_ADC2R_TO_DSP2TXR_MASK 0x0002 /* ADC2R_TO_DSP2TXR */
3149#define WM8915_ADC2R_TO_DSP2TXR_SHIFT 1 /* ADC2R_TO_DSP2TXR */
3150#define WM8915_ADC2R_TO_DSP2TXR_WIDTH 1 /* ADC2R_TO_DSP2TXR */
3151#define WM8915_DACR_TO_DSP2TXR 0x0001 /* DACR_TO_DSP2TXR */
3152#define WM8915_DACR_TO_DSP2TXR_MASK 0x0001 /* DACR_TO_DSP2TXR */
3153#define WM8915_DACR_TO_DSP2TXR_SHIFT 0 /* DACR_TO_DSP2TXR */
3154#define WM8915_DACR_TO_DSP2TXR_WIDTH 1 /* DACR_TO_DSP2TXR */
3155
3156/*
3157 * R1546 (0x60A) - DSP TX Mixer Select
3158 */
3159#define WM8915_DAC_TO_DSPTX_SRC 0x0001 /* DAC_TO_DSPTX_SRC */
3160#define WM8915_DAC_TO_DSPTX_SRC_MASK 0x0001 /* DAC_TO_DSPTX_SRC */
3161#define WM8915_DAC_TO_DSPTX_SRC_SHIFT 0 /* DAC_TO_DSPTX_SRC */
3162#define WM8915_DAC_TO_DSPTX_SRC_WIDTH 1 /* DAC_TO_DSPTX_SRC */
3163
3164/*
3165 * R1552 (0x610) - DAC Softmute
3166 */
3167#define WM8915_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */
3168#define WM8915_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */
3169#define WM8915_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */
3170#define WM8915_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */
3171#define WM8915_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */
3172#define WM8915_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */
3173#define WM8915_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */
3174#define WM8915_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
3175
3176/*
3177 * R1568 (0x620) - Oversampling
3178 */
3179#define WM8915_SPK_OSR128 0x0008 /* SPK_OSR128 */
3180#define WM8915_SPK_OSR128_MASK 0x0008 /* SPK_OSR128 */
3181#define WM8915_SPK_OSR128_SHIFT 3 /* SPK_OSR128 */
3182#define WM8915_SPK_OSR128_WIDTH 1 /* SPK_OSR128 */
3183#define WM8915_DMIC_OSR64 0x0004 /* DMIC_OSR64 */
3184#define WM8915_DMIC_OSR64_MASK 0x0004 /* DMIC_OSR64 */
3185#define WM8915_DMIC_OSR64_SHIFT 2 /* DMIC_OSR64 */
3186#define WM8915_DMIC_OSR64_WIDTH 1 /* DMIC_OSR64 */
3187#define WM8915_ADC_OSR128 0x0002 /* ADC_OSR128 */
3188#define WM8915_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */
3189#define WM8915_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */
3190#define WM8915_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
3191#define WM8915_DAC_OSR128 0x0001 /* DAC_OSR128 */
3192#define WM8915_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
3193#define WM8915_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
3194#define WM8915_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
3195
3196/*
3197 * R1569 (0x621) - Sidetone
3198 */
3199#define WM8915_ST_LPF 0x1000 /* ST_LPF */
3200#define WM8915_ST_LPF_MASK 0x1000 /* ST_LPF */
3201#define WM8915_ST_LPF_SHIFT 12 /* ST_LPF */
3202#define WM8915_ST_LPF_WIDTH 1 /* ST_LPF */
3203#define WM8915_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */
3204#define WM8915_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */
3205#define WM8915_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */
3206#define WM8915_ST_HPF 0x0040 /* ST_HPF */
3207#define WM8915_ST_HPF_MASK 0x0040 /* ST_HPF */
3208#define WM8915_ST_HPF_SHIFT 6 /* ST_HPF */
3209#define WM8915_ST_HPF_WIDTH 1 /* ST_HPF */
3210#define WM8915_STR_SEL 0x0002 /* STR_SEL */
3211#define WM8915_STR_SEL_MASK 0x0002 /* STR_SEL */
3212#define WM8915_STR_SEL_SHIFT 1 /* STR_SEL */
3213#define WM8915_STR_SEL_WIDTH 1 /* STR_SEL */
3214#define WM8915_STL_SEL 0x0001 /* STL_SEL */
3215#define WM8915_STL_SEL_MASK 0x0001 /* STL_SEL */
3216#define WM8915_STL_SEL_SHIFT 0 /* STL_SEL */
3217#define WM8915_STL_SEL_WIDTH 1 /* STL_SEL */
3218
3219/*
3220 * R1792 (0x700) - GPIO 1
3221 */
3222#define WM8915_GP1_DIR 0x8000 /* GP1_DIR */
3223#define WM8915_GP1_DIR_MASK 0x8000 /* GP1_DIR */
3224#define WM8915_GP1_DIR_SHIFT 15 /* GP1_DIR */
3225#define WM8915_GP1_DIR_WIDTH 1 /* GP1_DIR */
3226#define WM8915_GP1_PU 0x4000 /* GP1_PU */
3227#define WM8915_GP1_PU_MASK 0x4000 /* GP1_PU */
3228#define WM8915_GP1_PU_SHIFT 14 /* GP1_PU */
3229#define WM8915_GP1_PU_WIDTH 1 /* GP1_PU */
3230#define WM8915_GP1_PD 0x2000 /* GP1_PD */
3231#define WM8915_GP1_PD_MASK 0x2000 /* GP1_PD */
3232#define WM8915_GP1_PD_SHIFT 13 /* GP1_PD */
3233#define WM8915_GP1_PD_WIDTH 1 /* GP1_PD */
3234#define WM8915_GP1_POL 0x0400 /* GP1_POL */
3235#define WM8915_GP1_POL_MASK 0x0400 /* GP1_POL */
3236#define WM8915_GP1_POL_SHIFT 10 /* GP1_POL */
3237#define WM8915_GP1_POL_WIDTH 1 /* GP1_POL */
3238#define WM8915_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
3239#define WM8915_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
3240#define WM8915_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
3241#define WM8915_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
3242#define WM8915_GP1_DB 0x0100 /* GP1_DB */
3243#define WM8915_GP1_DB_MASK 0x0100 /* GP1_DB */
3244#define WM8915_GP1_DB_SHIFT 8 /* GP1_DB */
3245#define WM8915_GP1_DB_WIDTH 1 /* GP1_DB */
3246#define WM8915_GP1_LVL 0x0040 /* GP1_LVL */
3247#define WM8915_GP1_LVL_MASK 0x0040 /* GP1_LVL */
3248#define WM8915_GP1_LVL_SHIFT 6 /* GP1_LVL */
3249#define WM8915_GP1_LVL_WIDTH 1 /* GP1_LVL */
3250#define WM8915_GP1_FN_MASK 0x000F /* GP1_FN - [3:0] */
3251#define WM8915_GP1_FN_SHIFT 0 /* GP1_FN - [3:0] */
3252#define WM8915_GP1_FN_WIDTH 4 /* GP1_FN - [3:0] */
3253
3254/*
3255 * R1793 (0x701) - GPIO 2
3256 */
3257#define WM8915_GP2_DIR 0x8000 /* GP2_DIR */
3258#define WM8915_GP2_DIR_MASK 0x8000 /* GP2_DIR */
3259#define WM8915_GP2_DIR_SHIFT 15 /* GP2_DIR */
3260#define WM8915_GP2_DIR_WIDTH 1 /* GP2_DIR */
3261#define WM8915_GP2_PU 0x4000 /* GP2_PU */
3262#define WM8915_GP2_PU_MASK 0x4000 /* GP2_PU */
3263#define WM8915_GP2_PU_SHIFT 14 /* GP2_PU */
3264#define WM8915_GP2_PU_WIDTH 1 /* GP2_PU */
3265#define WM8915_GP2_PD 0x2000 /* GP2_PD */
3266#define WM8915_GP2_PD_MASK 0x2000 /* GP2_PD */
3267#define WM8915_GP2_PD_SHIFT 13 /* GP2_PD */
3268#define WM8915_GP2_PD_WIDTH 1 /* GP2_PD */
3269#define WM8915_GP2_POL 0x0400 /* GP2_POL */
3270#define WM8915_GP2_POL_MASK 0x0400 /* GP2_POL */
3271#define WM8915_GP2_POL_SHIFT 10 /* GP2_POL */
3272#define WM8915_GP2_POL_WIDTH 1 /* GP2_POL */
3273#define WM8915_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
3274#define WM8915_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
3275#define WM8915_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
3276#define WM8915_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
3277#define WM8915_GP2_DB 0x0100 /* GP2_DB */
3278#define WM8915_GP2_DB_MASK 0x0100 /* GP2_DB */
3279#define WM8915_GP2_DB_SHIFT 8 /* GP2_DB */
3280#define WM8915_GP2_DB_WIDTH 1 /* GP2_DB */
3281#define WM8915_GP2_LVL 0x0040 /* GP2_LVL */
3282#define WM8915_GP2_LVL_MASK 0x0040 /* GP2_LVL */
3283#define WM8915_GP2_LVL_SHIFT 6 /* GP2_LVL */
3284#define WM8915_GP2_LVL_WIDTH 1 /* GP2_LVL */
3285#define WM8915_GP2_FN_MASK 0x000F /* GP2_FN - [3:0] */
3286#define WM8915_GP2_FN_SHIFT 0 /* GP2_FN - [3:0] */
3287#define WM8915_GP2_FN_WIDTH 4 /* GP2_FN - [3:0] */
3288
3289/*
3290 * R1794 (0x702) - GPIO 3
3291 */
3292#define WM8915_GP3_DIR 0x8000 /* GP3_DIR */
3293#define WM8915_GP3_DIR_MASK 0x8000 /* GP3_DIR */
3294#define WM8915_GP3_DIR_SHIFT 15 /* GP3_DIR */
3295#define WM8915_GP3_DIR_WIDTH 1 /* GP3_DIR */
3296#define WM8915_GP3_PU 0x4000 /* GP3_PU */
3297#define WM8915_GP3_PU_MASK 0x4000 /* GP3_PU */
3298#define WM8915_GP3_PU_SHIFT 14 /* GP3_PU */
3299#define WM8915_GP3_PU_WIDTH 1 /* GP3_PU */
3300#define WM8915_GP3_PD 0x2000 /* GP3_PD */
3301#define WM8915_GP3_PD_MASK 0x2000 /* GP3_PD */
3302#define WM8915_GP3_PD_SHIFT 13 /* GP3_PD */
3303#define WM8915_GP3_PD_WIDTH 1 /* GP3_PD */
3304#define WM8915_GP3_POL 0x0400 /* GP3_POL */
3305#define WM8915_GP3_POL_MASK 0x0400 /* GP3_POL */
3306#define WM8915_GP3_POL_SHIFT 10 /* GP3_POL */
3307#define WM8915_GP3_POL_WIDTH 1 /* GP3_POL */
3308#define WM8915_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
3309#define WM8915_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
3310#define WM8915_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
3311#define WM8915_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
3312#define WM8915_GP3_DB 0x0100 /* GP3_DB */
3313#define WM8915_GP3_DB_MASK 0x0100 /* GP3_DB */
3314#define WM8915_GP3_DB_SHIFT 8 /* GP3_DB */
3315#define WM8915_GP3_DB_WIDTH 1 /* GP3_DB */
3316#define WM8915_GP3_LVL 0x0040 /* GP3_LVL */
3317#define WM8915_GP3_LVL_MASK 0x0040 /* GP3_LVL */
3318#define WM8915_GP3_LVL_SHIFT 6 /* GP3_LVL */
3319#define WM8915_GP3_LVL_WIDTH 1 /* GP3_LVL */
3320#define WM8915_GP3_FN_MASK 0x000F /* GP3_FN - [3:0] */
3321#define WM8915_GP3_FN_SHIFT 0 /* GP3_FN - [3:0] */
3322#define WM8915_GP3_FN_WIDTH 4 /* GP3_FN - [3:0] */
3323
3324/*
3325 * R1795 (0x703) - GPIO 4
3326 */
3327#define WM8915_GP4_DIR 0x8000 /* GP4_DIR */
3328#define WM8915_GP4_DIR_MASK 0x8000 /* GP4_DIR */
3329#define WM8915_GP4_DIR_SHIFT 15 /* GP4_DIR */
3330#define WM8915_GP4_DIR_WIDTH 1 /* GP4_DIR */
3331#define WM8915_GP4_PU 0x4000 /* GP4_PU */
3332#define WM8915_GP4_PU_MASK 0x4000 /* GP4_PU */
3333#define WM8915_GP4_PU_SHIFT 14 /* GP4_PU */
3334#define WM8915_GP4_PU_WIDTH 1 /* GP4_PU */
3335#define WM8915_GP4_PD 0x2000 /* GP4_PD */
3336#define WM8915_GP4_PD_MASK 0x2000 /* GP4_PD */
3337#define WM8915_GP4_PD_SHIFT 13 /* GP4_PD */
3338#define WM8915_GP4_PD_WIDTH 1 /* GP4_PD */
3339#define WM8915_GP4_POL 0x0400 /* GP4_POL */
3340#define WM8915_GP4_POL_MASK 0x0400 /* GP4_POL */
3341#define WM8915_GP4_POL_SHIFT 10 /* GP4_POL */
3342#define WM8915_GP4_POL_WIDTH 1 /* GP4_POL */
3343#define WM8915_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
3344#define WM8915_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
3345#define WM8915_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
3346#define WM8915_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
3347#define WM8915_GP4_DB 0x0100 /* GP4_DB */
3348#define WM8915_GP4_DB_MASK 0x0100 /* GP4_DB */
3349#define WM8915_GP4_DB_SHIFT 8 /* GP4_DB */
3350#define WM8915_GP4_DB_WIDTH 1 /* GP4_DB */
3351#define WM8915_GP4_LVL 0x0040 /* GP4_LVL */
3352#define WM8915_GP4_LVL_MASK 0x0040 /* GP4_LVL */
3353#define WM8915_GP4_LVL_SHIFT 6 /* GP4_LVL */
3354#define WM8915_GP4_LVL_WIDTH 1 /* GP4_LVL */
3355#define WM8915_GP4_FN_MASK 0x000F /* GP4_FN - [3:0] */
3356#define WM8915_GP4_FN_SHIFT 0 /* GP4_FN - [3:0] */
3357#define WM8915_GP4_FN_WIDTH 4 /* GP4_FN - [3:0] */
3358
3359/*
3360 * R1796 (0x704) - GPIO 5
3361 */
3362#define WM8915_GP5_DIR 0x8000 /* GP5_DIR */
3363#define WM8915_GP5_DIR_MASK 0x8000 /* GP5_DIR */
3364#define WM8915_GP5_DIR_SHIFT 15 /* GP5_DIR */
3365#define WM8915_GP5_DIR_WIDTH 1 /* GP5_DIR */
3366#define WM8915_GP5_PU 0x4000 /* GP5_PU */
3367#define WM8915_GP5_PU_MASK 0x4000 /* GP5_PU */
3368#define WM8915_GP5_PU_SHIFT 14 /* GP5_PU */
3369#define WM8915_GP5_PU_WIDTH 1 /* GP5_PU */
3370#define WM8915_GP5_PD 0x2000 /* GP5_PD */
3371#define WM8915_GP5_PD_MASK 0x2000 /* GP5_PD */
3372#define WM8915_GP5_PD_SHIFT 13 /* GP5_PD */
3373#define WM8915_GP5_PD_WIDTH 1 /* GP5_PD */
3374#define WM8915_GP5_POL 0x0400 /* GP5_POL */
3375#define WM8915_GP5_POL_MASK 0x0400 /* GP5_POL */
3376#define WM8915_GP5_POL_SHIFT 10 /* GP5_POL */
3377#define WM8915_GP5_POL_WIDTH 1 /* GP5_POL */
3378#define WM8915_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
3379#define WM8915_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
3380#define WM8915_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
3381#define WM8915_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
3382#define WM8915_GP5_DB 0x0100 /* GP5_DB */
3383#define WM8915_GP5_DB_MASK 0x0100 /* GP5_DB */
3384#define WM8915_GP5_DB_SHIFT 8 /* GP5_DB */
3385#define WM8915_GP5_DB_WIDTH 1 /* GP5_DB */
3386#define WM8915_GP5_LVL 0x0040 /* GP5_LVL */
3387#define WM8915_GP5_LVL_MASK 0x0040 /* GP5_LVL */
3388#define WM8915_GP5_LVL_SHIFT 6 /* GP5_LVL */
3389#define WM8915_GP5_LVL_WIDTH 1 /* GP5_LVL */
3390#define WM8915_GP5_FN_MASK 0x000F /* GP5_FN - [3:0] */
3391#define WM8915_GP5_FN_SHIFT 0 /* GP5_FN - [3:0] */
3392#define WM8915_GP5_FN_WIDTH 4 /* GP5_FN - [3:0] */
3393
3394/*
3395 * R1824 (0x720) - Pull Control (1)
3396 */
3397#define WM8915_DMICDAT2_PD 0x1000 /* DMICDAT2_PD */
3398#define WM8915_DMICDAT2_PD_MASK 0x1000 /* DMICDAT2_PD */
3399#define WM8915_DMICDAT2_PD_SHIFT 12 /* DMICDAT2_PD */
3400#define WM8915_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
3401#define WM8915_DMICDAT1_PD 0x0400 /* DMICDAT1_PD */
3402#define WM8915_DMICDAT1_PD_MASK 0x0400 /* DMICDAT1_PD */
3403#define WM8915_DMICDAT1_PD_SHIFT 10 /* DMICDAT1_PD */
3404#define WM8915_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
3405#define WM8915_MCLK2_PU 0x0200 /* MCLK2_PU */
3406#define WM8915_MCLK2_PU_MASK 0x0200 /* MCLK2_PU */
3407#define WM8915_MCLK2_PU_SHIFT 9 /* MCLK2_PU */
3408#define WM8915_MCLK2_PU_WIDTH 1 /* MCLK2_PU */
3409#define WM8915_MCLK2_PD 0x0100 /* MCLK2_PD */
3410#define WM8915_MCLK2_PD_MASK 0x0100 /* MCLK2_PD */
3411#define WM8915_MCLK2_PD_SHIFT 8 /* MCLK2_PD */
3412#define WM8915_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
3413#define WM8915_MCLK1_PU 0x0080 /* MCLK1_PU */
3414#define WM8915_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */
3415#define WM8915_MCLK1_PU_SHIFT 7 /* MCLK1_PU */
3416#define WM8915_MCLK1_PU_WIDTH 1 /* MCLK1_PU */
3417#define WM8915_MCLK1_PD 0x0040 /* MCLK1_PD */
3418#define WM8915_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */
3419#define WM8915_MCLK1_PD_SHIFT 6 /* MCLK1_PD */
3420#define WM8915_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
3421#define WM8915_DACDAT1_PU 0x0020 /* DACDAT1_PU */
3422#define WM8915_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */
3423#define WM8915_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */
3424#define WM8915_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
3425#define WM8915_DACDAT1_PD 0x0010 /* DACDAT1_PD */
3426#define WM8915_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */
3427#define WM8915_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */
3428#define WM8915_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
3429#define WM8915_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */
3430#define WM8915_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */
3431#define WM8915_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */
3432#define WM8915_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
3433#define WM8915_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */
3434#define WM8915_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */
3435#define WM8915_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */
3436#define WM8915_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
3437#define WM8915_BCLK1_PU 0x0002 /* BCLK1_PU */
3438#define WM8915_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */
3439#define WM8915_BCLK1_PU_SHIFT 1 /* BCLK1_PU */
3440#define WM8915_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
3441#define WM8915_BCLK1_PD 0x0001 /* BCLK1_PD */
3442#define WM8915_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */
3443#define WM8915_BCLK1_PD_SHIFT 0 /* BCLK1_PD */
3444#define WM8915_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
3445
3446/*
3447 * R1825 (0x721) - Pull Control (2)
3448 */
3449#define WM8915_LDO1ENA_PD 0x0100 /* LDO1ENA_PD */
3450#define WM8915_LDO1ENA_PD_MASK 0x0100 /* LDO1ENA_PD */
3451#define WM8915_LDO1ENA_PD_SHIFT 8 /* LDO1ENA_PD */
3452#define WM8915_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
3453#define WM8915_ADDR_PD 0x0040 /* ADDR_PD */
3454#define WM8915_ADDR_PD_MASK 0x0040 /* ADDR_PD */
3455#define WM8915_ADDR_PD_SHIFT 6 /* ADDR_PD */
3456#define WM8915_ADDR_PD_WIDTH 1 /* ADDR_PD */
3457#define WM8915_DACDAT2_PU 0x0020 /* DACDAT2_PU */
3458#define WM8915_DACDAT2_PU_MASK 0x0020 /* DACDAT2_PU */
3459#define WM8915_DACDAT2_PU_SHIFT 5 /* DACDAT2_PU */
3460#define WM8915_DACDAT2_PU_WIDTH 1 /* DACDAT2_PU */
3461#define WM8915_DACDAT2_PD 0x0010 /* DACDAT2_PD */
3462#define WM8915_DACDAT2_PD_MASK 0x0010 /* DACDAT2_PD */
3463#define WM8915_DACDAT2_PD_SHIFT 4 /* DACDAT2_PD */
3464#define WM8915_DACDAT2_PD_WIDTH 1 /* DACDAT2_PD */
3465#define WM8915_DACLRCLK2_PU 0x0008 /* DACLRCLK2_PU */
3466#define WM8915_DACLRCLK2_PU_MASK 0x0008 /* DACLRCLK2_PU */
3467#define WM8915_DACLRCLK2_PU_SHIFT 3 /* DACLRCLK2_PU */
3468#define WM8915_DACLRCLK2_PU_WIDTH 1 /* DACLRCLK2_PU */
3469#define WM8915_DACLRCLK2_PD 0x0004 /* DACLRCLK2_PD */
3470#define WM8915_DACLRCLK2_PD_MASK 0x0004 /* DACLRCLK2_PD */
3471#define WM8915_DACLRCLK2_PD_SHIFT 2 /* DACLRCLK2_PD */
3472#define WM8915_DACLRCLK2_PD_WIDTH 1 /* DACLRCLK2_PD */
3473#define WM8915_BCLK2_PU 0x0002 /* BCLK2_PU */
3474#define WM8915_BCLK2_PU_MASK 0x0002 /* BCLK2_PU */
3475#define WM8915_BCLK2_PU_SHIFT 1 /* BCLK2_PU */
3476#define WM8915_BCLK2_PU_WIDTH 1 /* BCLK2_PU */
3477#define WM8915_BCLK2_PD 0x0001 /* BCLK2_PD */
3478#define WM8915_BCLK2_PD_MASK 0x0001 /* BCLK2_PD */
3479#define WM8915_BCLK2_PD_SHIFT 0 /* BCLK2_PD */
3480#define WM8915_BCLK2_PD_WIDTH 1 /* BCLK2_PD */
3481
3482/*
3483 * R1840 (0x730) - Interrupt Status 1
3484 */
3485#define WM8915_GP5_EINT 0x0010 /* GP5_EINT */
3486#define WM8915_GP5_EINT_MASK 0x0010 /* GP5_EINT */
3487#define WM8915_GP5_EINT_SHIFT 4 /* GP5_EINT */
3488#define WM8915_GP5_EINT_WIDTH 1 /* GP5_EINT */
3489#define WM8915_GP4_EINT 0x0008 /* GP4_EINT */
3490#define WM8915_GP4_EINT_MASK 0x0008 /* GP4_EINT */
3491#define WM8915_GP4_EINT_SHIFT 3 /* GP4_EINT */
3492#define WM8915_GP4_EINT_WIDTH 1 /* GP4_EINT */
3493#define WM8915_GP3_EINT 0x0004 /* GP3_EINT */
3494#define WM8915_GP3_EINT_MASK 0x0004 /* GP3_EINT */
3495#define WM8915_GP3_EINT_SHIFT 2 /* GP3_EINT */
3496#define WM8915_GP3_EINT_WIDTH 1 /* GP3_EINT */
3497#define WM8915_GP2_EINT 0x0002 /* GP2_EINT */
3498#define WM8915_GP2_EINT_MASK 0x0002 /* GP2_EINT */
3499#define WM8915_GP2_EINT_SHIFT 1 /* GP2_EINT */
3500#define WM8915_GP2_EINT_WIDTH 1 /* GP2_EINT */
3501#define WM8915_GP1_EINT 0x0001 /* GP1_EINT */
3502#define WM8915_GP1_EINT_MASK 0x0001 /* GP1_EINT */
3503#define WM8915_GP1_EINT_SHIFT 0 /* GP1_EINT */
3504#define WM8915_GP1_EINT_WIDTH 1 /* GP1_EINT */
3505
3506/*
3507 * R1841 (0x731) - Interrupt Status 2
3508 */
3509#define WM8915_DCS_DONE_23_EINT 0x1000 /* DCS_DONE_23_EINT */
3510#define WM8915_DCS_DONE_23_EINT_MASK 0x1000 /* DCS_DONE_23_EINT */
3511#define WM8915_DCS_DONE_23_EINT_SHIFT 12 /* DCS_DONE_23_EINT */
3512#define WM8915_DCS_DONE_23_EINT_WIDTH 1 /* DCS_DONE_23_EINT */
3513#define WM8915_DCS_DONE_01_EINT 0x0800 /* DCS_DONE_01_EINT */
3514#define WM8915_DCS_DONE_01_EINT_MASK 0x0800 /* DCS_DONE_01_EINT */
3515#define WM8915_DCS_DONE_01_EINT_SHIFT 11 /* DCS_DONE_01_EINT */
3516#define WM8915_DCS_DONE_01_EINT_WIDTH 1 /* DCS_DONE_01_EINT */
3517#define WM8915_WSEQ_DONE_EINT 0x0400 /* WSEQ_DONE_EINT */
3518#define WM8915_WSEQ_DONE_EINT_MASK 0x0400 /* WSEQ_DONE_EINT */
3519#define WM8915_WSEQ_DONE_EINT_SHIFT 10 /* WSEQ_DONE_EINT */
3520#define WM8915_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
3521#define WM8915_FIFOS_ERR_EINT 0x0200 /* FIFOS_ERR_EINT */
3522#define WM8915_FIFOS_ERR_EINT_MASK 0x0200 /* FIFOS_ERR_EINT */
3523#define WM8915_FIFOS_ERR_EINT_SHIFT 9 /* FIFOS_ERR_EINT */
3524#define WM8915_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
3525#define WM8915_DSP2DRC_SIG_DET_EINT 0x0080 /* DSP2DRC_SIG_DET_EINT */
3526#define WM8915_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* DSP2DRC_SIG_DET_EINT */
3527#define WM8915_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* DSP2DRC_SIG_DET_EINT */
3528#define WM8915_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* DSP2DRC_SIG_DET_EINT */
3529#define WM8915_DSP1DRC_SIG_DET_EINT 0x0040 /* DSP1DRC_SIG_DET_EINT */
3530#define WM8915_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* DSP1DRC_SIG_DET_EINT */
3531#define WM8915_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* DSP1DRC_SIG_DET_EINT */
3532#define WM8915_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* DSP1DRC_SIG_DET_EINT */
3533#define WM8915_FLL_SW_CLK_DONE_EINT 0x0008 /* FLL_SW_CLK_DONE_EINT */
3534#define WM8915_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* FLL_SW_CLK_DONE_EINT */
3535#define WM8915_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* FLL_SW_CLK_DONE_EINT */
3536#define WM8915_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* FLL_SW_CLK_DONE_EINT */
3537#define WM8915_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */
3538#define WM8915_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */
3539#define WM8915_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */
3540#define WM8915_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
3541#define WM8915_HP_DONE_EINT 0x0002 /* HP_DONE_EINT */
3542#define WM8915_HP_DONE_EINT_MASK 0x0002 /* HP_DONE_EINT */
3543#define WM8915_HP_DONE_EINT_SHIFT 1 /* HP_DONE_EINT */
3544#define WM8915_HP_DONE_EINT_WIDTH 1 /* HP_DONE_EINT */
3545#define WM8915_MICD_EINT 0x0001 /* MICD_EINT */
3546#define WM8915_MICD_EINT_MASK 0x0001 /* MICD_EINT */
3547#define WM8915_MICD_EINT_SHIFT 0 /* MICD_EINT */
3548#define WM8915_MICD_EINT_WIDTH 1 /* MICD_EINT */
3549
3550/*
3551 * R1842 (0x732) - Interrupt Raw Status 2
3552 */
3553#define WM8915_DCS_DONE_23_STS 0x1000 /* DCS_DONE_23_STS */
3554#define WM8915_DCS_DONE_23_STS_MASK 0x1000 /* DCS_DONE_23_STS */
3555#define WM8915_DCS_DONE_23_STS_SHIFT 12 /* DCS_DONE_23_STS */
3556#define WM8915_DCS_DONE_23_STS_WIDTH 1 /* DCS_DONE_23_STS */
3557#define WM8915_DCS_DONE_01_STS 0x0800 /* DCS_DONE_01_STS */
3558#define WM8915_DCS_DONE_01_STS_MASK 0x0800 /* DCS_DONE_01_STS */
3559#define WM8915_DCS_DONE_01_STS_SHIFT 11 /* DCS_DONE_01_STS */
3560#define WM8915_DCS_DONE_01_STS_WIDTH 1 /* DCS_DONE_01_STS */
3561#define WM8915_WSEQ_DONE_STS 0x0400 /* WSEQ_DONE_STS */
3562#define WM8915_WSEQ_DONE_STS_MASK 0x0400 /* WSEQ_DONE_STS */
3563#define WM8915_WSEQ_DONE_STS_SHIFT 10 /* WSEQ_DONE_STS */
3564#define WM8915_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */
3565#define WM8915_FIFOS_ERR_STS 0x0200 /* FIFOS_ERR_STS */
3566#define WM8915_FIFOS_ERR_STS_MASK 0x0200 /* FIFOS_ERR_STS */
3567#define WM8915_FIFOS_ERR_STS_SHIFT 9 /* FIFOS_ERR_STS */
3568#define WM8915_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */
3569#define WM8915_DSP2DRC_SIG_DET_STS 0x0080 /* DSP2DRC_SIG_DET_STS */
3570#define WM8915_DSP2DRC_SIG_DET_STS_MASK 0x0080 /* DSP2DRC_SIG_DET_STS */
3571#define WM8915_DSP2DRC_SIG_DET_STS_SHIFT 7 /* DSP2DRC_SIG_DET_STS */
3572#define WM8915_DSP2DRC_SIG_DET_STS_WIDTH 1 /* DSP2DRC_SIG_DET_STS */
3573#define WM8915_DSP1DRC_SIG_DET_STS 0x0040 /* DSP1DRC_SIG_DET_STS */
3574#define WM8915_DSP1DRC_SIG_DET_STS_MASK 0x0040 /* DSP1DRC_SIG_DET_STS */
3575#define WM8915_DSP1DRC_SIG_DET_STS_SHIFT 6 /* DSP1DRC_SIG_DET_STS */
3576#define WM8915_DSP1DRC_SIG_DET_STS_WIDTH 1 /* DSP1DRC_SIG_DET_STS */
3577#define WM8915_FLL_LOCK_STS 0x0004 /* FLL_LOCK_STS */
3578#define WM8915_FLL_LOCK_STS_MASK 0x0004 /* FLL_LOCK_STS */
3579#define WM8915_FLL_LOCK_STS_SHIFT 2 /* FLL_LOCK_STS */
3580#define WM8915_FLL_LOCK_STS_WIDTH 1 /* FLL_LOCK_STS */
3581
3582/*
3583 * R1848 (0x738) - Interrupt Status 1 Mask
3584 */
3585#define WM8915_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
3586#define WM8915_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
3587#define WM8915_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
3588#define WM8915_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
3589#define WM8915_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
3590#define WM8915_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
3591#define WM8915_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
3592#define WM8915_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
3593#define WM8915_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
3594#define WM8915_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
3595#define WM8915_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
3596#define WM8915_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
3597#define WM8915_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
3598#define WM8915_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
3599#define WM8915_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
3600#define WM8915_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
3601#define WM8915_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
3602#define WM8915_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
3603#define WM8915_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
3604#define WM8915_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
3605
3606/*
3607 * R1849 (0x739) - Interrupt Status 2 Mask
3608 */
3609#define WM8915_IM_DCS_DONE_23_EINT 0x1000 /* IM_DCS_DONE_23_EINT */
3610#define WM8915_IM_DCS_DONE_23_EINT_MASK 0x1000 /* IM_DCS_DONE_23_EINT */
3611#define WM8915_IM_DCS_DONE_23_EINT_SHIFT 12 /* IM_DCS_DONE_23_EINT */
3612#define WM8915_IM_DCS_DONE_23_EINT_WIDTH 1 /* IM_DCS_DONE_23_EINT */
3613#define WM8915_IM_DCS_DONE_01_EINT 0x0800 /* IM_DCS_DONE_01_EINT */
3614#define WM8915_IM_DCS_DONE_01_EINT_MASK 0x0800 /* IM_DCS_DONE_01_EINT */
3615#define WM8915_IM_DCS_DONE_01_EINT_SHIFT 11 /* IM_DCS_DONE_01_EINT */
3616#define WM8915_IM_DCS_DONE_01_EINT_WIDTH 1 /* IM_DCS_DONE_01_EINT */
3617#define WM8915_IM_WSEQ_DONE_EINT 0x0400 /* IM_WSEQ_DONE_EINT */
3618#define WM8915_IM_WSEQ_DONE_EINT_MASK 0x0400 /* IM_WSEQ_DONE_EINT */
3619#define WM8915_IM_WSEQ_DONE_EINT_SHIFT 10 /* IM_WSEQ_DONE_EINT */
3620#define WM8915_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
3621#define WM8915_IM_FIFOS_ERR_EINT 0x0200 /* IM_FIFOS_ERR_EINT */
3622#define WM8915_IM_FIFOS_ERR_EINT_MASK 0x0200 /* IM_FIFOS_ERR_EINT */
3623#define WM8915_IM_FIFOS_ERR_EINT_SHIFT 9 /* IM_FIFOS_ERR_EINT */
3624#define WM8915_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
3625#define WM8915_IM_DSP2DRC_SIG_DET_EINT 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */
3626#define WM8915_IM_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */
3627#define WM8915_IM_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* IM_DSP2DRC_SIG_DET_EINT */
3628#define WM8915_IM_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP2DRC_SIG_DET_EINT */
3629#define WM8915_IM_DSP1DRC_SIG_DET_EINT 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */
3630#define WM8915_IM_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */
3631#define WM8915_IM_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* IM_DSP1DRC_SIG_DET_EINT */
3632#define WM8915_IM_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP1DRC_SIG_DET_EINT */
3633#define WM8915_IM_FLL_SW_CLK_DONE_EINT 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */
3634#define WM8915_IM_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */
3635#define WM8915_IM_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* IM_FLL_SW_CLK_DONE_EINT */
3636#define WM8915_IM_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* IM_FLL_SW_CLK_DONE_EINT */
3637#define WM8915_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */
3638#define WM8915_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */
3639#define WM8915_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */
3640#define WM8915_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
3641#define WM8915_IM_HP_DONE_EINT 0x0002 /* IM_HP_DONE_EINT */
3642#define WM8915_IM_HP_DONE_EINT_MASK 0x0002 /* IM_HP_DONE_EINT */
3643#define WM8915_IM_HP_DONE_EINT_SHIFT 1 /* IM_HP_DONE_EINT */
3644#define WM8915_IM_HP_DONE_EINT_WIDTH 1 /* IM_HP_DONE_EINT */
3645#define WM8915_IM_MICD_EINT 0x0001 /* IM_MICD_EINT */
3646#define WM8915_IM_MICD_EINT_MASK 0x0001 /* IM_MICD_EINT */
3647#define WM8915_IM_MICD_EINT_SHIFT 0 /* IM_MICD_EINT */
3648#define WM8915_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */
3649
3650/*
3651 * R1856 (0x740) - Interrupt Control
3652 */
3653#define WM8915_IM_IRQ 0x0001 /* IM_IRQ */
3654#define WM8915_IM_IRQ_MASK 0x0001 /* IM_IRQ */
3655#define WM8915_IM_IRQ_SHIFT 0 /* IM_IRQ */
3656#define WM8915_IM_IRQ_WIDTH 1 /* IM_IRQ */
3657
3658/*
3659 * R2048 (0x800) - Left PDM Speaker
3660 */
3661#define WM8915_SPKL_ENA 0x0010 /* SPKL_ENA */
3662#define WM8915_SPKL_ENA_MASK 0x0010 /* SPKL_ENA */
3663#define WM8915_SPKL_ENA_SHIFT 4 /* SPKL_ENA */
3664#define WM8915_SPKL_ENA_WIDTH 1 /* SPKL_ENA */
3665#define WM8915_SPKL_MUTE 0x0008 /* SPKL_MUTE */
3666#define WM8915_SPKL_MUTE_MASK 0x0008 /* SPKL_MUTE */
3667#define WM8915_SPKL_MUTE_SHIFT 3 /* SPKL_MUTE */
3668#define WM8915_SPKL_MUTE_WIDTH 1 /* SPKL_MUTE */
3669#define WM8915_SPKL_MUTE_ZC 0x0004 /* SPKL_MUTE_ZC */
3670#define WM8915_SPKL_MUTE_ZC_MASK 0x0004 /* SPKL_MUTE_ZC */
3671#define WM8915_SPKL_MUTE_ZC_SHIFT 2 /* SPKL_MUTE_ZC */
3672#define WM8915_SPKL_MUTE_ZC_WIDTH 1 /* SPKL_MUTE_ZC */
3673#define WM8915_SPKL_SRC_MASK 0x0003 /* SPKL_SRC - [1:0] */
3674#define WM8915_SPKL_SRC_SHIFT 0 /* SPKL_SRC - [1:0] */
3675#define WM8915_SPKL_SRC_WIDTH 2 /* SPKL_SRC - [1:0] */
3676
3677/*
3678 * R2049 (0x801) - Right PDM Speaker
3679 */
3680#define WM8915_SPKR_ENA 0x0010 /* SPKR_ENA */
3681#define WM8915_SPKR_ENA_MASK 0x0010 /* SPKR_ENA */
3682#define WM8915_SPKR_ENA_SHIFT 4 /* SPKR_ENA */
3683#define WM8915_SPKR_ENA_WIDTH 1 /* SPKR_ENA */
3684#define WM8915_SPKR_MUTE 0x0008 /* SPKR_MUTE */
3685#define WM8915_SPKR_MUTE_MASK 0x0008 /* SPKR_MUTE */
3686#define WM8915_SPKR_MUTE_SHIFT 3 /* SPKR_MUTE */
3687#define WM8915_SPKR_MUTE_WIDTH 1 /* SPKR_MUTE */
3688#define WM8915_SPKR_MUTE_ZC 0x0004 /* SPKR_MUTE_ZC */
3689#define WM8915_SPKR_MUTE_ZC_MASK 0x0004 /* SPKR_MUTE_ZC */
3690#define WM8915_SPKR_MUTE_ZC_SHIFT 2 /* SPKR_MUTE_ZC */
3691#define WM8915_SPKR_MUTE_ZC_WIDTH 1 /* SPKR_MUTE_ZC */
3692#define WM8915_SPKR_SRC_MASK 0x0003 /* SPKR_SRC - [1:0] */
3693#define WM8915_SPKR_SRC_SHIFT 0 /* SPKR_SRC - [1:0] */
3694#define WM8915_SPKR_SRC_WIDTH 2 /* SPKR_SRC - [1:0] */
3695
3696/*
3697 * R2050 (0x802) - PDM Speaker Mute Sequence
3698 */
3699#define WM8915_SPK_MUTE_ENDIAN 0x0100 /* SPK_MUTE_ENDIAN */
3700#define WM8915_SPK_MUTE_ENDIAN_MASK 0x0100 /* SPK_MUTE_ENDIAN */
3701#define WM8915_SPK_MUTE_ENDIAN_SHIFT 8 /* SPK_MUTE_ENDIAN */
3702#define WM8915_SPK_MUTE_ENDIAN_WIDTH 1 /* SPK_MUTE_ENDIAN */
3703#define WM8915_SPK_MUTE_SEQ1_MASK 0x00FF /* SPK_MUTE_SEQ1 - [7:0] */
3704#define WM8915_SPK_MUTE_SEQ1_SHIFT 0 /* SPK_MUTE_SEQ1 - [7:0] */
3705#define WM8915_SPK_MUTE_SEQ1_WIDTH 8 /* SPK_MUTE_SEQ1 - [7:0] */
3706
3707/*
3708 * R2051 (0x803) - PDM Speaker Volume
3709 */
3710#define WM8915_SPKR_VOL_MASK 0x00F0 /* SPKR_VOL - [7:4] */
3711#define WM8915_SPKR_VOL_SHIFT 4 /* SPKR_VOL - [7:4] */
3712#define WM8915_SPKR_VOL_WIDTH 4 /* SPKR_VOL - [7:4] */
3713#define WM8915_SPKL_VOL_MASK 0x000F /* SPKL_VOL - [3:0] */
3714#define WM8915_SPKL_VOL_SHIFT 0 /* SPKL_VOL - [3:0] */
3715#define WM8915_SPKL_VOL_WIDTH 4 /* SPKL_VOL - [3:0] */
3716
3717#endif
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
new file mode 100644
index 000000000000..0293763debe5
--- /dev/null
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -0,0 +1,1051 @@
1/*
2 * wm8958-dsp2.c -- WM8958 DSP2 support
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/platform_device.h>
20#include <linux/slab.h>
21#include <sound/soc.h>
22#include <sound/initval.h>
23#include <sound/tlv.h>
24#include <trace/events/asoc.h>
25
26#include <linux/mfd/wm8994/core.h>
27#include <linux/mfd/wm8994/registers.h>
28#include <linux/mfd/wm8994/pdata.h>
29#include <linux/mfd/wm8994/gpio.h>
30
31#include "wm8994.h"
32
33#define WM_FW_BLOCK_INFO 0xff
34#define WM_FW_BLOCK_PM 0x00
35#define WM_FW_BLOCK_X 0x01
36#define WM_FW_BLOCK_Y 0x02
37#define WM_FW_BLOCK_Z 0x03
38#define WM_FW_BLOCK_I 0x06
39#define WM_FW_BLOCK_A 0x08
40#define WM_FW_BLOCK_C 0x0c
41
42static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
43 const struct firmware *fw, bool check)
44{
45 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
46 u64 data64;
47 u32 data32;
48 const u8 *data;
49 char *str;
50 size_t block_len, len;
51 int ret = 0;
52
53 /* Suppress unneeded downloads */
54 if (wm8994->cur_fw == fw)
55 return 0;
56
57 if (fw->size < 32) {
58 dev_err(codec->dev, "%s: firmware too short\n", name);
59 goto err;
60 }
61
62 if (memcmp(fw->data, "WMFW", 4) != 0) {
63 dev_err(codec->dev, "%s: firmware has bad file magic %08x\n",
64 name, data32);
65 goto err;
66 }
67
68 memcpy(&data32, fw->data + 4, sizeof(data32));
69 len = be32_to_cpu(data32);
70
71 memcpy(&data32, fw->data + 8, sizeof(data32));
72 data32 = be32_to_cpu(data32);
73 if ((data32 >> 24) & 0xff) {
74 dev_err(codec->dev, "%s: unsupported firmware version %d\n",
75 name, (data32 >> 24) & 0xff);
76 goto err;
77 }
78 if ((data32 & 0xffff) != 8958) {
79 dev_err(codec->dev, "%s: unsupported target device %d\n",
80 name, data32 & 0xffff);
81 goto err;
82 }
83 if (((data32 >> 16) & 0xff) != 0xc) {
84 dev_err(codec->dev, "%s: unsupported target core %d\n",
85 name, (data32 >> 16) & 0xff);
86 goto err;
87 }
88
89 if (check) {
90 memcpy(&data64, fw->data + 24, sizeof(u64));
91 dev_info(codec->dev, "%s timestamp %llx\n",
92 name, be64_to_cpu(data64));
93 } else {
94 snd_soc_write(codec, 0x102, 0x2);
95 snd_soc_write(codec, 0x900, 0x2);
96 }
97
98 data = fw->data + len;
99 len = fw->size - len;
100 while (len) {
101 if (len < 12) {
102 dev_err(codec->dev, "%s short data block of %zd\n",
103 name, len);
104 goto err;
105 }
106
107 memcpy(&data32, data + 4, sizeof(data32));
108 block_len = be32_to_cpu(data32);
109 if (block_len + 8 > len) {
110 dev_err(codec->dev, "%zd byte block longer than file\n",
111 block_len);
112 goto err;
113 }
114 if (block_len == 0) {
115 dev_err(codec->dev, "Zero length block\n");
116 goto err;
117 }
118
119 memcpy(&data32, data, sizeof(data32));
120 data32 = be32_to_cpu(data32);
121
122 switch ((data32 >> 24) & 0xff) {
123 case WM_FW_BLOCK_INFO:
124 /* Informational text */
125 if (!check)
126 break;
127
128 str = kzalloc(block_len + 1, GFP_KERNEL);
129 if (str) {
130 memcpy(str, data + 8, block_len);
131 dev_info(codec->dev, "%s: %s\n", name, str);
132 kfree(str);
133 } else {
134 dev_err(codec->dev, "Out of memory\n");
135 }
136 break;
137 case WM_FW_BLOCK_PM:
138 case WM_FW_BLOCK_X:
139 case WM_FW_BLOCK_Y:
140 case WM_FW_BLOCK_Z:
141 case WM_FW_BLOCK_I:
142 case WM_FW_BLOCK_A:
143 case WM_FW_BLOCK_C:
144 dev_dbg(codec->dev, "%s: %zd bytes of %x@%x\n", name,
145 block_len, (data32 >> 24) & 0xff,
146 data32 & 0xffffff);
147
148 if (check)
149 break;
150
151 data32 &= 0xffffff;
152
153 wm8994_bulk_write(codec->control_data,
154 data32 & 0xffffff,
155 block_len / 2,
156 (void *)(data + 8));
157
158 break;
159 default:
160 dev_warn(codec->dev, "%s: unknown block type %d\n",
161 name, (data32 >> 24) & 0xff);
162 break;
163 }
164
165 /* Round up to the next 32 bit word */
166 block_len += block_len % 4;
167
168 data += block_len + 8;
169 len -= block_len + 8;
170 }
171
172 if (!check) {
173 dev_dbg(codec->dev, "%s: download done\n", name);
174 wm8994->cur_fw = fw;
175 } else {
176 dev_info(codec->dev, "%s: got firmware\n", name);
177 }
178
179 goto ok;
180
181err:
182 ret = -EINVAL;
183ok:
184 if (!check) {
185 snd_soc_write(codec, 0x900, 0x0);
186 snd_soc_write(codec, 0x102, 0x0);
187 }
188
189 return ret;
190}
191
192static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path)
193{
194 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
195 struct wm8994_pdata *pdata = wm8994->pdata;
196 int i;
197
198 /* If the DSP is already running then noop */
199 if (snd_soc_read(codec, WM8958_DSP2_PROGRAM) & WM8958_DSP2_ENA)
200 return;
201
202 /* If we have MBC firmware download it */
203 if (wm8994->mbc)
204 wm8958_dsp2_fw(codec, "MBC", wm8994->mbc, false);
205
206 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
207 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
208
209 /* If we've got user supplied MBC settings use them */
210 if (pdata && pdata->num_mbc_cfgs) {
211 struct wm8958_mbc_cfg *cfg
212 = &pdata->mbc_cfgs[wm8994->mbc_cfg];
213
214 for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++)
215 snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1,
216 cfg->coeff_regs[i]);
217
218 for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++)
219 snd_soc_write(codec,
220 i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1,
221 cfg->cutoff_regs[i]);
222 }
223
224 /* Run the DSP */
225 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
226 WM8958_DSP2_RUNR);
227
228 /* And we're off! */
229 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
230 WM8958_MBC_ENA |
231 WM8958_MBC_SEL_MASK,
232 path << WM8958_MBC_SEL_SHIFT |
233 WM8958_MBC_ENA);
234}
235
236static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path)
237{
238 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
239 struct wm8994_pdata *pdata = wm8994->pdata;
240 int i, ena;
241
242 if (wm8994->mbc_vss)
243 wm8958_dsp2_fw(codec, "MBC+VSS", wm8994->mbc_vss, false);
244
245 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
246 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
247
248 /* If we've got user supplied settings use them */
249 if (pdata && pdata->num_mbc_cfgs) {
250 struct wm8958_mbc_cfg *cfg
251 = &pdata->mbc_cfgs[wm8994->mbc_cfg];
252
253 for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++)
254 snd_soc_write(codec, i + 0x2800,
255 cfg->combined_regs[i]);
256 }
257
258 if (pdata && pdata->num_vss_cfgs) {
259 struct wm8958_vss_cfg *cfg
260 = &pdata->vss_cfgs[wm8994->vss_cfg];
261
262 for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
263 snd_soc_write(codec, i + 0x2600, cfg->regs[i]);
264 }
265
266 if (pdata && pdata->num_vss_hpf_cfgs) {
267 struct wm8958_vss_hpf_cfg *cfg
268 = &pdata->vss_hpf_cfgs[wm8994->vss_hpf_cfg];
269
270 for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
271 snd_soc_write(codec, i + 0x2400, cfg->regs[i]);
272 }
273
274 /* Run the DSP */
275 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
276 WM8958_DSP2_RUNR);
277
278 /* Enable the algorithms we've selected */
279 ena = 0;
280 if (wm8994->mbc_ena[path])
281 ena |= 0x8;
282 if (wm8994->hpf2_ena[path])
283 ena |= 0x4;
284 if (wm8994->hpf1_ena[path])
285 ena |= 0x2;
286 if (wm8994->vss_ena[path])
287 ena |= 0x1;
288
289 snd_soc_write(codec, 0x2201, ena);
290
291 /* Switch the DSP into the data path */
292 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
293 WM8958_MBC_SEL_MASK | WM8958_MBC_ENA,
294 path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA);
295}
296
297static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path)
298{
299 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
300 struct wm8994_pdata *pdata = wm8994->pdata;
301 int i;
302
303 wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false);
304
305 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
306 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
307
308 /* If we've got user supplied settings use them */
309 if (pdata && pdata->num_enh_eq_cfgs) {
310 struct wm8958_enh_eq_cfg *cfg
311 = &pdata->enh_eq_cfgs[wm8994->enh_eq_cfg];
312
313 for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
314 snd_soc_write(codec, i + 0x2200,
315 cfg->regs[i]);
316 }
317
318 /* Run the DSP */
319 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
320 WM8958_DSP2_RUNR);
321
322 /* Switch the DSP into the data path */
323 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
324 WM8958_MBC_SEL_MASK | WM8958_MBC_ENA,
325 path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA);
326}
327
328static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start)
329{
330 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
331 int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5);
332 int ena, reg, aif;
333
334 switch (path) {
335 case 0:
336 pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA);
337 aif = 0;
338 break;
339 case 1:
340 pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
341 aif = 0;
342 break;
343 case 2:
344 pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA);
345 aif = 1;
346 break;
347 default:
348 BUG();
349 return;
350 }
351
352 /* Do we have both an active AIF and an active algorithm? */
353 ena = wm8994->mbc_ena[path] || wm8994->vss_ena[path] ||
354 wm8994->hpf1_ena[path] || wm8994->hpf2_ena[path] ||
355 wm8994->enh_eq_ena[path];
356 if (!pwr_reg)
357 ena = 0;
358
359 reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM);
360
361 dev_dbg(codec->dev, "DSP path %d %d startup: %d, power: %x, DSP: %x\n",
362 path, wm8994->dsp_active, start, pwr_reg, reg);
363
364 if (start && ena) {
365 /* If the DSP is already running then noop */
366 if (reg & WM8958_DSP2_ENA)
367 return;
368
369 /* If either AIFnCLK is not yet enabled postpone */
370 if (!(snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
371 & WM8994_AIF1CLK_ENA_MASK) &&
372 !(snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
373 & WM8994_AIF2CLK_ENA_MASK))
374 return;
375
376 /* Switch the clock over to the appropriate AIF */
377 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
378 WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA,
379 aif << WM8958_DSP2CLK_SRC_SHIFT |
380 WM8958_DSP2CLK_ENA);
381
382 if (wm8994->enh_eq_ena[path])
383 wm8958_dsp_start_enh_eq(codec, path);
384 else if (wm8994->vss_ena[path] || wm8994->hpf1_ena[path] ||
385 wm8994->hpf2_ena[path])
386 wm8958_dsp_start_vss(codec, path);
387 else if (wm8994->mbc_ena[path])
388 wm8958_dsp_start_mbc(codec, path);
389
390 wm8994->dsp_active = path;
391
392 dev_dbg(codec->dev, "DSP running in path %d\n", path);
393 }
394
395 if (!start && wm8994->dsp_active == path) {
396 /* If the DSP is already stopped then noop */
397 if (!(reg & WM8958_DSP2_ENA))
398 return;
399
400 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
401 WM8958_MBC_ENA, 0);
402 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
403 WM8958_DSP2_STOP);
404 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
405 WM8958_DSP2_ENA, 0);
406 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
407 WM8958_DSP2CLK_ENA, 0);
408
409 wm8994->dsp_active = -1;
410
411 dev_dbg(codec->dev, "DSP stopped\n");
412 }
413}
414
415int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
416 struct snd_kcontrol *kcontrol, int event)
417{
418 struct snd_soc_codec *codec = w->codec;
419 int i;
420
421 switch (event) {
422 case SND_SOC_DAPM_POST_PMU:
423 case SND_SOC_DAPM_PRE_PMU:
424 for (i = 0; i < 3; i++)
425 wm8958_dsp_apply(codec, i, 1);
426 break;
427 case SND_SOC_DAPM_POST_PMD:
428 case SND_SOC_DAPM_PRE_PMD:
429 for (i = 0; i < 3; i++)
430 wm8958_dsp_apply(codec, i, 0);
431 break;
432 }
433
434 return 0;
435}
436
437/* Check if DSP2 is in use on another AIF */
438static int wm8958_dsp2_busy(struct wm8994_priv *wm8994, int aif)
439{
440 int i;
441
442 for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) {
443 if (i == aif)
444 continue;
445 if (wm8994->mbc_ena[i] || wm8994->vss_ena[i] ||
446 wm8994->hpf1_ena[i] || wm8994->hpf2_ena[i])
447 return 1;
448 }
449
450 return 0;
451}
452
453static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
454 struct snd_ctl_elem_value *ucontrol)
455{
456 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
457 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
458 struct wm8994_pdata *pdata = wm8994->pdata;
459 int value = ucontrol->value.integer.value[0];
460 int reg;
461
462 /* Don't allow on the fly reconfiguration */
463 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
464 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
465 return -EBUSY;
466
467 if (value >= pdata->num_mbc_cfgs)
468 return -EINVAL;
469
470 wm8994->mbc_cfg = value;
471
472 return 0;
473}
474
475static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol,
476 struct snd_ctl_elem_value *ucontrol)
477{
478 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
479 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
480
481 ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg;
482
483 return 0;
484}
485
486static int wm8958_mbc_info(struct snd_kcontrol *kcontrol,
487 struct snd_ctl_elem_info *uinfo)
488{
489 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
490 uinfo->count = 1;
491 uinfo->value.integer.min = 0;
492 uinfo->value.integer.max = 1;
493 return 0;
494}
495
496static int wm8958_mbc_get(struct snd_kcontrol *kcontrol,
497 struct snd_ctl_elem_value *ucontrol)
498{
499 int mbc = kcontrol->private_value;
500 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
501 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
502
503 ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc];
504
505 return 0;
506}
507
508static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
509 struct snd_ctl_elem_value *ucontrol)
510{
511 int mbc = kcontrol->private_value;
512 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
513 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
514
515 if (wm8994->mbc_ena[mbc] == ucontrol->value.integer.value[0])
516 return 0;
517
518 if (ucontrol->value.integer.value[0] > 1)
519 return -EINVAL;
520
521 if (wm8958_dsp2_busy(wm8994, mbc)) {
522 dev_dbg(codec->dev, "DSP2 active on %d already\n", mbc);
523 return -EBUSY;
524 }
525
526 if (wm8994->enh_eq_ena[mbc])
527 return -EBUSY;
528
529 wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0];
530
531 wm8958_dsp_apply(codec, mbc, wm8994->mbc_ena[mbc]);
532
533 return 0;
534}
535
536#define WM8958_MBC_SWITCH(xname, xval) {\
537 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
538 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
539 .info = wm8958_mbc_info, \
540 .get = wm8958_mbc_get, .put = wm8958_mbc_put, \
541 .private_value = xval }
542
543static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_value *ucontrol)
545{
546 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
547 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
548 struct wm8994_pdata *pdata = wm8994->pdata;
549 int value = ucontrol->value.integer.value[0];
550 int reg;
551
552 /* Don't allow on the fly reconfiguration */
553 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
554 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
555 return -EBUSY;
556
557 if (value >= pdata->num_vss_cfgs)
558 return -EINVAL;
559
560 wm8994->vss_cfg = value;
561
562 return 0;
563}
564
565static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol,
566 struct snd_ctl_elem_value *ucontrol)
567{
568 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
569 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
570
571 ucontrol->value.enumerated.item[0] = wm8994->vss_cfg;
572
573 return 0;
574}
575
576static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol,
577 struct snd_ctl_elem_value *ucontrol)
578{
579 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
580 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
581 struct wm8994_pdata *pdata = wm8994->pdata;
582 int value = ucontrol->value.integer.value[0];
583 int reg;
584
585 /* Don't allow on the fly reconfiguration */
586 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
587 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
588 return -EBUSY;
589
590 if (value >= pdata->num_vss_hpf_cfgs)
591 return -EINVAL;
592
593 wm8994->vss_hpf_cfg = value;
594
595 return 0;
596}
597
598static int wm8958_get_vss_hpf_enum(struct snd_kcontrol *kcontrol,
599 struct snd_ctl_elem_value *ucontrol)
600{
601 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
602 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
603
604 ucontrol->value.enumerated.item[0] = wm8994->vss_hpf_cfg;
605
606 return 0;
607}
608
609static int wm8958_vss_info(struct snd_kcontrol *kcontrol,
610 struct snd_ctl_elem_info *uinfo)
611{
612 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
613 uinfo->count = 1;
614 uinfo->value.integer.min = 0;
615 uinfo->value.integer.max = 1;
616 return 0;
617}
618
619static int wm8958_vss_get(struct snd_kcontrol *kcontrol,
620 struct snd_ctl_elem_value *ucontrol)
621{
622 int vss = kcontrol->private_value;
623 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
624 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
625
626 ucontrol->value.integer.value[0] = wm8994->vss_ena[vss];
627
628 return 0;
629}
630
631static int wm8958_vss_put(struct snd_kcontrol *kcontrol,
632 struct snd_ctl_elem_value *ucontrol)
633{
634 int vss = kcontrol->private_value;
635 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
636 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
637
638 if (wm8994->vss_ena[vss] == ucontrol->value.integer.value[0])
639 return 0;
640
641 if (ucontrol->value.integer.value[0] > 1)
642 return -EINVAL;
643
644 if (!wm8994->mbc_vss)
645 return -ENODEV;
646
647 if (wm8958_dsp2_busy(wm8994, vss)) {
648 dev_dbg(codec->dev, "DSP2 active on %d already\n", vss);
649 return -EBUSY;
650 }
651
652 if (wm8994->enh_eq_ena[vss])
653 return -EBUSY;
654
655 wm8994->vss_ena[vss] = ucontrol->value.integer.value[0];
656
657 wm8958_dsp_apply(codec, vss, wm8994->vss_ena[vss]);
658
659 return 0;
660}
661
662
663#define WM8958_VSS_SWITCH(xname, xval) {\
664 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
665 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
666 .info = wm8958_vss_info, \
667 .get = wm8958_vss_get, .put = wm8958_vss_put, \
668 .private_value = xval }
669
670static int wm8958_hpf_info(struct snd_kcontrol *kcontrol,
671 struct snd_ctl_elem_info *uinfo)
672{
673 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
674 uinfo->count = 1;
675 uinfo->value.integer.min = 0;
676 uinfo->value.integer.max = 1;
677 return 0;
678}
679
680static int wm8958_hpf_get(struct snd_kcontrol *kcontrol,
681 struct snd_ctl_elem_value *ucontrol)
682{
683 int hpf = kcontrol->private_value;
684 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
685 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
686
687 if (hpf < 3)
688 ucontrol->value.integer.value[0] = wm8994->hpf1_ena[hpf % 3];
689 else
690 ucontrol->value.integer.value[0] = wm8994->hpf2_ena[hpf % 3];
691
692 return 0;
693}
694
695static int wm8958_hpf_put(struct snd_kcontrol *kcontrol,
696 struct snd_ctl_elem_value *ucontrol)
697{
698 int hpf = kcontrol->private_value;
699 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
700 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
701
702 if (hpf < 3) {
703 if (wm8994->hpf1_ena[hpf % 3] ==
704 ucontrol->value.integer.value[0])
705 return 0;
706 } else {
707 if (wm8994->hpf2_ena[hpf % 3] ==
708 ucontrol->value.integer.value[0])
709 return 0;
710 }
711
712 if (ucontrol->value.integer.value[0] > 1)
713 return -EINVAL;
714
715 if (!wm8994->mbc_vss)
716 return -ENODEV;
717
718 if (wm8958_dsp2_busy(wm8994, hpf % 3)) {
719 dev_dbg(codec->dev, "DSP2 active on %d already\n", hpf);
720 return -EBUSY;
721 }
722
723 if (wm8994->enh_eq_ena[hpf % 3])
724 return -EBUSY;
725
726 if (hpf < 3)
727 wm8994->hpf1_ena[hpf % 3] = ucontrol->value.integer.value[0];
728 else
729 wm8994->hpf2_ena[hpf % 3] = ucontrol->value.integer.value[0];
730
731 wm8958_dsp_apply(codec, hpf % 3, ucontrol->value.integer.value[0]);
732
733 return 0;
734}
735
736#define WM8958_HPF_SWITCH(xname, xval) {\
737 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
738 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
739 .info = wm8958_hpf_info, \
740 .get = wm8958_hpf_get, .put = wm8958_hpf_put, \
741 .private_value = xval }
742
743static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol,
744 struct snd_ctl_elem_value *ucontrol)
745{
746 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
747 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
748 struct wm8994_pdata *pdata = wm8994->pdata;
749 int value = ucontrol->value.integer.value[0];
750 int reg;
751
752 /* Don't allow on the fly reconfiguration */
753 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
754 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
755 return -EBUSY;
756
757 if (value >= pdata->num_enh_eq_cfgs)
758 return -EINVAL;
759
760 wm8994->enh_eq_cfg = value;
761
762 return 0;
763}
764
765static int wm8958_get_enh_eq_enum(struct snd_kcontrol *kcontrol,
766 struct snd_ctl_elem_value *ucontrol)
767{
768 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
769 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
770
771 ucontrol->value.enumerated.item[0] = wm8994->enh_eq_cfg;
772
773 return 0;
774}
775
776static int wm8958_enh_eq_info(struct snd_kcontrol *kcontrol,
777 struct snd_ctl_elem_info *uinfo)
778{
779 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
780 uinfo->count = 1;
781 uinfo->value.integer.min = 0;
782 uinfo->value.integer.max = 1;
783 return 0;
784}
785
786static int wm8958_enh_eq_get(struct snd_kcontrol *kcontrol,
787 struct snd_ctl_elem_value *ucontrol)
788{
789 int eq = kcontrol->private_value;
790 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
791 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
792
793 ucontrol->value.integer.value[0] = wm8994->enh_eq_ena[eq];
794
795 return 0;
796}
797
798static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol,
799 struct snd_ctl_elem_value *ucontrol)
800{
801 int eq = kcontrol->private_value;
802 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
803 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
804
805 if (wm8994->enh_eq_ena[eq] == ucontrol->value.integer.value[0])
806 return 0;
807
808 if (ucontrol->value.integer.value[0] > 1)
809 return -EINVAL;
810
811 if (!wm8994->enh_eq)
812 return -ENODEV;
813
814 if (wm8958_dsp2_busy(wm8994, eq)) {
815 dev_dbg(codec->dev, "DSP2 active on %d already\n", eq);
816 return -EBUSY;
817 }
818
819 if (wm8994->mbc_ena[eq] || wm8994->vss_ena[eq] ||
820 wm8994->hpf1_ena[eq] || wm8994->hpf2_ena[eq])
821 return -EBUSY;
822
823 wm8994->enh_eq_ena[eq] = ucontrol->value.integer.value[0];
824
825 wm8958_dsp_apply(codec, eq, ucontrol->value.integer.value[0]);
826
827 return 0;
828}
829
830#define WM8958_ENH_EQ_SWITCH(xname, xval) {\
831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
832 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
833 .info = wm8958_enh_eq_info, \
834 .get = wm8958_enh_eq_get, .put = wm8958_enh_eq_put, \
835 .private_value = xval }
836
837static const struct snd_kcontrol_new wm8958_mbc_snd_controls[] = {
838WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0),
839WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1),
840WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2),
841};
842
843static const struct snd_kcontrol_new wm8958_vss_snd_controls[] = {
844WM8958_VSS_SWITCH("AIF1DAC1 VSS Switch", 0),
845WM8958_VSS_SWITCH("AIF1DAC2 VSS Switch", 1),
846WM8958_VSS_SWITCH("AIF2DAC VSS Switch", 2),
847WM8958_HPF_SWITCH("AIF1DAC1 HPF1 Switch", 0),
848WM8958_HPF_SWITCH("AIF1DAC2 HPF1 Switch", 1),
849WM8958_HPF_SWITCH("AIF2DAC HPF1 Switch", 2),
850WM8958_HPF_SWITCH("AIF1DAC1 HPF2 Switch", 3),
851WM8958_HPF_SWITCH("AIF1DAC2 HPF2 Switch", 4),
852WM8958_HPF_SWITCH("AIF2DAC HPF2 Switch", 5),
853};
854
855static const struct snd_kcontrol_new wm8958_enh_eq_snd_controls[] = {
856WM8958_ENH_EQ_SWITCH("AIF1DAC1 Enhanced EQ Switch", 0),
857WM8958_ENH_EQ_SWITCH("AIF1DAC2 Enhanced EQ Switch", 1),
858WM8958_ENH_EQ_SWITCH("AIF2DAC Enhanced EQ Switch", 2),
859};
860
861static void wm8958_enh_eq_loaded(const struct firmware *fw, void *context)
862{
863 struct snd_soc_codec *codec = context;
864 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
865
866 if (fw && (wm8958_dsp2_fw(codec, "ENH_EQ", fw, true) == 0)) {
867 mutex_lock(&codec->mutex);
868 wm8994->enh_eq = fw;
869 mutex_unlock(&codec->mutex);
870 }
871}
872
873static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context)
874{
875 struct snd_soc_codec *codec = context;
876 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
877
878 if (fw && (wm8958_dsp2_fw(codec, "MBC+VSS", fw, true) == 0)) {
879 mutex_lock(&codec->mutex);
880 wm8994->mbc_vss = fw;
881 mutex_unlock(&codec->mutex);
882 }
883
884 /* We can't have more than one request outstanding at once so
885 * we daisy chain.
886 */
887 request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
888 "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL,
889 codec, wm8958_enh_eq_loaded);
890}
891
892static void wm8958_mbc_loaded(const struct firmware *fw, void *context)
893{
894 struct snd_soc_codec *codec = context;
895 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
896
897 if (wm8958_dsp2_fw(codec, "MBC", fw, true) != 0)
898 return;
899
900 mutex_lock(&codec->mutex);
901 wm8994->mbc = fw;
902 mutex_unlock(&codec->mutex);
903
904 /* We can't have more than one request outstanding at once so
905 * we daisy chain.
906 */
907 request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
908 "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL,
909 codec, wm8958_mbc_vss_loaded);
910}
911
912void wm8958_dsp2_init(struct snd_soc_codec *codec)
913{
914 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
915 struct wm8994_pdata *pdata = wm8994->pdata;
916 int ret, i;
917
918 wm8994->dsp_active = -1;
919
920 snd_soc_add_controls(codec, wm8958_mbc_snd_controls,
921 ARRAY_SIZE(wm8958_mbc_snd_controls));
922 snd_soc_add_controls(codec, wm8958_vss_snd_controls,
923 ARRAY_SIZE(wm8958_vss_snd_controls));
924 snd_soc_add_controls(codec, wm8958_enh_eq_snd_controls,
925 ARRAY_SIZE(wm8958_enh_eq_snd_controls));
926
927
928 /* We don't *require* firmware and don't want to delay boot */
929 request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
930 "wm8958_mbc.wfw", codec->dev, GFP_KERNEL,
931 codec, wm8958_mbc_loaded);
932
933 if (!pdata)
934 return;
935
936 if (pdata->num_mbc_cfgs) {
937 struct snd_kcontrol_new control[] = {
938 SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum,
939 wm8958_get_mbc_enum, wm8958_put_mbc_enum),
940 };
941
942 /* We need an array of texts for the enum API */
943 wm8994->mbc_texts = kmalloc(sizeof(char *)
944 * pdata->num_mbc_cfgs, GFP_KERNEL);
945 if (!wm8994->mbc_texts) {
946 dev_err(wm8994->codec->dev,
947 "Failed to allocate %d MBC config texts\n",
948 pdata->num_mbc_cfgs);
949 return;
950 }
951
952 for (i = 0; i < pdata->num_mbc_cfgs; i++)
953 wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name;
954
955 wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
956 wm8994->mbc_enum.texts = wm8994->mbc_texts;
957
958 ret = snd_soc_add_controls(wm8994->codec, control, 1);
959 if (ret != 0)
960 dev_err(wm8994->codec->dev,
961 "Failed to add MBC mode controls: %d\n", ret);
962 }
963
964 if (pdata->num_vss_cfgs) {
965 struct snd_kcontrol_new control[] = {
966 SOC_ENUM_EXT("VSS Mode", wm8994->vss_enum,
967 wm8958_get_vss_enum, wm8958_put_vss_enum),
968 };
969
970 /* We need an array of texts for the enum API */
971 wm8994->vss_texts = kmalloc(sizeof(char *)
972 * pdata->num_vss_cfgs, GFP_KERNEL);
973 if (!wm8994->vss_texts) {
974 dev_err(wm8994->codec->dev,
975 "Failed to allocate %d VSS config texts\n",
976 pdata->num_vss_cfgs);
977 return;
978 }
979
980 for (i = 0; i < pdata->num_vss_cfgs; i++)
981 wm8994->vss_texts[i] = pdata->vss_cfgs[i].name;
982
983 wm8994->vss_enum.max = pdata->num_vss_cfgs;
984 wm8994->vss_enum.texts = wm8994->vss_texts;
985
986 ret = snd_soc_add_controls(wm8994->codec, control, 1);
987 if (ret != 0)
988 dev_err(wm8994->codec->dev,
989 "Failed to add VSS mode controls: %d\n", ret);
990 }
991
992 if (pdata->num_vss_hpf_cfgs) {
993 struct snd_kcontrol_new control[] = {
994 SOC_ENUM_EXT("VSS HPF Mode", wm8994->vss_hpf_enum,
995 wm8958_get_vss_hpf_enum,
996 wm8958_put_vss_hpf_enum),
997 };
998
999 /* We need an array of texts for the enum API */
1000 wm8994->vss_hpf_texts = kmalloc(sizeof(char *)
1001 * pdata->num_vss_hpf_cfgs, GFP_KERNEL);
1002 if (!wm8994->vss_hpf_texts) {
1003 dev_err(wm8994->codec->dev,
1004 "Failed to allocate %d VSS HPF config texts\n",
1005 pdata->num_vss_hpf_cfgs);
1006 return;
1007 }
1008
1009 for (i = 0; i < pdata->num_vss_hpf_cfgs; i++)
1010 wm8994->vss_hpf_texts[i] = pdata->vss_hpf_cfgs[i].name;
1011
1012 wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs;
1013 wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts;
1014
1015 ret = snd_soc_add_controls(wm8994->codec, control, 1);
1016 if (ret != 0)
1017 dev_err(wm8994->codec->dev,
1018 "Failed to add VSS HPFmode controls: %d\n",
1019 ret);
1020 }
1021
1022 if (pdata->num_enh_eq_cfgs) {
1023 struct snd_kcontrol_new control[] = {
1024 SOC_ENUM_EXT("Enhanced EQ Mode", wm8994->enh_eq_enum,
1025 wm8958_get_enh_eq_enum,
1026 wm8958_put_enh_eq_enum),
1027 };
1028
1029 /* We need an array of texts for the enum API */
1030 wm8994->enh_eq_texts = kmalloc(sizeof(char *)
1031 * pdata->num_enh_eq_cfgs, GFP_KERNEL);
1032 if (!wm8994->enh_eq_texts) {
1033 dev_err(wm8994->codec->dev,
1034 "Failed to allocate %d enhanced EQ config texts\n",
1035 pdata->num_enh_eq_cfgs);
1036 return;
1037 }
1038
1039 for (i = 0; i < pdata->num_enh_eq_cfgs; i++)
1040 wm8994->enh_eq_texts[i] = pdata->enh_eq_cfgs[i].name;
1041
1042 wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs;
1043 wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts;
1044
1045 ret = snd_soc_add_controls(wm8994->codec, control, 1);
1046 if (ret != 0)
1047 dev_err(wm8994->codec->dev,
1048 "Failed to add enhanced EQ controls: %d\n",
1049 ret);
1050 }
1051}
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 500011eb8b2b..f90ae427242b 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -58,6 +58,7 @@ struct wm8962_priv {
58 int bclk; /* Desired BCLK */ 58 int bclk; /* Desired BCLK */
59 int lrclk; 59 int lrclk;
60 60
61 struct completion fll_lock;
61 int fll_src; 62 int fll_src;
62 int fll_fref; 63 int fll_fref;
63 int fll_fout; 64 int fll_fout;
@@ -2038,6 +2039,13 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
2038 return 0; 2039 return 0;
2039} 2040}
2040 2041
2042static const char *cap_hpf_mode_text[] = {
2043 "Hi-fi", "Application"
2044};
2045
2046static const struct soc_enum cap_hpf_mode =
2047 SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text);
2048
2041static const struct snd_kcontrol_new wm8962_snd_controls[] = { 2049static const struct snd_kcontrol_new wm8962_snd_controls[] = {
2042SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1), 2050SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1),
2043 2051
@@ -2063,6 +2071,9 @@ SOC_DOUBLE_R("Capture Switch", WM8962_LEFT_INPUT_VOLUME,
2063 WM8962_RIGHT_INPUT_VOLUME, 7, 1, 1), 2071 WM8962_RIGHT_INPUT_VOLUME, 7, 1, 1),
2064SOC_DOUBLE_R("Capture ZC Switch", WM8962_LEFT_INPUT_VOLUME, 2072SOC_DOUBLE_R("Capture ZC Switch", WM8962_LEFT_INPUT_VOLUME,
2065 WM8962_RIGHT_INPUT_VOLUME, 6, 1, 1), 2073 WM8962_RIGHT_INPUT_VOLUME, 6, 1, 1),
2074SOC_SINGLE("Capture HPF Switch", WM8962_ADC_DAC_CONTROL_1, 0, 1, 1),
2075SOC_ENUM("Capture HPF Mode", cap_hpf_mode),
2076SOC_SINGLE("Capture HPF Cutoff", WM8962_ADC_DAC_CONTROL_2, 7, 7, 0),
2066 2077
2067SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1, 2078SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1,
2068 WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv), 2079 WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv),
@@ -2467,6 +2478,7 @@ SND_SOC_DAPM_INPUT("IN3R"),
2467SND_SOC_DAPM_INPUT("IN4L"), 2478SND_SOC_DAPM_INPUT("IN4L"),
2468SND_SOC_DAPM_INPUT("IN4R"), 2479SND_SOC_DAPM_INPUT("IN4R"),
2469SND_SOC_DAPM_INPUT("Beep"), 2480SND_SOC_DAPM_INPUT("Beep"),
2481SND_SOC_DAPM_INPUT("DMICDAT"),
2470 2482
2471SND_SOC_DAPM_MICBIAS("MICBIAS", WM8962_PWR_MGMT_1, 1, 0), 2483SND_SOC_DAPM_MICBIAS("MICBIAS", WM8962_PWR_MGMT_1, 1, 0),
2472 2484
@@ -2486,6 +2498,8 @@ SND_SOC_DAPM_MIXER("MIXINL", WM8962_PWR_MGMT_1, 5, 0,
2486SND_SOC_DAPM_MIXER("MIXINR", WM8962_PWR_MGMT_1, 4, 0, 2498SND_SOC_DAPM_MIXER("MIXINR", WM8962_PWR_MGMT_1, 4, 0,
2487 mixinr, ARRAY_SIZE(mixinr)), 2499 mixinr, ARRAY_SIZE(mixinr)),
2488 2500
2501SND_SOC_DAPM_AIF_IN("DMIC", NULL, 0, WM8962_PWR_MGMT_1, 10, 0),
2502
2489SND_SOC_DAPM_ADC("ADCL", "Capture", WM8962_PWR_MGMT_1, 3, 0), 2503SND_SOC_DAPM_ADC("ADCL", "Capture", WM8962_PWR_MGMT_1, 3, 0),
2490SND_SOC_DAPM_ADC("ADCR", "Capture", WM8962_PWR_MGMT_1, 2, 0), 2504SND_SOC_DAPM_ADC("ADCR", "Capture", WM8962_PWR_MGMT_1, 2, 0),
2491 2505
@@ -2563,13 +2577,17 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = {
2563 2577
2564 { "MICBIAS", NULL, "SYSCLK" }, 2578 { "MICBIAS", NULL, "SYSCLK" },
2565 2579
2580 { "DMIC", NULL, "DMICDAT" },
2581
2566 { "ADCL", NULL, "SYSCLK" }, 2582 { "ADCL", NULL, "SYSCLK" },
2567 { "ADCL", NULL, "TOCLK" }, 2583 { "ADCL", NULL, "TOCLK" },
2568 { "ADCL", NULL, "MIXINL" }, 2584 { "ADCL", NULL, "MIXINL" },
2585 { "ADCL", NULL, "DMIC" },
2569 2586
2570 { "ADCR", NULL, "SYSCLK" }, 2587 { "ADCR", NULL, "SYSCLK" },
2571 { "ADCR", NULL, "TOCLK" }, 2588 { "ADCR", NULL, "TOCLK" },
2572 { "ADCR", NULL, "MIXINR" }, 2589 { "ADCR", NULL, "MIXINR" },
2590 { "ADCR", NULL, "DMIC" },
2573 2591
2574 { "STL", "Left", "ADCL" }, 2592 { "STL", "Left", "ADCL" },
2575 { "STL", "Right", "ADCR" }, 2593 { "STL", "Right", "ADCR" },
@@ -2990,7 +3008,6 @@ static int wm8962_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
2990 case WM8962_SYSCLK_FLL: 3008 case WM8962_SYSCLK_FLL:
2991 wm8962->sysclk = WM8962_SYSCLK_FLL; 3009 wm8962->sysclk = WM8962_SYSCLK_FLL;
2992 src = 1 << WM8962_SYSCLK_SRC_SHIFT; 3010 src = 1 << WM8962_SYSCLK_SRC_SHIFT;
2993 WARN_ON(freq != wm8962->fll_fout);
2994 break; 3011 break;
2995 default: 3012 default:
2996 return -EINVAL; 3013 return -EINVAL;
@@ -3172,12 +3189,12 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
3172 return 0; 3189 return 0;
3173} 3190}
3174 3191
3175static int wm8962_set_fll(struct snd_soc_dai *dai, int fll_id, int source, 3192static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
3176 unsigned int Fref, unsigned int Fout) 3193 unsigned int Fref, unsigned int Fout)
3177{ 3194{
3178 struct snd_soc_codec *codec = dai->codec;
3179 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 3195 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3180 struct _fll_div fll_div; 3196 struct _fll_div fll_div;
3197 unsigned long timeout;
3181 int ret; 3198 int ret;
3182 int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA; 3199 int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA;
3183 3200
@@ -3244,6 +3261,11 @@ static int wm8962_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
3244 3261
3245 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); 3262 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
3246 3263
3264 /* This should be a massive overestimate */
3265 timeout = msecs_to_jiffies(1);
3266
3267 wait_for_completion_timeout(&wm8962->fll_lock, timeout);
3268
3247 wm8962->fll_fref = Fref; 3269 wm8962->fll_fref = Fref;
3248 wm8962->fll_fout = Fout; 3270 wm8962->fll_fout = Fout;
3249 wm8962->fll_src = source; 3271 wm8962->fll_src = source;
@@ -3274,7 +3296,6 @@ static struct snd_soc_dai_ops wm8962_dai_ops = {
3274 .hw_params = wm8962_hw_params, 3296 .hw_params = wm8962_hw_params,
3275 .set_sysclk = wm8962_set_dai_sysclk, 3297 .set_sysclk = wm8962_set_dai_sysclk,
3276 .set_fmt = wm8962_set_dai_fmt, 3298 .set_fmt = wm8962_set_dai_fmt,
3277 .set_pll = wm8962_set_fll,
3278 .digital_mute = wm8962_mute, 3299 .digital_mute = wm8962_mute,
3279}; 3300};
3280 3301
@@ -3340,6 +3361,11 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3340 active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); 3361 active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
3341 active &= ~mask; 3362 active &= ~mask;
3342 3363
3364 if (active & WM8962_FLL_LOCK_EINT) {
3365 dev_dbg(codec->dev, "FLL locked\n");
3366 complete(&wm8962->fll_lock);
3367 }
3368
3343 if (active & WM8962_FIFOS_ERR_EINT) 3369 if (active & WM8962_FIFOS_ERR_EINT)
3344 dev_err(codec->dev, "FIFO error\n"); 3370 dev_err(codec->dev, "FIFO error\n");
3345 3371
@@ -3709,9 +3735,11 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3709 dev); 3735 dev);
3710 u16 *reg_cache = codec->reg_cache; 3736 u16 *reg_cache = codec->reg_cache;
3711 int i, trigger, irq_pol; 3737 int i, trigger, irq_pol;
3738 bool dmicclk, dmicdat;
3712 3739
3713 wm8962->codec = codec; 3740 wm8962->codec = codec;
3714 INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work); 3741 INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work);
3742 init_completion(&wm8962->fll_lock);
3715 3743
3716 codec->cache_sync = 1; 3744 codec->cache_sync = 1;
3717 codec->dapm.idle_bias_off = 1; 3745 codec->dapm.idle_bias_off = 1;
@@ -3845,6 +3873,29 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3845 3873
3846 wm8962_add_widgets(codec); 3874 wm8962_add_widgets(codec);
3847 3875
3876 /* Save boards having to disable DMIC when not in use */
3877 dmicclk = false;
3878 dmicdat = false;
3879 for (i = 0; i < WM8962_MAX_GPIO; i++) {
3880 switch (snd_soc_read(codec, WM8962_GPIO_BASE + i)
3881 & WM8962_GP2_FN_MASK) {
3882 case WM8962_GPIO_FN_DMICCLK:
3883 dmicclk = true;
3884 break;
3885 case WM8962_GPIO_FN_DMICDAT:
3886 dmicdat = true;
3887 break;
3888 default:
3889 break;
3890 }
3891 }
3892 if (!dmicclk || !dmicdat) {
3893 dev_dbg(codec->dev, "DMIC not in use, disabling\n");
3894 snd_soc_dapm_nc_pin(&codec->dapm, "DMICDAT");
3895 }
3896 if (dmicclk != dmicdat)
3897 dev_warn(codec->dev, "DMIC GPIOs partially configured\n");
3898
3848 wm8962_init_beep(codec); 3899 wm8962_init_beep(codec);
3849 wm8962_init_gpio(codec); 3900 wm8962_init_gpio(codec);
3850 3901
@@ -3868,9 +3919,10 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3868 i2c->irq, ret); 3919 i2c->irq, ret);
3869 /* Non-fatal */ 3920 /* Non-fatal */
3870 } else { 3921 } else {
3871 /* Enable error reporting IRQs by default */ 3922 /* Enable some IRQs by default */
3872 snd_soc_update_bits(codec, 3923 snd_soc_update_bits(codec,
3873 WM8962_INTERRUPT_STATUS_2_MASK, 3924 WM8962_INTERRUPT_STATUS_2_MASK,
3925 WM8962_FLL_LOCK_EINT |
3874 WM8962_TEMP_SHUT_EINT | 3926 WM8962_TEMP_SHUT_EINT |
3875 WM8962_FIFOS_ERR_EINT, 0); 3927 WM8962_FIFOS_ERR_EINT, 0);
3876 } 3928 }
@@ -3918,6 +3970,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
3918 .reg_cache_default = wm8962_reg, 3970 .reg_cache_default = wm8962_reg,
3919 .volatile_register = wm8962_volatile_register, 3971 .volatile_register = wm8962_volatile_register,
3920 .readable_register = wm8962_readable_register, 3972 .readable_register = wm8962_readable_register,
3973 .set_pll = wm8962_set_fll,
3921}; 3974};
3922 3975
3923#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 3976#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 056aef904347..9e5ff789b805 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -718,7 +718,8 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
718static int class_w_put(struct snd_kcontrol *kcontrol, 718static int class_w_put(struct snd_kcontrol *kcontrol,
719 struct snd_ctl_elem_value *ucontrol) 719 struct snd_ctl_elem_value *ucontrol)
720{ 720{
721 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 721 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
722 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
722 struct snd_soc_codec *codec = widget->codec; 723 struct snd_soc_codec *codec = widget->codec;
723 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 724 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
724 int ret; 725 int ret;
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 84e1bd1d2822..970a95c5360b 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -38,12 +38,6 @@
38#include "wm8994.h" 38#include "wm8994.h"
39#include "wm_hubs.h" 39#include "wm_hubs.h"
40 40
41struct fll_config {
42 int src;
43 int in;
44 int out;
45};
46
47#define WM8994_NUM_DRC 3 41#define WM8994_NUM_DRC 3
48#define WM8994_NUM_EQ 3 42#define WM8994_NUM_EQ 3
49 43
@@ -59,63 +53,11 @@ static int wm8994_retune_mobile_base[] = {
59 WM8994_AIF2_EQ_GAINS_1, 53 WM8994_AIF2_EQ_GAINS_1,
60}; 54};
61 55
62struct wm8994_micdet {
63 struct snd_soc_jack *jack;
64 int det;
65 int shrt;
66};
67
68/* codec private data */
69struct wm8994_priv {
70 struct wm_hubs_data hubs;
71 enum snd_soc_control_type control_type;
72 void *control_data;
73 struct snd_soc_codec *codec;
74 int sysclk[2];
75 int sysclk_rate[2];
76 int mclk[2];
77 int aifclk[2];
78 struct fll_config fll[2], fll_suspend[2];
79
80 int dac_rates[2];
81 int lrclk_shared[2];
82
83 int mbc_ena[3];
84
85 /* Platform dependent DRC configuration */
86 const char **drc_texts;
87 int drc_cfg[WM8994_NUM_DRC];
88 struct soc_enum drc_enum;
89
90 /* Platform dependent ReTune mobile configuration */
91 int num_retune_mobile_texts;
92 const char **retune_mobile_texts;
93 int retune_mobile_cfg[WM8994_NUM_EQ];
94 struct soc_enum retune_mobile_enum;
95
96 /* Platform dependent MBC configuration */
97 int mbc_cfg;
98 const char **mbc_texts;
99 struct soc_enum mbc_enum;
100
101 struct wm8994_micdet micdet[2];
102
103 wm8958_micdet_cb jack_cb;
104 void *jack_cb_data;
105 int micdet_irq;
106
107 int revision;
108 struct wm8994_pdata *pdata;
109
110 unsigned int aif1clk_enable:1;
111 unsigned int aif2clk_enable:1;
112
113 unsigned int aif1clk_disable:1;
114 unsigned int aif2clk_disable:1;
115};
116
117static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) 56static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg)
118{ 57{
58 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
59 struct wm8994 *control = wm8994->control_data;
60
119 switch (reg) { 61 switch (reg) {
120 case WM8994_GPIO_1: 62 case WM8994_GPIO_1:
121 case WM8994_GPIO_2: 63 case WM8994_GPIO_2:
@@ -132,6 +74,15 @@ static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg)
132 case WM8994_INTERRUPT_STATUS_2: 74 case WM8994_INTERRUPT_STATUS_2:
133 case WM8994_INTERRUPT_RAW_STATUS_2: 75 case WM8994_INTERRUPT_RAW_STATUS_2:
134 return 1; 76 return 1;
77
78 case WM8958_DSP2_PROGRAM:
79 case WM8958_DSP2_CONFIG:
80 case WM8958_DSP2_EXECCONTROL:
81 if (control->type == WM8958)
82 return 1;
83 else
84 return 0;
85
135 default: 86 default:
136 break; 87 break;
137 } 88 }
@@ -574,215 +525,6 @@ static const struct soc_enum dac_osr =
574static const struct soc_enum adc_osr = 525static const struct soc_enum adc_osr =
575 SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text); 526 SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text);
576 527
577static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start)
578{
579 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
580 struct wm8994_pdata *pdata = wm8994->pdata;
581 int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5);
582 int ena, reg, aif, i;
583
584 switch (mbc) {
585 case 0:
586 pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA);
587 aif = 0;
588 break;
589 case 1:
590 pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
591 aif = 0;
592 break;
593 case 2:
594 pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA);
595 aif = 1;
596 break;
597 default:
598 BUG();
599 return;
600 }
601
602 /* We can only enable the MBC if the AIF is enabled and we
603 * want it to be enabled. */
604 ena = pwr_reg && wm8994->mbc_ena[mbc];
605
606 reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM);
607
608 dev_dbg(codec->dev, "MBC %d startup: %d, power: %x, DSP: %x\n",
609 mbc, start, pwr_reg, reg);
610
611 if (start && ena) {
612 /* If the DSP is already running then noop */
613 if (reg & WM8958_DSP2_ENA)
614 return;
615
616 /* Switch the clock over to the appropriate AIF */
617 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
618 WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA,
619 aif << WM8958_DSP2CLK_SRC_SHIFT |
620 WM8958_DSP2CLK_ENA);
621
622 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
623 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
624
625 /* If we've got user supplied MBC settings use them */
626 if (pdata && pdata->num_mbc_cfgs) {
627 struct wm8958_mbc_cfg *cfg
628 = &pdata->mbc_cfgs[wm8994->mbc_cfg];
629
630 for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++)
631 snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1,
632 cfg->coeff_regs[i]);
633
634 for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++)
635 snd_soc_write(codec,
636 i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1,
637 cfg->cutoff_regs[i]);
638 }
639
640 /* Run the DSP */
641 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
642 WM8958_DSP2_RUNR);
643
644 /* And we're off! */
645 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
646 WM8958_MBC_ENA | WM8958_MBC_SEL_MASK,
647 mbc << WM8958_MBC_SEL_SHIFT |
648 WM8958_MBC_ENA);
649 } else {
650 /* If the DSP is already stopped then noop */
651 if (!(reg & WM8958_DSP2_ENA))
652 return;
653
654 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
655 WM8958_MBC_ENA, 0);
656 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
657 WM8958_DSP2_ENA, 0);
658 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
659 WM8958_DSP2CLK_ENA, 0);
660 }
661}
662
663static int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
664 struct snd_kcontrol *kcontrol, int event)
665{
666 struct snd_soc_codec *codec = w->codec;
667 int mbc;
668
669 switch (w->shift) {
670 case 13:
671 case 12:
672 mbc = 2;
673 break;
674 case 11:
675 case 10:
676 mbc = 1;
677 break;
678 case 9:
679 case 8:
680 mbc = 0;
681 break;
682 default:
683 BUG();
684 return -EINVAL;
685 }
686
687 switch (event) {
688 case SND_SOC_DAPM_POST_PMU:
689 wm8958_mbc_apply(codec, mbc, 1);
690 break;
691 case SND_SOC_DAPM_POST_PMD:
692 wm8958_mbc_apply(codec, mbc, 0);
693 break;
694 }
695
696 return 0;
697}
698
699static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
700 struct snd_ctl_elem_value *ucontrol)
701{
702 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
703 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
704 struct wm8994_pdata *pdata = wm8994->pdata;
705 int value = ucontrol->value.integer.value[0];
706 int reg;
707
708 /* Don't allow on the fly reconfiguration */
709 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
710 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
711 return -EBUSY;
712
713 if (value >= pdata->num_mbc_cfgs)
714 return -EINVAL;
715
716 wm8994->mbc_cfg = value;
717
718 return 0;
719}
720
721static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol,
722 struct snd_ctl_elem_value *ucontrol)
723{
724 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
725 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
726
727 ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg;
728
729 return 0;
730}
731
732static int wm8958_mbc_info(struct snd_kcontrol *kcontrol,
733 struct snd_ctl_elem_info *uinfo)
734{
735 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
736 uinfo->count = 1;
737 uinfo->value.integer.min = 0;
738 uinfo->value.integer.max = 1;
739 return 0;
740}
741
742static int wm8958_mbc_get(struct snd_kcontrol *kcontrol,
743 struct snd_ctl_elem_value *ucontrol)
744{
745 int mbc = kcontrol->private_value;
746 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
747 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
748
749 ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc];
750
751 return 0;
752}
753
754static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
755 struct snd_ctl_elem_value *ucontrol)
756{
757 int mbc = kcontrol->private_value;
758 int i;
759 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
760 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
761
762 if (ucontrol->value.integer.value[0] > 1)
763 return -EINVAL;
764
765 for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) {
766 if (mbc != i && wm8994->mbc_ena[i]) {
767 dev_dbg(codec->dev, "MBC %d active already\n", mbc);
768 return -EBUSY;
769 }
770 }
771
772 wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0];
773
774 wm8958_mbc_apply(codec, mbc, wm8994->mbc_ena[mbc]);
775
776 return 0;
777}
778
779#define WM8958_MBC_SWITCH(xname, xval) {\
780 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
781 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
782 .info = wm8958_mbc_info, \
783 .get = wm8958_mbc_get, .put = wm8958_mbc_put, \
784 .private_value = xval }
785
786static const struct snd_kcontrol_new wm8994_snd_controls[] = { 528static const struct snd_kcontrol_new wm8994_snd_controls[] = {
787SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, 529SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
788 WM8994_AIF1_ADC1_RIGHT_VOLUME, 530 WM8994_AIF1_ADC1_RIGHT_VOLUME,
@@ -924,9 +666,6 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
924 666
925static const struct snd_kcontrol_new wm8958_snd_controls[] = { 667static const struct snd_kcontrol_new wm8958_snd_controls[] = {
926SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), 668SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv),
927WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0),
928WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1),
929WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2),
930}; 669};
931 670
932static int clk_sys_event(struct snd_soc_dapm_widget *w, 671static int clk_sys_event(struct snd_soc_dapm_widget *w,
@@ -1032,6 +771,9 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w,
1032 break; 771 break;
1033 } 772 }
1034 773
774 /* We may also have postponed startup of DSP, handle that. */
775 wm8958_aif_ev(w, kcontrol, event);
776
1035 return 0; 777 return 0;
1036} 778}
1037 779
@@ -1135,7 +877,8 @@ static const char *hp_mux_text[] = {
1135static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol, 877static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol,
1136 struct snd_ctl_elem_value *ucontrol) 878 struct snd_ctl_elem_value *ucontrol)
1137{ 879{
1138 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol); 880 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
881 struct snd_soc_dapm_widget *w = wlist->widgets[0];
1139 struct snd_soc_codec *codec = w->codec; 882 struct snd_soc_codec *codec = w->codec;
1140 int ret; 883 int ret;
1141 884
@@ -1262,7 +1005,8 @@ SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
1262static int wm8994_put_class_w(struct snd_kcontrol *kcontrol, 1005static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
1263 struct snd_ctl_elem_value *ucontrol) 1006 struct snd_ctl_elem_value *ucontrol)
1264{ 1007{
1265 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol); 1008 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1009 struct snd_soc_dapm_widget *w = wlist->widgets[0];
1266 struct snd_soc_codec *codec = w->codec; 1010 struct snd_soc_codec *codec = w->codec;
1267 int ret; 1011 int ret;
1268 1012
@@ -2180,6 +1924,8 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2180 WM8994_VMID_BUF_ENA | 1924 WM8994_VMID_BUF_ENA |
2181 WM8994_VMID_RAMP_MASK, 0); 1925 WM8994_VMID_RAMP_MASK, 0);
2182 1926
1927 wm8994->cur_fw = NULL;
1928
2183 pm_runtime_put(codec->dev); 1929 pm_runtime_put(codec->dev);
2184 } 1930 }
2185 break; 1931 break;
@@ -2672,11 +2418,22 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2672static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state) 2418static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
2673{ 2419{
2674 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2420 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2421 struct wm8994 *control = codec->control_data;
2675 int i, ret; 2422 int i, ret;
2676 2423
2424 switch (control->type) {
2425 case WM8994:
2426 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0);
2427 break;
2428 case WM8958:
2429 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
2430 WM8958_MICD_ENA, 0);
2431 break;
2432 }
2433
2677 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { 2434 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
2678 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i], 2435 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
2679 sizeof(struct fll_config)); 2436 sizeof(struct wm8994_fll_config));
2680 ret = _wm8994_set_fll(codec, i + 1, 0, 0, 0); 2437 ret = _wm8994_set_fll(codec, i + 1, 0, 0, 0);
2681 if (ret < 0) 2438 if (ret < 0)
2682 dev_warn(codec->dev, "Failed to stop FLL%d: %d\n", 2439 dev_warn(codec->dev, "Failed to stop FLL%d: %d\n",
@@ -2691,6 +2448,7 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
2691static int wm8994_resume(struct snd_soc_codec *codec) 2448static int wm8994_resume(struct snd_soc_codec *codec)
2692{ 2449{
2693 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2450 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2451 struct wm8994 *control = codec->control_data;
2694 int i, ret; 2452 int i, ret;
2695 unsigned int val, mask; 2453 unsigned int val, mask;
2696 2454
@@ -2729,6 +2487,19 @@ static int wm8994_resume(struct snd_soc_codec *codec)
2729 i + 1, ret); 2487 i + 1, ret);
2730 } 2488 }
2731 2489
2490 switch (control->type) {
2491 case WM8994:
2492 if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
2493 snd_soc_update_bits(codec, WM8994_MICBIAS,
2494 WM8994_MICD_ENA, WM8994_MICD_ENA);
2495 break;
2496 case WM8958:
2497 if (wm8994->jack_cb)
2498 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
2499 WM8958_MICD_ENA, WM8958_MICD_ENA);
2500 break;
2501 }
2502
2732 return 0; 2503 return 0;
2733} 2504}
2734#else 2505#else
@@ -2862,34 +2633,6 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2862 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n", 2633 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
2863 pdata->num_retune_mobile_cfgs); 2634 pdata->num_retune_mobile_cfgs);
2864 2635
2865 if (pdata->num_mbc_cfgs) {
2866 struct snd_kcontrol_new control[] = {
2867 SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum,
2868 wm8958_get_mbc_enum, wm8958_put_mbc_enum),
2869 };
2870
2871 /* We need an array of texts for the enum API */
2872 wm8994->mbc_texts = kmalloc(sizeof(char *)
2873 * pdata->num_mbc_cfgs, GFP_KERNEL);
2874 if (!wm8994->mbc_texts) {
2875 dev_err(wm8994->codec->dev,
2876 "Failed to allocate %d MBC config texts\n",
2877 pdata->num_mbc_cfgs);
2878 return;
2879 }
2880
2881 for (i = 0; i < pdata->num_mbc_cfgs; i++)
2882 wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name;
2883
2884 wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
2885 wm8994->mbc_enum.texts = wm8994->mbc_texts;
2886
2887 ret = snd_soc_add_controls(wm8994->codec, control, 1);
2888 if (ret != 0)
2889 dev_err(wm8994->codec->dev,
2890 "Failed to add MBC mode controls: %d\n", ret);
2891 }
2892
2893 if (pdata->num_retune_mobile_cfgs) 2636 if (pdata->num_retune_mobile_cfgs)
2894 wm8994_handle_retune_mobile_pdata(wm8994); 2637 wm8994_handle_retune_mobile_pdata(wm8994);
2895 else 2638 else
@@ -3343,14 +3086,23 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3343 case WM8958: 3086 case WM8958:
3344 snd_soc_add_controls(codec, wm8958_snd_controls, 3087 snd_soc_add_controls(codec, wm8958_snd_controls,
3345 ARRAY_SIZE(wm8958_snd_controls)); 3088 ARRAY_SIZE(wm8958_snd_controls));
3346 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
3347 ARRAY_SIZE(wm8994_lateclk_widgets));
3348 snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
3349 ARRAY_SIZE(wm8994_adc_widgets));
3350 snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
3351 ARRAY_SIZE(wm8994_dac_widgets));
3352 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, 3089 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
3353 ARRAY_SIZE(wm8958_dapm_widgets)); 3090 ARRAY_SIZE(wm8958_dapm_widgets));
3091 if (wm8994->revision < 1) {
3092 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets,
3093 ARRAY_SIZE(wm8994_lateclk_revd_widgets));
3094 snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets,
3095 ARRAY_SIZE(wm8994_adc_revd_widgets));
3096 snd_soc_dapm_new_controls(dapm, wm8994_dac_revd_widgets,
3097 ARRAY_SIZE(wm8994_dac_revd_widgets));
3098 } else {
3099 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
3100 ARRAY_SIZE(wm8994_lateclk_widgets));
3101 snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
3102 ARRAY_SIZE(wm8994_adc_widgets));
3103 snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
3104 ARRAY_SIZE(wm8994_dac_widgets));
3105 }
3354 break; 3106 break;
3355 } 3107 }
3356 3108
@@ -3374,10 +3126,19 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3374 } 3126 }
3375 break; 3127 break;
3376 case WM8958: 3128 case WM8958:
3377 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon, 3129 if (wm8994->revision < 1) {
3378 ARRAY_SIZE(wm8994_lateclk_intercon)); 3130 snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon,
3379 snd_soc_dapm_add_routes(dapm, wm8958_intercon, 3131 ARRAY_SIZE(wm8994_revd_intercon));
3380 ARRAY_SIZE(wm8958_intercon)); 3132 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon,
3133 ARRAY_SIZE(wm8994_lateclk_revd_intercon));
3134 } else {
3135 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon,
3136 ARRAY_SIZE(wm8994_lateclk_intercon));
3137 snd_soc_dapm_add_routes(dapm, wm8958_intercon,
3138 ARRAY_SIZE(wm8958_intercon));
3139 }
3140
3141 wm8958_dsp2_init(codec);
3381 break; 3142 break;
3382 } 3143 }
3383 3144
@@ -3420,6 +3181,12 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3420 free_irq(wm8994->micdet_irq, wm8994); 3181 free_irq(wm8994->micdet_irq, wm8994);
3421 break; 3182 break;
3422 } 3183 }
3184 if (wm8994->mbc)
3185 release_firmware(wm8994->mbc);
3186 if (wm8994->mbc_vss)
3187 release_firmware(wm8994->mbc_vss);
3188 if (wm8994->enh_eq)
3189 release_firmware(wm8994->enh_eq);
3423 kfree(wm8994->retune_mobile_texts); 3190 kfree(wm8994->retune_mobile_texts);
3424 kfree(wm8994->drc_texts); 3191 kfree(wm8994->drc_texts);
3425 kfree(wm8994); 3192 kfree(wm8994);
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 999b8851226b..0a1db04b73bd 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -10,6 +10,9 @@
10#define _WM8994_H 10#define _WM8994_H
11 11
12#include <sound/soc.h> 12#include <sound/soc.h>
13#include <linux/firmware.h>
14
15#include "wm_hubs.h"
13 16
14/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */ 17/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
15#define WM8994_SYSCLK_MCLK1 1 18#define WM8994_SYSCLK_MCLK1 1
@@ -45,4 +48,98 @@ struct wm8994_access_mask {
45extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE]; 48extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE];
46extern const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE]; 49extern const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE];
47 50
51int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
52 struct snd_kcontrol *kcontrol, int event);
53
54void wm8958_dsp2_init(struct snd_soc_codec *codec);
55
56struct wm8994_micdet {
57 struct snd_soc_jack *jack;
58 int det;
59 int shrt;
60};
61
62/* codec private data */
63struct wm8994_fll_config {
64 int src;
65 int in;
66 int out;
67};
68
69#define WM8994_NUM_DRC 3
70#define WM8994_NUM_EQ 3
71
72struct wm8994_priv {
73 struct wm_hubs_data hubs;
74 enum snd_soc_control_type control_type;
75 void *control_data;
76 struct snd_soc_codec *codec;
77 int sysclk[2];
78 int sysclk_rate[2];
79 int mclk[2];
80 int aifclk[2];
81 struct wm8994_fll_config fll[2], fll_suspend[2];
82
83 int dac_rates[2];
84 int lrclk_shared[2];
85
86 int mbc_ena[3];
87 int hpf1_ena[3];
88 int hpf2_ena[3];
89 int vss_ena[3];
90 int enh_eq_ena[3];
91
92 /* Platform dependant DRC configuration */
93 const char **drc_texts;
94 int drc_cfg[WM8994_NUM_DRC];
95 struct soc_enum drc_enum;
96
97 /* Platform dependant ReTune mobile configuration */
98 int num_retune_mobile_texts;
99 const char **retune_mobile_texts;
100 int retune_mobile_cfg[WM8994_NUM_EQ];
101 struct soc_enum retune_mobile_enum;
102
103 /* Platform dependant MBC configuration */
104 int mbc_cfg;
105 const char **mbc_texts;
106 struct soc_enum mbc_enum;
107
108 /* Platform dependant VSS configuration */
109 int vss_cfg;
110 const char **vss_texts;
111 struct soc_enum vss_enum;
112
113 /* Platform dependant VSS HPF configuration */
114 int vss_hpf_cfg;
115 const char **vss_hpf_texts;
116 struct soc_enum vss_hpf_enum;
117
118 /* Platform dependant enhanced EQ configuration */
119 int enh_eq_cfg;
120 const char **enh_eq_texts;
121 struct soc_enum enh_eq_enum;
122
123 struct wm8994_micdet micdet[2];
124
125 wm8958_micdet_cb jack_cb;
126 void *jack_cb_data;
127 int micdet_irq;
128
129 int revision;
130 struct wm8994_pdata *pdata;
131
132 unsigned int aif1clk_enable:1;
133 unsigned int aif2clk_enable:1;
134
135 unsigned int aif1clk_disable:1;
136 unsigned int aif2clk_disable:1;
137
138 int dsp_active;
139 const struct firmware *cur_fw;
140 const struct firmware *mbc;
141 const struct firmware *mbc_vss;
142 const struct firmware *enh_eq;
143};
144
48#endif 145#endif
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index 67eaaecbb42e..5ad873fda814 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -305,11 +305,11 @@ static int check_clk_sys(struct snd_soc_dapm_widget *source,
305static int wm8995_put_class_w(struct snd_kcontrol *kcontrol, 305static int wm8995_put_class_w(struct snd_kcontrol *kcontrol,
306 struct snd_ctl_elem_value *ucontrol) 306 struct snd_ctl_elem_value *ucontrol)
307{ 307{
308 struct snd_soc_dapm_widget *w; 308 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
309 struct snd_soc_dapm_widget *w = wlist->widgets[0];
309 struct snd_soc_codec *codec; 310 struct snd_soc_codec *codec;
310 int ret; 311 int ret;
311 312
312 w = snd_kcontrol_chip(kcontrol);
313 codec = w->codec; 313 codec = w->codec;
314 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); 314 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
315 wm8995_update_class_w(codec); 315 wm8995_update_class_w(codec);
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 47b357adabdd..646b58dda849 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -142,7 +142,7 @@ static const struct snd_soc_dapm_widget wm9705_dapm_widgets[] = {
142 * constantly enabled, we use the mutes on those inputs to simulate such 142 * constantly enabled, we use the mutes on those inputs to simulate such
143 * controls. 143 * controls.
144 */ 144 */
145static const struct snd_soc_dapm_route audio_map[] = { 145static const struct snd_soc_dapm_route wm9705_audio_map[] = {
146 /* HP mixer */ 146 /* HP mixer */
147 {"HP Mixer", "PCBeep Playback Switch", "PCBEEP PGA"}, 147 {"HP Mixer", "PCBeep Playback Switch", "PCBEEP PGA"},
148 {"HP Mixer", "CD Playback Switch", "CD PGA"}, 148 {"HP Mixer", "CD Playback Switch", "CD PGA"},
@@ -200,17 +200,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
200 {"Right ADC", NULL, "ADC PGA"}, 200 {"Right ADC", NULL, "ADC PGA"},
201}; 201};
202 202
203static int wm9705_add_widgets(struct snd_soc_codec *codec)
204{
205 struct snd_soc_dapm_context *dapm = &codec->dapm;
206
207 snd_soc_dapm_new_controls(dapm, wm9705_dapm_widgets,
208 ARRAY_SIZE(wm9705_dapm_widgets));
209 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
210
211 return 0;
212}
213
214/* We use a register cache to enhance read performance. */ 203/* We use a register cache to enhance read performance. */
215static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) 204static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg)
216{ 205{
@@ -364,7 +353,6 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
364 353
365 snd_soc_add_controls(codec, wm9705_snd_ac97_controls, 354 snd_soc_add_controls(codec, wm9705_snd_ac97_controls,
366 ARRAY_SIZE(wm9705_snd_ac97_controls)); 355 ARRAY_SIZE(wm9705_snd_ac97_controls));
367 wm9705_add_widgets(codec);
368 356
369 return 0; 357 return 0;
370 358
@@ -390,6 +378,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9705 = {
390 .reg_word_size = sizeof(u16), 378 .reg_word_size = sizeof(u16),
391 .reg_cache_step = 2, 379 .reg_cache_step = 2,
392 .reg_cache_default = wm9705_reg, 380 .reg_cache_default = wm9705_reg,
381 .dapm_widgets = wm9705_dapm_widgets,
382 .num_dapm_widgets = ARRAY_SIZE(wm9705_dapm_widgets),
383 .dapm_routes = wm9705_audio_map,
384 .num_dapm_routes = ARRAY_SIZE(wm9705_audio_map),
393}; 385};
394 386
395static __devinit int wm9705_probe(struct platform_device *pdev) 387static __devinit int wm9705_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index bf5d4ef1a2a6..90117f8156e8 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -332,7 +332,7 @@ SND_SOC_DAPM_INPUT("MIC1"),
332SND_SOC_DAPM_INPUT("MIC2"), 332SND_SOC_DAPM_INPUT("MIC2"),
333}; 333};
334 334
335static const struct snd_soc_dapm_route audio_map[] = { 335static const struct snd_soc_dapm_route wm9712_audio_map[] = {
336 /* virtual mixer - mixes left & right channels for spk and mono */ 336 /* virtual mixer - mixes left & right channels for spk and mono */
337 {"AC97 Mixer", NULL, "Left DAC"}, 337 {"AC97 Mixer", NULL, "Left DAC"},
338 {"AC97 Mixer", NULL, "Right DAC"}, 338 {"AC97 Mixer", NULL, "Right DAC"},
@@ -429,17 +429,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
429 {"ROUT2", NULL, "Speaker PGA"}, 429 {"ROUT2", NULL, "Speaker PGA"},
430}; 430};
431 431
432static int wm9712_add_widgets(struct snd_soc_codec *codec)
433{
434 struct snd_soc_dapm_context *dapm = &codec->dapm;
435
436 snd_soc_dapm_new_controls(dapm, wm9712_dapm_widgets,
437 ARRAY_SIZE(wm9712_dapm_widgets));
438 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
439
440 return 0;
441}
442
443static unsigned int ac97_read(struct snd_soc_codec *codec, 432static unsigned int ac97_read(struct snd_soc_codec *codec,
444 unsigned int reg) 433 unsigned int reg)
445{ 434{
@@ -651,7 +640,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
651 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 640 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
652 snd_soc_add_controls(codec, wm9712_snd_ac97_controls, 641 snd_soc_add_controls(codec, wm9712_snd_ac97_controls,
653 ARRAY_SIZE(wm9712_snd_ac97_controls)); 642 ARRAY_SIZE(wm9712_snd_ac97_controls));
654 wm9712_add_widgets(codec);
655 643
656 return 0; 644 return 0;
657 645
@@ -678,6 +666,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
678 .reg_word_size = sizeof(u16), 666 .reg_word_size = sizeof(u16),
679 .reg_cache_step = 2, 667 .reg_cache_step = 2,
680 .reg_cache_default = wm9712_reg, 668 .reg_cache_default = wm9712_reg,
669 .dapm_widgets = wm9712_dapm_widgets,
670 .num_dapm_widgets = ARRAY_SIZE(wm9712_dapm_widgets),
671 .dapm_routes = wm9712_audio_map,
672 .num_dapm_routes = ARRAY_SIZE(wm9712_audio_map),
681}; 673};
682 674
683static __devinit int wm9712_probe(struct platform_device *pdev) 675static __devinit int wm9712_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 38ed98558718..7167cb6787db 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -487,7 +487,7 @@ SND_SOC_DAPM_INPUT("MIC2B"),
487SND_SOC_DAPM_VMID("VMID"), 487SND_SOC_DAPM_VMID("VMID"),
488}; 488};
489 489
490static const struct snd_soc_dapm_route audio_map[] = { 490static const struct snd_soc_dapm_route wm9713_audio_map[] = {
491 /* left HP mixer */ 491 /* left HP mixer */
492 {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"}, 492 {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"},
493 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"}, 493 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"},
@@ -644,18 +644,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
644 {"Capture Mono Mux", "Right", "Right Capture Source"}, 644 {"Capture Mono Mux", "Right", "Right Capture Source"},
645}; 645};
646 646
647static int wm9713_add_widgets(struct snd_soc_codec *codec)
648{
649 struct snd_soc_dapm_context *dapm = &codec->dapm;
650
651 snd_soc_dapm_new_controls(dapm, wm9713_dapm_widgets,
652 ARRAY_SIZE(wm9713_dapm_widgets));
653
654 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
655
656 return 0;
657}
658
659static unsigned int ac97_read(struct snd_soc_codec *codec, 647static unsigned int ac97_read(struct snd_soc_codec *codec,
660 unsigned int reg) 648 unsigned int reg)
661{ 649{
@@ -1231,7 +1219,6 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
1231 1219
1232 snd_soc_add_controls(codec, wm9713_snd_ac97_controls, 1220 snd_soc_add_controls(codec, wm9713_snd_ac97_controls,
1233 ARRAY_SIZE(wm9713_snd_ac97_controls)); 1221 ARRAY_SIZE(wm9713_snd_ac97_controls));
1234 wm9713_add_widgets(codec);
1235 1222
1236 return 0; 1223 return 0;
1237 1224
@@ -1262,6 +1249,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
1262 .reg_word_size = sizeof(u16), 1249 .reg_word_size = sizeof(u16),
1263 .reg_cache_step = 2, 1250 .reg_cache_step = 2,
1264 .reg_cache_default = wm9713_reg, 1251 .reg_cache_default = wm9713_reg,
1252 .dapm_widgets = wm9713_dapm_widgets,
1253 .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets),
1254 .dapm_routes = wm9713_audio_map,
1255 .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map),
1265}; 1256};
1266 1257
1267static __devinit int wm9713_probe(struct platform_device *pdev) 1258static __devinit int wm9713_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 4005e9af5d61..e55b298c14a0 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -787,17 +787,17 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
787static const struct snd_soc_dapm_route lineout1_diff_routes[] = { 787static const struct snd_soc_dapm_route lineout1_diff_routes[] = {
788 { "LINEOUT1 Mixer", "IN1L Switch", "IN1L PGA" }, 788 { "LINEOUT1 Mixer", "IN1L Switch", "IN1L PGA" },
789 { "LINEOUT1 Mixer", "IN1R Switch", "IN1R PGA" }, 789 { "LINEOUT1 Mixer", "IN1R Switch", "IN1R PGA" },
790 { "LINEOUT1 Mixer", "Output Switch", "Left Output Mixer" }, 790 { "LINEOUT1 Mixer", "Output Switch", "Left Output PGA" },
791 791
792 { "LINEOUT1N Driver", NULL, "LINEOUT1 Mixer" }, 792 { "LINEOUT1N Driver", NULL, "LINEOUT1 Mixer" },
793 { "LINEOUT1P Driver", NULL, "LINEOUT1 Mixer" }, 793 { "LINEOUT1P Driver", NULL, "LINEOUT1 Mixer" },
794}; 794};
795 795
796static const struct snd_soc_dapm_route lineout1_se_routes[] = { 796static const struct snd_soc_dapm_route lineout1_se_routes[] = {
797 { "LINEOUT1N Mixer", "Left Output Switch", "Left Output Mixer" }, 797 { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" },
798 { "LINEOUT1N Mixer", "Right Output Switch", "Left Output Mixer" }, 798 { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" },
799 799
800 { "LINEOUT1P Mixer", "Left Output Switch", "Left Output Mixer" }, 800 { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" },
801 801
802 { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" }, 802 { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" },
803 { "LINEOUT1P Driver", NULL, "LINEOUT1P Mixer" }, 803 { "LINEOUT1P Driver", NULL, "LINEOUT1P Mixer" },
@@ -806,17 +806,17 @@ static const struct snd_soc_dapm_route lineout1_se_routes[] = {
806static const struct snd_soc_dapm_route lineout2_diff_routes[] = { 806static const struct snd_soc_dapm_route lineout2_diff_routes[] = {
807 { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" }, 807 { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" },
808 { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" }, 808 { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" },
809 { "LINEOUT2 Mixer", "Output Switch", "Right Output Mixer" }, 809 { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" },
810 810
811 { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" }, 811 { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" },
812 { "LINEOUT2P Driver", NULL, "LINEOUT2 Mixer" }, 812 { "LINEOUT2P Driver", NULL, "LINEOUT2 Mixer" },
813}; 813};
814 814
815static const struct snd_soc_dapm_route lineout2_se_routes[] = { 815static const struct snd_soc_dapm_route lineout2_se_routes[] = {
816 { "LINEOUT2N Mixer", "Left Output Switch", "Left Output Mixer" }, 816 { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" },
817 { "LINEOUT2N Mixer", "Right Output Switch", "Left Output Mixer" }, 817 { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" },
818 818
819 { "LINEOUT2P Mixer", "Right Output Switch", "Right Output Mixer" }, 819 { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" },
820 820
821 { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" }, 821 { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" },
822 { "LINEOUT2P Driver", NULL, "LINEOUT2P Mixer" }, 822 { "LINEOUT2P Driver", NULL, "LINEOUT2P Mixer" },
@@ -836,17 +836,21 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
836 snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 836 snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_3_4_VOLUME,
837 WM8993_IN2_VU, WM8993_IN2_VU); 837 WM8993_IN2_VU, WM8993_IN2_VU);
838 838
839 snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_LEFT,
840 WM8993_SPKOUT_VU, WM8993_SPKOUT_VU);
839 snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_RIGHT, 841 snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_RIGHT,
840 WM8993_SPKOUT_VU, WM8993_SPKOUT_VU); 842 WM8993_SPKOUT_VU, WM8993_SPKOUT_VU);
841 843
842 snd_soc_update_bits(codec, WM8993_LEFT_OUTPUT_VOLUME, 844 snd_soc_update_bits(codec, WM8993_LEFT_OUTPUT_VOLUME,
843 WM8993_HPOUT1L_ZC, WM8993_HPOUT1L_ZC); 845 WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC,
846 WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC);
844 snd_soc_update_bits(codec, WM8993_RIGHT_OUTPUT_VOLUME, 847 snd_soc_update_bits(codec, WM8993_RIGHT_OUTPUT_VOLUME,
845 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC, 848 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC,
846 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC); 849 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC);
847 850
848 snd_soc_update_bits(codec, WM8993_LEFT_OPGA_VOLUME, 851 snd_soc_update_bits(codec, WM8993_LEFT_OPGA_VOLUME,
849 WM8993_MIXOUTL_ZC, WM8993_MIXOUTL_ZC); 852 WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU,
853 WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU);
850 snd_soc_update_bits(codec, WM8993_RIGHT_OPGA_VOLUME, 854 snd_soc_update_bits(codec, WM8993_RIGHT_OPGA_VOLUME,
851 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU, 855 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU,
852 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU); 856 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU);
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 4ddc6d3b6678..8566238db2a5 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -909,6 +909,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
909 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; 909 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
910 dma_data->asp_chan_q = pdata->asp_chan_q; 910 dma_data->asp_chan_q = pdata->asp_chan_q;
911 dma_data->ram_chan_q = pdata->ram_chan_q; 911 dma_data->ram_chan_q = pdata->ram_chan_q;
912 dma_data->sram_size = pdata->sram_size_playback;
912 dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + 913 dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
913 mem->start); 914 mem->start);
914 915
@@ -925,6 +926,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
925 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; 926 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE];
926 dma_data->asp_chan_q = pdata->asp_chan_q; 927 dma_data->asp_chan_q = pdata->asp_chan_q;
927 dma_data->ram_chan_q = pdata->ram_chan_q; 928 dma_data->ram_chan_q = pdata->ram_chan_q;
929 dma_data->sram_size = pdata->sram_size_capture;
928 dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + 930 dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
929 mem->start); 931 mem->start);
930 932
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index ac2ded969253..5b13feca7537 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -667,12 +667,6 @@ static int imx_ssi_probe(struct platform_device *pdev)
667 if (res) 667 if (res)
668 ssi->dma_params_rx.dma = res->start; 668 ssi->dma_params_rx.dma = res->start;
669 669
670 if ((cpu_is_mx27() || cpu_is_mx21()) &&
671 !(ssi->flags & IMX_SSI_USE_AC97) &&
672 (ssi->flags & IMX_SSI_DMA)) {
673 ssi->flags |= IMX_SSI_DMA;
674 }
675
676 platform_set_drvdata(pdev, ssi); 670 platform_set_drvdata(pdev, ssi);
677 671
678 ret = snd_soc_register_dai(&pdev->dev, dai); 672 ret = snd_soc_register_dai(&pdev->dev, dai);
diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c
index 49723e3e7e38..c5fc339f68f1 100644
--- a/sound/soc/jz4740/qi_lb60.c
+++ b/sound/soc/jz4740/qi_lb60.c
@@ -27,11 +27,7 @@
27static int qi_lb60_spk_event(struct snd_soc_dapm_widget *widget, 27static int qi_lb60_spk_event(struct snd_soc_dapm_widget *widget,
28 struct snd_kcontrol *ctrl, int event) 28 struct snd_kcontrol *ctrl, int event)
29{ 29{
30 int on = 0; 30 int on = !SND_SOC_DAPM_EVENT_OFF(event);
31 if (event & SND_SOC_DAPM_POST_PMU)
32 on = 1;
33 else if (event & SND_SOC_DAPM_PRE_PMD)
34 on = 0;
35 31
36 gpio_set_value(QI_LB60_SND_GPIO, on); 32 gpio_set_value(QI_LB60_SND_GPIO, on);
37 gpio_set_value(QI_LB60_AMP_GPIO, on); 33 gpio_set_value(QI_LB60_AMP_GPIO, on);
@@ -70,12 +66,6 @@ static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd)
70 return ret; 66 return ret;
71 } 67 }
72 68
73 snd_soc_dapm_new_controls(dapm, qi_lb60_widgets,
74 ARRAY_SIZE(qi_lb60_widgets));
75 snd_soc_dapm_add_routes(dapm, qi_lb60_routes,
76 ARRAY_SIZE(qi_lb60_routes));
77 snd_soc_dapm_sync(dapm);
78
79 return 0; 69 return 0;
80} 70}
81 71
@@ -93,10 +83,20 @@ static struct snd_soc_card qi_lb60 = {
93 .name = "QI LB60", 83 .name = "QI LB60",
94 .dai_link = &qi_lb60_dai, 84 .dai_link = &qi_lb60_dai,
95 .num_links = 1, 85 .num_links = 1,
86
87 .dapm_widgets = qi_lb60_widgets,
88 .num_dapm_widgets = ARRAY_SIZE(qi_lb60_widgets),
89 .dapm_routes = qi_lb60_routes,
90 .num_dapm_routes = ARRAY_SIZE(qi_lb60_routes),
96}; 91};
97 92
98static struct platform_device *qi_lb60_snd_device; 93static struct platform_device *qi_lb60_snd_device;
99 94
95static const struct gpio qi_lb60_gpios[] = {
96 { QI_LB60_SND_GPIO, GPIOF_OUT_INIT_LOW, "SND" },
97 { QI_LB60_AMP_GPIO, GPIOF_OUT_INIT_LOW, "AMP" },
98};
99
100static int __init qi_lb60_init(void) 100static int __init qi_lb60_init(void)
101{ 101{
102 int ret; 102 int ret;
@@ -106,23 +106,12 @@ static int __init qi_lb60_init(void)
106 if (!qi_lb60_snd_device) 106 if (!qi_lb60_snd_device)
107 return -ENOMEM; 107 return -ENOMEM;
108 108
109 ret = gpio_request(QI_LB60_SND_GPIO, "SND"); 109 ret = gpio_request_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
110 if (ret) { 110 if (ret) {
111 pr_err("qi_lb60 snd: Failed to request SND GPIO(%d): %d\n", 111 pr_err("qi_lb60 snd: Failed to request gpios: %d\n", ret);
112 QI_LB60_SND_GPIO, ret);
113 goto err_device_put; 112 goto err_device_put;
114 } 113 }
115 114
116 ret = gpio_request(QI_LB60_AMP_GPIO, "AMP");
117 if (ret) {
118 pr_err("qi_lb60 snd: Failed to request AMP GPIO(%d): %d\n",
119 QI_LB60_AMP_GPIO, ret);
120 goto err_gpio_free_snd;
121 }
122
123 gpio_direction_output(QI_LB60_SND_GPIO, 0);
124 gpio_direction_output(QI_LB60_AMP_GPIO, 0);
125
126 platform_set_drvdata(qi_lb60_snd_device, &qi_lb60); 115 platform_set_drvdata(qi_lb60_snd_device, &qi_lb60);
127 116
128 ret = platform_device_add(qi_lb60_snd_device); 117 ret = platform_device_add(qi_lb60_snd_device);
@@ -135,10 +124,8 @@ static int __init qi_lb60_init(void)
135 124
136err_unset_pdata: 125err_unset_pdata:
137 platform_set_drvdata(qi_lb60_snd_device, NULL); 126 platform_set_drvdata(qi_lb60_snd_device, NULL);
138/*err_gpio_free_amp:*/ 127/*err_gpio_free_array:*/
139 gpio_free(QI_LB60_AMP_GPIO); 128 gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
140err_gpio_free_snd:
141 gpio_free(QI_LB60_SND_GPIO);
142err_device_put: 129err_device_put:
143 platform_device_put(qi_lb60_snd_device); 130 platform_device_put(qi_lb60_snd_device);
144 131
@@ -148,9 +135,8 @@ module_init(qi_lb60_init);
148 135
149static void __exit qi_lb60_exit(void) 136static void __exit qi_lb60_exit(void)
150{ 137{
151 gpio_free(QI_LB60_AMP_GPIO);
152 gpio_free(QI_LB60_SND_GPIO);
153 platform_device_unregister(qi_lb60_snd_device); 138 platform_device_unregister(qi_lb60_snd_device);
139 gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
154} 140}
155module_exit(qi_lb60_exit); 141module_exit(qi_lb60_exit);
156 142
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
index 6b1f9d3bf34e..5a946b4115a2 100644
--- a/sound/soc/mid-x86/sst_platform.c
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -249,10 +249,13 @@ static int sst_platform_open(struct snd_pcm_substream *substream)
249 return -ENOMEM; 249 return -ENOMEM;
250 } 250 }
251 stream->sstdrv_ops->vendor_id = MSIC_VENDOR_ID; 251 stream->sstdrv_ops->vendor_id = MSIC_VENDOR_ID;
252 stream->sstdrv_ops->module_name = SST_CARD_NAMES;
252 /* registering with SST driver to get access to SST APIs to use */ 253 /* registering with SST driver to get access to SST APIs to use */
253 ret_val = register_sst_card(stream->sstdrv_ops); 254 ret_val = register_sst_card(stream->sstdrv_ops);
254 if (ret_val) { 255 if (ret_val) {
255 pr_err("sst: sst card registration failed\n"); 256 pr_err("sst: sst card registration failed\n");
257 kfree(stream->sstdrv_ops);
258 kfree(stream);
256 return ret_val; 259 return ret_val;
257 } 260 }
258 runtime->private_data = stream; 261 runtime->private_data = stream;
@@ -270,6 +273,7 @@ static int sst_platform_close(struct snd_pcm_substream *substream)
270 str_id = stream->stream_info.str_id; 273 str_id = stream->stream_info.str_id;
271 if (str_id) 274 if (str_id)
272 ret_val = stream->sstdrv_ops->pcm_control->close(str_id); 275 ret_val = stream->sstdrv_ops->pcm_control->close(str_id);
276 unregister_sst_card(stream->sstdrv_ops);
273 kfree(stream->sstdrv_ops); 277 kfree(stream->sstdrv_ops);
274 kfree(stream); 278 kfree(stream);
275 return ret_val; 279 return ret_val;
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 2175f09e57b6..07b772357244 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -4,7 +4,7 @@
4 * Copyright (C) 2008 Nokia Corporation 4 * Copyright (C) 2008 Nokia Corporation
5 * 5 *
6 * Contact: Jarkko Nikula <jhnikula@gmail.com> 6 * Contact: Jarkko Nikula <jhnikula@gmail.com>
7 * Peter Ujfalusi <peter.ujfalusi@nokia.com> 7 * Peter Ujfalusi <peter.ujfalusi@ti.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
@@ -146,7 +146,7 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
146 * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) 146 * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words)
147 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) 147 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words)
148 */ 148 */
149 if (cpu_is_omap343x() || cpu_is_omap44xx()) { 149 if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
150 /* 150 /*
151 * Rule for the buffer size. We should not allow 151 * Rule for the buffer size. We should not allow
152 * smaller buffer than the FIFO size to avoid underruns 152 * smaller buffer than the FIFO size to avoid underruns
@@ -258,7 +258,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
258 default: 258 default:
259 return -EINVAL; 259 return -EINVAL;
260 } 260 }
261 if (cpu_is_omap343x()) { 261 if (cpu_is_omap34xx()) {
262 dma_data->set_threshold = omap_mcbsp_set_threshold; 262 dma_data->set_threshold = omap_mcbsp_set_threshold;
263 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ 263 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
264 if (omap_mcbsp_get_dma_op_mode(bus_id) == 264 if (omap_mcbsp_get_dma_op_mode(bus_id) ==
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index 37dc7211ed3f..9a7dedd6f5a9 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -4,7 +4,7 @@
4 * Copyright (C) 2008 Nokia Corporation 4 * Copyright (C) 2008 Nokia Corporation
5 * 5 *
6 * Contact: Jarkko Nikula <jhnikula@gmail.com> 6 * Contact: Jarkko Nikula <jhnikula@gmail.com>
7 * Peter Ujfalusi <peter.ujfalusi@nokia.com> 7 * Peter Ujfalusi <peter.ujfalusi@ti.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 8caeb8d305c3..e6a6b991d05f 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -4,7 +4,7 @@
4 * Copyright (C) 2008 Nokia Corporation 4 * Copyright (C) 2008 Nokia Corporation
5 * 5 *
6 * Contact: Jarkko Nikula <jhnikula@gmail.com> 6 * Contact: Jarkko Nikula <jhnikula@gmail.com>
7 * Peter Ujfalusi <peter.ujfalusi@nokia.com> 7 * Peter Ujfalusi <peter.ujfalusi@ti.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
@@ -37,7 +37,8 @@ static const struct snd_pcm_hardware omap_pcm_hardware = {
37 SNDRV_PCM_INFO_MMAP_VALID | 37 SNDRV_PCM_INFO_MMAP_VALID |
38 SNDRV_PCM_INFO_INTERLEAVED | 38 SNDRV_PCM_INFO_INTERLEAVED |
39 SNDRV_PCM_INFO_PAUSE | 39 SNDRV_PCM_INFO_PAUSE |
40 SNDRV_PCM_INFO_RESUME, 40 SNDRV_PCM_INFO_RESUME |
41 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
41 .formats = SNDRV_PCM_FMTBIT_S16_LE | 42 .formats = SNDRV_PCM_FMTBIT_S16_LE |
42 SNDRV_PCM_FMTBIT_S32_LE, 43 SNDRV_PCM_FMTBIT_S32_LE,
43 .period_bytes_min = 32, 44 .period_bytes_min = 32,
@@ -195,7 +196,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
195 if ((cpu_is_omap1510())) 196 if ((cpu_is_omap1510()))
196 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ | 197 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
197 OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); 198 OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
198 else 199 else if (!substream->runtime->no_period_wakeup)
199 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); 200 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ);
200 201
201 if (!(cpu_class_is_omap1())) { 202 if (!(cpu_class_is_omap1())) {
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h
index fea0515331fb..a0ed1dbb52d6 100644
--- a/sound/soc/omap/omap-pcm.h
+++ b/sound/soc/omap/omap-pcm.h
@@ -4,7 +4,7 @@
4 * Copyright (C) 2008 Nokia Corporation 4 * Copyright (C) 2008 Nokia Corporation
5 * 5 *
6 * Contact: Jarkko Nikula <jhnikula@gmail.com> 6 * Contact: Jarkko Nikula <jhnikula@gmail.com>
7 * Peter Ujfalusi <peter.ujfalusi@nokia.com> 7 * Peter Ujfalusi <peter.ujfalusi@ti.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index d0986220eff9..0aae998b6540 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2008 - 2009 Nokia Corporation 4 * Copyright (C) 2008 - 2009 Nokia Corporation
5 * 5 *
6 * Contact: Peter Ujfalusi <peter.ujfalusi@nokia.com> 6 * Contact: Peter Ujfalusi <peter.ujfalusi@ti.com>
7 * Eduardo Valentin <eduardo.valentin@nokia.com> 7 * Eduardo Valentin <eduardo.valentin@nokia.com>
8 * Jarkko Nikula <jhnikula@gmail.com> 8 * Jarkko Nikula <jhnikula@gmail.com>
9 * 9 *
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 580f48571303..33ebc46b45b5 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -155,6 +155,15 @@ config SND_SOC_RAUMFELD
155 help 155 help
156 Say Y if you want to add support for SoC audio on Raumfeld devices 156 Say Y if you want to add support for SoC audio on Raumfeld devices
157 157
158config SND_PXA2XX_SOC_HX4700
159 tristate "SoC Audio support for HP iPAQ hx4700"
160 depends on SND_PXA2XX_SOC && MACH_H4700
161 select SND_PXA2XX_SOC_I2S
162 select SND_SOC_AK4641
163 help
164 Say Y if you want to add support for SoC audio on the
165 HP iPAQ hx4700.
166
158config SND_PXA2XX_SOC_MAGICIAN 167config SND_PXA2XX_SOC_MAGICIAN
159 tristate "SoC Audio support for HTC Magician" 168 tristate "SoC Audio support for HTC Magician"
160 depends on SND_PXA2XX_SOC && MACH_MAGICIAN 169 depends on SND_PXA2XX_SOC && MACH_MAGICIAN
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 07660165ec8d..af357623be9d 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -22,6 +22,7 @@ snd-soc-palm27x-objs := palm27x.o
22snd-soc-saarb-objs := saarb.o 22snd-soc-saarb-objs := saarb.o
23snd-soc-tavorevb3-objs := tavorevb3.o 23snd-soc-tavorevb3-objs := tavorevb3.o
24snd-soc-zylonite-objs := zylonite.o 24snd-soc-zylonite-objs := zylonite.o
25snd-soc-hx4700-objs := hx4700.o
25snd-soc-magician-objs := magician.o 26snd-soc-magician-objs := magician.o
26snd-soc-mioa701-objs := mioa701_wm9713.o 27snd-soc-mioa701-objs := mioa701_wm9713.o
27snd-soc-z2-objs := z2.o 28snd-soc-z2-objs := z2.o
@@ -37,6 +38,7 @@ obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o
37obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o 38obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o
38obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o 39obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o
39obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o 40obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
41obj-$(CONFIG_SND_PXA2XX_SOC_HX4700) += snd-soc-hx4700.o
40obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o 42obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
41obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o 43obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
42obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o 44obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 9027da466cae..28757fb9df31 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -310,7 +310,7 @@ static struct snd_soc_dai_link corgi_dai = {
310 .cpu_dai_name = "pxa2xx-i2s", 310 .cpu_dai_name = "pxa2xx-i2s",
311 .codec_dai_name = "wm8731-hifi", 311 .codec_dai_name = "wm8731-hifi",
312 .platform_name = "pxa-pcm-audio", 312 .platform_name = "pxa-pcm-audio",
313 .codec_name = "wm8731-codec.0-001b", 313 .codec_name = "wm8731.0-001b",
314 .init = corgi_wm8731_init, 314 .init = corgi_wm8731_init,
315 .ops = &corgi_ops, 315 .ops = &corgi_ops,
316}; 316};
diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c
new file mode 100644
index 000000000000..65c124831a00
--- /dev/null
+++ b/sound/soc/pxa/hx4700.c
@@ -0,0 +1,255 @@
1/*
2 * SoC audio for HP iPAQ hx4700
3 *
4 * Copyright (c) 2009 Philipp Zabel
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/timer.h>
15#include <linux/interrupt.h>
16#include <linux/platform_device.h>
17#include <linux/delay.h>
18#include <linux/gpio.h>
19
20#include <sound/core.h>
21#include <sound/jack.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25
26#include <mach/hx4700.h>
27#include <asm/mach-types.h>
28#include "pxa2xx-i2s.h"
29
30#include "../codecs/ak4641.h"
31
32static struct snd_soc_jack hs_jack;
33
34/* Headphones jack detection DAPM pin */
35static struct snd_soc_jack_pin hs_jack_pin[] = {
36 {
37 .pin = "Headphone Jack",
38 .mask = SND_JACK_HEADPHONE,
39 },
40 {
41 .pin = "Speaker",
42 /* disable speaker when hp jack is inserted */
43 .mask = SND_JACK_HEADPHONE,
44 .invert = 1,
45 },
46};
47
48/* Headphones jack detection GPIO */
49static struct snd_soc_jack_gpio hs_jack_gpio = {
50 .gpio = GPIO75_HX4700_EARPHONE_nDET,
51 .invert = true,
52 .name = "hp-gpio",
53 .report = SND_JACK_HEADPHONE,
54 .debounce_time = 200,
55};
56
57/*
58 * iPAQ hx4700 uses I2S for capture and playback.
59 */
60static int hx4700_hw_params(struct snd_pcm_substream *substream,
61 struct snd_pcm_hw_params *params)
62{
63 struct snd_soc_pcm_runtime *rtd = substream->private_data;
64 struct snd_soc_dai *codec_dai = rtd->codec_dai;
65 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
66 int ret = 0;
67
68 /* set codec DAI configuration */
69 ret = snd_soc_dai_set_fmt(codec_dai,
70 SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
71 SND_SOC_DAIFMT_CBS_CFS);
72 if (ret < 0)
73 return ret;
74
75 /* set cpu DAI configuration */
76 ret = snd_soc_dai_set_fmt(cpu_dai,
77 SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
78 SND_SOC_DAIFMT_CBS_CFS);
79 if (ret < 0)
80 return ret;
81
82 /* set the I2S system clock as output */
83 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
84 SND_SOC_CLOCK_OUT);
85 if (ret < 0)
86 return ret;
87
88 /* inform codec driver about clock freq *
89 * (PXA I2S always uses divider 256) */
90 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 256 * params_rate(params),
91 SND_SOC_CLOCK_IN);
92 if (ret < 0)
93 return ret;
94
95 return 0;
96}
97
98static struct snd_soc_ops hx4700_ops = {
99 .hw_params = hx4700_hw_params,
100};
101
102static int hx4700_spk_power(struct snd_soc_dapm_widget *w,
103 struct snd_kcontrol *k, int event)
104{
105 gpio_set_value(GPIO107_HX4700_SPK_nSD, !!SND_SOC_DAPM_EVENT_ON(event));
106 return 0;
107}
108
109static int hx4700_hp_power(struct snd_soc_dapm_widget *w,
110 struct snd_kcontrol *k, int event)
111{
112 gpio_set_value(GPIO92_HX4700_HP_DRIVER, !!SND_SOC_DAPM_EVENT_ON(event));
113 return 0;
114}
115
116/* hx4700 machine dapm widgets */
117static const struct snd_soc_dapm_widget hx4700_dapm_widgets[] = {
118 SND_SOC_DAPM_HP("Headphone Jack", hx4700_hp_power),
119 SND_SOC_DAPM_SPK("Speaker", hx4700_spk_power),
120 SND_SOC_DAPM_MIC("Built-in Microphone", NULL),
121};
122
123/* hx4700 machine audio_map */
124static const struct snd_soc_dapm_route hx4700_audio_map[] = {
125
126 /* Headphone connected to LOUT, ROUT */
127 {"Headphone Jack", NULL, "LOUT"},
128 {"Headphone Jack", NULL, "ROUT"},
129
130 /* Speaker connected to MOUT2 */
131 {"Speaker", NULL, "MOUT2"},
132
133 /* Microphone connected to MICIN */
134 {"MICIN", NULL, "Built-in Microphone"},
135 {"AIN", NULL, "MICOUT"},
136};
137
138/*
139 * Logic for a ak4641 as connected on a HP iPAQ hx4700
140 */
141static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd)
142{
143 struct snd_soc_codec *codec = rtd->codec;
144 struct snd_soc_dapm_context *dapm = &codec->dapm;
145 int err;
146
147 /* NC codec pins */
148 /* FIXME: is anything connected here? */
149 snd_soc_dapm_nc_pin(dapm, "MOUT1");
150 snd_soc_dapm_nc_pin(dapm, "MICEXT");
151 snd_soc_dapm_nc_pin(dapm, "AUX");
152
153 /* Jack detection API stuff */
154 err = snd_soc_jack_new(codec, "Headphone Jack",
155 SND_JACK_HEADPHONE, &hs_jack);
156 if (err)
157 return err;
158
159 err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pin),
160 hs_jack_pin);
161 if (err)
162 return err;
163
164 err = snd_soc_jack_add_gpios(&hs_jack, 1, &hs_jack_gpio);
165
166 return err;
167}
168
169/* hx4700 digital audio interface glue - connects codec <--> CPU */
170static struct snd_soc_dai_link hx4700_dai = {
171 .name = "ak4641",
172 .stream_name = "AK4641",
173 .cpu_dai_name = "pxa2xx-i2s",
174 .codec_dai_name = "ak4641-hifi",
175 .platform_name = "pxa-pcm-audio",
176 .codec_name = "ak4641.0-0012",
177 .init = hx4700_ak4641_init,
178 .ops = &hx4700_ops,
179};
180
181/* hx4700 audio machine driver */
182static struct snd_soc_card snd_soc_card_hx4700 = {
183 .name = "iPAQ hx4700",
184 .dai_link = &hx4700_dai,
185 .num_links = 1,
186 .dapm_widgets = hx4700_dapm_widgets,
187 .num_dapm_widgets = ARRAY_SIZE(hx4700_dapm_widgets),
188 .dapm_routes = hx4700_audio_map,
189 .num_dapm_routes = ARRAY_SIZE(hx4700_audio_map),
190};
191
192static struct gpio hx4700_audio_gpios[] = {
193 { GPIO107_HX4700_SPK_nSD, GPIOF_OUT_INIT_HIGH, "SPK_POWER" },
194 { GPIO92_HX4700_HP_DRIVER, GPIOF_OUT_INIT_LOW, "EP_POWER" },
195};
196
197static int __devinit hx4700_audio_probe(struct platform_device *pdev)
198{
199 int ret;
200
201 if (!machine_is_h4700())
202 return -ENODEV;
203
204 ret = gpio_request_array(hx4700_audio_gpios,
205 ARRAY_SIZE(hx4700_audio_gpios));
206 if (ret)
207 return ret;
208
209 snd_soc_card_hx4700.dev = &pdev->dev;
210 ret = snd_soc_register_card(&snd_soc_card_hx4700);
211 if (ret)
212 return ret;
213
214 return 0;
215}
216
217static int __devexit hx4700_audio_remove(struct platform_device *pdev)
218{
219 snd_soc_jack_free_gpios(&hs_jack, 1, &hs_jack_gpio);
220 snd_soc_unregister_card(&snd_soc_card_hx4700);
221
222 gpio_set_value(GPIO92_HX4700_HP_DRIVER, 0);
223 gpio_set_value(GPIO107_HX4700_SPK_nSD, 0);
224
225 gpio_free_array(hx4700_audio_gpios, ARRAY_SIZE(hx4700_audio_gpios));
226 return 0;
227}
228
229static struct platform_driver hx4700_audio_driver = {
230 .driver = {
231 .name = "hx4700-audio",
232 .owner = THIS_MODULE,
233 .pm = &snd_soc_pm_ops,
234 },
235 .probe = hx4700_audio_probe,
236 .remove = __devexit_p(hx4700_audio_remove),
237};
238
239static int __init hx4700_modinit(void)
240{
241 return platform_driver_register(&hx4700_audio_driver);
242}
243module_init(hx4700_modinit);
244
245static void __exit hx4700_modexit(void)
246{
247 platform_driver_unregister(&hx4700_audio_driver);
248}
249
250module_exit(hx4700_modexit);
251
252MODULE_AUTHOR("Philipp Zabel");
253MODULE_DESCRIPTION("ALSA SoC iPAQ hx4700");
254MODULE_LICENSE("GPL");
255MODULE_ALIAS("platform:hx4700-audio");
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index a7d4999f9b24..da3ae4316cf2 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -276,7 +276,7 @@ static struct snd_soc_dai_link poodle_dai = {
276 .cpu_dai_name = "pxa2xx-i2s", 276 .cpu_dai_name = "pxa2xx-i2s",
277 .codec_dai_name = "wm8731-hifi", 277 .codec_dai_name = "wm8731-hifi",
278 .platform_name = "pxa-pcm-audio", 278 .platform_name = "pxa-pcm-audio",
279 .codec_name = "wm8731-codec.0-001b", 279 .codec_name = "wm8731.0-001b",
280 .init = poodle_wm8731_init, 280 .init = poodle_wm8731_init,
281 .ops = &poodle_ops, 281 .ops = &poodle_ops,
282}; 282};
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 8e1571350630..b253d864868a 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -42,6 +42,7 @@
42 42
43static int spitz_jack_func; 43static int spitz_jack_func;
44static int spitz_spk_func; 44static int spitz_spk_func;
45static int spitz_mic_gpio;
45 46
46static void spitz_ext_control(struct snd_soc_codec *codec) 47static void spitz_ext_control(struct snd_soc_codec *codec)
47{ 48{
@@ -217,14 +218,7 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol,
217static int spitz_mic_bias(struct snd_soc_dapm_widget *w, 218static int spitz_mic_bias(struct snd_soc_dapm_widget *w,
218 struct snd_kcontrol *k, int event) 219 struct snd_kcontrol *k, int event)
219{ 220{
220 if (machine_is_borzoi() || machine_is_spitz()) 221 gpio_set_value_cansleep(spitz_mic_gpio, SND_SOC_DAPM_EVENT_ON(event));
221 gpio_set_value(SPITZ_GPIO_MIC_BIAS,
222 SND_SOC_DAPM_EVENT_ON(event));
223
224 if (machine_is_akita())
225 gpio_set_value(AKITA_GPIO_MIC_BIAS,
226 SND_SOC_DAPM_EVENT_ON(event));
227
228 return 0; 222 return 0;
229} 223}
230 224
@@ -339,22 +333,45 @@ static int __init spitz_init(void)
339 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) 333 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita()))
340 return -ENODEV; 334 return -ENODEV;
341 335
336 if (machine_is_borzoi() || machine_is_spitz())
337 spitz_mic_gpio = SPITZ_GPIO_MIC_BIAS;
338 else
339 spitz_mic_gpio = AKITA_GPIO_MIC_BIAS;
340
341 ret = gpio_request(spitz_mic_gpio, "MIC GPIO");
342 if (ret)
343 goto err1;
344
345 ret = gpio_direction_output(spitz_mic_gpio, 0);
346 if (ret)
347 goto err2;
348
342 spitz_snd_device = platform_device_alloc("soc-audio", -1); 349 spitz_snd_device = platform_device_alloc("soc-audio", -1);
343 if (!spitz_snd_device) 350 if (!spitz_snd_device) {
344 return -ENOMEM; 351 ret = -ENOMEM;
352 goto err2;
353 }
345 354
346 platform_set_drvdata(spitz_snd_device, &snd_soc_spitz); 355 platform_set_drvdata(spitz_snd_device, &snd_soc_spitz);
347 ret = platform_device_add(spitz_snd_device);
348 356
357 ret = platform_device_add(spitz_snd_device);
349 if (ret) 358 if (ret)
350 platform_device_put(spitz_snd_device); 359 goto err3;
360
361 return 0;
351 362
363err3:
364 platform_device_put(spitz_snd_device);
365err2:
366 gpio_free(spitz_mic_gpio);
367err1:
352 return ret; 368 return ret;
353} 369}
354 370
355static void __exit spitz_exit(void) 371static void __exit spitz_exit(void)
356{ 372{
357 platform_device_unregister(spitz_snd_device); 373 platform_device_unregister(spitz_snd_device);
374 gpio_free(spitz_mic_gpio);
358} 375}
359 376
360module_init(spitz_init); 377module_init(spitz_init);
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index a3fdfb631469..459566bfcd35 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -162,3 +162,18 @@ config SND_SOC_SAMSUNG_SMDK_SPDIF
162 select SND_SAMSUNG_SPDIF 162 select SND_SAMSUNG_SPDIF
163 help 163 help
164 Say Y if you want to add support for SoC S/PDIF audio on the SMDK. 164 Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
165
166config SND_SOC_SMDK_WM8580_PCM
167 tristate "SoC PCM Audio support for WM8580 on SMDK"
168 depends on SND_SOC_SAMSUNG && (MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110)
169 select SND_SOC_WM8580
170 select SND_SAMSUNG_PCM
171 help
172 Say Y if you want to add support for SoC audio on the SMDK.
173
174config SND_SOC_SPEYSIDE
175 tristate "Audio support for Wolfson Speyside"
176 depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
177 select SND_SAMSUNG_I2S
178 select SND_SOC_WM8915
179 select SND_SOC_WM9081
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index 294dec05c26d..683843a2744f 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -34,6 +34,8 @@ snd-soc-smdk-wm9713-objs := smdk_wm9713.o
34snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o 34snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
35snd-soc-goni-wm8994-objs := goni_wm8994.o 35snd-soc-goni-wm8994-objs := goni_wm8994.o
36snd-soc-smdk-spdif-objs := smdk_spdif.o 36snd-soc-smdk-spdif-objs := smdk_spdif.o
37snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o
38snd-soc-speyside-objs := speyside.o
37 39
38obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o 40obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
39obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 41obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -51,3 +53,5 @@ obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o
51obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o 53obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o
52obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o 54obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o
53obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o 55obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o
56obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o
57obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o
diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c
index 0e80daee8b6f..eb6d72ed55a7 100644
--- a/sound/soc/samsung/goni_wm8994.c
+++ b/sound/soc/samsung/goni_wm8994.c
@@ -246,7 +246,6 @@ static struct snd_soc_dai_link goni_dai[] = {
246 .stream_name = "Voice", 246 .stream_name = "Voice",
247 .cpu_dai_name = "goni-voice-dai", 247 .cpu_dai_name = "goni-voice-dai",
248 .codec_dai_name = "wm8994-aif2", 248 .codec_dai_name = "wm8994-aif2",
249 .platform_name = "samsung-audio",
250 .codec_name = "wm8994-codec.0-001a", 249 .codec_name = "wm8994-codec.0-001a",
251 .ops = &goni_voice_ops, 250 .ops = &goni_voice_ops,
252}, 251},
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index 452230975632..16152ed08648 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -432,7 +432,6 @@ static struct snd_soc_dai_link neo1973_dai[] = {
432{ /* Voice via BT */ 432{ /* Voice via BT */
433 .name = "Bluetooth", 433 .name = "Bluetooth",
434 .stream_name = "Voice", 434 .stream_name = "Voice",
435 .platform_name = "samsung-audio",
436 .cpu_dai_name = "dfbmcs320-pcm", 435 .cpu_dai_name = "dfbmcs320-pcm",
437 .codec_dai_name = "wm8753-voice", 436 .codec_dai_name = "wm8753-voice",
438 .codec_name = "wm8753-codec.0-001a", 437 .codec_name = "wm8753-codec.0-001a",
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c
new file mode 100644
index 000000000000..0d12092df164
--- /dev/null
+++ b/sound/soc/samsung/smdk_wm8580pcm.c
@@ -0,0 +1,206 @@
1/*
2 * sound/soc/samsung/smdk_wm8580pcm.c
3 *
4 * Copyright (c) 2011 Samsung Electronics Co. Ltd
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11#include <sound/soc.h>
12#include <sound/pcm_params.h>
13#include <sound/pcm.h>
14
15#include <asm/mach-types.h>
16
17#include "../codecs/wm8580.h"
18#include "dma.h"
19#include "pcm.h"
20
21/*
22 * Board Settings:
23 * o '1' means 'ON'
24 * o '0' means 'OFF'
25 * o 'X' means 'Don't care'
26 *
27 * SMDK6410, SMDK6440, SMDK6450 Base B/D: CFG1-0000, CFG2-1111
28 * SMDKC110, SMDKV210: CFGB11-100100, CFGB12-0000
29 */
30
31#define SMDK_WM8580_EXT_OSC 12000000
32#define SMDK_WM8580_EXT_MCLK 4096000
33#define SMDK_WM8580_EXT_VOICE 2048000
34
35static unsigned long mclk_freq;
36static unsigned long xtal_freq;
37
38/*
39 * If MCLK clock directly gets from XTAL, we don't have to use PLL
40 * to make MCLK, but if XTAL clock source connects with other codec
41 * pin (like XTI), we should have to set codec's PLL to make MCLK.
42 * Because Samsung SoC does not support pcmcdclk output like I2S.
43 */
44
45static int smdk_wm8580_pcm_hw_params(struct snd_pcm_substream *substream,
46 struct snd_pcm_hw_params *params)
47{
48 struct snd_soc_pcm_runtime *rtd = substream->private_data;
49 struct snd_soc_dai *codec_dai = rtd->codec_dai;
50 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
51 int rfs, ret;
52
53 switch (params_rate(params)) {
54 case 8000:
55 break;
56 default:
57 printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n",
58 __func__, __LINE__, params_rate(params));
59 return -EINVAL;
60 }
61
62 rfs = mclk_freq / params_rate(params) / 2;
63
64 /* Set the codec DAI configuration */
65 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B
66 | SND_SOC_DAIFMT_IB_NF
67 | SND_SOC_DAIFMT_CBS_CFS);
68 if (ret < 0)
69 return ret;
70
71 /* Set the cpu DAI configuration */
72 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B
73 | SND_SOC_DAIFMT_IB_NF
74 | SND_SOC_DAIFMT_CBS_CFS);
75 if (ret < 0)
76 return ret;
77
78 if (mclk_freq == xtal_freq) {
79 ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_MCLK,
80 mclk_freq, SND_SOC_CLOCK_IN);
81 if (ret < 0)
82 return ret;
83
84 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
85 WM8580_CLKSRC_MCLK);
86 if (ret < 0)
87 return ret;
88 } else {
89 ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_PLLA,
90 mclk_freq, SND_SOC_CLOCK_IN);
91 if (ret < 0)
92 return ret;
93
94 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
95 WM8580_CLKSRC_PLLA);
96 if (ret < 0)
97 return ret;
98
99 ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0,
100 xtal_freq, mclk_freq);
101 if (ret < 0)
102 return ret;
103 }
104
105 /* Set PCM source clock on CPU */
106 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_PCM_CLKSRC_MUX,
107 mclk_freq, SND_SOC_CLOCK_IN);
108 if (ret < 0)
109 return ret;
110
111 /* Set SCLK_DIV for making bclk */
112 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_PCM_SCLK_PER_FS, rfs);
113 if (ret < 0)
114 return ret;
115
116 return 0;
117}
118
119static struct snd_soc_ops smdk_wm8580_pcm_ops = {
120 .hw_params = smdk_wm8580_pcm_hw_params,
121};
122
123static struct snd_soc_dai_link smdk_dai[] = {
124 {
125 .name = "WM8580 PAIF PCM RX",
126 .stream_name = "Playback",
127 .cpu_dai_name = "samsung-pcm.0",
128 .codec_dai_name = "wm8580-hifi-playback",
129 .platform_name = "samsung-audio",
130 .codec_name = "wm8580-codec.0-001b",
131 .ops = &smdk_wm8580_pcm_ops,
132 }, {
133 .name = "WM8580 PAIF PCM TX",
134 .stream_name = "Capture",
135 .cpu_dai_name = "samsung-pcm.0",
136 .codec_dai_name = "wm8580-hifi-capture",
137 .platform_name = "samsung-audio",
138 .codec_name = "wm8580-codec.0-001b",
139 .ops = &smdk_wm8580_pcm_ops,
140 },
141};
142
143static struct snd_soc_card smdk_pcm = {
144 .name = "SMDK-PCM",
145 .dai_link = smdk_dai,
146 .num_links = 2,
147};
148
149/*
150 * After SMDKC110 Base Board's Rev is '0.1', 12MHz External OSC(X1)
151 * is absent (or not connected), so we connect EXT_VOICE_CLK(OSC4),
152 * 2.0484Mhz, directly with MCLK both Codec and SoC.
153 */
154static int __devinit snd_smdk_probe(struct platform_device *pdev)
155{
156 int ret = 0;
157
158 xtal_freq = SMDK_WM8580_EXT_OSC;
159 mclk_freq = SMDK_WM8580_EXT_MCLK;
160
161 if (machine_is_smdkc110() || machine_is_smdkv210())
162 xtal_freq = mclk_freq = SMDK_WM8580_EXT_VOICE;
163
164 smdk_pcm.dev = &pdev->dev;
165 ret = snd_soc_register_card(&smdk_pcm);
166 if (ret) {
167 dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret);
168 return ret;
169 }
170
171 return 0;
172}
173
174static int __devexit snd_smdk_remove(struct platform_device *pdev)
175{
176 snd_soc_unregister_card(&smdk_pcm);
177 platform_set_drvdata(pdev, NULL);
178 return 0;
179}
180
181static struct platform_driver snd_smdk_driver = {
182 .driver = {
183 .owner = THIS_MODULE,
184 .name = "samsung-smdk-pcm",
185 },
186 .probe = snd_smdk_probe,
187 .remove = __devexit_p(snd_smdk_remove),
188};
189
190static int __init smdk_audio_init(void)
191{
192 return platform_driver_register(&snd_smdk_driver);
193}
194
195module_init(smdk_audio_init);
196
197static void __exit smdk_audio_exit(void)
198{
199 platform_driver_unregister(&snd_smdk_driver);
200}
201
202module_exit(smdk_audio_exit);
203
204MODULE_AUTHOR("Sangbeom Kim, <sbkim73@samsung.com>");
205MODULE_DESCRIPTION("ALSA SoC SMDK WM8580 for PCM");
206MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
new file mode 100644
index 000000000000..360a333cb7c0
--- /dev/null
+++ b/sound/soc/samsung/speyside.c
@@ -0,0 +1,332 @@
1/*
2 * Speyside audio support
3 *
4 * Copyright 2011 Wolfson Microelectronics
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <sound/soc.h>
13#include <sound/soc-dapm.h>
14#include <sound/jack.h>
15#include <linux/gpio.h>
16
17#include "../codecs/wm8915.h"
18#include "../codecs/wm9081.h"
19
20#define WM8915_HPSEL_GPIO 214
21
22static int speyside_set_bias_level(struct snd_soc_card *card,
23 enum snd_soc_bias_level level)
24{
25 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
26 int ret;
27
28 switch (level) {
29 case SND_SOC_BIAS_STANDBY:
30 ret = snd_soc_dai_set_sysclk(codec_dai, WM8915_SYSCLK_MCLK1,
31 32768, SND_SOC_CLOCK_IN);
32 if (ret < 0)
33 return ret;
34
35 ret = snd_soc_dai_set_pll(codec_dai, WM8915_FLL_MCLK1,
36 0, 0, 0);
37 if (ret < 0) {
38 pr_err("Failed to stop FLL\n");
39 return ret;
40 }
41
42 default:
43 break;
44 }
45
46 return 0;
47}
48
49static int speyside_hw_params(struct snd_pcm_substream *substream,
50 struct snd_pcm_hw_params *params)
51{
52 struct snd_soc_pcm_runtime *rtd = substream->private_data;
53 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
54 struct snd_soc_dai *codec_dai = rtd->codec_dai;
55 int ret;
56
57 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
58 | SND_SOC_DAIFMT_NB_NF
59 | SND_SOC_DAIFMT_CBM_CFM);
60 if (ret < 0)
61 return ret;
62
63 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
64 | SND_SOC_DAIFMT_NB_NF
65 | SND_SOC_DAIFMT_CBM_CFM);
66 if (ret < 0)
67 return ret;
68
69 ret = snd_soc_dai_set_pll(codec_dai, 0, WM8915_FLL_MCLK1,
70 32768, 256 * 48000);
71 if (ret < 0)
72 return ret;
73
74 ret = snd_soc_dai_set_sysclk(codec_dai, WM8915_SYSCLK_FLL,
75 256 * 48000, SND_SOC_CLOCK_IN);
76 if (ret < 0)
77 return ret;
78
79 return 0;
80}
81
82static struct snd_soc_ops speyside_ops = {
83 .hw_params = speyside_hw_params,
84};
85
86static struct snd_soc_jack speyside_headset;
87
88/* Headset jack detection DAPM pins */
89static struct snd_soc_jack_pin speyside_headset_pins[] = {
90 {
91 .pin = "Headset Mic",
92 .mask = SND_JACK_MICROPHONE,
93 },
94 {
95 .pin = "Headphone",
96 .mask = SND_JACK_HEADPHONE,
97 },
98};
99
100/* Default the headphone selection to active high */
101static int speyside_jack_polarity;
102
103static int speyside_get_micbias(struct snd_soc_dapm_widget *source,
104 struct snd_soc_dapm_widget *sink)
105{
106 if (speyside_jack_polarity && (strcmp(source->name, "MICB1") == 0))
107 return 1;
108 if (!speyside_jack_polarity && (strcmp(source->name, "MICB2") == 0))
109 return 1;
110
111 return 0;
112}
113
114static void speyside_set_polarity(struct snd_soc_codec *codec,
115 int polarity)
116{
117 speyside_jack_polarity = !polarity;
118 gpio_direction_output(WM8915_HPSEL_GPIO, speyside_jack_polarity);
119
120 /* Re-run DAPM to make sure we're using the correct mic bias */
121 snd_soc_dapm_sync(&codec->dapm);
122}
123
124static int speyside_wm8915_init(struct snd_soc_pcm_runtime *rtd)
125{
126 struct snd_soc_dai *dai = rtd->codec_dai;
127 struct snd_soc_codec *codec = rtd->codec;
128 int ret;
129
130 ret = snd_soc_dai_set_sysclk(dai, WM8915_SYSCLK_MCLK1, 32768, 0);
131 if (ret < 0)
132 return ret;
133
134 ret = gpio_request(WM8915_HPSEL_GPIO, "HP_SEL");
135 if (ret != 0)
136 pr_err("Failed to request HP_SEL GPIO: %d\n", ret);
137 gpio_direction_output(WM8915_HPSEL_GPIO, speyside_jack_polarity);
138
139 ret = snd_soc_jack_new(codec, "Headset",
140 SND_JACK_HEADSET | SND_JACK_BTN_0,
141 &speyside_headset);
142 if (ret)
143 return ret;
144
145 ret = snd_soc_jack_add_pins(&speyside_headset,
146 ARRAY_SIZE(speyside_headset_pins),
147 speyside_headset_pins);
148 if (ret)
149 return ret;
150
151 wm8915_detect(codec, &speyside_headset, speyside_set_polarity);
152
153 return 0;
154}
155
156static int speyside_late_probe(struct snd_soc_card *card)
157{
158 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
159 snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic");
160 snd_soc_dapm_ignore_suspend(&card->dapm, "Main AMIC");
161 snd_soc_dapm_ignore_suspend(&card->dapm, "Main DMIC");
162 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
163 snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Output");
164 snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Input");
165
166 return 0;
167}
168
169static struct snd_soc_dai_link speyside_dai[] = {
170 {
171 .name = "CPU",
172 .stream_name = "CPU",
173 .cpu_dai_name = "samsung-i2s.0",
174 .codec_dai_name = "wm8915-aif1",
175 .platform_name = "samsung-audio",
176 .codec_name = "wm8915.1-001a",
177 .init = speyside_wm8915_init,
178 .ops = &speyside_ops,
179 },
180 {
181 .name = "Baseband",
182 .stream_name = "Baseband",
183 .cpu_dai_name = "wm8915-aif2",
184 .codec_dai_name = "wm1250-ev1",
185 .codec_name = "wm1250-ev1.1-0027",
186 .ops = &speyside_ops,
187 .ignore_suspend = 1,
188 },
189};
190
191static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm)
192{
193 snd_soc_dapm_nc_pin(dapm, "LINEOUT");
194
195 /* At any time the WM9081 is active it will have this clock */
196 return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK,
197 48000 * 256, 0);
198}
199
200static struct snd_soc_aux_dev speyside_aux_dev[] = {
201 {
202 .name = "wm9081",
203 .codec_name = "wm9081.1-006c",
204 .init = speyside_wm9081_init,
205 },
206};
207
208static struct snd_soc_codec_conf speyside_codec_conf[] = {
209 {
210 .dev_name = "wm9081.1-006c",
211 .name_prefix = "Sub",
212 },
213};
214
215static const struct snd_kcontrol_new controls[] = {
216 SOC_DAPM_PIN_SWITCH("Main Speaker"),
217 SOC_DAPM_PIN_SWITCH("Main DMIC"),
218 SOC_DAPM_PIN_SWITCH("Main AMIC"),
219 SOC_DAPM_PIN_SWITCH("WM1250 Input"),
220 SOC_DAPM_PIN_SWITCH("WM1250 Output"),
221};
222
223static struct snd_soc_dapm_widget widgets[] = {
224 SND_SOC_DAPM_HP("Headphone", NULL),
225 SND_SOC_DAPM_MIC("Headset Mic", NULL),
226
227 SND_SOC_DAPM_SPK("Main Speaker", NULL),
228
229 SND_SOC_DAPM_MIC("Main AMIC", NULL),
230 SND_SOC_DAPM_MIC("Main DMIC", NULL),
231};
232
233static struct snd_soc_dapm_route audio_paths[] = {
234 { "IN1RN", NULL, "MICB1" },
235 { "IN1RP", NULL, "MICB1" },
236 { "IN1RN", NULL, "MICB2" },
237 { "IN1RP", NULL, "MICB2" },
238 { "MICB1", NULL, "Headset Mic", speyside_get_micbias },
239 { "MICB2", NULL, "Headset Mic", speyside_get_micbias },
240
241 { "IN1LP", NULL, "MICB2" },
242 { "IN1RN", NULL, "MICB1" },
243 { "MICB2", NULL, "Main AMIC" },
244
245 { "DMIC1DAT", NULL, "MICB1" },
246 { "DMIC2DAT", NULL, "MICB1" },
247 { "MICB1", NULL, "Main DMIC" },
248
249 { "Headphone", NULL, "HPOUT1L" },
250 { "Headphone", NULL, "HPOUT1R" },
251
252 { "Sub IN1", NULL, "HPOUT2L" },
253 { "Sub IN2", NULL, "HPOUT2R" },
254
255 { "Main Speaker", NULL, "Sub SPKN" },
256 { "Main Speaker", NULL, "Sub SPKP" },
257 { "Main Speaker", NULL, "SPKDAT" },
258};
259
260static struct snd_soc_card speyside = {
261 .name = "Speyside",
262 .dai_link = speyside_dai,
263 .num_links = ARRAY_SIZE(speyside_dai),
264 .aux_dev = speyside_aux_dev,
265 .num_aux_devs = ARRAY_SIZE(speyside_aux_dev),
266 .codec_conf = speyside_codec_conf,
267 .num_configs = ARRAY_SIZE(speyside_codec_conf),
268
269 .set_bias_level = speyside_set_bias_level,
270
271 .controls = controls,
272 .num_controls = ARRAY_SIZE(controls),
273 .dapm_widgets = widgets,
274 .num_dapm_widgets = ARRAY_SIZE(widgets),
275 .dapm_routes = audio_paths,
276 .num_dapm_routes = ARRAY_SIZE(audio_paths),
277
278 .late_probe = speyside_late_probe,
279};
280
281static __devinit int speyside_probe(struct platform_device *pdev)
282{
283 struct snd_soc_card *card = &speyside;
284 int ret;
285
286 card->dev = &pdev->dev;
287
288 ret = snd_soc_register_card(card);
289 if (ret) {
290 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
291 ret);
292 return ret;
293 }
294
295 return 0;
296}
297
298static int __devexit speyside_remove(struct platform_device *pdev)
299{
300 struct snd_soc_card *card = platform_get_drvdata(pdev);
301
302 snd_soc_unregister_card(card);
303
304 return 0;
305}
306
307static struct platform_driver speyside_driver = {
308 .driver = {
309 .name = "speyside",
310 .owner = THIS_MODULE,
311 .pm = &snd_soc_pm_ops,
312 },
313 .probe = speyside_probe,
314 .remove = __devexit_p(speyside_remove),
315};
316
317static int __init speyside_audio_init(void)
318{
319 return platform_driver_register(&speyside_driver);
320}
321module_init(speyside_audio_init);
322
323static void __exit speyside_audio_exit(void)
324{
325 platform_driver_unregister(&speyside_driver);
326}
327module_exit(speyside_audio_exit);
328
329MODULE_DESCRIPTION("Speyside audio support");
330MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
331MODULE_LICENSE("GPL");
332MODULE_ALIAS("platform:speyside");
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 23c0e83d4c19..4a9da6b5f4e1 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -86,8 +86,8 @@
86#define SE (1 << 0) /* Fix the master clock */ 86#define SE (1 << 0) /* Fix the master clock */
87 87
88/* CLK_RST */ 88/* CLK_RST */
89#define B_CLK 0x00000010 89#define CRB (1 << 4)
90#define A_CLK 0x00000001 90#define CRA (1 << 0)
91 91
92/* IO SHIFT / MACRO */ 92/* IO SHIFT / MACRO */
93#define BI_SHIFT 12 93#define BI_SHIFT 12
@@ -146,11 +146,20 @@ struct fsi_priv {
146 void __iomem *base; 146 void __iomem *base;
147 struct fsi_master *master; 147 struct fsi_master *master;
148 148
149 int chan_num;
150 struct fsi_stream playback; 149 struct fsi_stream playback;
151 struct fsi_stream capture; 150 struct fsi_stream capture;
152 151
152 int chan_num:16;
153 int clk_master:1;
154
153 long rate; 155 long rate;
156
157 /* for suspend/resume */
158 u32 saved_do_fmt;
159 u32 saved_di_fmt;
160 u32 saved_ckg1;
161 u32 saved_ckg2;
162 u32 saved_out_sel;
154}; 163};
155 164
156struct fsi_core { 165struct fsi_core {
@@ -171,6 +180,14 @@ struct fsi_master {
171 struct fsi_core *core; 180 struct fsi_core *core;
172 struct sh_fsi_platform_info *info; 181 struct sh_fsi_platform_info *info;
173 spinlock_t lock; 182 spinlock_t lock;
183
184 /* for suspend/resume */
185 u32 saved_a_mclk;
186 u32 saved_b_mclk;
187 u32 saved_iemsk;
188 u32 saved_imsk;
189 u32 saved_clk_rst;
190 u32 saved_soft_rst;
174}; 191};
175 192
176/* 193/*
@@ -244,6 +261,11 @@ static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
244 return fsi->master; 261 return fsi->master;
245} 262}
246 263
264static int fsi_is_clk_master(struct fsi_priv *fsi)
265{
266 return fsi->clk_master;
267}
268
247static int fsi_is_port_a(struct fsi_priv *fsi) 269static int fsi_is_port_a(struct fsi_priv *fsi)
248{ 270{
249 return fsi->master->base == fsi->base; 271 return fsi->master->base == fsi->base;
@@ -535,20 +557,45 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
535} 557}
536 558
537/* 559/*
538 * ctrl function 560 * clock function
539 */ 561 */
562#define fsi_module_init(m, d) __fsi_module_clk_ctrl(m, d, 1)
563#define fsi_module_kill(m, d) __fsi_module_clk_ctrl(m, d, 0)
564static void __fsi_module_clk_ctrl(struct fsi_master *master,
565 struct device *dev,
566 int enable)
567{
568 pm_runtime_get_sync(dev);
569
570 if (enable) {
571 /* enable only SR */
572 fsi_master_mask_set(master, SOFT_RST, FSISR, FSISR);
573 fsi_master_mask_set(master, SOFT_RST, PASR | PBSR, 0);
574 } else {
575 /* clear all registers */
576 fsi_master_mask_set(master, SOFT_RST, FSISR, 0);
577 }
540 578
541static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable) 579 pm_runtime_put_sync(dev);
580}
581
582#define fsi_port_start(f) __fsi_port_clk_ctrl(f, 1)
583#define fsi_port_stop(f) __fsi_port_clk_ctrl(f, 0)
584static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int enable)
542{ 585{
543 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
544 struct fsi_master *master = fsi_get_master(fsi); 586 struct fsi_master *master = fsi_get_master(fsi);
587 u32 soft = fsi_is_port_a(fsi) ? PASR : PBSR;
588 u32 clk = fsi_is_port_a(fsi) ? CRA : CRB;
589 int is_master = fsi_is_clk_master(fsi);
545 590
546 if (enable) 591 fsi_master_mask_set(master, SOFT_RST, soft, (enable) ? soft : 0);
547 fsi_master_mask_set(master, CLK_RST, val, val); 592 if (is_master)
548 else 593 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
549 fsi_master_mask_set(master, CLK_RST, val, 0);
550} 594}
551 595
596/*
597 * ctrl function
598 */
552static void fsi_fifo_init(struct fsi_priv *fsi, 599static void fsi_fifo_init(struct fsi_priv *fsi,
553 int is_play, 600 int is_play,
554 struct snd_soc_dai *dai) 601 struct snd_soc_dai *dai)
@@ -601,18 +648,6 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
601 } 648 }
602} 649}
603 650
604static void fsi_soft_all_reset(struct fsi_master *master)
605{
606 /* port AB reset */
607 fsi_master_mask_set(master, SOFT_RST, PASR | PBSR, 0);
608 mdelay(10);
609
610 /* soft reset */
611 fsi_master_mask_set(master, SOFT_RST, FSISR, 0);
612 fsi_master_mask_set(master, SOFT_RST, FSISR, FSISR);
613 mdelay(10);
614}
615
616static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream) 651static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
617{ 652{
618 struct snd_pcm_runtime *runtime; 653 struct snd_pcm_runtime *runtime;
@@ -793,14 +828,13 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
793 struct fsi_priv *fsi = fsi_get_priv(substream); 828 struct fsi_priv *fsi = fsi_get_priv(substream);
794 int is_play = fsi_is_play(substream); 829 int is_play = fsi_is_play(substream);
795 struct fsi_master *master = fsi_get_master(fsi); 830 struct fsi_master *master = fsi_get_master(fsi);
796 set_rate_func set_rate; 831 set_rate_func set_rate = fsi_get_info_set_rate(master);
797 832
798 fsi_irq_disable(fsi, is_play); 833 fsi_irq_disable(fsi, is_play);
799 fsi_clk_ctrl(fsi, 0);
800 834
801 set_rate = fsi_get_info_set_rate(master); 835 if (fsi_is_clk_master(fsi))
802 if (set_rate && fsi->rate)
803 set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0); 836 set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
837
804 fsi->rate = 0; 838 fsi->rate = 0;
805 839
806 pm_runtime_put_sync(dai->dev); 840 pm_runtime_put_sync(dai->dev);
@@ -821,8 +855,10 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
821 frames_to_bytes(runtime, runtime->period_size)); 855 frames_to_bytes(runtime, runtime->period_size));
822 ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); 856 ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
823 fsi_irq_enable(fsi, is_play); 857 fsi_irq_enable(fsi, is_play);
858 fsi_port_start(fsi);
824 break; 859 break;
825 case SNDRV_PCM_TRIGGER_STOP: 860 case SNDRV_PCM_TRIGGER_STOP:
861 fsi_port_stop(fsi);
826 fsi_irq_disable(fsi, is_play); 862 fsi_irq_disable(fsi, is_play);
827 fsi_stream_pop(fsi, is_play); 863 fsi_stream_pop(fsi, is_play);
828 break; 864 break;
@@ -876,6 +912,8 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
876static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 912static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
877{ 913{
878 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); 914 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
915 struct fsi_master *master = fsi_get_master(fsi);
916 set_rate_func set_rate = fsi_get_info_set_rate(master);
879 u32 flags = fsi_get_info_flags(fsi); 917 u32 flags = fsi_get_info_flags(fsi);
880 u32 data = 0; 918 u32 data = 0;
881 int ret; 919 int ret;
@@ -886,6 +924,7 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
886 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 924 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
887 case SND_SOC_DAIFMT_CBM_CFM: 925 case SND_SOC_DAIFMT_CBM_CFM:
888 data = DIMD | DOMD; 926 data = DIMD | DOMD;
927 fsi->clk_master = 1;
889 break; 928 break;
890 case SND_SOC_DAIFMT_CBS_CFS: 929 case SND_SOC_DAIFMT_CBS_CFS:
891 break; 930 break;
@@ -893,6 +932,13 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
893 ret = -EINVAL; 932 ret = -EINVAL;
894 goto set_fmt_exit; 933 goto set_fmt_exit;
895 } 934 }
935
936 if (fsi_is_clk_master(fsi) && !set_rate) {
937 dev_err(dai->dev, "platform doesn't have set_rate\n");
938 ret = -EINVAL;
939 goto set_fmt_exit;
940 }
941
896 fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data); 942 fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data);
897 943
898 /* set format */ 944 /* set format */
@@ -919,13 +965,12 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
919{ 965{
920 struct fsi_priv *fsi = fsi_get_priv(substream); 966 struct fsi_priv *fsi = fsi_get_priv(substream);
921 struct fsi_master *master = fsi_get_master(fsi); 967 struct fsi_master *master = fsi_get_master(fsi);
922 set_rate_func set_rate; 968 set_rate_func set_rate = fsi_get_info_set_rate(master);
923 int fsi_ver = master->core->ver; 969 int fsi_ver = master->core->ver;
924 long rate = params_rate(params); 970 long rate = params_rate(params);
925 int ret; 971 int ret;
926 972
927 set_rate = fsi_get_info_set_rate(master); 973 if (!fsi_is_clk_master(fsi))
928 if (!set_rate)
929 return 0; 974 return 0;
930 975
931 ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1); 976 ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1);
@@ -987,7 +1032,6 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
987 1032
988 fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data); 1033 fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data);
989 udelay(10); 1034 udelay(10);
990 fsi_clk_ctrl(fsi, 1);
991 ret = 0; 1035 ret = 0;
992 } 1036 }
993 1037
@@ -1202,9 +1246,7 @@ static int fsi_probe(struct platform_device *pdev)
1202 pm_runtime_enable(&pdev->dev); 1246 pm_runtime_enable(&pdev->dev);
1203 dev_set_drvdata(&pdev->dev, master); 1247 dev_set_drvdata(&pdev->dev, master);
1204 1248
1205 pm_runtime_get_sync(&pdev->dev); 1249 fsi_module_init(master, &pdev->dev);
1206 fsi_soft_all_reset(master);
1207 pm_runtime_put_sync(&pdev->dev);
1208 1250
1209 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, 1251 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED,
1210 id_entry->name, master); 1252 id_entry->name, master);
@@ -1248,6 +1290,8 @@ static int fsi_remove(struct platform_device *pdev)
1248 1290
1249 master = dev_get_drvdata(&pdev->dev); 1291 master = dev_get_drvdata(&pdev->dev);
1250 1292
1293 fsi_module_kill(master, &pdev->dev);
1294
1251 free_irq(master->irq, master); 1295 free_irq(master->irq, master);
1252 pm_runtime_disable(&pdev->dev); 1296 pm_runtime_disable(&pdev->dev);
1253 1297
@@ -1260,6 +1304,82 @@ static int fsi_remove(struct platform_device *pdev)
1260 return 0; 1304 return 0;
1261} 1305}
1262 1306
1307static void __fsi_suspend(struct fsi_priv *fsi,
1308 struct device *dev,
1309 set_rate_func set_rate)
1310{
1311 fsi->saved_do_fmt = fsi_reg_read(fsi, DO_FMT);
1312 fsi->saved_di_fmt = fsi_reg_read(fsi, DI_FMT);
1313 fsi->saved_ckg1 = fsi_reg_read(fsi, CKG1);
1314 fsi->saved_ckg2 = fsi_reg_read(fsi, CKG2);
1315 fsi->saved_out_sel = fsi_reg_read(fsi, OUT_SEL);
1316
1317 if (fsi_is_clk_master(fsi))
1318 set_rate(dev, fsi_is_port_a(fsi), fsi->rate, 0);
1319}
1320
1321static void __fsi_resume(struct fsi_priv *fsi,
1322 struct device *dev,
1323 set_rate_func set_rate)
1324{
1325 fsi_reg_write(fsi, DO_FMT, fsi->saved_do_fmt);
1326 fsi_reg_write(fsi, DI_FMT, fsi->saved_di_fmt);
1327 fsi_reg_write(fsi, CKG1, fsi->saved_ckg1);
1328 fsi_reg_write(fsi, CKG2, fsi->saved_ckg2);
1329 fsi_reg_write(fsi, OUT_SEL, fsi->saved_out_sel);
1330
1331 if (fsi_is_clk_master(fsi))
1332 set_rate(dev, fsi_is_port_a(fsi), fsi->rate, 1);
1333}
1334
1335static int fsi_suspend(struct device *dev)
1336{
1337 struct fsi_master *master = dev_get_drvdata(dev);
1338 set_rate_func set_rate = fsi_get_info_set_rate(master);
1339
1340 pm_runtime_get_sync(dev);
1341
1342 __fsi_suspend(&master->fsia, dev, set_rate);
1343 __fsi_suspend(&master->fsib, dev, set_rate);
1344
1345 master->saved_a_mclk = fsi_core_read(master, a_mclk);
1346 master->saved_b_mclk = fsi_core_read(master, b_mclk);
1347 master->saved_iemsk = fsi_core_read(master, iemsk);
1348 master->saved_imsk = fsi_core_read(master, imsk);
1349 master->saved_clk_rst = fsi_master_read(master, CLK_RST);
1350 master->saved_soft_rst = fsi_master_read(master, SOFT_RST);
1351
1352 fsi_module_kill(master, dev);
1353
1354 pm_runtime_put_sync(dev);
1355
1356 return 0;
1357}
1358
1359static int fsi_resume(struct device *dev)
1360{
1361 struct fsi_master *master = dev_get_drvdata(dev);
1362 set_rate_func set_rate = fsi_get_info_set_rate(master);
1363
1364 pm_runtime_get_sync(dev);
1365
1366 fsi_module_init(master, dev);
1367
1368 fsi_master_mask_set(master, SOFT_RST, 0xffff, master->saved_soft_rst);
1369 fsi_master_mask_set(master, CLK_RST, 0xffff, master->saved_clk_rst);
1370 fsi_core_mask_set(master, a_mclk, 0xffff, master->saved_a_mclk);
1371 fsi_core_mask_set(master, b_mclk, 0xffff, master->saved_b_mclk);
1372 fsi_core_mask_set(master, iemsk, 0xffff, master->saved_iemsk);
1373 fsi_core_mask_set(master, imsk, 0xffff, master->saved_imsk);
1374
1375 __fsi_resume(&master->fsia, dev, set_rate);
1376 __fsi_resume(&master->fsib, dev, set_rate);
1377
1378 pm_runtime_put_sync(dev);
1379
1380 return 0;
1381}
1382
1263static int fsi_runtime_nop(struct device *dev) 1383static int fsi_runtime_nop(struct device *dev)
1264{ 1384{
1265 /* Runtime PM callback shared between ->runtime_suspend() 1385 /* Runtime PM callback shared between ->runtime_suspend()
@@ -1273,6 +1393,8 @@ static int fsi_runtime_nop(struct device *dev)
1273} 1393}
1274 1394
1275static struct dev_pm_ops fsi_pm_ops = { 1395static struct dev_pm_ops fsi_pm_ops = {
1396 .suspend = fsi_suspend,
1397 .resume = fsi_resume,
1276 .runtime_suspend = fsi_runtime_nop, 1398 .runtime_suspend = fsi_runtime_nop,
1277 .runtime_resume = fsi_runtime_nop, 1399 .runtime_resume = fsi_runtime_nop,
1278}; 1400};
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 5d76da43b14c..06b7b81a1601 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -20,40 +20,28 @@
20 20
21#include <trace/events/asoc.h> 21#include <trace/events/asoc.h>
22 22
23static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, 23#ifdef CONFIG_SPI_MASTER
24 unsigned int reg) 24static int do_spi_write(void *control, const char *data, int len)
25{ 25{
26 struct spi_device *spi = control;
26 int ret; 27 int ret;
27 unsigned int val;
28
29 if (reg >= codec->driver->reg_cache_size ||
30 snd_soc_codec_volatile_register(codec, reg) ||
31 codec->cache_bypass) {
32 if (codec->cache_only)
33 return -1;
34
35 BUG_ON(!codec->hw_read);
36 return codec->hw_read(codec, reg);
37 }
38 28
39 ret = snd_soc_cache_read(codec, reg, &val); 29 ret = spi_write(spi, data, len);
40 if (ret < 0) 30 if (ret < 0)
41 return -1; 31 return ret;
42 return val; 32
33 return len;
43} 34}
35#endif
44 36
45static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, 37static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
46 unsigned int value) 38 unsigned int value, const void *data, int len)
47{ 39{
48 u8 data[2];
49 int ret; 40 int ret;
50 41
51 data[0] = (reg << 4) | ((value >> 8) & 0x000f);
52 data[1] = value & 0x00ff;
53
54 if (!snd_soc_codec_volatile_register(codec, reg) && 42 if (!snd_soc_codec_volatile_register(codec, reg) &&
55 reg < codec->driver->reg_cache_size && 43 reg < codec->driver->reg_cache_size &&
56 !codec->cache_bypass) { 44 !codec->cache_bypass) {
57 ret = snd_soc_cache_write(codec, reg, value); 45 ret = snd_soc_cache_write(codec, reg, value);
58 if (ret < 0) 46 if (ret < 0)
59 return -1; 47 return -1;
@@ -64,8 +52,8 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
64 return 0; 52 return 0;
65 } 53 }
66 54
67 ret = codec->hw_write(codec->control_data, data, 2); 55 ret = codec->hw_write(codec->control_data, data, len);
68 if (ret == 2) 56 if (ret == len)
69 return 0; 57 return 0;
70 if (ret < 0) 58 if (ret < 0)
71 return ret; 59 return ret;
@@ -73,50 +61,19 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
73 return -EIO; 61 return -EIO;
74} 62}
75 63
76#if defined(CONFIG_SPI_MASTER) 64static unsigned int do_hw_read(struct snd_soc_codec *codec, unsigned int reg)
77static int snd_soc_4_12_spi_write(void *control_data, const char *data,
78 int len)
79{
80 struct spi_device *spi = control_data;
81 struct spi_transfer t;
82 struct spi_message m;
83 u8 msg[2];
84
85 if (len <= 0)
86 return 0;
87
88 msg[0] = data[1];
89 msg[1] = data[0];
90
91 spi_message_init(&m);
92 memset(&t, 0, sizeof t);
93
94 t.tx_buf = &msg[0];
95 t.len = len;
96
97 spi_message_add_tail(&t, &m);
98 spi_sync(spi, &m);
99
100 return len;
101}
102#else
103#define snd_soc_4_12_spi_write NULL
104#endif
105
106static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
107 unsigned int reg)
108{ 65{
109 int ret; 66 int ret;
110 unsigned int val; 67 unsigned int val;
111 68
112 if (reg >= codec->driver->reg_cache_size || 69 if (reg >= codec->driver->reg_cache_size ||
113 snd_soc_codec_volatile_register(codec, reg) || 70 snd_soc_codec_volatile_register(codec, reg) ||
114 codec->cache_bypass) { 71 codec->cache_bypass) {
115 if (codec->cache_only) 72 if (codec->cache_only)
116 return -1; 73 return -1;
117 74
118 BUG_ON(!codec->hw_read); 75 BUG_ON(!codec->hw_read);
119 return codec->hw_read(codec, reg); 76 return codec->hw_read(codec, reg);
120 } 77 }
121 78
122 ret = snd_soc_cache_read(codec, reg, &val); 79 ret = snd_soc_cache_read(codec, reg, &val);
@@ -125,259 +82,117 @@ static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
125 return val; 82 return val;
126} 83}
127 84
128static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, 85static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
129 unsigned int value) 86 unsigned int reg)
130{ 87{
131 u8 data[2]; 88 return do_hw_read(codec, reg);
132 int ret;
133
134 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
135 data[1] = value & 0x00ff;
136
137 if (!snd_soc_codec_volatile_register(codec, reg) &&
138 reg < codec->driver->reg_cache_size &&
139 !codec->cache_bypass) {
140 ret = snd_soc_cache_write(codec, reg, value);
141 if (ret < 0)
142 return -1;
143 }
144
145 if (codec->cache_only) {
146 codec->cache_sync = 1;
147 return 0;
148 }
149
150 ret = codec->hw_write(codec->control_data, data, 2);
151 if (ret == 2)
152 return 0;
153 if (ret < 0)
154 return ret;
155 else
156 return -EIO;
157} 89}
158 90
159#if defined(CONFIG_SPI_MASTER) 91static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
160static int snd_soc_7_9_spi_write(void *control_data, const char *data, 92 unsigned int value)
161 int len)
162{ 93{
163 struct spi_device *spi = control_data; 94 u16 data;
164 struct spi_transfer t;
165 struct spi_message m;
166 u8 msg[2];
167 95
168 if (len <= 0) 96 data = cpu_to_be16((reg << 12) | (value & 0xffffff));
169 return 0;
170 97
171 msg[0] = data[0]; 98 return do_hw_write(codec, reg, value, &data, 2);
172 msg[1] = data[1]; 99}
173 100
174 spi_message_init(&m); 101static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
175 memset(&t, 0, sizeof t); 102 unsigned int reg)
103{
104 return do_hw_read(codec, reg);
105}
176 106
177 t.tx_buf = &msg[0]; 107static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
178 t.len = len; 108 unsigned int value)
109{
110 u8 data[2];
179 111
180 spi_message_add_tail(&t, &m); 112 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
181 spi_sync(spi, &m); 113 data[1] = value & 0x00ff;
182 114
183 return len; 115 return do_hw_write(codec, reg, value, data, 2);
184} 116}
185#else
186#define snd_soc_7_9_spi_write NULL
187#endif
188 117
189static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, 118static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
190 unsigned int value) 119 unsigned int value)
191{ 120{
192 u8 data[2]; 121 u8 data[2];
193 int ret;
194 122
195 reg &= 0xff; 123 reg &= 0xff;
196 data[0] = reg; 124 data[0] = reg;
197 data[1] = value & 0xff; 125 data[1] = value & 0xff;
198 126
199 if (!snd_soc_codec_volatile_register(codec, reg) && 127 return do_hw_write(codec, reg, value, data, 2);
200 reg < codec->driver->reg_cache_size &&
201 !codec->cache_bypass) {
202 ret = snd_soc_cache_write(codec, reg, value);
203 if (ret < 0)
204 return -1;
205 }
206
207 if (codec->cache_only) {
208 codec->cache_sync = 1;
209 return 0;
210 }
211
212 if (codec->hw_write(codec->control_data, data, 2) == 2)
213 return 0;
214 else
215 return -EIO;
216} 128}
217 129
218static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, 130static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
219 unsigned int reg) 131 unsigned int reg)
220{ 132{
221 int ret; 133 return do_hw_read(codec, reg);
222 unsigned int val;
223
224 reg &= 0xff;
225 if (reg >= codec->driver->reg_cache_size ||
226 snd_soc_codec_volatile_register(codec, reg) ||
227 codec->cache_bypass) {
228 if (codec->cache_only)
229 return -1;
230
231 BUG_ON(!codec->hw_read);
232 return codec->hw_read(codec, reg);
233 }
234
235 ret = snd_soc_cache_read(codec, reg, &val);
236 if (ret < 0)
237 return -1;
238 return val;
239}
240
241#if defined(CONFIG_SPI_MASTER)
242static int snd_soc_8_8_spi_write(void *control_data, const char *data,
243 int len)
244{
245 struct spi_device *spi = control_data;
246 struct spi_transfer t;
247 struct spi_message m;
248 u8 msg[2];
249
250 if (len <= 0)
251 return 0;
252
253 msg[0] = data[0];
254 msg[1] = data[1];
255
256 spi_message_init(&m);
257 memset(&t, 0, sizeof t);
258
259 t.tx_buf = &msg[0];
260 t.len = len;
261
262 spi_message_add_tail(&t, &m);
263 spi_sync(spi, &m);
264
265 return len;
266} 134}
267#else
268#define snd_soc_8_8_spi_write NULL
269#endif
270 135
271static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, 136static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
272 unsigned int value) 137 unsigned int value)
273{ 138{
274 u8 data[3]; 139 u8 data[3];
275 int ret;
276 140
277 data[0] = reg; 141 data[0] = reg;
278 data[1] = (value >> 8) & 0xff; 142 data[1] = (value >> 8) & 0xff;
279 data[2] = value & 0xff; 143 data[2] = value & 0xff;
280 144
281 if (!snd_soc_codec_volatile_register(codec, reg) && 145 return do_hw_write(codec, reg, value, data, 3);
282 reg < codec->driver->reg_cache_size &&
283 !codec->cache_bypass) {
284 ret = snd_soc_cache_write(codec, reg, value);
285 if (ret < 0)
286 return -1;
287 }
288
289 if (codec->cache_only) {
290 codec->cache_sync = 1;
291 return 0;
292 }
293
294 if (codec->hw_write(codec->control_data, data, 3) == 3)
295 return 0;
296 else
297 return -EIO;
298} 146}
299 147
300static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, 148static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
301 unsigned int reg) 149 unsigned int reg)
302{ 150{
303 int ret; 151 return do_hw_read(codec, reg);
304 unsigned int val;
305
306 if (reg >= codec->driver->reg_cache_size ||
307 snd_soc_codec_volatile_register(codec, reg) ||
308 codec->cache_bypass) {
309 if (codec->cache_only)
310 return -1;
311
312 BUG_ON(!codec->hw_read);
313 return codec->hw_read(codec, reg);
314 }
315
316 ret = snd_soc_cache_read(codec, reg, &val);
317 if (ret < 0)
318 return -1;
319 return val;
320}
321
322#if defined(CONFIG_SPI_MASTER)
323static int snd_soc_8_16_spi_write(void *control_data, const char *data,
324 int len)
325{
326 struct spi_device *spi = control_data;
327 struct spi_transfer t;
328 struct spi_message m;
329 u8 msg[3];
330
331 if (len <= 0)
332 return 0;
333
334 msg[0] = data[0];
335 msg[1] = data[1];
336 msg[2] = data[2];
337
338 spi_message_init(&m);
339 memset(&t, 0, sizeof t);
340
341 t.tx_buf = &msg[0];
342 t.len = len;
343
344 spi_message_add_tail(&t, &m);
345 spi_sync(spi, &m);
346
347 return len;
348} 152}
349#else
350#define snd_soc_8_16_spi_write NULL
351#endif
352 153
353#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 154#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
354static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, 155static unsigned int do_i2c_read(struct snd_soc_codec *codec,
355 unsigned int r) 156 void *reg, int reglen,
157 void *data, int datalen)
356{ 158{
357 struct i2c_msg xfer[2]; 159 struct i2c_msg xfer[2];
358 u8 reg = r;
359 u8 data;
360 int ret; 160 int ret;
361 struct i2c_client *client = codec->control_data; 161 struct i2c_client *client = codec->control_data;
362 162
363 /* Write register */ 163 /* Write register */
364 xfer[0].addr = client->addr; 164 xfer[0].addr = client->addr;
365 xfer[0].flags = 0; 165 xfer[0].flags = 0;
366 xfer[0].len = 1; 166 xfer[0].len = reglen;
367 xfer[0].buf = &reg; 167 xfer[0].buf = reg;
368 168
369 /* Read data */ 169 /* Read data */
370 xfer[1].addr = client->addr; 170 xfer[1].addr = client->addr;
371 xfer[1].flags = I2C_M_RD; 171 xfer[1].flags = I2C_M_RD;
372 xfer[1].len = 1; 172 xfer[1].len = datalen;
373 xfer[1].buf = &data; 173 xfer[1].buf = data;
374 174
375 ret = i2c_transfer(client->adapter, xfer, 2); 175 ret = i2c_transfer(client->adapter, xfer, 2);
376 if (ret != 2) { 176 if (ret == 2)
377 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
378 return 0; 177 return 0;
379 } 178 else if (ret < 0)
179 return ret;
180 else
181 return -EIO;
182}
183#endif
380 184
185#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
186static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
187 unsigned int r)
188{
189 u8 reg = r;
190 u8 data;
191 int ret;
192
193 ret = do_i2c_read(codec, &reg, 1, &data, 1);
194 if (ret < 0)
195 return 0;
381 return data; 196 return data;
382} 197}
383#else 198#else
@@ -388,30 +203,13 @@ static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
388static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, 203static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
389 unsigned int r) 204 unsigned int r)
390{ 205{
391 struct i2c_msg xfer[2];
392 u8 reg = r; 206 u8 reg = r;
393 u16 data; 207 u16 data;
394 int ret; 208 int ret;
395 struct i2c_client *client = codec->control_data;
396 209
397 /* Write register */ 210 ret = do_i2c_read(codec, &reg, 1, &data, 2);
398 xfer[0].addr = client->addr; 211 if (ret < 0)
399 xfer[0].flags = 0;
400 xfer[0].len = 1;
401 xfer[0].buf = &reg;
402
403 /* Read data */
404 xfer[1].addr = client->addr;
405 xfer[1].flags = I2C_M_RD;
406 xfer[1].len = 2;
407 xfer[1].buf = (u8 *)&data;
408
409 ret = i2c_transfer(client->adapter, xfer, 2);
410 if (ret != 2) {
411 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
412 return 0; 212 return 0;
413 }
414
415 return (data >> 8) | ((data & 0xff) << 8); 213 return (data >> 8) | ((data & 0xff) << 8);
416} 214}
417#else 215#else
@@ -422,30 +220,13 @@ static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
422static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, 220static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
423 unsigned int r) 221 unsigned int r)
424{ 222{
425 struct i2c_msg xfer[2];
426 u16 reg = r; 223 u16 reg = r;
427 u8 data; 224 u8 data;
428 int ret; 225 int ret;
429 struct i2c_client *client = codec->control_data;
430
431 /* Write register */
432 xfer[0].addr = client->addr;
433 xfer[0].flags = 0;
434 xfer[0].len = 2;
435 xfer[0].buf = (u8 *)&reg;
436
437 /* Read data */
438 xfer[1].addr = client->addr;
439 xfer[1].flags = I2C_M_RD;
440 xfer[1].len = 1;
441 xfer[1].buf = &data;
442 226
443 ret = i2c_transfer(client->adapter, xfer, 2); 227 ret = do_i2c_read(codec, &reg, 2, &data, 1);
444 if (ret != 2) { 228 if (ret < 0)
445 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
446 return 0; 229 return 0;
447 }
448
449 return data; 230 return data;
450} 231}
451#else 232#else
@@ -453,120 +234,34 @@ static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
453#endif 234#endif
454 235
455static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, 236static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
456 unsigned int reg) 237 unsigned int reg)
457{ 238{
458 int ret; 239 return do_hw_read(codec, reg);
459 unsigned int val;
460
461 reg &= 0xff;
462 if (reg >= codec->driver->reg_cache_size ||
463 snd_soc_codec_volatile_register(codec, reg) ||
464 codec->cache_bypass) {
465 if (codec->cache_only)
466 return -1;
467
468 BUG_ON(!codec->hw_read);
469 return codec->hw_read(codec, reg);
470 }
471
472 ret = snd_soc_cache_read(codec, reg, &val);
473 if (ret < 0)
474 return -1;
475 return val;
476} 240}
477 241
478static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, 242static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
479 unsigned int value) 243 unsigned int value)
480{ 244{
481 u8 data[3]; 245 u8 data[3];
482 int ret;
483 246
484 data[0] = (reg >> 8) & 0xff; 247 data[0] = (reg >> 8) & 0xff;
485 data[1] = reg & 0xff; 248 data[1] = reg & 0xff;
486 data[2] = value; 249 data[2] = value;
487 250
488 reg &= 0xff; 251 return do_hw_write(codec, reg, value, data, 3);
489 if (!snd_soc_codec_volatile_register(codec, reg) &&
490 reg < codec->driver->reg_cache_size &&
491 !codec->cache_bypass) {
492 ret = snd_soc_cache_write(codec, reg, value);
493 if (ret < 0)
494 return -1;
495 }
496
497 if (codec->cache_only) {
498 codec->cache_sync = 1;
499 return 0;
500 }
501
502 ret = codec->hw_write(codec->control_data, data, 3);
503 if (ret == 3)
504 return 0;
505 if (ret < 0)
506 return ret;
507 else
508 return -EIO;
509}
510
511#if defined(CONFIG_SPI_MASTER)
512static int snd_soc_16_8_spi_write(void *control_data, const char *data,
513 int len)
514{
515 struct spi_device *spi = control_data;
516 struct spi_transfer t;
517 struct spi_message m;
518 u8 msg[3];
519
520 if (len <= 0)
521 return 0;
522
523 msg[0] = data[0];
524 msg[1] = data[1];
525 msg[2] = data[2];
526
527 spi_message_init(&m);
528 memset(&t, 0, sizeof t);
529
530 t.tx_buf = &msg[0];
531 t.len = len;
532
533 spi_message_add_tail(&t, &m);
534 spi_sync(spi, &m);
535
536 return len;
537} 252}
538#else
539#define snd_soc_16_8_spi_write NULL
540#endif
541 253
542#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 254#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
543static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, 255static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
544 unsigned int r) 256 unsigned int r)
545{ 257{
546 struct i2c_msg xfer[2];
547 u16 reg = cpu_to_be16(r); 258 u16 reg = cpu_to_be16(r);
548 u16 data; 259 u16 data;
549 int ret; 260 int ret;
550 struct i2c_client *client = codec->control_data;
551
552 /* Write register */
553 xfer[0].addr = client->addr;
554 xfer[0].flags = 0;
555 xfer[0].len = 2;
556 xfer[0].buf = (u8 *)&reg;
557 261
558 /* Read data */ 262 ret = do_i2c_read(codec, &reg, 2, &data, 2);
559 xfer[1].addr = client->addr; 263 if (ret < 0)
560 xfer[1].flags = I2C_M_RD;
561 xfer[1].len = 2;
562 xfer[1].buf = (u8 *)&data;
563
564 ret = i2c_transfer(client->adapter, xfer, 2);
565 if (ret != 2) {
566 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
567 return 0; 264 return 0;
568 }
569
570 return be16_to_cpu(data); 265 return be16_to_cpu(data);
571} 266}
572#else 267#else
@@ -576,52 +271,59 @@ static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
576static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec, 271static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
577 unsigned int reg) 272 unsigned int reg)
578{ 273{
579 int ret; 274 return do_hw_read(codec, reg);
580 unsigned int val;
581
582 if (reg >= codec->driver->reg_cache_size ||
583 snd_soc_codec_volatile_register(codec, reg) ||
584 codec->cache_bypass) {
585 if (codec->cache_only)
586 return -1;
587
588 BUG_ON(!codec->hw_read);
589 return codec->hw_read(codec, reg);
590 }
591
592 ret = snd_soc_cache_read(codec, reg, &val);
593 if (ret < 0)
594 return -1;
595
596 return val;
597} 275}
598 276
599static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, 277static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
600 unsigned int value) 278 unsigned int value)
601{ 279{
602 u8 data[4]; 280 u8 data[4];
603 int ret;
604 281
605 data[0] = (reg >> 8) & 0xff; 282 data[0] = (reg >> 8) & 0xff;
606 data[1] = reg & 0xff; 283 data[1] = reg & 0xff;
607 data[2] = (value >> 8) & 0xff; 284 data[2] = (value >> 8) & 0xff;
608 data[3] = value & 0xff; 285 data[3] = value & 0xff;
609 286
610 if (!snd_soc_codec_volatile_register(codec, reg) && 287 return do_hw_write(codec, reg, value, data, 4);
611 reg < codec->driver->reg_cache_size && 288}
612 !codec->cache_bypass) {
613 ret = snd_soc_cache_write(codec, reg, value);
614 if (ret < 0)
615 return -1;
616 }
617 289
618 if (codec->cache_only) { 290/* Primitive bulk write support for soc-cache. The data pointed to by
619 codec->cache_sync = 1; 291 * `data' needs to already be in the form the hardware expects
620 return 0; 292 * including any leading register specific data. Any data written
293 * through this function will not go through the cache as it only
294 * handles writing to volatile or out of bounds registers.
295 */
296static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int reg,
297 const void *data, size_t len)
298{
299 int ret;
300
301 /* To ensure that we don't get out of sync with the cache, check
302 * whether the base register is volatile or if we've directly asked
303 * to bypass the cache. Out of bounds registers are considered
304 * volatile.
305 */
306 if (!codec->cache_bypass
307 && !snd_soc_codec_volatile_register(codec, reg)
308 && reg < codec->driver->reg_cache_size)
309 return -EINVAL;
310
311 switch (codec->control_type) {
312#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
313 case SND_SOC_I2C:
314 ret = i2c_master_send(codec->control_data, data, len);
315 break;
316#endif
317#if defined(CONFIG_SPI_MASTER)
318 case SND_SOC_SPI:
319 ret = spi_write(codec->control_data, data, len);
320 break;
321#endif
322 default:
323 BUG();
621 } 324 }
622 325
623 ret = codec->hw_write(codec->control_data, data, 4); 326 if (ret == len)
624 if (ret == 4)
625 return 0; 327 return 0;
626 if (ret < 0) 328 if (ret < 0)
627 return ret; 329 return ret;
@@ -629,79 +331,40 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
629 return -EIO; 331 return -EIO;
630} 332}
631 333
632#if defined(CONFIG_SPI_MASTER)
633static int snd_soc_16_16_spi_write(void *control_data, const char *data,
634 int len)
635{
636 struct spi_device *spi = control_data;
637 struct spi_transfer t;
638 struct spi_message m;
639 u8 msg[4];
640
641 if (len <= 0)
642 return 0;
643
644 msg[0] = data[0];
645 msg[1] = data[1];
646 msg[2] = data[2];
647 msg[3] = data[3];
648
649 spi_message_init(&m);
650 memset(&t, 0, sizeof t);
651
652 t.tx_buf = &msg[0];
653 t.len = len;
654
655 spi_message_add_tail(&t, &m);
656 spi_sync(spi, &m);
657
658 return len;
659}
660#else
661#define snd_soc_16_16_spi_write NULL
662#endif
663
664static struct { 334static struct {
665 int addr_bits; 335 int addr_bits;
666 int data_bits; 336 int data_bits;
667 int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int); 337 int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
668 int (*spi_write)(void *, const char *, int);
669 unsigned int (*read)(struct snd_soc_codec *, unsigned int); 338 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
670 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); 339 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
671} io_types[] = { 340} io_types[] = {
672 { 341 {
673 .addr_bits = 4, .data_bits = 12, 342 .addr_bits = 4, .data_bits = 12,
674 .write = snd_soc_4_12_write, .read = snd_soc_4_12_read, 343 .write = snd_soc_4_12_write, .read = snd_soc_4_12_read,
675 .spi_write = snd_soc_4_12_spi_write,
676 }, 344 },
677 { 345 {
678 .addr_bits = 7, .data_bits = 9, 346 .addr_bits = 7, .data_bits = 9,
679 .write = snd_soc_7_9_write, .read = snd_soc_7_9_read, 347 .write = snd_soc_7_9_write, .read = snd_soc_7_9_read,
680 .spi_write = snd_soc_7_9_spi_write,
681 }, 348 },
682 { 349 {
683 .addr_bits = 8, .data_bits = 8, 350 .addr_bits = 8, .data_bits = 8,
684 .write = snd_soc_8_8_write, .read = snd_soc_8_8_read, 351 .write = snd_soc_8_8_write, .read = snd_soc_8_8_read,
685 .i2c_read = snd_soc_8_8_read_i2c, 352 .i2c_read = snd_soc_8_8_read_i2c,
686 .spi_write = snd_soc_8_8_spi_write,
687 }, 353 },
688 { 354 {
689 .addr_bits = 8, .data_bits = 16, 355 .addr_bits = 8, .data_bits = 16,
690 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read, 356 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read,
691 .i2c_read = snd_soc_8_16_read_i2c, 357 .i2c_read = snd_soc_8_16_read_i2c,
692 .spi_write = snd_soc_8_16_spi_write,
693 }, 358 },
694 { 359 {
695 .addr_bits = 16, .data_bits = 8, 360 .addr_bits = 16, .data_bits = 8,
696 .write = snd_soc_16_8_write, .read = snd_soc_16_8_read, 361 .write = snd_soc_16_8_write, .read = snd_soc_16_8_read,
697 .i2c_read = snd_soc_16_8_read_i2c, 362 .i2c_read = snd_soc_16_8_read_i2c,
698 .spi_write = snd_soc_16_8_spi_write,
699 }, 363 },
700 { 364 {
701 .addr_bits = 16, .data_bits = 16, 365 .addr_bits = 16, .data_bits = 16,
702 .write = snd_soc_16_16_write, .read = snd_soc_16_16_read, 366 .write = snd_soc_16_16_write, .read = snd_soc_16_16_read,
703 .i2c_read = snd_soc_16_16_read_i2c, 367 .i2c_read = snd_soc_16_16_read_i2c,
704 .spi_write = snd_soc_16_16_spi_write,
705 }, 368 },
706}; 369};
707 370
@@ -709,7 +372,6 @@ static struct {
709 * snd_soc_codec_set_cache_io: Set up standard I/O functions. 372 * snd_soc_codec_set_cache_io: Set up standard I/O functions.
710 * 373 *
711 * @codec: CODEC to configure. 374 * @codec: CODEC to configure.
712 * @type: Type of cache.
713 * @addr_bits: Number of bits of register address data. 375 * @addr_bits: Number of bits of register address data.
714 * @data_bits: Number of bits of data per register. 376 * @data_bits: Number of bits of data per register.
715 * @control: Control bus used. 377 * @control: Control bus used.
@@ -744,6 +406,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
744 406
745 codec->write = io_types[i].write; 407 codec->write = io_types[i].write;
746 codec->read = io_types[i].read; 408 codec->read = io_types[i].read;
409 codec->bulk_write_raw = snd_soc_hw_bulk_write_raw;
747 410
748 switch (control) { 411 switch (control) {
749 case SND_SOC_CUSTOM: 412 case SND_SOC_CUSTOM:
@@ -762,8 +425,9 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
762 break; 425 break;
763 426
764 case SND_SOC_SPI: 427 case SND_SOC_SPI:
765 if (io_types[i].spi_write) 428#ifdef CONFIG_SPI_MASTER
766 codec->hw_write = io_types[i].spi_write; 429 codec->hw_write = do_spi_write;
430#endif
767 431
768 codec->control_data = container_of(codec->dev, 432 codec->control_data = container_of(codec->dev,
769 struct spi_device, 433 struct spi_device,
@@ -889,6 +553,8 @@ static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec)
889 rbnode = rb_entry(node, struct snd_soc_rbtree_node, node); 553 rbnode = rb_entry(node, struct snd_soc_rbtree_node, node);
890 if (rbnode->value == rbnode->defval) 554 if (rbnode->value == rbnode->defval)
891 continue; 555 continue;
556 WARN_ON(codec->writable_register &&
557 codec->writable_register(codec, rbnode->reg));
892 ret = snd_soc_cache_read(codec, rbnode->reg, &val); 558 ret = snd_soc_cache_read(codec, rbnode->reg, &val);
893 if (ret) 559 if (ret)
894 return ret; 560 return ret;
@@ -1149,6 +815,8 @@ static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
1149 815
1150 lzo_blocks = codec->reg_cache; 816 lzo_blocks = codec->reg_cache;
1151 for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) { 817 for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
818 WARN_ON(codec->writable_register &&
819 codec->writable_register(codec, i));
1152 ret = snd_soc_cache_read(codec, i, &val); 820 ret = snd_soc_cache_read(codec, i, &val);
1153 if (ret) 821 if (ret)
1154 return ret; 822 return ret;
@@ -1407,6 +1075,8 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
1407 1075
1408 codec_drv = codec->driver; 1076 codec_drv = codec->driver;
1409 for (i = 0; i < codec_drv->reg_cache_size; ++i) { 1077 for (i = 0; i < codec_drv->reg_cache_size; ++i) {
1078 WARN_ON(codec->writable_register &&
1079 codec->writable_register(codec, i));
1410 ret = snd_soc_cache_read(codec, i, &val); 1080 ret = snd_soc_cache_read(codec, i, &val);
1411 if (ret) 1081 if (ret)
1412 return ret; 1082 return ret;
@@ -1523,7 +1193,7 @@ int snd_soc_cache_init(struct snd_soc_codec *codec)
1523 codec->cache_ops->name, codec->name); 1193 codec->cache_ops->name, codec->name);
1524 return codec->cache_ops->init(codec); 1194 return codec->cache_ops->init(codec);
1525 } 1195 }
1526 return -EINVAL; 1196 return -ENOSYS;
1527} 1197}
1528 1198
1529/* 1199/*
@@ -1538,7 +1208,7 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec)
1538 codec->cache_ops->name, codec->name); 1208 codec->cache_ops->name, codec->name);
1539 return codec->cache_ops->exit(codec); 1209 return codec->cache_ops->exit(codec);
1540 } 1210 }
1541 return -EINVAL; 1211 return -ENOSYS;
1542} 1212}
1543 1213
1544/** 1214/**
@@ -1562,7 +1232,7 @@ int snd_soc_cache_read(struct snd_soc_codec *codec,
1562 } 1232 }
1563 1233
1564 mutex_unlock(&codec->cache_rw_mutex); 1234 mutex_unlock(&codec->cache_rw_mutex);
1565 return -EINVAL; 1235 return -ENOSYS;
1566} 1236}
1567EXPORT_SYMBOL_GPL(snd_soc_cache_read); 1237EXPORT_SYMBOL_GPL(snd_soc_cache_read);
1568 1238
@@ -1587,7 +1257,7 @@ int snd_soc_cache_write(struct snd_soc_codec *codec,
1587 } 1257 }
1588 1258
1589 mutex_unlock(&codec->cache_rw_mutex); 1259 mutex_unlock(&codec->cache_rw_mutex);
1590 return -EINVAL; 1260 return -ENOSYS;
1591} 1261}
1592EXPORT_SYMBOL_GPL(snd_soc_cache_write); 1262EXPORT_SYMBOL_GPL(snd_soc_cache_write);
1593 1263
@@ -1610,7 +1280,7 @@ int snd_soc_cache_sync(struct snd_soc_codec *codec)
1610 } 1280 }
1611 1281
1612 if (!codec->cache_ops || !codec->cache_ops->sync) 1282 if (!codec->cache_ops || !codec->cache_ops->sync)
1613 return -EINVAL; 1283 return -ENOSYS;
1614 1284
1615 if (codec->cache_ops->name) 1285 if (codec->cache_ops->name)
1616 name = codec->cache_ops->name; 1286 name = codec->cache_ops->name;
@@ -1677,3 +1347,17 @@ int snd_soc_default_readable_register(struct snd_soc_codec *codec,
1677 return codec->driver->reg_access_default[index].read; 1347 return codec->driver->reg_access_default[index].read;
1678} 1348}
1679EXPORT_SYMBOL_GPL(snd_soc_default_readable_register); 1349EXPORT_SYMBOL_GPL(snd_soc_default_readable_register);
1350
1351int snd_soc_default_writable_register(struct snd_soc_codec *codec,
1352 unsigned int reg)
1353{
1354 int index;
1355
1356 if (reg >= codec->driver->reg_cache_size)
1357 return 1;
1358 index = snd_soc_get_reg_access_index(codec, reg);
1359 if (index < 0)
1360 return 0;
1361 return codec->driver->reg_access_default[index].write;
1362}
1363EXPORT_SYMBOL_GPL(snd_soc_default_writable_register);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index dd55d1069468..bb7cd5812945 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -242,7 +242,7 @@ static ssize_t codec_reg_write_file(struct file *file,
242 const char __user *user_buf, size_t count, loff_t *ppos) 242 const char __user *user_buf, size_t count, loff_t *ppos)
243{ 243{
244 char buf[32]; 244 char buf[32];
245 int buf_size; 245 size_t buf_size;
246 char *start = buf; 246 char *start = buf;
247 unsigned long reg, value; 247 unsigned long reg, value;
248 int step = 1; 248 int step = 1;
@@ -302,13 +302,7 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
302 printk(KERN_WARNING 302 printk(KERN_WARNING
303 "ASoC: Failed to create codec register debugfs file\n"); 303 "ASoC: Failed to create codec register debugfs file\n");
304 304
305 codec->dapm.debugfs_dapm = debugfs_create_dir("dapm", 305 snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root);
306 codec->debugfs_codec_root);
307 if (!codec->dapm.debugfs_dapm)
308 printk(KERN_WARNING
309 "Failed to create DAPM debugfs directory\n");
310
311 snd_soc_dapm_debugfs_init(&codec->dapm);
312} 306}
313 307
314static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) 308static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
@@ -555,7 +549,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
555 } 549 }
556 } 550 }
557 551
558 if (platform->driver->ops->open) { 552 if (platform->driver->ops && platform->driver->ops->open) {
559 ret = platform->driver->ops->open(substream); 553 ret = platform->driver->ops->open(substream);
560 if (ret < 0) { 554 if (ret < 0) {
561 printk(KERN_ERR "asoc: can't open platform %s\n", platform->name); 555 printk(KERN_ERR "asoc: can't open platform %s\n", platform->name);
@@ -685,7 +679,7 @@ machine_err:
685 codec_dai->driver->ops->shutdown(substream, codec_dai); 679 codec_dai->driver->ops->shutdown(substream, codec_dai);
686 680
687codec_dai_err: 681codec_dai_err:
688 if (platform->driver->ops->close) 682 if (platform->driver->ops && platform->driver->ops->close)
689 platform->driver->ops->close(substream); 683 platform->driver->ops->close(substream);
690 684
691platform_err: 685platform_err:
@@ -767,7 +761,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
767 if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown) 761 if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
768 rtd->dai_link->ops->shutdown(substream); 762 rtd->dai_link->ops->shutdown(substream);
769 763
770 if (platform->driver->ops->close) 764 if (platform->driver->ops && platform->driver->ops->close)
771 platform->driver->ops->close(substream); 765 platform->driver->ops->close(substream);
772 cpu_dai->runtime = NULL; 766 cpu_dai->runtime = NULL;
773 767
@@ -810,7 +804,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
810 } 804 }
811 } 805 }
812 806
813 if (platform->driver->ops->prepare) { 807 if (platform->driver->ops && platform->driver->ops->prepare) {
814 ret = platform->driver->ops->prepare(substream); 808 ret = platform->driver->ops->prepare(substream);
815 if (ret < 0) { 809 if (ret < 0) {
816 printk(KERN_ERR "asoc: platform prepare error\n"); 810 printk(KERN_ERR "asoc: platform prepare error\n");
@@ -899,7 +893,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
899 } 893 }
900 } 894 }
901 895
902 if (platform->driver->ops->hw_params) { 896 if (platform->driver->ops && platform->driver->ops->hw_params) {
903 ret = platform->driver->ops->hw_params(substream, params); 897 ret = platform->driver->ops->hw_params(substream, params);
904 if (ret < 0) { 898 if (ret < 0) {
905 printk(KERN_ERR "asoc: platform %s hw params failed\n", 899 printk(KERN_ERR "asoc: platform %s hw params failed\n",
@@ -952,7 +946,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
952 rtd->dai_link->ops->hw_free(substream); 946 rtd->dai_link->ops->hw_free(substream);
953 947
954 /* free any DMA resources */ 948 /* free any DMA resources */
955 if (platform->driver->ops->hw_free) 949 if (platform->driver->ops && platform->driver->ops->hw_free)
956 platform->driver->ops->hw_free(substream); 950 platform->driver->ops->hw_free(substream);
957 951
958 /* now free hw params for the DAIs */ 952 /* now free hw params for the DAIs */
@@ -980,7 +974,7 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
980 return ret; 974 return ret;
981 } 975 }
982 976
983 if (platform->driver->ops->trigger) { 977 if (platform->driver->ops && platform->driver->ops->trigger) {
984 ret = platform->driver->ops->trigger(substream, cmd); 978 ret = platform->driver->ops->trigger(substream, cmd);
985 if (ret < 0) 979 if (ret < 0)
986 return ret; 980 return ret;
@@ -1009,7 +1003,7 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
1009 snd_pcm_uframes_t offset = 0; 1003 snd_pcm_uframes_t offset = 0;
1010 snd_pcm_sframes_t delay = 0; 1004 snd_pcm_sframes_t delay = 0;
1011 1005
1012 if (platform->driver->ops->pointer) 1006 if (platform->driver->ops && platform->driver->ops->pointer)
1013 offset = platform->driver->ops->pointer(substream); 1007 offset = platform->driver->ops->pointer(substream);
1014 1008
1015 if (cpu_dai->driver->ops->delay) 1009 if (cpu_dai->driver->ops->delay)
@@ -1299,6 +1293,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
1299 struct snd_soc_codec *codec; 1293 struct snd_soc_codec *codec;
1300 struct snd_soc_platform *platform; 1294 struct snd_soc_platform *platform;
1301 struct snd_soc_dai *codec_dai, *cpu_dai; 1295 struct snd_soc_dai *codec_dai, *cpu_dai;
1296 const char *platform_name;
1302 1297
1303 if (rtd->complete) 1298 if (rtd->complete)
1304 return 1; 1299 return 1;
@@ -1351,13 +1346,18 @@ find_codec:
1351 dai_link->codec_name); 1346 dai_link->codec_name);
1352 1347
1353find_platform: 1348find_platform:
1354 /* do we already have the CODEC DAI for this link ? */ 1349 /* do we need a platform? */
1355 if (rtd->platform) { 1350 if (rtd->platform)
1356 goto out; 1351 goto out;
1357 } 1352
1358 /* no, then find CPU DAI from registered DAIs*/ 1353 /* if there's no platform we match on the empty platform */
1354 platform_name = dai_link->platform_name;
1355 if (!platform_name)
1356 platform_name = "snd-soc-dummy";
1357
1358 /* no, then find one from the set of registered platforms */
1359 list_for_each_entry(platform, &platform_list, list) { 1359 list_for_each_entry(platform, &platform_list, list) {
1360 if (!strcmp(platform->name, dai_link->platform_name)) { 1360 if (!strcmp(platform->name, platform_name)) {
1361 rtd->platform = platform; 1361 rtd->platform = platform;
1362 goto out; 1362 goto out;
1363 } 1363 }
@@ -1453,6 +1453,16 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
1453 } 1453 }
1454} 1454}
1455 1455
1456static void soc_remove_dai_links(struct snd_soc_card *card)
1457{
1458 int i;
1459
1460 for (i = 0; i < card->num_rtd; i++)
1461 soc_remove_dai_link(card, i);
1462
1463 card->num_rtd = 0;
1464}
1465
1456static void soc_set_name_prefix(struct snd_soc_card *card, 1466static void soc_set_name_prefix(struct snd_soc_card *card,
1457 struct snd_soc_codec *codec) 1467 struct snd_soc_codec *codec)
1458{ 1468{
@@ -1483,6 +1493,12 @@ static int soc_probe_codec(struct snd_soc_card *card,
1483 if (!try_module_get(codec->dev->driver->owner)) 1493 if (!try_module_get(codec->dev->driver->owner))
1484 return -ENODEV; 1494 return -ENODEV;
1485 1495
1496 soc_init_codec_debugfs(codec);
1497
1498 if (driver->dapm_widgets)
1499 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
1500 driver->num_dapm_widgets);
1501
1486 if (driver->probe) { 1502 if (driver->probe) {
1487 ret = driver->probe(codec); 1503 ret = driver->probe(codec);
1488 if (ret < 0) { 1504 if (ret < 0) {
@@ -1493,15 +1509,13 @@ static int soc_probe_codec(struct snd_soc_card *card,
1493 } 1509 }
1494 } 1510 }
1495 1511
1496 if (driver->dapm_widgets) 1512 if (driver->controls)
1497 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, 1513 snd_soc_add_controls(codec, driver->controls,
1498 driver->num_dapm_widgets); 1514 driver->num_controls);
1499 if (driver->dapm_routes) 1515 if (driver->dapm_routes)
1500 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes, 1516 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes,
1501 driver->num_dapm_routes); 1517 driver->num_dapm_routes);
1502 1518
1503 soc_init_codec_debugfs(codec);
1504
1505 /* mark codec as probed and add to card codec list */ 1519 /* mark codec as probed and add to card codec list */
1506 codec->probed = 1; 1520 codec->probed = 1;
1507 list_add(&codec->card_list, &card->codec_dev_list); 1521 list_add(&codec->card_list, &card->codec_dev_list);
@@ -1510,6 +1524,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
1510 return 0; 1524 return 0;
1511 1525
1512err_probe: 1526err_probe:
1527 soc_cleanup_codec_debugfs(codec);
1513 module_put(codec->dev->driver->owner); 1528 module_put(codec->dev->driver->owner);
1514 1529
1515 return ret; 1530 return ret;
@@ -1860,11 +1875,19 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1860 card->dapm.card = card; 1875 card->dapm.card = card;
1861 list_add(&card->dapm.list, &card->dapm_list); 1876 list_add(&card->dapm.list, &card->dapm_list);
1862 1877
1878#ifdef CONFIG_DEBUG_FS
1879 snd_soc_dapm_debugfs_init(&card->dapm, card->debugfs_card_root);
1880#endif
1881
1863#ifdef CONFIG_PM_SLEEP 1882#ifdef CONFIG_PM_SLEEP
1864 /* deferred resume work */ 1883 /* deferred resume work */
1865 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); 1884 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
1866#endif 1885#endif
1867 1886
1887 if (card->dapm_widgets)
1888 snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets,
1889 card->num_dapm_widgets);
1890
1868 /* initialise the sound card only once */ 1891 /* initialise the sound card only once */
1869 if (card->probe) { 1892 if (card->probe) {
1870 ret = card->probe(card); 1893 ret = card->probe(card);
@@ -1890,27 +1913,24 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1890 } 1913 }
1891 } 1914 }
1892 1915
1893 if (card->dapm_widgets) 1916 /* We should have a non-codec control add function but we don't */
1894 snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets, 1917 if (card->controls)
1895 card->num_dapm_widgets); 1918 snd_soc_add_controls(list_first_entry(&card->codec_dev_list,
1919 struct snd_soc_codec,
1920 card_list),
1921 card->controls,
1922 card->num_controls);
1923
1896 if (card->dapm_routes) 1924 if (card->dapm_routes)
1897 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, 1925 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
1898 card->num_dapm_routes); 1926 card->num_dapm_routes);
1899 1927
1900#ifdef CONFIG_DEBUG_FS
1901 card->dapm.debugfs_dapm = debugfs_create_dir("dapm",
1902 card->debugfs_card_root);
1903 if (!card->dapm.debugfs_dapm)
1904 printk(KERN_WARNING
1905 "Failed to create card DAPM debugfs directory\n");
1906
1907 snd_soc_dapm_debugfs_init(&card->dapm);
1908#endif
1909
1910 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), 1928 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
1911 "%s", card->name);
1912 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
1913 "%s", card->name); 1929 "%s", card->name);
1930 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
1931 "%s", card->long_name ? card->long_name : card->name);
1932 snprintf(card->snd_card->driver, sizeof(card->snd_card->driver),
1933 "%s", card->driver_name ? card->driver_name : card->name);
1914 1934
1915 if (card->late_probe) { 1935 if (card->late_probe) {
1916 ret = card->late_probe(card); 1936 ret = card->late_probe(card);
@@ -1949,8 +1969,7 @@ probe_aux_dev_err:
1949 soc_remove_aux_dev(card, i); 1969 soc_remove_aux_dev(card, i);
1950 1970
1951probe_dai_err: 1971probe_dai_err:
1952 for (i = 0; i < card->num_links; i++) 1972 soc_remove_dai_links(card);
1953 soc_remove_dai_link(card, i);
1954 1973
1955card_probe_error: 1974card_probe_error:
1956 if (card->remove) 1975 if (card->remove)
@@ -2012,8 +2031,7 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
2012 soc_remove_aux_dev(card, i); 2031 soc_remove_aux_dev(card, i);
2013 2032
2014 /* remove and free each DAI */ 2033 /* remove and free each DAI */
2015 for (i = 0; i < card->num_rtd; i++) 2034 soc_remove_dai_links(card);
2016 soc_remove_dai_link(card, i);
2017 2035
2018 soc_cleanup_card_debugfs(card); 2036 soc_cleanup_card_debugfs(card);
2019 2037
@@ -2021,6 +2039,8 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
2021 if (card->remove) 2039 if (card->remove)
2022 card->remove(card); 2040 card->remove(card);
2023 2041
2042 snd_soc_dapm_free(&card->dapm);
2043
2024 kfree(card->rtd); 2044 kfree(card->rtd);
2025 snd_card_free(card->snd_card); 2045 snd_card_free(card->snd_card);
2026 return 0; 2046 return 0;
@@ -2105,13 +2125,15 @@ static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2105 2125
2106 rtd->pcm = pcm; 2126 rtd->pcm = pcm;
2107 pcm->private_data = rtd; 2127 pcm->private_data = rtd;
2108 soc_pcm_ops.mmap = platform->driver->ops->mmap; 2128 if (platform->driver->ops) {
2109 soc_pcm_ops.pointer = platform->driver->ops->pointer; 2129 soc_pcm_ops.mmap = platform->driver->ops->mmap;
2110 soc_pcm_ops.ioctl = platform->driver->ops->ioctl; 2130 soc_pcm_ops.pointer = platform->driver->ops->pointer;
2111 soc_pcm_ops.copy = platform->driver->ops->copy; 2131 soc_pcm_ops.ioctl = platform->driver->ops->ioctl;
2112 soc_pcm_ops.silence = platform->driver->ops->silence; 2132 soc_pcm_ops.copy = platform->driver->ops->copy;
2113 soc_pcm_ops.ack = platform->driver->ops->ack; 2133 soc_pcm_ops.silence = platform->driver->ops->silence;
2114 soc_pcm_ops.page = platform->driver->ops->page; 2134 soc_pcm_ops.ack = platform->driver->ops->ack;
2135 soc_pcm_ops.page = platform->driver->ops->page;
2136 }
2115 2137
2116 if (playback) 2138 if (playback)
2117 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops); 2139 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops);
@@ -2119,10 +2141,13 @@ static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2119 if (capture) 2141 if (capture)
2120 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops); 2142 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops);
2121 2143
2122 ret = platform->driver->pcm_new(rtd->card->snd_card, codec_dai, pcm); 2144 if (platform->driver->pcm_new) {
2123 if (ret < 0) { 2145 ret = platform->driver->pcm_new(rtd->card->snd_card,
2124 printk(KERN_ERR "asoc: platform pcm constructor failed\n"); 2146 codec_dai, pcm);
2125 return ret; 2147 if (ret < 0) {
2148 pr_err("asoc: platform pcm constructor failed\n");
2149 return ret;
2150 }
2126 } 2151 }
2127 2152
2128 pcm->private_free = platform->driver->pcm_free; 2153 pcm->private_free = platform->driver->pcm_free;
@@ -2150,6 +2175,42 @@ int snd_soc_codec_volatile_register(struct snd_soc_codec *codec,
2150EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register); 2175EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register);
2151 2176
2152/** 2177/**
2178 * snd_soc_codec_readable_register: Report if a register is readable.
2179 *
2180 * @codec: CODEC to query.
2181 * @reg: Register to query.
2182 *
2183 * Boolean function indicating if a CODEC register is readable.
2184 */
2185int snd_soc_codec_readable_register(struct snd_soc_codec *codec,
2186 unsigned int reg)
2187{
2188 if (codec->readable_register)
2189 return codec->readable_register(codec, reg);
2190 else
2191 return 0;
2192}
2193EXPORT_SYMBOL_GPL(snd_soc_codec_readable_register);
2194
2195/**
2196 * snd_soc_codec_writable_register: Report if a register is writable.
2197 *
2198 * @codec: CODEC to query.
2199 * @reg: Register to query.
2200 *
2201 * Boolean function indicating if a CODEC register is writable.
2202 */
2203int snd_soc_codec_writable_register(struct snd_soc_codec *codec,
2204 unsigned int reg)
2205{
2206 if (codec->writable_register)
2207 return codec->writable_register(codec, reg);
2208 else
2209 return 0;
2210}
2211EXPORT_SYMBOL_GPL(snd_soc_codec_writable_register);
2212
2213/**
2153 * snd_soc_new_ac97_codec - initailise AC97 device 2214 * snd_soc_new_ac97_codec - initailise AC97 device
2154 * @codec: audio codec 2215 * @codec: audio codec
2155 * @ops: AC97 bus operations 2216 * @ops: AC97 bus operations
@@ -2231,6 +2292,13 @@ unsigned int snd_soc_write(struct snd_soc_codec *codec,
2231} 2292}
2232EXPORT_SYMBOL_GPL(snd_soc_write); 2293EXPORT_SYMBOL_GPL(snd_soc_write);
2233 2294
2295unsigned int snd_soc_bulk_write_raw(struct snd_soc_codec *codec,
2296 unsigned int reg, const void *data, size_t len)
2297{
2298 return codec->bulk_write_raw(codec, reg, data, len);
2299}
2300EXPORT_SYMBOL_GPL(snd_soc_bulk_write_raw);
2301
2234/** 2302/**
2235 * snd_soc_update_bits - update codec register bits 2303 * snd_soc_update_bits - update codec register bits
2236 * @codec: audio codec 2304 * @codec: audio codec
@@ -3414,7 +3482,7 @@ int snd_soc_register_dai(struct device *dev,
3414 3482
3415 dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); 3483 dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
3416 if (dai == NULL) 3484 if (dai == NULL)
3417 return -ENOMEM; 3485 return -ENOMEM;
3418 3486
3419 /* create DAI component name */ 3487 /* create DAI component name */
3420 dai->name = fmt_single_name(dev, &dai->id); 3488 dai->name = fmt_single_name(dev, &dai->id);
@@ -3553,7 +3621,7 @@ int snd_soc_register_platform(struct device *dev,
3553 3621
3554 platform = kzalloc(sizeof(struct snd_soc_platform), GFP_KERNEL); 3622 platform = kzalloc(sizeof(struct snd_soc_platform), GFP_KERNEL);
3555 if (platform == NULL) 3623 if (platform == NULL)
3556 return -ENOMEM; 3624 return -ENOMEM;
3557 3625
3558 /* create platform component name */ 3626 /* create platform component name */
3559 platform->name = fmt_single_name(dev, &platform->id); 3627 platform->name = fmt_single_name(dev, &platform->id);
@@ -3671,6 +3739,7 @@ int snd_soc_register_codec(struct device *dev,
3671 codec->read = codec_drv->read; 3739 codec->read = codec_drv->read;
3672 codec->volatile_register = codec_drv->volatile_register; 3740 codec->volatile_register = codec_drv->volatile_register;
3673 codec->readable_register = codec_drv->readable_register; 3741 codec->readable_register = codec_drv->readable_register;
3742 codec->writable_register = codec_drv->writable_register;
3674 codec->dapm.bias_level = SND_SOC_BIAS_OFF; 3743 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
3675 codec->dapm.dev = dev; 3744 codec->dapm.dev = dev;
3676 codec->dapm.codec = codec; 3745 codec->dapm.codec = codec;
@@ -3705,6 +3774,8 @@ int snd_soc_register_codec(struct device *dev,
3705 codec->volatile_register = snd_soc_default_volatile_register; 3774 codec->volatile_register = snd_soc_default_volatile_register;
3706 if (!codec->readable_register) 3775 if (!codec->readable_register)
3707 codec->readable_register = snd_soc_default_readable_register; 3776 codec->readable_register = snd_soc_default_readable_register;
3777 if (!codec->writable_register)
3778 codec->writable_register = snd_soc_default_writable_register;
3708 } 3779 }
3709 3780
3710 for (i = 0; i < num_dai; i++) { 3781 for (i = 0; i < num_dai; i++) {
@@ -3793,12 +3864,16 @@ static int __init snd_soc_init(void)
3793 pr_warn("ASoC: Failed to create platform list debugfs file\n"); 3864 pr_warn("ASoC: Failed to create platform list debugfs file\n");
3794#endif 3865#endif
3795 3866
3867 snd_soc_util_init();
3868
3796 return platform_driver_register(&soc_driver); 3869 return platform_driver_register(&soc_driver);
3797} 3870}
3798module_init(snd_soc_init); 3871module_init(snd_soc_init);
3799 3872
3800static void __exit snd_soc_exit(void) 3873static void __exit snd_soc_exit(void)
3801{ 3874{
3875 snd_soc_util_exit();
3876
3802#ifdef CONFIG_DEBUG_FS 3877#ifdef CONFIG_DEBUG_FS
3803 debugfs_remove_recursive(snd_soc_debugfs_root); 3878 debugfs_remove_recursive(snd_soc_debugfs_root);
3804#endif 3879#endif
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 81c4052c127c..456617e63789 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -187,7 +187,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
187 case snd_soc_dapm_mixer_named_ctl: { 187 case snd_soc_dapm_mixer_named_ctl: {
188 int val; 188 int val;
189 struct soc_mixer_control *mc = (struct soc_mixer_control *) 189 struct soc_mixer_control *mc = (struct soc_mixer_control *)
190 w->kcontrols[i].private_value; 190 w->kcontrol_news[i].private_value;
191 unsigned int reg = mc->reg; 191 unsigned int reg = mc->reg;
192 unsigned int shift = mc->shift; 192 unsigned int shift = mc->shift;
193 int max = mc->max; 193 int max = mc->max;
@@ -204,7 +204,8 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
204 } 204 }
205 break; 205 break;
206 case snd_soc_dapm_mux: { 206 case snd_soc_dapm_mux: {
207 struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value; 207 struct soc_enum *e = (struct soc_enum *)
208 w->kcontrol_news[i].private_value;
208 int val, item, bitmask; 209 int val, item, bitmask;
209 210
210 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 211 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
@@ -220,7 +221,8 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
220 } 221 }
221 break; 222 break;
222 case snd_soc_dapm_virt_mux: { 223 case snd_soc_dapm_virt_mux: {
223 struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value; 224 struct soc_enum *e = (struct soc_enum *)
225 w->kcontrol_news[i].private_value;
224 226
225 p->connect = 0; 227 p->connect = 0;
226 /* since a virtual mux has no backing registers to 228 /* since a virtual mux has no backing registers to
@@ -235,7 +237,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
235 break; 237 break;
236 case snd_soc_dapm_value_mux: { 238 case snd_soc_dapm_value_mux: {
237 struct soc_enum *e = (struct soc_enum *) 239 struct soc_enum *e = (struct soc_enum *)
238 w->kcontrols[i].private_value; 240 w->kcontrol_news[i].private_value;
239 int val, item; 241 int val, item;
240 242
241 val = snd_soc_read(w->codec, e->reg); 243 val = snd_soc_read(w->codec, e->reg);
@@ -310,11 +312,11 @@ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
310 312
311 /* search for mixer kcontrol */ 313 /* search for mixer kcontrol */
312 for (i = 0; i < dest->num_kcontrols; i++) { 314 for (i = 0; i < dest->num_kcontrols; i++) {
313 if (!strcmp(control_name, dest->kcontrols[i].name)) { 315 if (!strcmp(control_name, dest->kcontrol_news[i].name)) {
314 list_add(&path->list, &dapm->card->paths); 316 list_add(&path->list, &dapm->card->paths);
315 list_add(&path->list_sink, &dest->sources); 317 list_add(&path->list_sink, &dest->sources);
316 list_add(&path->list_source, &src->sinks); 318 list_add(&path->list_source, &src->sinks);
317 path->name = dest->kcontrols[i].name; 319 path->name = dest->kcontrol_news[i].name;
318 dapm_set_path_status(dest, path, i); 320 dapm_set_path_status(dest, path, i);
319 return 0; 321 return 0;
320 } 322 }
@@ -322,43 +324,26 @@ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
322 return -ENODEV; 324 return -ENODEV;
323} 325}
324 326
325/* update dapm codec register bits */ 327static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm,
326static int dapm_update_bits(struct snd_soc_dapm_widget *widget) 328 const struct snd_kcontrol_new *kcontrol_new,
329 struct snd_kcontrol **kcontrol)
327{ 330{
328 int change, power; 331 struct snd_soc_dapm_widget *w;
329 unsigned int old, new; 332 int i;
330 struct snd_soc_codec *codec = widget->codec;
331 struct snd_soc_dapm_context *dapm = widget->dapm;
332 struct snd_soc_card *card = dapm->card;
333
334 /* check for valid widgets */
335 if (widget->reg < 0 || widget->id == snd_soc_dapm_input ||
336 widget->id == snd_soc_dapm_output ||
337 widget->id == snd_soc_dapm_hp ||
338 widget->id == snd_soc_dapm_mic ||
339 widget->id == snd_soc_dapm_line ||
340 widget->id == snd_soc_dapm_spk)
341 return 0;
342
343 power = widget->power;
344 if (widget->invert)
345 power = (power ? 0:1);
346 333
347 old = snd_soc_read(codec, widget->reg); 334 *kcontrol = NULL;
348 new = (old & ~(0x1 << widget->shift)) | (power << widget->shift);
349 335
350 change = old != new; 336 list_for_each_entry(w, &dapm->card->widgets, list) {
351 if (change) { 337 for (i = 0; i < w->num_kcontrols; i++) {
352 pop_dbg(dapm->dev, card->pop_time, 338 if (&w->kcontrol_news[i] == kcontrol_new) {
353 "pop test %s : %s in %d ms\n", 339 if (w->kcontrols)
354 widget->name, widget->power ? "on" : "off", 340 *kcontrol = w->kcontrols[i];
355 card->pop_time); 341 return 1;
356 pop_wait(card->pop_time); 342 }
357 snd_soc_write(codec, widget->reg, new); 343 }
358 } 344 }
359 dev_dbg(dapm->dev, "reg %x old %x new %x change %d\n", widget->reg, 345
360 old, new, change); 346 return 0;
361 return change;
362} 347}
363 348
364/* create new dapm mixer control */ 349/* create new dapm mixer control */
@@ -370,6 +355,8 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
370 struct snd_soc_dapm_path *path; 355 struct snd_soc_dapm_path *path;
371 struct snd_card *card = dapm->card->snd_card; 356 struct snd_card *card = dapm->card->snd_card;
372 const char *prefix; 357 const char *prefix;
358 struct snd_soc_dapm_widget_list *wlist;
359 size_t wlistsize;
373 360
374 if (dapm->codec) 361 if (dapm->codec)
375 prefix = dapm->codec->name_prefix; 362 prefix = dapm->codec->name_prefix;
@@ -388,23 +375,37 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
388 list_for_each_entry(path, &w->sources, list_sink) { 375 list_for_each_entry(path, &w->sources, list_sink) {
389 376
390 /* mixer/mux paths name must match control name */ 377 /* mixer/mux paths name must match control name */
391 if (path->name != (char*)w->kcontrols[i].name) 378 if (path->name != (char *)w->kcontrol_news[i].name)
392 continue; 379 continue;
393 380
381 wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
382 sizeof(struct snd_soc_dapm_widget *),
383 wlist = kzalloc(wlistsize, GFP_KERNEL);
384 if (wlist == NULL) {
385 dev_err(dapm->dev,
386 "asoc: can't allocate widget list for %s\n",
387 w->name);
388 return -ENOMEM;
389 }
390 wlist->num_widgets = 1;
391 wlist->widgets[0] = w;
392
394 /* add dapm control with long name. 393 /* add dapm control with long name.
395 * for dapm_mixer this is the concatenation of the 394 * for dapm_mixer this is the concatenation of the
396 * mixer and kcontrol name. 395 * mixer and kcontrol name.
397 * for dapm_mixer_named_ctl this is simply the 396 * for dapm_mixer_named_ctl this is simply the
398 * kcontrol name. 397 * kcontrol name.
399 */ 398 */
400 name_len = strlen(w->kcontrols[i].name) + 1; 399 name_len = strlen(w->kcontrol_news[i].name) + 1;
401 if (w->id != snd_soc_dapm_mixer_named_ctl) 400 if (w->id != snd_soc_dapm_mixer_named_ctl)
402 name_len += 1 + strlen(w->name); 401 name_len += 1 + strlen(w->name);
403 402
404 path->long_name = kmalloc(name_len, GFP_KERNEL); 403 path->long_name = kmalloc(name_len, GFP_KERNEL);
405 404
406 if (path->long_name == NULL) 405 if (path->long_name == NULL) {
406 kfree(wlist);
407 return -ENOMEM; 407 return -ENOMEM;
408 }
408 409
409 switch (w->id) { 410 switch (w->id) {
410 default: 411 default:
@@ -416,27 +417,30 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
416 */ 417 */
417 snprintf(path->long_name, name_len, "%s %s", 418 snprintf(path->long_name, name_len, "%s %s",
418 w->name + prefix_len, 419 w->name + prefix_len,
419 w->kcontrols[i].name); 420 w->kcontrol_news[i].name);
420 break; 421 break;
421 case snd_soc_dapm_mixer_named_ctl: 422 case snd_soc_dapm_mixer_named_ctl:
422 snprintf(path->long_name, name_len, "%s", 423 snprintf(path->long_name, name_len, "%s",
423 w->kcontrols[i].name); 424 w->kcontrol_news[i].name);
424 break; 425 break;
425 } 426 }
426 427
427 path->long_name[name_len - 1] = '\0'; 428 path->long_name[name_len - 1] = '\0';
428 429
429 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, 430 path->kcontrol = snd_soc_cnew(&w->kcontrol_news[i],
430 path->long_name, prefix); 431 wlist, path->long_name,
432 prefix);
431 ret = snd_ctl_add(card, path->kcontrol); 433 ret = snd_ctl_add(card, path->kcontrol);
432 if (ret < 0) { 434 if (ret < 0) {
433 dev_err(dapm->dev, 435 dev_err(dapm->dev,
434 "asoc: failed to add dapm kcontrol %s: %d\n", 436 "asoc: failed to add dapm kcontrol %s: %d\n",
435 path->long_name, ret); 437 path->long_name, ret);
438 kfree(wlist);
436 kfree(path->long_name); 439 kfree(path->long_name);
437 path->long_name = NULL; 440 path->long_name = NULL;
438 return ret; 441 return ret;
439 } 442 }
443 w->kcontrols[i] = path->kcontrol;
440 } 444 }
441 } 445 }
442 return ret; 446 return ret;
@@ -451,42 +455,80 @@ static int dapm_new_mux(struct snd_soc_dapm_context *dapm,
451 struct snd_card *card = dapm->card->snd_card; 455 struct snd_card *card = dapm->card->snd_card;
452 const char *prefix; 456 const char *prefix;
453 size_t prefix_len; 457 size_t prefix_len;
454 int ret = 0; 458 int ret;
455 459 struct snd_soc_dapm_widget_list *wlist;
456 if (!w->num_kcontrols) { 460 int shared, wlistentries;
457 dev_err(dapm->dev, "asoc: mux %s has no controls\n", w->name); 461 size_t wlistsize;
462 char *name;
463
464 if (w->num_kcontrols != 1) {
465 dev_err(dapm->dev,
466 "asoc: mux %s has incorrect number of controls\n",
467 w->name);
458 return -EINVAL; 468 return -EINVAL;
459 } 469 }
460 470
461 if (dapm->codec) 471 shared = dapm_is_shared_kcontrol(dapm, &w->kcontrol_news[0],
462 prefix = dapm->codec->name_prefix; 472 &kcontrol);
463 else 473 if (kcontrol) {
464 prefix = NULL; 474 wlist = kcontrol->private_data;
475 wlistentries = wlist->num_widgets + 1;
476 } else {
477 wlist = NULL;
478 wlistentries = 1;
479 }
480 wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
481 wlistentries * sizeof(struct snd_soc_dapm_widget *),
482 wlist = krealloc(wlist, wlistsize, GFP_KERNEL);
483 if (wlist == NULL) {
484 dev_err(dapm->dev,
485 "asoc: can't allocate widget list for %s\n", w->name);
486 return -ENOMEM;
487 }
488 wlist->num_widgets = wlistentries;
489 wlist->widgets[wlistentries - 1] = w;
465 490
466 if (prefix) 491 if (!kcontrol) {
467 prefix_len = strlen(prefix) + 1; 492 if (dapm->codec)
468 else 493 prefix = dapm->codec->name_prefix;
469 prefix_len = 0; 494 else
495 prefix = NULL;
496
497 if (shared) {
498 name = w->kcontrol_news[0].name;
499 prefix_len = 0;
500 } else {
501 name = w->name;
502 if (prefix)
503 prefix_len = strlen(prefix) + 1;
504 else
505 prefix_len = 0;
506 }
470 507
471 /* The control will get a prefix from the control creation 508 /*
472 * process but we're also using the same prefix for widgets so 509 * The control will get a prefix from the control creation
473 * cut the prefix off the front of the widget name. 510 * process but we're also using the same prefix for widgets so
474 */ 511 * cut the prefix off the front of the widget name.
475 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name + prefix_len, 512 */
476 prefix); 513 kcontrol = snd_soc_cnew(&w->kcontrol_news[0], wlist,
477 ret = snd_ctl_add(card, kcontrol); 514 name + prefix_len, prefix);
515 ret = snd_ctl_add(card, kcontrol);
516 if (ret < 0) {
517 dev_err(dapm->dev,
518 "asoc: failed to add kcontrol %s\n", w->name);
519 kfree(wlist);
520 return ret;
521 }
522 }
478 523
479 if (ret < 0) 524 kcontrol->private_data = wlist;
480 goto err; 525
526 w->kcontrols[0] = kcontrol;
481 527
482 list_for_each_entry(path, &w->sources, list_sink) 528 list_for_each_entry(path, &w->sources, list_sink)
483 path->kcontrol = kcontrol; 529 path->kcontrol = kcontrol;
484 530
485 return ret; 531 return 0;
486
487err:
488 dev_err(dapm->dev, "asoc: failed to add kcontrol %s\n", w->name);
489 return ret;
490} 532}
491 533
492/* create new dapm volume control */ 534/* create new dapm volume control */
@@ -644,57 +686,6 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
644} 686}
645EXPORT_SYMBOL_GPL(dapm_reg_event); 687EXPORT_SYMBOL_GPL(dapm_reg_event);
646 688
647/* Standard power change method, used to apply power changes to most
648 * widgets.
649 */
650static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w)
651{
652 int ret;
653
654 /* call any power change event handlers */
655 if (w->event)
656 dev_dbg(w->dapm->dev, "power %s event for %s flags %x\n",
657 w->power ? "on" : "off",
658 w->name, w->event_flags);
659
660 /* power up pre event */
661 if (w->power && w->event &&
662 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
663 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
664 if (ret < 0)
665 return ret;
666 }
667
668 /* power down pre event */
669 if (!w->power && w->event &&
670 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
671 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
672 if (ret < 0)
673 return ret;
674 }
675
676 dapm_update_bits(w);
677
678 /* power up post event */
679 if (w->power && w->event &&
680 (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
681 ret = w->event(w,
682 NULL, SND_SOC_DAPM_POST_PMU);
683 if (ret < 0)
684 return ret;
685 }
686
687 /* power down post event */
688 if (!w->power && w->event &&
689 (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
690 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
691 if (ret < 0)
692 return ret;
693 }
694
695 return 0;
696}
697
698/* Generic check to see if a widget should be powered. 689/* Generic check to see if a widget should be powered.
699 */ 690 */
700static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) 691static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
@@ -981,16 +972,6 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
981 NULL, SND_SOC_DAPM_POST_PMD); 972 NULL, SND_SOC_DAPM_POST_PMD);
982 break; 973 break;
983 974
984 case snd_soc_dapm_input:
985 case snd_soc_dapm_output:
986 case snd_soc_dapm_hp:
987 case snd_soc_dapm_mic:
988 case snd_soc_dapm_line:
989 case snd_soc_dapm_spk:
990 /* No register support currently */
991 ret = dapm_generic_apply_power(w);
992 break;
993
994 default: 975 default:
995 /* Queue it up for application */ 976 /* Queue it up for application */
996 cur_sort = sort[w->id]; 977 cur_sort = sort[w->id];
@@ -1201,6 +1182,15 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1201 } 1182 }
1202 } 1183 }
1203 1184
1185 /* Force all contexts in the card to the same bias state */
1186 power = 0;
1187 list_for_each_entry(d, &card->dapm_list, list)
1188 if (d->dev_power)
1189 power = 1;
1190 list_for_each_entry(d, &card->dapm_list, list)
1191 d->dev_power = power;
1192
1193
1204 /* Run all the bias changes in parallel */ 1194 /* Run all the bias changes in parallel */
1205 list_for_each_entry(d, &dapm->card->dapm_list, list) 1195 list_for_each_entry(d, &dapm->card->dapm_list, list)
1206 async_schedule_domain(dapm_pre_sequence_async, d, 1196 async_schedule_domain(dapm_pre_sequence_async, d,
@@ -1304,31 +1294,104 @@ static const struct file_operations dapm_widget_power_fops = {
1304 .llseek = default_llseek, 1294 .llseek = default_llseek,
1305}; 1295};
1306 1296
1307void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm) 1297static int dapm_bias_open_file(struct inode *inode, struct file *file)
1298{
1299 file->private_data = inode->i_private;
1300 return 0;
1301}
1302
1303static ssize_t dapm_bias_read_file(struct file *file, char __user *user_buf,
1304 size_t count, loff_t *ppos)
1305{
1306 struct snd_soc_dapm_context *dapm = file->private_data;
1307 char *level;
1308
1309 switch (dapm->bias_level) {
1310 case SND_SOC_BIAS_ON:
1311 level = "On\n";
1312 break;
1313 case SND_SOC_BIAS_PREPARE:
1314 level = "Prepare\n";
1315 break;
1316 case SND_SOC_BIAS_STANDBY:
1317 level = "Standby\n";
1318 break;
1319 case SND_SOC_BIAS_OFF:
1320 level = "Off\n";
1321 break;
1322 default:
1323 BUG();
1324 level = "Unknown\n";
1325 break;
1326 }
1327
1328 return simple_read_from_buffer(user_buf, count, ppos, level,
1329 strlen(level));
1330}
1331
1332static const struct file_operations dapm_bias_fops = {
1333 .open = dapm_bias_open_file,
1334 .read = dapm_bias_read_file,
1335 .llseek = default_llseek,
1336};
1337
1338void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
1339 struct dentry *parent)
1308{ 1340{
1309 struct snd_soc_dapm_widget *w;
1310 struct dentry *d; 1341 struct dentry *d;
1311 1342
1312 if (!dapm->debugfs_dapm) 1343 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent);
1344
1345 if (!dapm->debugfs_dapm) {
1346 printk(KERN_WARNING
1347 "Failed to create DAPM debugfs directory\n");
1313 return; 1348 return;
1349 }
1314 1350
1315 list_for_each_entry(w, &dapm->card->widgets, list) { 1351 d = debugfs_create_file("bias_level", 0444,
1316 if (!w->name || w->dapm != dapm) 1352 dapm->debugfs_dapm, dapm,
1317 continue; 1353 &dapm_bias_fops);
1354 if (!d)
1355 dev_warn(dapm->dev,
1356 "ASoC: Failed to create bias level debugfs file\n");
1357}
1318 1358
1319 d = debugfs_create_file(w->name, 0444, 1359static void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
1320 dapm->debugfs_dapm, w, 1360{
1321 &dapm_widget_power_fops); 1361 struct snd_soc_dapm_context *dapm = w->dapm;
1322 if (!d) 1362 struct dentry *d;
1323 dev_warn(w->dapm->dev, 1363
1324 "ASoC: Failed to create %s debugfs file\n", 1364 if (!dapm->debugfs_dapm || !w->name)
1325 w->name); 1365 return;
1326 } 1366
1367 d = debugfs_create_file(w->name, 0444,
1368 dapm->debugfs_dapm, w,
1369 &dapm_widget_power_fops);
1370 if (!d)
1371 dev_warn(w->dapm->dev,
1372 "ASoC: Failed to create %s debugfs file\n",
1373 w->name);
1374}
1375
1376static void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
1377{
1378 debugfs_remove_recursive(dapm->debugfs_dapm);
1327} 1379}
1380
1328#else 1381#else
1329void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm) 1382void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
1383 struct dentry *parent)
1384{
1385}
1386
1387static inline void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
1388{
1389}
1390
1391static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
1330{ 1392{
1331} 1393}
1394
1332#endif 1395#endif
1333 1396
1334/* test and update the power status of a mux widget */ 1397/* test and update the power status of a mux widget */
@@ -1496,32 +1559,49 @@ static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
1496 kfree(p->long_name); 1559 kfree(p->long_name);
1497 kfree(p); 1560 kfree(p);
1498 } 1561 }
1562 kfree(w->kcontrols);
1499 kfree(w->name); 1563 kfree(w->name);
1500 kfree(w); 1564 kfree(w);
1501 } 1565 }
1502} 1566}
1503 1567
1504static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, 1568static struct snd_soc_dapm_widget *dapm_find_widget(
1505 const char *pin, int status) 1569 struct snd_soc_dapm_context *dapm, const char *pin,
1570 bool search_other_contexts)
1506{ 1571{
1507 struct snd_soc_dapm_widget *w; 1572 struct snd_soc_dapm_widget *w;
1573 struct snd_soc_dapm_widget *fallback = NULL;
1508 1574
1509 list_for_each_entry(w, &dapm->card->widgets, list) { 1575 list_for_each_entry(w, &dapm->card->widgets, list) {
1510 if (w->dapm != dapm)
1511 continue;
1512 if (!strcmp(w->name, pin)) { 1576 if (!strcmp(w->name, pin)) {
1513 dev_dbg(w->dapm->dev, "dapm: pin %s = %d\n", 1577 if (w->dapm == dapm)
1514 pin, status); 1578 return w;
1515 w->connected = status; 1579 else
1516 /* Allow disabling of forced pins */ 1580 fallback = w;
1517 if (status == 0)
1518 w->force = 0;
1519 return 0;
1520 } 1581 }
1521 } 1582 }
1522 1583
1523 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); 1584 if (search_other_contexts)
1524 return -EINVAL; 1585 return fallback;
1586
1587 return NULL;
1588}
1589
1590static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
1591 const char *pin, int status)
1592{
1593 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
1594
1595 if (!w) {
1596 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
1597 return -EINVAL;
1598 }
1599
1600 w->connected = status;
1601 if (status == 0)
1602 w->force = 0;
1603
1604 return 0;
1525} 1605}
1526 1606
1527/** 1607/**
@@ -1627,7 +1707,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
1627 } 1707 }
1628 1708
1629 /* connect dynamic paths */ 1709 /* connect dynamic paths */
1630 switch(wsink->id) { 1710 switch (wsink->id) {
1631 case snd_soc_dapm_adc: 1711 case snd_soc_dapm_adc:
1632 case snd_soc_dapm_dac: 1712 case snd_soc_dapm_dac:
1633 case snd_soc_dapm_pga: 1713 case snd_soc_dapm_pga:
@@ -1650,7 +1730,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
1650 case snd_soc_dapm_virt_mux: 1730 case snd_soc_dapm_virt_mux:
1651 case snd_soc_dapm_value_mux: 1731 case snd_soc_dapm_value_mux:
1652 ret = dapm_connect_mux(dapm, wsource, wsink, path, control, 1732 ret = dapm_connect_mux(dapm, wsource, wsink, path, control,
1653 &wsink->kcontrols[0]); 1733 &wsink->kcontrol_news[0]);
1654 if (ret != 0) 1734 if (ret != 0)
1655 goto err; 1735 goto err;
1656 break; 1736 break;
@@ -1730,6 +1810,14 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
1730 if (w->new) 1810 if (w->new)
1731 continue; 1811 continue;
1732 1812
1813 if (w->num_kcontrols) {
1814 w->kcontrols = kzalloc(w->num_kcontrols *
1815 sizeof(struct snd_kcontrol *),
1816 GFP_KERNEL);
1817 if (!w->kcontrols)
1818 return -ENOMEM;
1819 }
1820
1733 switch(w->id) { 1821 switch(w->id) {
1734 case snd_soc_dapm_switch: 1822 case snd_soc_dapm_switch:
1735 case snd_soc_dapm_mixer: 1823 case snd_soc_dapm_mixer:
@@ -1785,6 +1873,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
1785 } 1873 }
1786 1874
1787 w->new = 1; 1875 w->new = 1;
1876
1877 dapm_debugfs_add_widget(w);
1788 } 1878 }
1789 1879
1790 dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); 1880 dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
@@ -1804,7 +1894,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
1804int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, 1894int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
1805 struct snd_ctl_elem_value *ucontrol) 1895 struct snd_ctl_elem_value *ucontrol)
1806{ 1896{
1807 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1897 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1898 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1808 struct soc_mixer_control *mc = 1899 struct soc_mixer_control *mc =
1809 (struct soc_mixer_control *)kcontrol->private_value; 1900 (struct soc_mixer_control *)kcontrol->private_value;
1810 unsigned int reg = mc->reg; 1901 unsigned int reg = mc->reg;
@@ -1843,7 +1934,9 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw);
1843int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, 1934int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1844 struct snd_ctl_elem_value *ucontrol) 1935 struct snd_ctl_elem_value *ucontrol)
1845{ 1936{
1846 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1937 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1938 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1939 struct snd_soc_codec *codec = widget->codec;
1847 struct soc_mixer_control *mc = 1940 struct soc_mixer_control *mc =
1848 (struct soc_mixer_control *)kcontrol->private_value; 1941 (struct soc_mixer_control *)kcontrol->private_value;
1849 unsigned int reg = mc->reg; 1942 unsigned int reg = mc->reg;
@@ -1854,6 +1947,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1854 unsigned int val; 1947 unsigned int val;
1855 int connect, change; 1948 int connect, change;
1856 struct snd_soc_dapm_update update; 1949 struct snd_soc_dapm_update update;
1950 int wi;
1857 1951
1858 val = (ucontrol->value.integer.value[0] & mask); 1952 val = (ucontrol->value.integer.value[0] & mask);
1859 1953
@@ -1862,31 +1956,36 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1862 mask = mask << shift; 1956 mask = mask << shift;
1863 val = val << shift; 1957 val = val << shift;
1864 1958
1865 mutex_lock(&widget->codec->mutex); 1959 if (val)
1866 widget->value = val; 1960 /* new connection */
1961 connect = invert ? 0 : 1;
1962 else
1963 /* old connection must be powered down */
1964 connect = invert ? 1 : 0;
1965
1966 mutex_lock(&codec->mutex);
1867 1967
1868 change = snd_soc_test_bits(widget->codec, reg, mask, val); 1968 change = snd_soc_test_bits(widget->codec, reg, mask, val);
1869 if (change) { 1969 if (change) {
1870 if (val) 1970 for (wi = 0; wi < wlist->num_widgets; wi++) {
1871 /* new connection */ 1971 widget = wlist->widgets[wi];
1872 connect = invert ? 0:1;
1873 else
1874 /* old connection must be powered down */
1875 connect = invert ? 1:0;
1876 1972
1877 update.kcontrol = kcontrol; 1973 widget->value = val;
1878 update.widget = widget;
1879 update.reg = reg;
1880 update.mask = mask;
1881 update.val = val;
1882 widget->dapm->update = &update;
1883 1974
1884 dapm_mixer_update_power(widget, kcontrol, connect); 1975 update.kcontrol = kcontrol;
1976 update.widget = widget;
1977 update.reg = reg;
1978 update.mask = mask;
1979 update.val = val;
1980 widget->dapm->update = &update;
1885 1981
1886 widget->dapm->update = NULL; 1982 dapm_mixer_update_power(widget, kcontrol, connect);
1983
1984 widget->dapm->update = NULL;
1985 }
1887 } 1986 }
1888 1987
1889 mutex_unlock(&widget->codec->mutex); 1988 mutex_unlock(&codec->mutex);
1890 return 0; 1989 return 0;
1891} 1990}
1892EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw); 1991EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
@@ -1903,7 +2002,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
1903int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, 2002int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
1904 struct snd_ctl_elem_value *ucontrol) 2003 struct snd_ctl_elem_value *ucontrol)
1905{ 2004{
1906 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 2005 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2006 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1907 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2007 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1908 unsigned int val, bitmask; 2008 unsigned int val, bitmask;
1909 2009
@@ -1931,11 +2031,14 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
1931int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, 2031int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1932 struct snd_ctl_elem_value *ucontrol) 2032 struct snd_ctl_elem_value *ucontrol)
1933{ 2033{
1934 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 2034 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2035 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2036 struct snd_soc_codec *codec = widget->codec;
1935 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2037 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1936 unsigned int val, mux, change; 2038 unsigned int val, mux, change;
1937 unsigned int mask, bitmask; 2039 unsigned int mask, bitmask;
1938 struct snd_soc_dapm_update update; 2040 struct snd_soc_dapm_update update;
2041 int wi;
1939 2042
1940 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 2043 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1941 ; 2044 ;
@@ -1951,22 +2054,29 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1951 mask |= (bitmask - 1) << e->shift_r; 2054 mask |= (bitmask - 1) << e->shift_r;
1952 } 2055 }
1953 2056
1954 mutex_lock(&widget->codec->mutex); 2057 mutex_lock(&codec->mutex);
1955 widget->value = val; 2058
1956 change = snd_soc_test_bits(widget->codec, e->reg, mask, val); 2059 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
2060 if (change) {
2061 for (wi = 0; wi < wlist->num_widgets; wi++) {
2062 widget = wlist->widgets[wi];
1957 2063
1958 update.kcontrol = kcontrol; 2064 widget->value = val;
1959 update.widget = widget;
1960 update.reg = e->reg;
1961 update.mask = mask;
1962 update.val = val;
1963 widget->dapm->update = &update;
1964 2065
1965 dapm_mux_update_power(widget, kcontrol, change, mux, e); 2066 update.kcontrol = kcontrol;
2067 update.widget = widget;
2068 update.reg = e->reg;
2069 update.mask = mask;
2070 update.val = val;
2071 widget->dapm->update = &update;
1966 2072
1967 widget->dapm->update = NULL; 2073 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1968 2074
1969 mutex_unlock(&widget->codec->mutex); 2075 widget->dapm->update = NULL;
2076 }
2077 }
2078
2079 mutex_unlock(&codec->mutex);
1970 return change; 2080 return change;
1971} 2081}
1972EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); 2082EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
@@ -1981,7 +2091,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
1981int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol, 2091int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol,
1982 struct snd_ctl_elem_value *ucontrol) 2092 struct snd_ctl_elem_value *ucontrol)
1983{ 2093{
1984 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 2094 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2095 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1985 2096
1986 ucontrol->value.enumerated.item[0] = widget->value; 2097 ucontrol->value.enumerated.item[0] = widget->value;
1987 2098
@@ -1999,22 +2110,33 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt);
1999int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol, 2110int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
2000 struct snd_ctl_elem_value *ucontrol) 2111 struct snd_ctl_elem_value *ucontrol)
2001{ 2112{
2002 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 2113 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2114 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2115 struct snd_soc_codec *codec = widget->codec;
2003 struct soc_enum *e = 2116 struct soc_enum *e =
2004 (struct soc_enum *)kcontrol->private_value; 2117 (struct soc_enum *)kcontrol->private_value;
2005 int change; 2118 int change;
2006 int ret = 0; 2119 int ret = 0;
2120 int wi;
2007 2121
2008 if (ucontrol->value.enumerated.item[0] >= e->max) 2122 if (ucontrol->value.enumerated.item[0] >= e->max)
2009 return -EINVAL; 2123 return -EINVAL;
2010 2124
2011 mutex_lock(&widget->codec->mutex); 2125 mutex_lock(&codec->mutex);
2012 2126
2013 change = widget->value != ucontrol->value.enumerated.item[0]; 2127 change = widget->value != ucontrol->value.enumerated.item[0];
2014 widget->value = ucontrol->value.enumerated.item[0]; 2128 if (change) {
2015 dapm_mux_update_power(widget, kcontrol, change, widget->value, e); 2129 for (wi = 0; wi < wlist->num_widgets; wi++) {
2130 widget = wlist->widgets[wi];
2016 2131
2017 mutex_unlock(&widget->codec->mutex); 2132 widget->value = ucontrol->value.enumerated.item[0];
2133
2134 dapm_mux_update_power(widget, kcontrol, change,
2135 widget->value, e);
2136 }
2137 }
2138
2139 mutex_unlock(&codec->mutex);
2018 return ret; 2140 return ret;
2019} 2141}
2020EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt); 2142EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
@@ -2035,7 +2157,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
2035int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol, 2157int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
2036 struct snd_ctl_elem_value *ucontrol) 2158 struct snd_ctl_elem_value *ucontrol)
2037{ 2159{
2038 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 2160 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2161 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2039 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2162 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2040 unsigned int reg_val, val, mux; 2163 unsigned int reg_val, val, mux;
2041 2164
@@ -2075,11 +2198,14 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_value_enum_double);
2075int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, 2198int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2076 struct snd_ctl_elem_value *ucontrol) 2199 struct snd_ctl_elem_value *ucontrol)
2077{ 2200{
2078 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 2201 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2202 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2203 struct snd_soc_codec *codec = widget->codec;
2079 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2204 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2080 unsigned int val, mux, change; 2205 unsigned int val, mux, change;
2081 unsigned int mask; 2206 unsigned int mask;
2082 struct snd_soc_dapm_update update; 2207 struct snd_soc_dapm_update update;
2208 int wi;
2083 2209
2084 if (ucontrol->value.enumerated.item[0] > e->max - 1) 2210 if (ucontrol->value.enumerated.item[0] > e->max - 1)
2085 return -EINVAL; 2211 return -EINVAL;
@@ -2093,22 +2219,29 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2093 mask |= e->mask << e->shift_r; 2219 mask |= e->mask << e->shift_r;
2094 } 2220 }
2095 2221
2096 mutex_lock(&widget->codec->mutex); 2222 mutex_lock(&codec->mutex);
2097 widget->value = val; 2223
2098 change = snd_soc_test_bits(widget->codec, e->reg, mask, val); 2224 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
2225 if (change) {
2226 for (wi = 0; wi < wlist->num_widgets; wi++) {
2227 widget = wlist->widgets[wi];
2099 2228
2100 update.kcontrol = kcontrol; 2229 widget->value = val;
2101 update.widget = widget;
2102 update.reg = e->reg;
2103 update.mask = mask;
2104 update.val = val;
2105 widget->dapm->update = &update;
2106 2230
2107 dapm_mux_update_power(widget, kcontrol, change, mux, e); 2231 update.kcontrol = kcontrol;
2232 update.widget = widget;
2233 update.reg = e->reg;
2234 update.mask = mask;
2235 update.val = val;
2236 widget->dapm->update = &update;
2108 2237
2109 widget->dapm->update = NULL; 2238 dapm_mux_update_power(widget, kcontrol, change, mux, e);
2239
2240 widget->dapm->update = NULL;
2241 }
2242 }
2110 2243
2111 mutex_unlock(&widget->codec->mutex); 2244 mutex_unlock(&codec->mutex);
2112 return change; 2245 return change;
2113} 2246}
2114EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double); 2247EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double);
@@ -2346,22 +2479,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
2346int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, 2479int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
2347 const char *pin) 2480 const char *pin)
2348{ 2481{
2349 struct snd_soc_dapm_widget *w; 2482 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
2350 2483
2351 list_for_each_entry(w, &dapm->card->widgets, list) { 2484 if (!w) {
2352 if (w->dapm != dapm) 2485 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
2353 continue; 2486 return -EINVAL;
2354 if (!strcmp(w->name, pin)) {
2355 dev_dbg(w->dapm->dev,
2356 "dapm: force enable pin %s\n", pin);
2357 w->connected = 1;
2358 w->force = 1;
2359 return 0;
2360 }
2361 } 2487 }
2362 2488
2363 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); 2489 dev_dbg(w->dapm->dev, "dapm: force enable pin %s\n", pin);
2364 return -EINVAL; 2490 w->connected = 1;
2491 w->force = 1;
2492
2493 return 0;
2365} 2494}
2366EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); 2495EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin);
2367 2496
@@ -2413,14 +2542,10 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
2413int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, 2542int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm,
2414 const char *pin) 2543 const char *pin)
2415{ 2544{
2416 struct snd_soc_dapm_widget *w; 2545 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
2417 2546
2418 list_for_each_entry(w, &dapm->card->widgets, list) { 2547 if (w)
2419 if (w->dapm != dapm) 2548 return w->connected;
2420 continue;
2421 if (!strcmp(w->name, pin))
2422 return w->connected;
2423 }
2424 2549
2425 return 0; 2550 return 0;
2426} 2551}
@@ -2440,19 +2565,16 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
2440int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, 2565int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
2441 const char *pin) 2566 const char *pin)
2442{ 2567{
2443 struct snd_soc_dapm_widget *w; 2568 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, false);
2444 2569
2445 list_for_each_entry(w, &dapm->card->widgets, list) { 2570 if (!w) {
2446 if (w->dapm != dapm) 2571 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
2447 continue; 2572 return -EINVAL;
2448 if (!strcmp(w->name, pin)) {
2449 w->ignore_suspend = 1;
2450 return 0;
2451 }
2452 } 2573 }
2453 2574
2454 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); 2575 w->ignore_suspend = 1;
2455 return -EINVAL; 2576
2577 return 0;
2456} 2578}
2457EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); 2579EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
2458 2580
@@ -2465,6 +2587,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
2465void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm) 2587void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm)
2466{ 2588{
2467 snd_soc_dapm_sys_remove(dapm->dev); 2589 snd_soc_dapm_sys_remove(dapm->dev);
2590 dapm_debugfs_cleanup(dapm);
2468 dapm_free_widgets(dapm); 2591 dapm_free_widgets(dapm);
2469 list_del(&dapm->list); 2592 list_del(&dapm->list);
2470} 2593}
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index fc017c0a7b5d..7c17b98d5846 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -325,7 +325,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
325 gpio_handler, 325 gpio_handler,
326 IRQF_TRIGGER_RISING | 326 IRQF_TRIGGER_RISING |
327 IRQF_TRIGGER_FALLING, 327 IRQF_TRIGGER_FALLING,
328 jack->codec->dev->driver->name, 328 gpios[i].name,
329 &gpios[i]); 329 &gpios[i]);
330 if (ret) 330 if (ret)
331 goto err; 331 goto err;
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index 3f45e6a439bf..ec921ec99c26 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -13,6 +13,7 @@
13 * option) any later version. 13 * option) any later version.
14 */ 14 */
15 15
16#include <linux/platform_device.h>
16#include <sound/core.h> 17#include <sound/core.h>
17#include <sound/pcm.h> 18#include <sound/pcm.h>
18#include <sound/pcm_params.h> 19#include <sound/pcm_params.h>
@@ -55,3 +56,55 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *params)
55 return ret; 56 return ret;
56} 57}
57EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk); 58EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk);
59
60static struct snd_soc_platform_driver dummy_platform;
61
62static __devinit int snd_soc_dummy_probe(struct platform_device *pdev)
63{
64 return snd_soc_register_platform(&pdev->dev, &dummy_platform);
65}
66
67static __devexit int snd_soc_dummy_remove(struct platform_device *pdev)
68{
69 snd_soc_unregister_platform(&pdev->dev);
70
71 return 0;
72}
73
74static struct platform_driver soc_dummy_driver = {
75 .driver = {
76 .name = "snd-soc-dummy",
77 .owner = THIS_MODULE,
78 },
79 .probe = snd_soc_dummy_probe,
80 .remove = __devexit_p(snd_soc_dummy_remove),
81};
82
83static struct platform_device *soc_dummy_dev;
84
85int __init snd_soc_util_init(void)
86{
87 int ret;
88
89 soc_dummy_dev = platform_device_alloc("snd-soc-dummy", -1);
90 if (!soc_dummy_dev)
91 return -ENOMEM;
92
93 ret = platform_device_add(soc_dummy_dev);
94 if (ret != 0) {
95 platform_device_put(soc_dummy_dev);
96 return ret;
97 }
98
99 ret = platform_driver_register(&soc_dummy_driver);
100 if (ret != 0)
101 platform_device_unregister(soc_dummy_dev);
102
103 return ret;
104}
105
106void __exit snd_soc_util_exit(void)
107{
108 platform_device_unregister(soc_dummy_dev);
109 platform_driver_unregister(&soc_dummy_driver);
110}
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index 66b504f06c23..035d39a4beb4 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -1,26 +1,40 @@
1config SND_TEGRA_SOC 1config SND_SOC_TEGRA
2 tristate "SoC Audio for the Tegra System-on-Chip" 2 tristate "SoC Audio for the Tegra System-on-Chip"
3 depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA 3 depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA
4 default m
5 help 4 help
6 Say Y or M here if you want support for SoC audio on Tegra. 5 Say Y or M here if you want support for SoC audio on Tegra.
7 6
8config SND_TEGRA_SOC_I2S 7config SND_SOC_TEGRA_I2S
9 tristate 8 tristate
10 depends on SND_TEGRA_SOC 9 depends on SND_SOC_TEGRA
11 default m
12 help 10 help
13 Say Y or M if you want to add support for codecs attached to the 11 Say Y or M if you want to add support for codecs attached to the
14 Tegra I2S interface. You will also need to select the individual 12 Tegra I2S interface. You will also need to select the individual
15 machine drivers to support below. 13 machine drivers to support below.
16 14
17config SND_TEGRA_SOC_HARMONY 15config MACH_HAS_SND_SOC_TEGRA_WM8903
18 tristate "SoC Audio support for Tegra Harmony reference board" 16 bool
19 depends on SND_TEGRA_SOC && MACH_HARMONY && I2C 17 help
20 default m 18 Machines that use the SND_SOC_TEGRA_WM8903 driver should select
21 select SND_TEGRA_SOC_I2S 19 this config option, in order to allow the user to enable
20 SND_SOC_TEGRA_WM8903.
21
22config SND_SOC_TEGRA_WM8903
23 tristate "SoC Audio support for Tegra boards using a WM8903 codec"
24 depends on SND_SOC_TEGRA && I2C
25 depends on MACH_HAS_SND_SOC_TEGRA_WM8903
26 select SND_SOC_TEGRA_I2S
22 select SND_SOC_WM8903 27 select SND_SOC_WM8903
23 help 28 help
24 Say Y or M here if you want to add support for SoC audio on the 29 Say Y or M here if you want to add support for SoC audio on Tegra
25 Tegra Harmony reference board. 30 boards using the WM8093 codec. Currently, the supported boards are
31 Harmony, Ventana, Seaboard, Kaen, and Aebl.
26 32
33config SND_SOC_TEGRA_TRIMSLICE
34 tristate "SoC Audio support for TrimSlice board"
35 depends on SND_SOC_TEGRA && MACH_TRIMSLICE && I2C
36 select SND_SOC_TEGRA_I2S
37 select SND_SOC_TLV320AIC23
38 help
39 Say Y or M here if you want to add support for SoC audio on the
40 TrimSlice platform.
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index fd183d3ab4f1..fa6574d92a31 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -4,12 +4,14 @@ snd-soc-tegra-pcm-objs := tegra_pcm.o
4snd-soc-tegra-i2s-objs := tegra_i2s.o 4snd-soc-tegra-i2s-objs := tegra_i2s.o
5snd-soc-tegra-utils-objs += tegra_asoc_utils.o 5snd-soc-tegra-utils-objs += tegra_asoc_utils.o
6 6
7obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-utils.o 7obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o
8obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-das.o 8obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-das.o
9obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-pcm.o 9obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o
10obj-$(CONFIG_SND_TEGRA_SOC_I2S) += snd-soc-tegra-i2s.o 10obj-$(CONFIG_SND_SOC_TEGRA_I2S) += snd-soc-tegra-i2s.o
11 11
12# Tegra machine Support 12# Tegra machine Support
13snd-soc-tegra-harmony-objs := harmony.o 13snd-soc-tegra-wm8903-objs := tegra_wm8903.o
14snd-soc-tegra-trimslice-objs := trimslice.o
14 15
15obj-$(CONFIG_SND_TEGRA_SOC_HARMONY) += snd-soc-tegra-harmony.o 16obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o
17obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o
diff --git a/sound/soc/tegra/harmony.c b/sound/soc/tegra/harmony.c
deleted file mode 100644
index 556a57133925..000000000000
--- a/sound/soc/tegra/harmony.c
+++ /dev/null
@@ -1,394 +0,0 @@
1/*
2 * harmony.c - Harmony machine ASoC driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010-2011 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd.
10 *
11 * Copyright 2007 Wolfson Microelectronics PLC.
12 * Author: Graeme Gregory
13 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#include <asm/mach-types.h>
32
33#include <linux/module.h>
34#include <linux/platform_device.h>
35#include <linux/slab.h>
36#include <linux/gpio.h>
37
38#include <mach/harmony_audio.h>
39
40#include <sound/core.h>
41#include <sound/jack.h>
42#include <sound/pcm.h>
43#include <sound/pcm_params.h>
44#include <sound/soc.h>
45
46#include "../codecs/wm8903.h"
47
48#include "tegra_das.h"
49#include "tegra_i2s.h"
50#include "tegra_pcm.h"
51#include "tegra_asoc_utils.h"
52
53#define DRV_NAME "tegra-snd-harmony"
54
55#define GPIO_SPKR_EN BIT(0)
56#define GPIO_INT_MIC_EN BIT(1)
57#define GPIO_EXT_MIC_EN BIT(2)
58
59struct tegra_harmony {
60 struct tegra_asoc_utils_data util_data;
61 struct harmony_audio_platform_data *pdata;
62 int gpio_requested;
63};
64
65static int harmony_asoc_hw_params(struct snd_pcm_substream *substream,
66 struct snd_pcm_hw_params *params)
67{
68 struct snd_soc_pcm_runtime *rtd = substream->private_data;
69 struct snd_soc_dai *codec_dai = rtd->codec_dai;
70 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
71 struct snd_soc_codec *codec = rtd->codec;
72 struct snd_soc_card *card = codec->card;
73 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
74 int srate, mclk, mclk_change;
75 int err;
76
77 srate = params_rate(params);
78 switch (srate) {
79 case 64000:
80 case 88200:
81 case 96000:
82 mclk = 128 * srate;
83 break;
84 default:
85 mclk = 256 * srate;
86 break;
87 }
88 /* FIXME: Codec only requires >= 3MHz if OSR==0 */
89 while (mclk < 6000000)
90 mclk *= 2;
91
92 err = tegra_asoc_utils_set_rate(&harmony->util_data, srate, mclk,
93 &mclk_change);
94 if (err < 0) {
95 dev_err(card->dev, "Can't configure clocks\n");
96 return err;
97 }
98
99 err = snd_soc_dai_set_fmt(codec_dai,
100 SND_SOC_DAIFMT_I2S |
101 SND_SOC_DAIFMT_NB_NF |
102 SND_SOC_DAIFMT_CBS_CFS);
103 if (err < 0) {
104 dev_err(card->dev, "codec_dai fmt not set\n");
105 return err;
106 }
107
108 err = snd_soc_dai_set_fmt(cpu_dai,
109 SND_SOC_DAIFMT_I2S |
110 SND_SOC_DAIFMT_NB_NF |
111 SND_SOC_DAIFMT_CBS_CFS);
112 if (err < 0) {
113 dev_err(card->dev, "cpu_dai fmt not set\n");
114 return err;
115 }
116
117 if (mclk_change) {
118 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
119 SND_SOC_CLOCK_IN);
120 if (err < 0) {
121 dev_err(card->dev, "codec_dai clock not set\n");
122 return err;
123 }
124 }
125
126 return 0;
127}
128
129static struct snd_soc_ops harmony_asoc_ops = {
130 .hw_params = harmony_asoc_hw_params,
131};
132
133static struct snd_soc_jack harmony_hp_jack;
134
135static struct snd_soc_jack_pin harmony_hp_jack_pins[] = {
136 {
137 .pin = "Headphone Jack",
138 .mask = SND_JACK_HEADPHONE,
139 },
140};
141
142static struct snd_soc_jack_gpio harmony_hp_jack_gpios[] = {
143 {
144 .name = "headphone detect",
145 .report = SND_JACK_HEADPHONE,
146 .debounce_time = 150,
147 .invert = 1,
148 }
149};
150
151static struct snd_soc_jack harmony_mic_jack;
152
153static struct snd_soc_jack_pin harmony_mic_jack_pins[] = {
154 {
155 .pin = "Mic Jack",
156 .mask = SND_JACK_MICROPHONE,
157 },
158};
159
160static int harmony_event_int_spk(struct snd_soc_dapm_widget *w,
161 struct snd_kcontrol *k, int event)
162{
163 struct snd_soc_codec *codec = w->codec;
164 struct snd_soc_card *card = codec->card;
165 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
166 struct harmony_audio_platform_data *pdata = harmony->pdata;
167
168 gpio_set_value_cansleep(pdata->gpio_spkr_en,
169 SND_SOC_DAPM_EVENT_ON(event));
170
171 return 0;
172}
173
174static const struct snd_soc_dapm_widget harmony_dapm_widgets[] = {
175 SND_SOC_DAPM_SPK("Int Spk", harmony_event_int_spk),
176 SND_SOC_DAPM_HP("Headphone Jack", NULL),
177 SND_SOC_DAPM_MIC("Mic Jack", NULL),
178};
179
180static const struct snd_soc_dapm_route harmony_audio_map[] = {
181 {"Headphone Jack", NULL, "HPOUTR"},
182 {"Headphone Jack", NULL, "HPOUTL"},
183 {"Int Spk", NULL, "ROP"},
184 {"Int Spk", NULL, "RON"},
185 {"Int Spk", NULL, "LOP"},
186 {"Int Spk", NULL, "LON"},
187 {"Mic Bias", NULL, "Mic Jack"},
188 {"IN1L", NULL, "Mic Bias"},
189};
190
191static const struct snd_kcontrol_new harmony_controls[] = {
192 SOC_DAPM_PIN_SWITCH("Int Spk"),
193};
194
195static int harmony_asoc_init(struct snd_soc_pcm_runtime *rtd)
196{
197 struct snd_soc_codec *codec = rtd->codec;
198 struct snd_soc_dapm_context *dapm = &codec->dapm;
199 struct snd_soc_card *card = codec->card;
200 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
201 struct harmony_audio_platform_data *pdata = harmony->pdata;
202 int ret;
203
204 ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
205 if (ret) {
206 dev_err(card->dev, "cannot get spkr_en gpio\n");
207 return ret;
208 }
209 harmony->gpio_requested |= GPIO_SPKR_EN;
210
211 gpio_direction_output(pdata->gpio_spkr_en, 0);
212
213 ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
214 if (ret) {
215 dev_err(card->dev, "cannot get int_mic_en gpio\n");
216 return ret;
217 }
218 harmony->gpio_requested |= GPIO_INT_MIC_EN;
219
220 /* Disable int mic; enable signal is active-high */
221 gpio_direction_output(pdata->gpio_int_mic_en, 0);
222
223 ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
224 if (ret) {
225 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
226 return ret;
227 }
228 harmony->gpio_requested |= GPIO_EXT_MIC_EN;
229
230 /* Enable ext mic; enable signal is active-low */
231 gpio_direction_output(pdata->gpio_ext_mic_en, 0);
232
233 ret = snd_soc_add_controls(codec, harmony_controls,
234 ARRAY_SIZE(harmony_controls));
235 if (ret < 0)
236 return ret;
237
238 snd_soc_dapm_new_controls(dapm, harmony_dapm_widgets,
239 ARRAY_SIZE(harmony_dapm_widgets));
240
241 snd_soc_dapm_add_routes(dapm, harmony_audio_map,
242 ARRAY_SIZE(harmony_audio_map));
243
244 harmony_hp_jack_gpios[0].gpio = pdata->gpio_hp_det;
245 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
246 &harmony_hp_jack);
247 snd_soc_jack_add_pins(&harmony_hp_jack,
248 ARRAY_SIZE(harmony_hp_jack_pins),
249 harmony_hp_jack_pins);
250 snd_soc_jack_add_gpios(&harmony_hp_jack,
251 ARRAY_SIZE(harmony_hp_jack_gpios),
252 harmony_hp_jack_gpios);
253
254 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
255 &harmony_mic_jack);
256 snd_soc_jack_add_pins(&harmony_mic_jack,
257 ARRAY_SIZE(harmony_mic_jack_pins),
258 harmony_mic_jack_pins);
259 wm8903_mic_detect(codec, &harmony_mic_jack, SND_JACK_MICROPHONE, 0);
260
261 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
262
263 snd_soc_dapm_nc_pin(dapm, "IN3L");
264 snd_soc_dapm_nc_pin(dapm, "IN3R");
265 snd_soc_dapm_nc_pin(dapm, "LINEOUTL");
266 snd_soc_dapm_nc_pin(dapm, "LINEOUTR");
267
268 snd_soc_dapm_sync(dapm);
269
270 return 0;
271}
272
273static struct snd_soc_dai_link harmony_wm8903_dai = {
274 .name = "WM8903",
275 .stream_name = "WM8903 PCM",
276 .codec_name = "wm8903.0-001a",
277 .platform_name = "tegra-pcm-audio",
278 .cpu_dai_name = "tegra-i2s.0",
279 .codec_dai_name = "wm8903-hifi",
280 .init = harmony_asoc_init,
281 .ops = &harmony_asoc_ops,
282};
283
284static struct snd_soc_card snd_soc_harmony = {
285 .name = "tegra-harmony",
286 .dai_link = &harmony_wm8903_dai,
287 .num_links = 1,
288};
289
290static __devinit int tegra_snd_harmony_probe(struct platform_device *pdev)
291{
292 struct snd_soc_card *card = &snd_soc_harmony;
293 struct tegra_harmony *harmony;
294 struct harmony_audio_platform_data *pdata;
295 int ret;
296
297 if (!machine_is_harmony()) {
298 dev_err(&pdev->dev, "Not running on Tegra Harmony!\n");
299 return -ENODEV;
300 }
301
302 pdata = pdev->dev.platform_data;
303 if (!pdata) {
304 dev_err(&pdev->dev, "no platform data supplied\n");
305 return -EINVAL;
306 }
307
308 harmony = kzalloc(sizeof(struct tegra_harmony), GFP_KERNEL);
309 if (!harmony) {
310 dev_err(&pdev->dev, "Can't allocate tegra_harmony\n");
311 return -ENOMEM;
312 }
313
314 harmony->pdata = pdata;
315
316 ret = tegra_asoc_utils_init(&harmony->util_data, &pdev->dev);
317 if (ret)
318 goto err_free_harmony;
319
320 card->dev = &pdev->dev;
321 platform_set_drvdata(pdev, card);
322 snd_soc_card_set_drvdata(card, harmony);
323
324 ret = snd_soc_register_card(card);
325 if (ret) {
326 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
327 ret);
328 goto err_clear_drvdata;
329 }
330
331 return 0;
332
333err_clear_drvdata:
334 snd_soc_card_set_drvdata(card, NULL);
335 platform_set_drvdata(pdev, NULL);
336 card->dev = NULL;
337 tegra_asoc_utils_fini(&harmony->util_data);
338err_free_harmony:
339 kfree(harmony);
340 return ret;
341}
342
343static int __devexit tegra_snd_harmony_remove(struct platform_device *pdev)
344{
345 struct snd_soc_card *card = platform_get_drvdata(pdev);
346 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
347 struct harmony_audio_platform_data *pdata = harmony->pdata;
348
349 snd_soc_unregister_card(card);
350
351 snd_soc_card_set_drvdata(card, NULL);
352 platform_set_drvdata(pdev, NULL);
353 card->dev = NULL;
354
355 tegra_asoc_utils_fini(&harmony->util_data);
356
357 if (harmony->gpio_requested & GPIO_EXT_MIC_EN)
358 gpio_free(pdata->gpio_ext_mic_en);
359 if (harmony->gpio_requested & GPIO_INT_MIC_EN)
360 gpio_free(pdata->gpio_int_mic_en);
361 if (harmony->gpio_requested & GPIO_SPKR_EN)
362 gpio_free(pdata->gpio_spkr_en);
363
364 kfree(harmony);
365
366 return 0;
367}
368
369static struct platform_driver tegra_snd_harmony_driver = {
370 .driver = {
371 .name = DRV_NAME,
372 .owner = THIS_MODULE,
373 .pm = &snd_soc_pm_ops,
374 },
375 .probe = tegra_snd_harmony_probe,
376 .remove = __devexit_p(tegra_snd_harmony_remove),
377};
378
379static int __init snd_tegra_harmony_init(void)
380{
381 return platform_driver_register(&tegra_snd_harmony_driver);
382}
383module_init(snd_tegra_harmony_init);
384
385static void __exit snd_tegra_harmony_exit(void)
386{
387 platform_driver_unregister(&tegra_snd_harmony_driver);
388}
389module_exit(snd_tegra_harmony_exit);
390
391MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
392MODULE_DESCRIPTION("Harmony machine ASoC driver");
393MODULE_LICENSE("GPL");
394MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
index 52f0a3f9ce40..dfa85cbb05c8 100644
--- a/sound/soc/tegra/tegra_asoc_utils.c
+++ b/sound/soc/tegra/tegra_asoc_utils.c
@@ -28,9 +28,10 @@
28#include "tegra_asoc_utils.h" 28#include "tegra_asoc_utils.h"
29 29
30int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, 30int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
31 int mclk, int *mclk_change) 31 int mclk)
32{ 32{
33 int new_baseclock; 33 int new_baseclock;
34 bool clk_change;
34 int err; 35 int err;
35 36
36 switch (srate) { 37 switch (srate) {
@@ -52,10 +53,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
52 return -EINVAL; 53 return -EINVAL;
53 } 54 }
54 55
55 *mclk_change = ((new_baseclock != data->set_baseclock) || 56 clk_change = ((new_baseclock != data->set_baseclock) ||
56 (mclk != data->set_mclk)); 57 (mclk != data->set_mclk));
57 if (!*mclk_change) 58 if (!clk_change)
58 return 0; 59 return 0;
59 60
60 data->set_baseclock = 0; 61 data->set_baseclock = 0;
61 data->set_mclk = 0; 62 data->set_mclk = 0;
diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h
index bbba7afdfc2c..4818195da25c 100644
--- a/sound/soc/tegra/tegra_asoc_utils.h
+++ b/sound/soc/tegra/tegra_asoc_utils.h
@@ -36,7 +36,7 @@ struct tegra_asoc_utils_data {
36}; 36};
37 37
38int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, 38int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
39 int mclk, int *mclk_change); 39 int mclk);
40int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, 40int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
41 struct device *dev); 41 struct device *dev);
42void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data); 42void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data);
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c
index 4f5e2c90b020..6b817e20548c 100644
--- a/sound/soc/tegra/tegra_i2s.c
+++ b/sound/soc/tegra/tegra_i2s.c
@@ -114,7 +114,7 @@ static void tegra_i2s_debug_remove(struct tegra_i2s *i2s)
114 debugfs_remove(i2s->debug); 114 debugfs_remove(i2s->debug);
115} 115}
116#else 116#else
117static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s) 117static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s, int id)
118{ 118{
119} 119}
120 120
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
new file mode 100644
index 000000000000..0d6738a8b29a
--- /dev/null
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -0,0 +1,475 @@
1/*
2 * tegra_wm8903.c - Tegra machine ASoC driver for boards using WM8903 codec.
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010-2011 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd.
10 *
11 * Copyright 2007 Wolfson Microelectronics PLC.
12 * Author: Graeme Gregory
13 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#include <asm/mach-types.h>
32
33#include <linux/module.h>
34#include <linux/platform_device.h>
35#include <linux/slab.h>
36#include <linux/gpio.h>
37
38#include <mach/tegra_wm8903_pdata.h>
39
40#include <sound/core.h>
41#include <sound/jack.h>
42#include <sound/pcm.h>
43#include <sound/pcm_params.h>
44#include <sound/soc.h>
45
46#include "../codecs/wm8903.h"
47
48#include "tegra_das.h"
49#include "tegra_i2s.h"
50#include "tegra_pcm.h"
51#include "tegra_asoc_utils.h"
52
53#define DRV_NAME "tegra-snd-wm8903"
54
55#define GPIO_SPKR_EN BIT(0)
56#define GPIO_HP_MUTE BIT(1)
57#define GPIO_INT_MIC_EN BIT(2)
58#define GPIO_EXT_MIC_EN BIT(3)
59
60struct tegra_wm8903 {
61 struct tegra_asoc_utils_data util_data;
62 struct tegra_wm8903_platform_data *pdata;
63 int gpio_requested;
64};
65
66static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream,
67 struct snd_pcm_hw_params *params)
68{
69 struct snd_soc_pcm_runtime *rtd = substream->private_data;
70 struct snd_soc_dai *codec_dai = rtd->codec_dai;
71 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
72 struct snd_soc_codec *codec = rtd->codec;
73 struct snd_soc_card *card = codec->card;
74 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
75 int srate, mclk;
76 int err;
77
78 srate = params_rate(params);
79 switch (srate) {
80 case 64000:
81 case 88200:
82 case 96000:
83 mclk = 128 * srate;
84 break;
85 default:
86 mclk = 256 * srate;
87 break;
88 }
89 /* FIXME: Codec only requires >= 3MHz if OSR==0 */
90 while (mclk < 6000000)
91 mclk *= 2;
92
93 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
94 if (err < 0) {
95 dev_err(card->dev, "Can't configure clocks\n");
96 return err;
97 }
98
99 err = snd_soc_dai_set_fmt(codec_dai,
100 SND_SOC_DAIFMT_I2S |
101 SND_SOC_DAIFMT_NB_NF |
102 SND_SOC_DAIFMT_CBS_CFS);
103 if (err < 0) {
104 dev_err(card->dev, "codec_dai fmt not set\n");
105 return err;
106 }
107
108 err = snd_soc_dai_set_fmt(cpu_dai,
109 SND_SOC_DAIFMT_I2S |
110 SND_SOC_DAIFMT_NB_NF |
111 SND_SOC_DAIFMT_CBS_CFS);
112 if (err < 0) {
113 dev_err(card->dev, "cpu_dai fmt not set\n");
114 return err;
115 }
116
117 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
118 SND_SOC_CLOCK_IN);
119 if (err < 0) {
120 dev_err(card->dev, "codec_dai clock not set\n");
121 return err;
122 }
123
124 return 0;
125}
126
127static struct snd_soc_ops tegra_wm8903_ops = {
128 .hw_params = tegra_wm8903_hw_params,
129};
130
131static struct snd_soc_jack tegra_wm8903_hp_jack;
132
133static struct snd_soc_jack_pin tegra_wm8903_hp_jack_pins[] = {
134 {
135 .pin = "Headphone Jack",
136 .mask = SND_JACK_HEADPHONE,
137 },
138};
139
140static struct snd_soc_jack_gpio tegra_wm8903_hp_jack_gpio = {
141 .name = "headphone detect",
142 .report = SND_JACK_HEADPHONE,
143 .debounce_time = 150,
144 .invert = 1,
145};
146
147static struct snd_soc_jack tegra_wm8903_mic_jack;
148
149static struct snd_soc_jack_pin tegra_wm8903_mic_jack_pins[] = {
150 {
151 .pin = "Mic Jack",
152 .mask = SND_JACK_MICROPHONE,
153 },
154};
155
156static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w,
157 struct snd_kcontrol *k, int event)
158{
159 struct snd_soc_dapm_context *dapm = w->dapm;
160 struct snd_soc_card *card = dapm->card;
161 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
162 struct tegra_wm8903_platform_data *pdata = machine->pdata;
163
164 if (!(machine->gpio_requested & GPIO_SPKR_EN))
165 return 0;
166
167 gpio_set_value_cansleep(pdata->gpio_spkr_en,
168 SND_SOC_DAPM_EVENT_ON(event));
169
170 return 0;
171}
172
173static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w,
174 struct snd_kcontrol *k, int event)
175{
176 struct snd_soc_dapm_context *dapm = w->dapm;
177 struct snd_soc_card *card = dapm->card;
178 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
179 struct tegra_wm8903_platform_data *pdata = machine->pdata;
180
181 if (!(machine->gpio_requested & GPIO_HP_MUTE))
182 return 0;
183
184 gpio_set_value_cansleep(pdata->gpio_hp_mute,
185 !SND_SOC_DAPM_EVENT_ON(event));
186
187 return 0;
188}
189
190static const struct snd_soc_dapm_widget tegra_wm8903_dapm_widgets[] = {
191 SND_SOC_DAPM_SPK("Int Spk", tegra_wm8903_event_int_spk),
192 SND_SOC_DAPM_HP("Headphone Jack", tegra_wm8903_event_hp),
193 SND_SOC_DAPM_MIC("Mic Jack", NULL),
194};
195
196static const struct snd_soc_dapm_route harmony_audio_map[] = {
197 {"Headphone Jack", NULL, "HPOUTR"},
198 {"Headphone Jack", NULL, "HPOUTL"},
199 {"Int Spk", NULL, "ROP"},
200 {"Int Spk", NULL, "RON"},
201 {"Int Spk", NULL, "LOP"},
202 {"Int Spk", NULL, "LON"},
203 {"Mic Bias", NULL, "Mic Jack"},
204 {"IN1L", NULL, "Mic Bias"},
205};
206
207static const struct snd_soc_dapm_route seaboard_audio_map[] = {
208 {"Headphone Jack", NULL, "HPOUTR"},
209 {"Headphone Jack", NULL, "HPOUTL"},
210 {"Int Spk", NULL, "ROP"},
211 {"Int Spk", NULL, "RON"},
212 {"Int Spk", NULL, "LOP"},
213 {"Int Spk", NULL, "LON"},
214 {"Mic Bias", NULL, "Mic Jack"},
215 {"IN1R", NULL, "Mic Bias"},
216};
217
218static const struct snd_soc_dapm_route kaen_audio_map[] = {
219 {"Headphone Jack", NULL, "HPOUTR"},
220 {"Headphone Jack", NULL, "HPOUTL"},
221 {"Int Spk", NULL, "ROP"},
222 {"Int Spk", NULL, "RON"},
223 {"Int Spk", NULL, "LOP"},
224 {"Int Spk", NULL, "LON"},
225 {"Mic Bias", NULL, "Mic Jack"},
226 {"IN2R", NULL, "Mic Bias"},
227};
228
229static const struct snd_soc_dapm_route aebl_audio_map[] = {
230 {"Headphone Jack", NULL, "HPOUTR"},
231 {"Headphone Jack", NULL, "HPOUTL"},
232 {"Int Spk", NULL, "LINEOUTR"},
233 {"Int Spk", NULL, "LINEOUTL"},
234 {"Mic Bias", NULL, "Mic Jack"},
235 {"IN1R", NULL, "Mic Bias"},
236};
237
238static const struct snd_kcontrol_new tegra_wm8903_controls[] = {
239 SOC_DAPM_PIN_SWITCH("Int Spk"),
240};
241
242static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
243{
244 struct snd_soc_codec *codec = rtd->codec;
245 struct snd_soc_dapm_context *dapm = &codec->dapm;
246 struct snd_soc_card *card = codec->card;
247 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
248 struct tegra_wm8903_platform_data *pdata = machine->pdata;
249 int ret;
250
251 if (gpio_is_valid(pdata->gpio_spkr_en)) {
252 ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
253 if (ret) {
254 dev_err(card->dev, "cannot get spkr_en gpio\n");
255 return ret;
256 }
257 machine->gpio_requested |= GPIO_SPKR_EN;
258
259 gpio_direction_output(pdata->gpio_spkr_en, 0);
260 }
261
262 if (gpio_is_valid(pdata->gpio_hp_mute)) {
263 ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
264 if (ret) {
265 dev_err(card->dev, "cannot get hp_mute gpio\n");
266 return ret;
267 }
268 machine->gpio_requested |= GPIO_HP_MUTE;
269
270 gpio_direction_output(pdata->gpio_hp_mute, 0);
271 }
272
273 if (gpio_is_valid(pdata->gpio_int_mic_en)) {
274 ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
275 if (ret) {
276 dev_err(card->dev, "cannot get int_mic_en gpio\n");
277 return ret;
278 }
279 machine->gpio_requested |= GPIO_INT_MIC_EN;
280
281 /* Disable int mic; enable signal is active-high */
282 gpio_direction_output(pdata->gpio_int_mic_en, 0);
283 }
284
285 if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
286 ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
287 if (ret) {
288 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
289 return ret;
290 }
291 machine->gpio_requested |= GPIO_EXT_MIC_EN;
292
293 /* Enable ext mic; enable signal is active-low */
294 gpio_direction_output(pdata->gpio_ext_mic_en, 0);
295 }
296
297 if (gpio_is_valid(pdata->gpio_hp_det)) {
298 tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det;
299 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
300 &tegra_wm8903_hp_jack);
301 snd_soc_jack_add_pins(&tegra_wm8903_hp_jack,
302 ARRAY_SIZE(tegra_wm8903_hp_jack_pins),
303 tegra_wm8903_hp_jack_pins);
304 snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack,
305 1,
306 &tegra_wm8903_hp_jack_gpio);
307 }
308
309 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
310 &tegra_wm8903_mic_jack);
311 snd_soc_jack_add_pins(&tegra_wm8903_mic_jack,
312 ARRAY_SIZE(tegra_wm8903_mic_jack_pins),
313 tegra_wm8903_mic_jack_pins);
314 wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE,
315 0);
316
317 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
318
319 /* FIXME: Calculate automatically based on DAPM routes? */
320 if (!machine_is_harmony() && !machine_is_ventana())
321 snd_soc_dapm_nc_pin(dapm, "IN1L");
322 if (!machine_is_seaboard() && !machine_is_aebl())
323 snd_soc_dapm_nc_pin(dapm, "IN1R");
324 snd_soc_dapm_nc_pin(dapm, "IN2L");
325 if (!machine_is_kaen())
326 snd_soc_dapm_nc_pin(dapm, "IN2R");
327 snd_soc_dapm_nc_pin(dapm, "IN3L");
328 snd_soc_dapm_nc_pin(dapm, "IN3R");
329
330 if (machine_is_aebl()) {
331 snd_soc_dapm_nc_pin(dapm, "LON");
332 snd_soc_dapm_nc_pin(dapm, "RON");
333 snd_soc_dapm_nc_pin(dapm, "ROP");
334 snd_soc_dapm_nc_pin(dapm, "LOP");
335 } else {
336 snd_soc_dapm_nc_pin(dapm, "LINEOUTR");
337 snd_soc_dapm_nc_pin(dapm, "LINEOUTL");
338 }
339
340 snd_soc_dapm_sync(dapm);
341
342 return 0;
343}
344
345static struct snd_soc_dai_link tegra_wm8903_dai = {
346 .name = "WM8903",
347 .stream_name = "WM8903 PCM",
348 .codec_name = "wm8903.0-001a",
349 .platform_name = "tegra-pcm-audio",
350 .cpu_dai_name = "tegra-i2s.0",
351 .codec_dai_name = "wm8903-hifi",
352 .init = tegra_wm8903_init,
353 .ops = &tegra_wm8903_ops,
354};
355
356static struct snd_soc_card snd_soc_tegra_wm8903 = {
357 .name = "tegra-wm8903",
358 .dai_link = &tegra_wm8903_dai,
359 .num_links = 1,
360
361 .controls = tegra_wm8903_controls,
362 .num_controls = ARRAY_SIZE(tegra_wm8903_controls),
363 .dapm_widgets = tegra_wm8903_dapm_widgets,
364 .num_dapm_widgets = ARRAY_SIZE(tegra_wm8903_dapm_widgets),
365};
366
367static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
368{
369 struct snd_soc_card *card = &snd_soc_tegra_wm8903;
370 struct tegra_wm8903 *machine;
371 struct tegra_wm8903_platform_data *pdata;
372 int ret;
373
374 pdata = pdev->dev.platform_data;
375 if (!pdata) {
376 dev_err(&pdev->dev, "No platform data supplied\n");
377 return -EINVAL;
378 }
379
380 machine = kzalloc(sizeof(struct tegra_wm8903), GFP_KERNEL);
381 if (!machine) {
382 dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n");
383 return -ENOMEM;
384 }
385
386 machine->pdata = pdata;
387
388 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
389 if (ret)
390 goto err_free_machine;
391
392 card->dev = &pdev->dev;
393 platform_set_drvdata(pdev, card);
394 snd_soc_card_set_drvdata(card, machine);
395
396 if (machine_is_harmony() || machine_is_ventana()) {
397 card->dapm_routes = harmony_audio_map;
398 card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map);
399 } else if (machine_is_seaboard()) {
400 card->dapm_routes = seaboard_audio_map;
401 card->num_dapm_routes = ARRAY_SIZE(seaboard_audio_map);
402 } else if (machine_is_kaen()) {
403 card->dapm_routes = kaen_audio_map;
404 card->num_dapm_routes = ARRAY_SIZE(kaen_audio_map);
405 } else {
406 card->dapm_routes = aebl_audio_map;
407 card->num_dapm_routes = ARRAY_SIZE(aebl_audio_map);
408 }
409
410 ret = snd_soc_register_card(card);
411 if (ret) {
412 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
413 ret);
414 goto err_fini_utils;
415 }
416
417 return 0;
418
419err_fini_utils:
420 tegra_asoc_utils_fini(&machine->util_data);
421err_free_machine:
422 kfree(machine);
423 return ret;
424}
425
426static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev)
427{
428 struct snd_soc_card *card = platform_get_drvdata(pdev);
429 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
430 struct tegra_wm8903_platform_data *pdata = machine->pdata;
431
432 snd_soc_unregister_card(card);
433
434 tegra_asoc_utils_fini(&machine->util_data);
435
436 if (machine->gpio_requested & GPIO_EXT_MIC_EN)
437 gpio_free(pdata->gpio_ext_mic_en);
438 if (machine->gpio_requested & GPIO_INT_MIC_EN)
439 gpio_free(pdata->gpio_int_mic_en);
440 if (machine->gpio_requested & GPIO_HP_MUTE)
441 gpio_free(pdata->gpio_hp_mute);
442 if (machine->gpio_requested & GPIO_SPKR_EN)
443 gpio_free(pdata->gpio_spkr_en);
444
445 kfree(machine);
446
447 return 0;
448}
449
450static struct platform_driver tegra_wm8903_driver = {
451 .driver = {
452 .name = DRV_NAME,
453 .owner = THIS_MODULE,
454 .pm = &snd_soc_pm_ops,
455 },
456 .probe = tegra_wm8903_driver_probe,
457 .remove = __devexit_p(tegra_wm8903_driver_remove),
458};
459
460static int __init tegra_wm8903_modinit(void)
461{
462 return platform_driver_register(&tegra_wm8903_driver);
463}
464module_init(tegra_wm8903_modinit);
465
466static void __exit tegra_wm8903_modexit(void)
467{
468 platform_driver_unregister(&tegra_wm8903_driver);
469}
470module_exit(tegra_wm8903_modexit);
471
472MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
473MODULE_DESCRIPTION("Tegra+WM8903 machine ASoC driver");
474MODULE_LICENSE("GPL");
475MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
new file mode 100644
index 000000000000..8fc07e9adf2e
--- /dev/null
+++ b/sound/soc/tegra/trimslice.c
@@ -0,0 +1,228 @@
1/*
2 * trimslice.c - TrimSlice machine ASoC driver
3 *
4 * Copyright (C) 2011 - CompuLab, Ltd.
5 * Author: Mike Rapoport <mike@compulab.co.il>
6 *
7 * Based on code copyright/by:
8 * Author: Stephen Warren <swarren@nvidia.com>
9 * Copyright (C) 2010-2011 - NVIDIA, Inc.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 *
25 */
26
27#include <asm/mach-types.h>
28
29#include <linux/module.h>
30#include <linux/platform_device.h>
31#include <linux/slab.h>
32
33#include <sound/core.h>
34#include <sound/jack.h>
35#include <sound/pcm.h>
36#include <sound/pcm_params.h>
37#include <sound/soc.h>
38
39#include "../codecs/tlv320aic23.h"
40
41#include "tegra_das.h"
42#include "tegra_i2s.h"
43#include "tegra_pcm.h"
44#include "tegra_asoc_utils.h"
45
46#define DRV_NAME "tegra-snd-trimslice"
47
48struct tegra_trimslice {
49 struct tegra_asoc_utils_data util_data;
50};
51
52static int trimslice_asoc_hw_params(struct snd_pcm_substream *substream,
53 struct snd_pcm_hw_params *params)
54{
55 struct snd_soc_pcm_runtime *rtd = substream->private_data;
56 struct snd_soc_dai *codec_dai = rtd->codec_dai;
57 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
58 struct snd_soc_codec *codec = rtd->codec;
59 struct snd_soc_card *card = codec->card;
60 struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card);
61 int srate, mclk;
62 int err;
63
64 srate = params_rate(params);
65 mclk = 128 * srate;
66
67 err = tegra_asoc_utils_set_rate(&trimslice->util_data, srate, mclk);
68 if (err < 0) {
69 dev_err(card->dev, "Can't configure clocks\n");
70 return err;
71 }
72
73 err = snd_soc_dai_set_fmt(codec_dai,
74 SND_SOC_DAIFMT_I2S |
75 SND_SOC_DAIFMT_NB_NF |
76 SND_SOC_DAIFMT_CBS_CFS);
77 if (err < 0) {
78 dev_err(card->dev, "codec_dai fmt not set\n");
79 return err;
80 }
81
82 err = snd_soc_dai_set_fmt(cpu_dai,
83 SND_SOC_DAIFMT_I2S |
84 SND_SOC_DAIFMT_NB_NF |
85 SND_SOC_DAIFMT_CBS_CFS);
86 if (err < 0) {
87 dev_err(card->dev, "cpu_dai fmt not set\n");
88 return err;
89 }
90
91 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
92 SND_SOC_CLOCK_IN);
93 if (err < 0) {
94 dev_err(card->dev, "codec_dai clock not set\n");
95 return err;
96 }
97
98 return 0;
99}
100
101static struct snd_soc_ops trimslice_asoc_ops = {
102 .hw_params = trimslice_asoc_hw_params,
103};
104
105static const struct snd_soc_dapm_widget trimslice_dapm_widgets[] = {
106 SND_SOC_DAPM_HP("Line Out", NULL),
107 SND_SOC_DAPM_LINE("Line In", NULL),
108};
109
110static const struct snd_soc_dapm_route trimslice_audio_map[] = {
111 {"Line Out", NULL, "LOUT"},
112 {"Line Out", NULL, "ROUT"},
113
114 {"LLINEIN", NULL, "Line In"},
115 {"RLINEIN", NULL, "Line In"},
116};
117
118static int trimslice_asoc_init(struct snd_soc_pcm_runtime *rtd)
119{
120 struct snd_soc_codec *codec = rtd->codec;
121 struct snd_soc_dapm_context *dapm = &codec->dapm;
122
123 snd_soc_dapm_nc_pin(dapm, "LHPOUT");
124 snd_soc_dapm_nc_pin(dapm, "RHPOUT");
125 snd_soc_dapm_nc_pin(dapm, "MICIN");
126
127 snd_soc_dapm_sync(dapm);
128
129 return 0;
130}
131
132static struct snd_soc_dai_link trimslice_tlv320aic23_dai = {
133 .name = "TLV320AIC23",
134 .stream_name = "AIC23",
135 .codec_name = "tlv320aic23-codec.2-001a",
136 .platform_name = "tegra-pcm-audio",
137 .cpu_dai_name = "tegra-i2s.0",
138 .codec_dai_name = "tlv320aic23-hifi",
139 .init = trimslice_asoc_init,
140 .ops = &trimslice_asoc_ops,
141};
142
143static struct snd_soc_card snd_soc_trimslice = {
144 .name = "tegra-trimslice",
145 .dai_link = &trimslice_tlv320aic23_dai,
146 .num_links = 1,
147
148 .dapm_widgets = trimslice_dapm_widgets,
149 .num_dapm_widgets = ARRAY_SIZE(trimslice_dapm_widgets),
150 .dapm_routes = trimslice_audio_map,
151 .num_dapm_routes = ARRAY_SIZE(trimslice_audio_map),
152};
153
154static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
155{
156 struct snd_soc_card *card = &snd_soc_trimslice;
157 struct tegra_trimslice *trimslice;
158 int ret;
159
160 trimslice = kzalloc(sizeof(struct tegra_trimslice), GFP_KERNEL);
161 if (!trimslice) {
162 dev_err(&pdev->dev, "Can't allocate tegra_trimslice\n");
163 return -ENOMEM;
164 }
165
166 ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev);
167 if (ret)
168 goto err_free_trimslice;
169
170 card->dev = &pdev->dev;
171 platform_set_drvdata(pdev, card);
172 snd_soc_card_set_drvdata(card, trimslice);
173
174 ret = snd_soc_register_card(card);
175 if (ret) {
176 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
177 ret);
178 goto err_fini_utils;
179 }
180
181 return 0;
182
183err_fini_utils:
184 tegra_asoc_utils_fini(&trimslice->util_data);
185err_free_trimslice:
186 kfree(trimslice);
187 return ret;
188}
189
190static int __devexit tegra_snd_trimslice_remove(struct platform_device *pdev)
191{
192 struct snd_soc_card *card = platform_get_drvdata(pdev);
193 struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card);
194
195 snd_soc_unregister_card(card);
196
197 tegra_asoc_utils_fini(&trimslice->util_data);
198
199 kfree(trimslice);
200
201 return 0;
202}
203
204static struct platform_driver tegra_snd_trimslice_driver = {
205 .driver = {
206 .name = DRV_NAME,
207 .owner = THIS_MODULE,
208 },
209 .probe = tegra_snd_trimslice_probe,
210 .remove = __devexit_p(tegra_snd_trimslice_remove),
211};
212
213static int __init snd_tegra_trimslice_init(void)
214{
215 return platform_driver_register(&tegra_snd_trimslice_driver);
216}
217module_init(snd_tegra_trimslice_init);
218
219static void __exit snd_tegra_trimslice_exit(void)
220{
221 platform_driver_unregister(&tegra_snd_trimslice_driver);
222}
223module_exit(snd_tegra_trimslice_exit);
224
225MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
226MODULE_DESCRIPTION("Trimslice machine ASoC driver");
227MODULE_LICENSE("GPL");
228MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c
index 248463511186..ac828eff1a63 100644
--- a/sound/usb/6fire/control.c
+++ b/sound/usb/6fire/control.c
@@ -65,6 +65,15 @@ init_data[] = {
65 { 0 } /* TERMINATING ENTRY */ 65 { 0 } /* TERMINATING ENTRY */
66}; 66};
67 67
68static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 };
69/* values to write to soundcard register for all samplerates */
70static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01};
71static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00};
72
73enum {
74 DIGITAL_THRU_ONLY_SAMPLERATE = 3
75};
76
68static void usb6fire_control_master_vol_update(struct control_runtime *rt) 77static void usb6fire_control_master_vol_update(struct control_runtime *rt)
69{ 78{
70 struct comm_runtime *comm_rt = rt->chip->comm; 79 struct comm_runtime *comm_rt = rt->chip->comm;
@@ -95,6 +104,67 @@ static void usb6fire_control_opt_coax_update(struct control_runtime *rt)
95 } 104 }
96} 105}
97 106
107static int usb6fire_control_set_rate(struct control_runtime *rt, int rate)
108{
109 int ret;
110 struct usb_device *device = rt->chip->dev;
111 struct comm_runtime *comm_rt = rt->chip->comm;
112
113 if (rate < 0 || rate >= CONTROL_N_RATES)
114 return -EINVAL;
115
116 ret = usb_set_interface(device, 1, rates_altsetting[rate]);
117 if (ret < 0)
118 return ret;
119
120 /* set soundcard clock */
121 ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rate],
122 rates_6fire_vh[rate]);
123 if (ret < 0)
124 return ret;
125
126 return 0;
127}
128
129static int usb6fire_control_set_channels(
130 struct control_runtime *rt, int n_analog_out,
131 int n_analog_in, bool spdif_out, bool spdif_in)
132{
133 int ret;
134 struct comm_runtime *comm_rt = rt->chip->comm;
135
136 /* enable analog inputs and outputs
137 * (one bit per stereo-channel) */
138 ret = comm_rt->write16(comm_rt, 0x02, 0x02,
139 (1 << (n_analog_out / 2)) - 1,
140 (1 << (n_analog_in / 2)) - 1);
141 if (ret < 0)
142 return ret;
143
144 /* disable digital inputs and outputs */
145 /* TODO: use spdif_x to enable/disable digital channels */
146 ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00);
147 if (ret < 0)
148 return ret;
149
150 return 0;
151}
152
153static int usb6fire_control_streaming_update(struct control_runtime *rt)
154{
155 struct comm_runtime *comm_rt = rt->chip->comm;
156
157 if (comm_rt) {
158 if (!rt->usb_streaming && rt->digital_thru_switch)
159 usb6fire_control_set_rate(rt,
160 DIGITAL_THRU_ONLY_SAMPLERATE);
161 return comm_rt->write16(comm_rt, 0x02, 0x00, 0x00,
162 (rt->usb_streaming ? 0x01 : 0x00) |
163 (rt->digital_thru_switch ? 0x08 : 0x00));
164 }
165 return -EINVAL;
166}
167
98static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol, 168static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol,
99 struct snd_ctl_elem_info *uinfo) 169 struct snd_ctl_elem_info *uinfo)
100{ 170{
@@ -195,6 +265,28 @@ static int usb6fire_control_opt_coax_get(struct snd_kcontrol *kcontrol,
195 return 0; 265 return 0;
196} 266}
197 267
268static int usb6fire_control_digital_thru_put(struct snd_kcontrol *kcontrol,
269 struct snd_ctl_elem_value *ucontrol)
270{
271 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
272 int changed = 0;
273
274 if (rt->digital_thru_switch != ucontrol->value.integer.value[0]) {
275 rt->digital_thru_switch = ucontrol->value.integer.value[0];
276 usb6fire_control_streaming_update(rt);
277 changed = 1;
278 }
279 return changed;
280}
281
282static int usb6fire_control_digital_thru_get(struct snd_kcontrol *kcontrol,
283 struct snd_ctl_elem_value *ucontrol)
284{
285 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
286 ucontrol->value.integer.value[0] = rt->digital_thru_switch;
287 return 0;
288}
289
198static struct __devinitdata snd_kcontrol_new elements[] = { 290static struct __devinitdata snd_kcontrol_new elements[] = {
199 { 291 {
200 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 292 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -223,6 +315,15 @@ static struct __devinitdata snd_kcontrol_new elements[] = {
223 .get = usb6fire_control_opt_coax_get, 315 .get = usb6fire_control_opt_coax_get,
224 .put = usb6fire_control_opt_coax_put 316 .put = usb6fire_control_opt_coax_put
225 }, 317 },
318 {
319 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
320 .name = "Digital Thru Playback Route",
321 .index = 0,
322 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
323 .info = snd_ctl_boolean_mono_info,
324 .get = usb6fire_control_digital_thru_get,
325 .put = usb6fire_control_digital_thru_put
326 },
226 {} 327 {}
227}; 328};
228 329
@@ -238,6 +339,9 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip)
238 return -ENOMEM; 339 return -ENOMEM;
239 340
240 rt->chip = chip; 341 rt->chip = chip;
342 rt->update_streaming = usb6fire_control_streaming_update;
343 rt->set_rate = usb6fire_control_set_rate;
344 rt->set_channels = usb6fire_control_set_channels;
241 345
242 i = 0; 346 i = 0;
243 while (init_data[i].type) { 347 while (init_data[i].type) {
@@ -249,6 +353,7 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip)
249 usb6fire_control_opt_coax_update(rt); 353 usb6fire_control_opt_coax_update(rt);
250 usb6fire_control_line_phono_update(rt); 354 usb6fire_control_line_phono_update(rt);
251 usb6fire_control_master_vol_update(rt); 355 usb6fire_control_master_vol_update(rt);
356 usb6fire_control_streaming_update(rt);
252 357
253 i = 0; 358 i = 0;
254 while (elements[i].name) { 359 while (elements[i].name) {
diff --git a/sound/usb/6fire/control.h b/sound/usb/6fire/control.h
index b534c777ab02..8f5aeead2e3d 100644
--- a/sound/usb/6fire/control.h
+++ b/sound/usb/6fire/control.h
@@ -21,12 +21,29 @@ enum {
21 CONTROL_MAX_ELEMENTS = 32 21 CONTROL_MAX_ELEMENTS = 32
22}; 22};
23 23
24enum {
25 CONTROL_RATE_44KHZ,
26 CONTROL_RATE_48KHZ,
27 CONTROL_RATE_88KHZ,
28 CONTROL_RATE_96KHZ,
29 CONTROL_RATE_176KHZ,
30 CONTROL_RATE_192KHZ,
31 CONTROL_N_RATES
32};
33
24struct control_runtime { 34struct control_runtime {
35 int (*update_streaming)(struct control_runtime *rt);
36 int (*set_rate)(struct control_runtime *rt, int rate);
37 int (*set_channels)(struct control_runtime *rt, int n_analog_out,
38 int n_analog_in, bool spdif_out, bool spdif_in);
39
25 struct sfire_chip *chip; 40 struct sfire_chip *chip;
26 41
27 struct snd_kcontrol *element[CONTROL_MAX_ELEMENTS]; 42 struct snd_kcontrol *element[CONTROL_MAX_ELEMENTS];
28 bool opt_coax_switch; 43 bool opt_coax_switch;
29 bool line_phono_switch; 44 bool line_phono_switch;
45 bool digital_thru_switch;
46 bool usb_streaming;
30 u8 master_vol; 47 u8 master_vol;
31}; 48};
32 49
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c
index 86c1a3103760..d47beffedb0f 100644
--- a/sound/usb/6fire/firmware.c
+++ b/sound/usb/6fire/firmware.c
@@ -3,12 +3,6 @@
3 * 3 *
4 * Firmware loader 4 * Firmware loader
5 * 5 *
6 * Currently not working for all devices. To be able to use the device
7 * in linux, it is also possible to let the windows driver upload the firmware.
8 * For that, start the computer in windows and reboot.
9 * As long as the device is connected to the power supply, no firmware reload
10 * needs to be performed.
11 *
12 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
13 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
14 * Version: 0.3.0 8 * Version: 0.3.0
@@ -21,6 +15,7 @@
21 */ 15 */
22 16
23#include <linux/firmware.h> 17#include <linux/firmware.h>
18#include <linux/bitrev.h>
24 19
25#include "firmware.h" 20#include "firmware.h"
26#include "chip.h" 21#include "chip.h"
@@ -33,32 +28,6 @@ enum {
33 FPGA_BUFSIZE = 512, FPGA_EP = 2 28 FPGA_BUFSIZE = 512, FPGA_EP = 2
34}; 29};
35 30
36static const u8 BIT_REVERSE_TABLE[256] = {
37 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50,
38 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8,
39 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04,
40 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4,
41 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c,
42 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82,
43 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32,
44 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
45 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46,
46 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6,
47 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e,
48 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1,
49 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71,
50 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99,
51 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25,
52 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
53 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d,
54 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3,
55 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b,
56 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb,
57 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67,
58 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f,
59 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f,
60 0xbf, 0x7f, 0xff };
61
62/* 31/*
63 * wMaxPacketSize of pcm endpoints. 32 * wMaxPacketSize of pcm endpoints.
64 * keep synced with rates_in_packet_size and rates_out_packet_size in pcm.c 33 * keep synced with rates_in_packet_size and rates_out_packet_size in pcm.c
@@ -72,6 +41,10 @@ static const u8 ep_w_max_packet_size[] = {
72 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */ 41 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */
73}; 42};
74 43
44static const u8 known_fw_versions[][4] = {
45 { 0x03, 0x01, 0x0b, 0x00 }
46};
47
75struct ihex_record { 48struct ihex_record {
76 u16 address; 49 u16 address;
77 u8 len; 50 u8 len;
@@ -340,7 +313,7 @@ static int usb6fire_fw_fpga_upload(
340 313
341 while (c != end) { 314 while (c != end) {
342 for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++) 315 for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++)
343 buffer[i] = BIT_REVERSE_TABLE[(u8) *c]; 316 buffer[i] = byte_rev_table[(u8) *c];
344 317
345 ret = usb6fire_fw_fpga_write(device, buffer, i); 318 ret = usb6fire_fw_fpga_write(device, buffer, i);
346 if (ret < 0) { 319 if (ret < 0) {
@@ -363,6 +336,25 @@ static int usb6fire_fw_fpga_upload(
363 return 0; 336 return 0;
364} 337}
365 338
339/* check, if the firmware version the devices has currently loaded
340 * is known by this driver. 'version' needs to have 4 bytes version
341 * info data. */
342static int usb6fire_fw_check(u8 *version)
343{
344 int i;
345
346 for (i = 0; i < ARRAY_SIZE(known_fw_versions); i++)
347 if (!memcmp(version, known_fw_versions + i, 4))
348 return 0;
349
350 snd_printk(KERN_ERR PREFIX "invalid fimware version in device: "
351 "%02x %02x %02x %02x. "
352 "please reconnect to power. if this failure "
353 "still happens, check your firmware installation.",
354 version[0], version[1], version[2], version[3]);
355 return -EINVAL;
356}
357
366int usb6fire_fw_init(struct usb_interface *intf) 358int usb6fire_fw_init(struct usb_interface *intf)
367{ 359{
368 int i; 360 int i;
@@ -378,9 +370,7 @@ int usb6fire_fw_init(struct usb_interface *intf)
378 "firmware state.\n"); 370 "firmware state.\n");
379 return ret; 371 return ret;
380 } 372 }
381 if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55 373 if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55) {
382 || buffer[4] != 0x03 || buffer[5] != 0x01 || buffer[7]
383 != 0x00) {
384 snd_printk(KERN_ERR PREFIX "unknown device firmware state " 374 snd_printk(KERN_ERR PREFIX "unknown device firmware state "
385 "received from device: "); 375 "received from device: ");
386 for (i = 0; i < 8; i++) 376 for (i = 0; i < 8; i++)
@@ -389,7 +379,7 @@ int usb6fire_fw_init(struct usb_interface *intf)
389 return -EIO; 379 return -EIO;
390 } 380 }
391 /* do we need fpga loader ezusb firmware? */ 381 /* do we need fpga loader ezusb firmware? */
392 if (buffer[3] == 0x01 && buffer[6] == 0x19) { 382 if (buffer[3] == 0x01) {
393 ret = usb6fire_fw_ezusb_upload(intf, 383 ret = usb6fire_fw_ezusb_upload(intf,
394 "6fire/dmx6firel2.ihx", 0, NULL, 0); 384 "6fire/dmx6firel2.ihx", 0, NULL, 0);
395 if (ret < 0) 385 if (ret < 0)
@@ -397,7 +387,10 @@ int usb6fire_fw_init(struct usb_interface *intf)
397 return FW_NOT_READY; 387 return FW_NOT_READY;
398 } 388 }
399 /* do we need fpga firmware and application ezusb firmware? */ 389 /* do we need fpga firmware and application ezusb firmware? */
400 else if (buffer[3] == 0x02 && buffer[6] == 0x0b) { 390 else if (buffer[3] == 0x02) {
391 ret = usb6fire_fw_check(buffer + 4);
392 if (ret < 0)
393 return ret;
401 ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin"); 394 ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin");
402 if (ret < 0) 395 if (ret < 0)
403 return ret; 396 return ret;
@@ -410,8 +403,8 @@ int usb6fire_fw_init(struct usb_interface *intf)
410 return FW_NOT_READY; 403 return FW_NOT_READY;
411 } 404 }
412 /* all fw loaded? */ 405 /* all fw loaded? */
413 else if (buffer[3] == 0x03 && buffer[6] == 0x0b) 406 else if (buffer[3] == 0x03)
414 return 0; 407 return usb6fire_fw_check(buffer + 4);
415 /* unknown data? */ 408 /* unknown data? */
416 else { 409 else {
417 snd_printk(KERN_ERR PREFIX "unknown device firmware state " 410 snd_printk(KERN_ERR PREFIX "unknown device firmware state "
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index ba62c7468ba8..b137b25865cc 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -17,26 +17,23 @@
17#include "pcm.h" 17#include "pcm.h"
18#include "chip.h" 18#include "chip.h"
19#include "comm.h" 19#include "comm.h"
20#include "control.h"
20 21
21enum { 22enum {
22 OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4 23 OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4
23}; 24};
24 25
25/* keep next two synced with 26/* keep next two synced with
26 * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE */ 27 * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE
28 * and CONTROL_RATE_XXX in control.h */
27static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 }; 29static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 };
28static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 }; 30static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 };
29static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 }; 31static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 };
30static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 };
31static const int rates_alsaid[] = { 32static const int rates_alsaid[] = {
32 SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000, 33 SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000,
33 SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000, 34 SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000,
34 SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 }; 35 SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 };
35 36
36/* values to write to soundcard register for all samplerates */
37static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01};
38static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00};
39
40enum { /* settings for pcm */ 37enum { /* settings for pcm */
41 OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024 38 OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024
42}; 39};
@@ -48,15 +45,6 @@ enum { /* pcm streaming states */
48 STREAM_STOPPING 45 STREAM_STOPPING
49}; 46};
50 47
51enum { /* pcm sample rates (also index into RATES_XXX[]) */
52 RATE_44KHZ,
53 RATE_48KHZ,
54 RATE_88KHZ,
55 RATE_96KHZ,
56 RATE_176KHZ,
57 RATE_192KHZ
58};
59
60static const struct snd_pcm_hardware pcm_hw = { 48static const struct snd_pcm_hardware pcm_hw = {
61 .info = SNDRV_PCM_INFO_MMAP | 49 .info = SNDRV_PCM_INFO_MMAP |
62 SNDRV_PCM_INFO_INTERLEAVED | 50 SNDRV_PCM_INFO_INTERLEAVED |
@@ -64,7 +52,7 @@ static const struct snd_pcm_hardware pcm_hw = {
64 SNDRV_PCM_INFO_MMAP_VALID | 52 SNDRV_PCM_INFO_MMAP_VALID |
65 SNDRV_PCM_INFO_BATCH, 53 SNDRV_PCM_INFO_BATCH,
66 54
67 .formats = SNDRV_PCM_FMTBIT_S24_LE, 55 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
68 56
69 .rates = SNDRV_PCM_RATE_44100 | 57 .rates = SNDRV_PCM_RATE_44100 |
70 SNDRV_PCM_RATE_48000 | 58 SNDRV_PCM_RATE_48000 |
@@ -87,57 +75,34 @@ static const struct snd_pcm_hardware pcm_hw = {
87static int usb6fire_pcm_set_rate(struct pcm_runtime *rt) 75static int usb6fire_pcm_set_rate(struct pcm_runtime *rt)
88{ 76{
89 int ret; 77 int ret;
90 struct usb_device *device = rt->chip->dev; 78 struct control_runtime *ctrl_rt = rt->chip->control;
91 struct comm_runtime *comm_rt = rt->chip->comm;
92 79
93 if (rt->rate >= ARRAY_SIZE(rates)) 80 ctrl_rt->usb_streaming = false;
94 return -EINVAL; 81 ret = ctrl_rt->update_streaming(ctrl_rt);
95 /* disable streaming */
96 ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x00);
97 if (ret < 0) { 82 if (ret < 0) {
98 snd_printk(KERN_ERR PREFIX "error stopping streaming while " 83 snd_printk(KERN_ERR PREFIX "error stopping streaming while "
99 "setting samplerate %d.\n", rates[rt->rate]); 84 "setting samplerate %d.\n", rates[rt->rate]);
100 return ret; 85 return ret;
101 } 86 }
102 87
103 ret = usb_set_interface(device, 1, rates_altsetting[rt->rate]); 88 ret = ctrl_rt->set_rate(ctrl_rt, rt->rate);
104 if (ret < 0) {
105 snd_printk(KERN_ERR PREFIX "error setting interface "
106 "altsetting %d for samplerate %d.\n",
107 rates_altsetting[rt->rate], rates[rt->rate]);
108 return ret;
109 }
110
111 /* set soundcard clock */
112 ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rt->rate],
113 rates_6fire_vh[rt->rate]);
114 if (ret < 0) { 89 if (ret < 0) {
115 snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n", 90 snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n",
116 rates[rt->rate]); 91 rates[rt->rate]);
117 return ret; 92 return ret;
118 } 93 }
119 94
120 /* enable analog inputs and outputs 95 ret = ctrl_rt->set_channels(ctrl_rt, OUT_N_CHANNELS, IN_N_CHANNELS,
121 * (one bit per stereo-channel) */ 96 false, false);
122 ret = comm_rt->write16(comm_rt, 0x02, 0x02,
123 (1 << (OUT_N_CHANNELS / 2)) - 1,
124 (1 << (IN_N_CHANNELS / 2)) - 1);
125 if (ret < 0) { 97 if (ret < 0) {
126 snd_printk(KERN_ERR PREFIX "error initializing analog channels " 98 snd_printk(KERN_ERR PREFIX "error initializing channels "
127 "while setting samplerate %d.\n", 99 "while setting samplerate %d.\n",
128 rates[rt->rate]); 100 rates[rt->rate]);
129 return ret; 101 return ret;
130 } 102 }
131 /* disable digital inputs and outputs */
132 ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00);
133 if (ret < 0) {
134 snd_printk(KERN_ERR PREFIX "error initializing digital "
135 "channels while setting samplerate %d.\n",
136 rates[rt->rate]);
137 return ret;
138 }
139 103
140 ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x01); 104 ctrl_rt->usb_streaming = true;
105 ret = ctrl_rt->update_streaming(ctrl_rt);
141 if (ret < 0) { 106 if (ret < 0) {
142 snd_printk(KERN_ERR PREFIX "error starting streaming while " 107 snd_printk(KERN_ERR PREFIX "error starting streaming while "
143 "setting samplerate %d.\n", rates[rt->rate]); 108 "setting samplerate %d.\n", rates[rt->rate]);
@@ -168,12 +133,15 @@ static struct pcm_substream *usb6fire_pcm_get_substream(
168static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt) 133static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt)
169{ 134{
170 int i; 135 int i;
136 struct control_runtime *ctrl_rt = rt->chip->control;
171 137
172 if (rt->stream_state != STREAM_DISABLED) { 138 if (rt->stream_state != STREAM_DISABLED) {
173 for (i = 0; i < PCM_N_URBS; i++) { 139 for (i = 0; i < PCM_N_URBS; i++) {
174 usb_kill_urb(&rt->in_urbs[i].instance); 140 usb_kill_urb(&rt->in_urbs[i].instance);
175 usb_kill_urb(&rt->out_urbs[i].instance); 141 usb_kill_urb(&rt->out_urbs[i].instance);
176 } 142 }
143 ctrl_rt->usb_streaming = false;
144 ctrl_rt->update_streaming(ctrl_rt);
177 rt->stream_state = STREAM_DISABLED; 145 rt->stream_state = STREAM_DISABLED;
178 } 146 }
179} 147}
@@ -228,7 +196,7 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
228 unsigned int total_length = 0; 196 unsigned int total_length = 0;
229 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance); 197 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
230 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime; 198 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
231 u32 *src = (u32 *) urb->buffer; 199 u32 *src = NULL;
232 u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off 200 u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off
233 * (alsa_rt->frame_bits >> 3)); 201 * (alsa_rt->frame_bits >> 3));
234 u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size 202 u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
@@ -244,7 +212,12 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
244 else 212 else
245 frame_count = 0; 213 frame_count = 0;
246 214
247 src = (u32 *) (urb->buffer + total_length); 215 if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE)
216 src = (u32 *) (urb->buffer + total_length);
217 else if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE)
218 src = (u32 *) (urb->buffer - 1 + total_length);
219 else
220 return;
248 src++; /* skip leading 4 bytes of every packet */ 221 src++; /* skip leading 4 bytes of every packet */
249 total_length += urb->packets[i].length; 222 total_length += urb->packets[i].length;
250 for (frame = 0; frame < frame_count; frame++) { 223 for (frame = 0; frame < frame_count; frame++) {
@@ -274,9 +247,18 @@ static void usb6fire_pcm_playback(struct pcm_substream *sub,
274 * (alsa_rt->frame_bits >> 3)); 247 * (alsa_rt->frame_bits >> 3));
275 u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size 248 u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
276 * (alsa_rt->frame_bits >> 3)); 249 * (alsa_rt->frame_bits >> 3));
277 u32 *dest = (u32 *) urb->buffer; 250 u32 *dest;
278 int bytes_per_frame = alsa_rt->channels << 2; 251 int bytes_per_frame = alsa_rt->channels << 2;
279 252
253 if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE)
254 dest = (u32 *) (urb->buffer - 1);
255 else if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE)
256 dest = (u32 *) (urb->buffer);
257 else {
258 snd_printk(KERN_ERR PREFIX "Unknown sample format.");
259 return;
260 }
261
280 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) { 262 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
281 /* at least 4 header bytes for valid packet. 263 /* at least 4 header bytes for valid packet.
282 * after that: 32 bits per sample for analog channels */ 264 * after that: 32 bits per sample for analog channels */
@@ -456,7 +438,7 @@ static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
456 /* all substreams closed? if so, stop streaming */ 438 /* all substreams closed? if so, stop streaming */
457 if (!rt->playback.instance && !rt->capture.instance) { 439 if (!rt->playback.instance && !rt->capture.instance) {
458 usb6fire_pcm_stream_stop(rt); 440 usb6fire_pcm_stream_stop(rt);
459 rt->rate = -1; 441 rt->rate = ARRAY_SIZE(rates);
460 } 442 }
461 } 443 }
462 mutex_unlock(&rt->stream_mutex); 444 mutex_unlock(&rt->stream_mutex);
@@ -480,7 +462,6 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
480 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub); 462 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
481 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub); 463 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
482 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime; 464 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
483 int i;
484 int ret; 465 int ret;
485 466
486 if (rt->panic) 467 if (rt->panic)
@@ -493,12 +474,10 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
493 sub->period_off = 0; 474 sub->period_off = 0;
494 475
495 if (rt->stream_state == STREAM_DISABLED) { 476 if (rt->stream_state == STREAM_DISABLED) {
496 for (i = 0; i < ARRAY_SIZE(rates); i++) 477 for (rt->rate = 0; rt->rate < ARRAY_SIZE(rates); rt->rate++)
497 if (alsa_rt->rate == rates[i]) { 478 if (alsa_rt->rate == rates[rt->rate])
498 rt->rate = i;
499 break; 479 break;
500 } 480 if (rt->rate == ARRAY_SIZE(rates)) {
501 if (i == ARRAY_SIZE(rates)) {
502 mutex_unlock(&rt->stream_mutex); 481 mutex_unlock(&rt->stream_mutex);
503 snd_printk("invalid rate %d in prepare.\n", 482 snd_printk("invalid rate %d in prepare.\n",
504 alsa_rt->rate); 483 alsa_rt->rate);
@@ -613,7 +592,7 @@ int __devinit usb6fire_pcm_init(struct sfire_chip *chip)
613 592
614 rt->chip = chip; 593 rt->chip = chip;
615 rt->stream_state = STREAM_DISABLED; 594 rt->stream_state = STREAM_DISABLED;
616 rt->rate = -1; 595 rt->rate = ARRAY_SIZE(rates);
617 init_waitqueue_head(&rt->stream_wait_queue); 596 init_waitqueue_head(&rt->stream_wait_queue);
618 mutex_init(&rt->stream_mutex); 597 mutex_init(&rt->stream_mutex);
619 598
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 97724d8fa9f6..8beb77563da2 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -100,19 +100,17 @@ config SND_USB_US122L
100 100
101config SND_USB_6FIRE 101config SND_USB_6FIRE
102 tristate "TerraTec DMX 6Fire USB" 102 tristate "TerraTec DMX 6Fire USB"
103 depends on EXPERIMENTAL
104 select FW_LOADER 103 select FW_LOADER
104 select BITREVERSE
105 select SND_RAWMIDI 105 select SND_RAWMIDI
106 select SND_PCM 106 select SND_PCM
107 help 107 help
108 Say Y here to include support for TerraTec 6fire DMX USB interface. 108 Say Y here to include support for TerraTec 6fire DMX USB interface.
109 109
110 You will need firmware files in order to be able to use the device 110 You will need firmware files in order to be able to use the device
111 after it has been coldstarted. This driver currently does not support 111 after it has been coldstarted. An install script for the firmware
112 firmware loading for all devices. If you own such a device, 112 and further help can be found at
113 you could start windows and let the windows driver upload 113 http://sixfireusb.sourceforge.net
114 the firmware. As long as you do not unplug your device from power,
115 it should be usable.
116 114
117endif # SND_USB 115endif # SND_USB
118 116
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 7754a1034545..075195e8661a 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -104,6 +104,15 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
104 int err; 104 int err;
105 unsigned char data; 105 unsigned char data;
106 struct usb_device *dev = chip->dev; 106 struct usb_device *dev = chip->dev;
107 struct uac_clock_source_descriptor *cs_desc =
108 snd_usb_find_clock_source(chip->ctrl_intf, source_id);
109
110 if (!cs_desc)
111 return 0;
112
113 /* If a clock source can't tell us whether it's valid, we assume it is */
114 if (!uac2_control_is_readable(cs_desc->bmControls, UAC2_CS_CONTROL_CLOCK_VALID))
115 return 1;
107 116
108 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, 117 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
109 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 118 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
@@ -114,7 +123,7 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
114 if (err < 0) { 123 if (err < 0) {
115 snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n", 124 snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n",
116 __func__, source_id); 125 __func__, source_id);
117 return err; 126 return 0;
118 } 127 }
119 128
120 return !!data; 129 return !!data;
diff --git a/sound/usb/debug.h b/sound/usb/debug.h
index 343ec2d9ee66..58030176f008 100644
--- a/sound/usb/debug.h
+++ b/sound/usb/debug.h
@@ -8,7 +8,7 @@
8#ifdef HW_CONST_DEBUG 8#ifdef HW_CONST_DEBUG
9#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args) 9#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args)
10#else 10#else
11#define hwc_debug(fmt, args...) /**/ 11#define hwc_debug(fmt, args...) do { } while(0)
12#endif 12#endif
13 13
14#endif /* __USBAUDIO_DEBUG_H */ 14#endif /* __USBAUDIO_DEBUG_H */
diff --git a/sound/usb/format.c b/sound/usb/format.c
index f079b5e2ab28..8d042dce0d16 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -30,6 +30,7 @@
30#include "helper.h" 30#include "helper.h"
31#include "debug.h" 31#include "debug.h"
32#include "clock.h" 32#include "clock.h"
33#include "format.h"
33 34
34/* 35/*
35 * parse the audio format type I descriptor 36 * parse the audio format type I descriptor
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 6ec33b62e6cf..eab06edcc9b7 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1097,11 +1097,13 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1097 append_ctl_name(kctl, control == UAC_FU_MUTE ? 1097 append_ctl_name(kctl, control == UAC_FU_MUTE ?
1098 " Switch" : " Volume"); 1098 " Switch" : " Volume");
1099 if (control == UAC_FU_VOLUME) { 1099 if (control == UAC_FU_VOLUME) {
1100 kctl->tlv.c = mixer_vol_tlv;
1101 kctl->vd[0].access |=
1102 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
1103 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1104 check_mapped_dB(map, cval); 1100 check_mapped_dB(map, cval);
1101 if (cval->dBmin < cval->dBmax) {
1102 kctl->tlv.c = mixer_vol_tlv;
1103 kctl->vd[0].access |=
1104 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
1105 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1106 }
1105 } 1107 }
1106 break; 1108 break;
1107 1109
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 73dcc8256bc0..9146cffa6ede 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -61,6 +61,7 @@ static const struct rc_config {
61 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */ 61 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
62 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */ 62 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
63 { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */ 63 { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */
64 { USB_ID(0x041e, 0x30df), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */
64 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ 65 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
65}; 66};
66 67
@@ -188,6 +189,12 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
188 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, 189 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
189 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 190 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
190 !value, 0, NULL, 0, 100); 191 !value, 0, NULL, 0, 100);
192 /* USB X-Fi S51 Pro */
193 if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df))
194 err = snd_usb_ctl_msg(mixer->chip->dev,
195 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
196 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
197 !value, 0, NULL, 0, 100);
191 else 198 else
192 err = snd_usb_ctl_msg(mixer->chip->dev, 199 err = snd_usb_ctl_msg(mixer->chip->dev,
193 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, 200 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
@@ -234,9 +241,13 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
234 /* USB X-Fi S51 doesn't have a CMSS LED */ 241 /* USB X-Fi S51 doesn't have a CMSS LED */
235 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0) 242 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0)
236 continue; 243 continue;
244 /* USB X-Fi S51 Pro doesn't have one either */
245 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) && i == 0)
246 continue;
237 if (i > 1 && /* Live24ext has 2 LEDs only */ 247 if (i > 1 && /* Live24ext has 2 LEDs only */
238 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || 248 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
239 mixer->chip->usb_id == USB_ID(0x041e, 0x3042) || 249 mixer->chip->usb_id == USB_ID(0x041e, 0x3042) ||
250 mixer->chip->usb_id == USB_ID(0x041e, 0x30df) ||
240 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))) 251 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
241 break; 252 break;
242 err = snd_ctl_add(mixer->chip->card, 253 err = snd_ctl_add(mixer->chip->card,
@@ -512,6 +523,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
512 case USB_ID(0x041e, 0x3020): 523 case USB_ID(0x041e, 0x3020):
513 case USB_ID(0x041e, 0x3040): 524 case USB_ID(0x041e, 0x3040):
514 case USB_ID(0x041e, 0x3042): 525 case USB_ID(0x041e, 0x3042):
526 case USB_ID(0x041e, 0x30df):
515 case USB_ID(0x041e, 0x3048): 527 case USB_ID(0x041e, 0x3048):
516 err = snd_audigy2nx_controls_create(mixer); 528 err = snd_audigy2nx_controls_create(mixer);
517 if (err < 0) 529 if (err < 0)
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index c66d3f64dcf8..78792a8900c3 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -1651,6 +1651,32 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1651 } 1651 }
1652 } 1652 }
1653}, 1653},
1654{
1655 USB_DEVICE(0x0582, 0x0127),
1656 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1657 /* .vendor_name = "Roland", */
1658 /* .product_name = "GR-55", */
1659 .ifnum = QUIRK_ANY_INTERFACE,
1660 .type = QUIRK_COMPOSITE,
1661 .data = (const struct snd_usb_audio_quirk[]) {
1662 {
1663 .ifnum = 0,
1664 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1665 },
1666 {
1667 .ifnum = 1,
1668 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1669 },
1670 {
1671 .ifnum = 2,
1672 .type = QUIRK_MIDI_STANDARD_INTERFACE
1673 },
1674 {
1675 .ifnum = -1
1676 }
1677 }
1678 }
1679},
1654 1680
1655/* Guillemot devices */ 1681/* Guillemot devices */
1656{ 1682{
@@ -1953,7 +1979,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1953 } 1979 }
1954}, 1980},
1955{ 1981{
1956 USB_DEVICE(0x0763, 0x2080), 1982 USB_DEVICE_VENDOR_SPEC(0x0763, 0x2080),
1957 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1983 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1958 /* .vendor_name = "M-Audio", */ 1984 /* .vendor_name = "M-Audio", */
1959 /* .product_name = "Fast Track Ultra", */ 1985 /* .product_name = "Fast Track Ultra", */
@@ -2020,7 +2046,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2020 } 2046 }
2021}, 2047},
2022{ 2048{
2023 USB_DEVICE(0x0763, 0x2081), 2049 USB_DEVICE_VENDOR_SPEC(0x0763, 0x2081),
2024 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 2050 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
2025 /* .vendor_name = "M-Audio", */ 2051 /* .vendor_name = "M-Audio", */
2026 /* .product_name = "Fast Track Ultra 8R", */ 2052 /* .product_name = "Fast Track Ultra 8R", */
@@ -2179,6 +2205,17 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2179 } 2205 }
2180}, 2206},
2181 2207
2208/* KORG devices */
2209{
2210 USB_DEVICE_VENDOR_SPEC(0x0944, 0x0200),
2211 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
2212 .vendor_name = "KORG, Inc.",
2213 /* .product_name = "PANDORA PX5D", */
2214 .ifnum = 3,
2215 .type = QUIRK_MIDI_STANDARD_INTERFACE,
2216 }
2217},
2218
2182/* AKAI devices */ 2219/* AKAI devices */
2183{ 2220{
2184 USB_DEVICE(0x09e8, 0x0062), 2221 USB_DEVICE(0x09e8, 0x0062),
@@ -2332,6 +2369,12 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2332 2369
2333/* Native Instruments MK2 series */ 2370/* Native Instruments MK2 series */
2334{ 2371{
2372 /* Komplete Audio 6 */
2373 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
2374 .idVendor = 0x17cc,
2375 .idProduct = 0x1000,
2376},
2377{
2335 /* Traktor Audio 6 */ 2378 /* Traktor Audio 6 */
2336 .match_flags = USB_DEVICE_ID_MATCH_DEVICE, 2379 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
2337 .idVendor = 0x17cc, 2380 .idVendor = 0x17cc,
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 1b94ec3a3368..bd13d7257240 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -540,6 +540,7 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
540 /* Access Music VirusTI Desktop */ 540 /* Access Music VirusTI Desktop */
541 return snd_usb_accessmusic_boot_quirk(dev); 541 return snd_usb_accessmusic_boot_quirk(dev);
542 542
543 case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */
543 case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */ 544 case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
544 case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */ 545 case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
545 return snd_usb_nativeinstruments_boot_quirk(dev); 546 return snd_usb_nativeinstruments_boot_quirk(dev);