aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt17
-rw-r--r--Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl4
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx_psc.h8
-rw-r--r--include/sound/ad1843.h46
-rw-r--r--include/sound/control.h3
-rw-r--r--include/sound/core.h8
-rw-r--r--include/sound/cs4231-regs.h8
-rw-r--r--include/sound/cs4231.h3
-rw-r--r--include/sound/emu10k1.h1
-rw-r--r--include/sound/seq_kernel.h2
-rw-r--r--include/sound/soc-dapm.h42
-rw-r--r--include/sound/soc.h175
-rw-r--r--include/sound/uda1341.h2
-rw-r--r--include/sound/version.h4
-rw-r--r--sound/Kconfig34
-rw-r--r--sound/aoa/Kconfig11
-rw-r--r--sound/aoa/codecs/Kconfig4
-rw-r--r--sound/aoa/fabrics/Kconfig1
-rw-r--r--sound/aoa/soundbus/Kconfig1
-rw-r--r--sound/arm/Kconfig21
-rw-r--r--sound/arm/sa11xx-uda1341.c2
-rw-r--r--sound/core/Kconfig29
-rw-r--r--sound/core/control.c7
-rw-r--r--sound/core/init.c67
-rw-r--r--sound/core/memalloc.c62
-rw-r--r--sound/core/seq/seq_clientmgr.c2
-rw-r--r--sound/core/seq/seq_device.c6
-rw-r--r--sound/core/sound.c8
-rw-r--r--sound/core/timer.c6
-rw-r--r--sound/drivers/Kconfig91
-rw-r--r--sound/drivers/vx/vx_hwdep.c2
-rw-r--r--sound/i2c/cs8427.c6
-rw-r--r--sound/i2c/l3/uda1341.c2
-rw-r--r--sound/isa/Kconfig61
-rw-r--r--sound/isa/cs423x/cs4231_lib.c118
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c1126
-rw-r--r--sound/isa/sb/Makefile2
-rw-r--r--sound/isa/wavefront/wavefront_synth.c2
-rw-r--r--sound/mips/Kconfig27
-rw-r--r--sound/mips/Makefile4
-rw-r--r--sound/mips/ad1843.c561
-rw-r--r--sound/mips/hal2.c947
-rw-r--r--sound/mips/hal2.h245
-rw-r--r--sound/mips/sgio2audio.c1006
-rw-r--r--sound/oss/Kconfig49
-rw-r--r--sound/oss/dmasound/dmasound_core.c7
-rw-r--r--sound/oss/dmasound/dmasound_paula.c2
-rw-r--r--sound/oss/dmasound/dmasound_q40.c2
-rw-r--r--sound/oss/msnd.c2
-rw-r--r--sound/oss/msnd.h2
-rw-r--r--sound/oss/msnd_classic.h2
-rw-r--r--sound/oss/msnd_pinnacle.c5
-rw-r--r--sound/oss/msnd_pinnacle.h2
-rw-r--r--sound/parisc/Kconfig13
-rw-r--r--sound/pci/Kconfig104
-rw-r--r--sound/pci/Makefile2
-rw-r--r--sound/pci/ac97/Makefile12
-rw-r--r--sound/pci/ac97/ac97_codec.c11
-rw-r--r--sound/pci/ac97/ac97_patch.c81
-rw-r--r--sound/pci/ak4531_codec.c (renamed from sound/pci/ac97/ak4531_codec.c)34
-rw-r--r--sound/pci/au88x0/au88x0_game.c2
-rw-r--r--sound/pci/azt3328.c1235
-rw-r--r--sound/pci/azt3328.h207
-rw-r--r--sound/pci/ca0106/ca0106_main.c5
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c1
-rw-r--r--sound/pci/emu10k1/emumixer.c13
-rw-r--r--sound/pci/emu10k1/memory.c69
-rw-r--r--sound/pci/hda/hda_codec.c2
-rw-r--r--sound/pci/hda/hda_codec.h2
-rw-r--r--sound/pci/hda/hda_hwdep.c2
-rw-r--r--sound/pci/hda/hda_intel.c306
-rw-r--r--sound/pci/hda/hda_proc.c5
-rw-r--r--sound/pci/hda/patch_analog.c38
-rw-r--r--sound/pci/hda/patch_conexant.c33
-rw-r--r--sound/pci/hda/patch_realtek.c548
-rw-r--r--sound/pci/hda/patch_sigmatel.c71
-rw-r--r--sound/pci/ice1712/envy24ht.h10
-rw-r--r--sound/pci/ice1712/ice1712.h2
-rw-r--r--sound/pci/ice1712/ice1724.c213
-rw-r--r--sound/pci/maestro3.c42
-rw-r--r--sound/pci/nm256/nm256.c4
-rw-r--r--sound/pci/oxygen/hifier.c33
-rw-r--r--sound/pci/oxygen/oxygen.c76
-rw-r--r--sound/pci/oxygen/oxygen.h14
-rw-r--r--sound/pci/oxygen/oxygen_io.c22
-rw-r--r--sound/pci/oxygen/oxygen_lib.c106
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c53
-rw-r--r--sound/pci/oxygen/virtuoso.c252
-rw-r--r--sound/pci/pcxhr/pcxhr.c4
-rw-r--r--sound/pci/pcxhr/pcxhr_core.c18
-rw-r--r--sound/pci/trident/trident_main.c5
-rw-r--r--sound/pci/trident/trident_memory.c178
-rw-r--r--sound/pci/via82xx.c6
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c2
-rw-r--r--sound/pcmcia/Kconfig15
-rw-r--r--sound/pcmcia/vx/vxp_ops.c2
-rw-r--r--sound/ppc/Kconfig26
-rw-r--r--sound/ppc/daca.c2
-rw-r--r--sound/ppc/tumbler.c2
-rw-r--r--sound/sh/Kconfig16
-rw-r--r--sound/soc/Kconfig19
-rw-r--r--sound/soc/Makefile3
-rw-r--r--sound/soc/at32/Kconfig34
-rw-r--r--sound/soc/at32/Makefile11
-rw-r--r--sound/soc/at32/at32-pcm.c491
-rw-r--r--sound/soc/at32/at32-pcm.h79
-rw-r--r--sound/soc/at32/at32-ssc.c849
-rw-r--r--sound/soc/at32/at32-ssc.h59
-rw-r--r--sound/soc/at32/playpaq_wm8510.c522
-rw-r--r--sound/soc/at91/Kconfig2
-rw-r--r--sound/soc/at91/at91-pcm.c6
-rw-r--r--sound/soc/at91/at91-ssc.c12
-rw-r--r--sound/soc/at91/at91-ssc.h2
-rw-r--r--sound/soc/at91/eti_b1_wm8731.c53
-rw-r--r--sound/soc/au1x/Kconfig32
-rw-r--r--sound/soc/au1x/Makefile13
-rw-r--r--sound/soc/au1x/dbdma2.c421
-rw-r--r--sound/soc/au1x/psc-ac97.c387
-rw-r--r--sound/soc/au1x/psc-i2s.c414
-rw-r--r--sound/soc/au1x/psc.h53
-rw-r--r--sound/soc/au1x/sample-ac97.c144
-rw-r--r--sound/soc/codecs/Kconfig22
-rw-r--r--sound/soc/codecs/Makefile8
-rw-r--r--sound/soc/codecs/ac97.c31
-rw-r--r--sound/soc/codecs/ac97.h2
-rw-r--r--sound/soc/codecs/ak4535.c696
-rw-r--r--sound/soc/codecs/ak4535.h46
-rw-r--r--sound/soc/codecs/cs4270.c8
-rw-r--r--sound/soc/codecs/cs4270.h2
-rw-r--r--sound/soc/codecs/tlv320aic3x.c384
-rw-r--r--sound/soc/codecs/tlv320aic3x.h55
-rw-r--r--sound/soc/codecs/uda1380.c852
-rw-r--r--sound/soc/codecs/uda1380.h89
-rw-r--r--sound/soc/codecs/wm8510.c817
-rw-r--r--sound/soc/codecs/wm8510.h103
-rw-r--r--sound/soc/codecs/wm8731.c79
-rw-r--r--sound/soc/codecs/wm8731.h2
-rw-r--r--sound/soc/codecs/wm8750.c87
-rw-r--r--sound/soc/codecs/wm8750.h2
-rw-r--r--sound/soc/codecs/wm8753.c183
-rw-r--r--sound/soc/codecs/wm8753.h2
-rw-r--r--sound/soc/codecs/wm8990.c1626
-rw-r--r--sound/soc/codecs/wm8990.h832
-rw-r--r--sound/soc/codecs/wm9712.c53
-rw-r--r--sound/soc/codecs/wm9712.h2
-rw-r--r--sound/soc/codecs/wm9713.c79
-rw-r--r--sound/soc/codecs/wm9713.h2
-rw-r--r--sound/soc/davinci/Kconfig2
-rw-r--r--sound/soc/davinci/davinci-evm.c40
-rw-r--r--sound/soc/davinci/davinci-i2s.c16
-rw-r--r--sound/soc/davinci/davinci-i2s.h2
-rw-r--r--sound/soc/davinci/davinci-pcm.c2
-rw-r--r--sound/soc/fsl/Kconfig6
-rw-r--r--sound/soc/fsl/fsl_dma.c2
-rw-r--r--sound/soc/fsl/fsl_dma.h2
-rw-r--r--sound/soc/fsl/fsl_ssi.c24
-rw-r--r--sound/soc/fsl/fsl_ssi.h4
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c72
-rw-r--r--sound/soc/omap/Kconfig4
-rw-r--r--sound/soc/omap/n810.c106
-rw-r--r--sound/soc/omap/omap-mcbsp.c16
-rw-r--r--sound/soc/omap/omap-mcbsp.h2
-rw-r--r--sound/soc/omap/omap-pcm.c2
-rw-r--r--sound/soc/pxa/Kconfig11
-rw-r--r--sound/soc/pxa/Makefile3
-rw-r--r--sound/soc/pxa/corgi.c70
-rw-r--r--sound/soc/pxa/em-x270.c102
-rw-r--r--sound/soc/pxa/poodle.c50
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c18
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.h2
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c17
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.h2
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c2
-rw-r--r--sound/soc/pxa/spitz.c91
-rw-r--r--sound/soc/pxa/tosa.c47
-rw-r--r--sound/soc/s3c24xx/Kconfig4
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c237
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c15
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.h2
-rw-r--r--sound/soc/s3c24xx/s3c2443-ac97.c15
-rw-r--r--sound/soc/s3c24xx/s3c24xx-ac97.h2
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c25
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.h2
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.c6
-rw-r--r--sound/soc/s3c24xx/smdk2443_wm9710.c3
-rw-r--r--sound/soc/sh/Kconfig5
-rw-r--r--sound/soc/sh/dma-sh7760.c2
-rw-r--r--sound/soc/sh/hac.c2
-rw-r--r--sound/soc/sh/sh7760-ac97.c4
-rw-r--r--sound/soc/sh/ssi.c8
-rw-r--r--sound/soc/soc-core.c443
-rw-r--r--sound/soc/soc-dapm.c344
-rw-r--r--sound/sparc/Kconfig17
-rw-r--r--sound/sparc/dbri.c2
-rw-r--r--sound/spi/Kconfig13
-rw-r--r--sound/usb/Kconfig16
-rw-r--r--sound/usb/caiaq/caiaq-audio.c1
-rw-r--r--sound/usb/caiaq/caiaq-device.c12
-rw-r--r--sound/usb/caiaq/caiaq-device.h1
-rw-r--r--sound/usb/usbaudio.c4
-rw-r--r--sound/usb/usbquirks.h38
201 files changed, 16473 insertions, 3893 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 0bbee38acd26..72aff61e7315 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -753,8 +753,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
753 753
754 [Multiple options for each card instance] 754 [Multiple options for each card instance]
755 model - force the model name 755 model - force the model name
756 position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) 756 position_fix - Fix DMA pointer (0 = auto, 1 = use LPIB, 2 = POSBUF)
757 probe_mask - Bitmask to probe codecs (default = -1, meaning all slots) 757 probe_mask - Bitmask to probe codecs (default = -1, meaning all slots)
758 bdl_pos_adj - Specifies the DMA IRQ timing delay in samples.
759 Passing -1 will make the driver to choose the appropriate
760 value based on the controller chip.
758 761
759 [Single (global) options] 762 [Single (global) options]
760 single_cmd - Use single immediate commands to communicate with 763 single_cmd - Use single immediate commands to communicate with
@@ -845,7 +848,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
845 ALC269 848 ALC269
846 basic Basic preset 849 basic Basic preset
847 850
848 ALC662 851 ALC662/663
849 3stack-dig 3-stack (2-channel) with SPDIF 852 3stack-dig 3-stack (2-channel) with SPDIF
850 3stack-6ch 3-stack (6-channel) 853 3stack-6ch 3-stack (6-channel)
851 3stack-6ch-dig 3-stack (6-channel) with SPDIF 854 3stack-6ch-dig 3-stack (6-channel) with SPDIF
@@ -853,6 +856,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
853 lenovo-101e Lenovo laptop 856 lenovo-101e Lenovo laptop
854 eeepc-p701 ASUS Eeepc P701 857 eeepc-p701 ASUS Eeepc P701
855 eeepc-ep20 ASUS Eeepc EP20 858 eeepc-ep20 ASUS Eeepc EP20
859 m51va ASUS M51VA
860 g71v ASUS G71V
861 h13 ASUS H13
862 g50v ASUS G50V
856 auto auto-config reading BIOS (default) 863 auto auto-config reading BIOS (default)
857 864
858 ALC882/885 865 ALC882/885
@@ -1091,7 +1098,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1091 This occurs when the access to non-existing or non-working codec slot 1098 This occurs when the access to non-existing or non-working codec slot
1092 (likely a modem one) causes a stall of the communication via HD-audio 1099 (likely a modem one) causes a stall of the communication via HD-audio
1093 bus. You can see which codec slots are probed by enabling 1100 bus. You can see which codec slots are probed by enabling
1094 CONFIG_SND_DEBUG_DETECT, or simply from the file name of the codec 1101 CONFIG_SND_DEBUG_VERBOSE, or simply from the file name of the codec
1095 proc files. Then limit the slots to probe by probe_mask option. 1102 proc files. Then limit the slots to probe by probe_mask option.
1096 For example, probe_mask=1 means to probe only the first slot, and 1103 For example, probe_mask=1 means to probe only the first slot, and
1097 probe_mask=4 means only the third slot. 1104 probe_mask=4 means only the third slot.
@@ -2267,6 +2274,10 @@ case above again, the first two slots are already reserved. If any
2267other driver (e.g. snd-usb-audio) is loaded before snd-interwave or 2274other driver (e.g. snd-usb-audio) is loaded before snd-interwave or
2268snd-ens1371, it will be assigned to the third or later slot. 2275snd-ens1371, it will be assigned to the third or later slot.
2269 2276
2277When a module name is given with '!', the slot will be given for any
2278modules but that name. For example, "slots=!snd-pcsp" will reserve
2279the first slot for any modules but snd-pcsp.
2280
2270 2281
2271ALSA PCM devices to OSS devices mapping 2282ALSA PCM devices to OSS devices mapping
2272======================================= 2283=======================================
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index b03df4d4795c..e13c4e67029f 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -6127,8 +6127,8 @@ struct _snd_pcm_runtime {
6127 6127
6128 <para> 6128 <para>
6129 <function>snd_printdd()</function> is compiled in only when 6129 <function>snd_printdd()</function> is compiled in only when
6130 <constant>CONFIG_SND_DEBUG_DETECT</constant> is set. Please note 6130 <constant>CONFIG_SND_DEBUG_VERBOSE</constant> is set. Please note
6131 that <constant>DEBUG_DETECT</constant> is not set as default 6131 that <constant>CONFIG_SND_DEBUG_VERBOSE</constant> is not set as default
6132 even if you configure the alsa-driver with 6132 even if you configure the alsa-driver with
6133 <option>--with-debug=full</option> option. You need to give 6133 <option>--with-debug=full</option> option. You need to give
6134 explicitly <option>--with-debug=detect</option> option instead. 6134 explicitly <option>--with-debug=detect</option> option instead.
diff --git a/include/asm-mips/mach-au1x00/au1xxx_psc.h b/include/asm-mips/mach-au1x00/au1xxx_psc.h
index dae4eca2417e..892b7f168eb4 100644
--- a/include/asm-mips/mach-au1x00/au1xxx_psc.h
+++ b/include/asm-mips/mach-au1x00/au1xxx_psc.h
@@ -204,6 +204,14 @@ typedef struct psc_i2s {
204 u32 psc_i2sudf; 204 u32 psc_i2sudf;
205} psc_i2s_t; 205} psc_i2s_t;
206 206
207#define PSC_I2SCFG_OFFSET 0x08
208#define PSC_I2SMASK_OFFSET 0x0C
209#define PSC_I2SPCR_OFFSET 0x10
210#define PSC_I2SSTAT_OFFSET 0x14
211#define PSC_I2SEVENT_OFFSET 0x18
212#define PSC_I2SRXTX_OFFSET 0x1C
213#define PSC_I2SUDF_OFFSET 0x20
214
207/* I2S Config Register. */ 215/* I2S Config Register. */
208#define PSC_I2SCFG_RT_MASK (3 << 30) 216#define PSC_I2SCFG_RT_MASK (3 << 30)
209#define PSC_I2SCFG_RT_FIFO1 (0 << 30) 217#define PSC_I2SCFG_RT_FIFO1 (0 << 30)
diff --git a/include/sound/ad1843.h b/include/sound/ad1843.h
new file mode 100644
index 000000000000..b236a9d1d6e4
--- /dev/null
+++ b/include/sound/ad1843.h
@@ -0,0 +1,46 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright 2003 Vivien Chappelier <vivien.chappelier@linux-mips.org>
7 * Copyright 2008 Thomas Bogendoerfer <tsbogend@franken.de>
8 */
9
10#ifndef __SOUND_AD1843_H
11#define __SOUND_AD1843_H
12
13struct snd_ad1843 {
14 void *chip;
15 int (*read)(void *chip, int reg);
16 int (*write)(void *chip, int reg, int val);
17};
18
19#define AD1843_GAIN_RECLEV 0
20#define AD1843_GAIN_LINE 1
21#define AD1843_GAIN_LINE_2 2
22#define AD1843_GAIN_MIC 3
23#define AD1843_GAIN_PCM_0 4
24#define AD1843_GAIN_PCM_1 5
25#define AD1843_GAIN_SIZE (AD1843_GAIN_PCM_1+1)
26
27int ad1843_get_gain_max(struct snd_ad1843 *ad1843, int id);
28int ad1843_get_gain(struct snd_ad1843 *ad1843, int id);
29int ad1843_set_gain(struct snd_ad1843 *ad1843, int id, int newval);
30int ad1843_get_recsrc(struct snd_ad1843 *ad1843);
31int ad1843_set_recsrc(struct snd_ad1843 *ad1843, int newsrc);
32void ad1843_setup_dac(struct snd_ad1843 *ad1843,
33 unsigned int id,
34 unsigned int framerate,
35 snd_pcm_format_t fmt,
36 unsigned int channels);
37void ad1843_shutdown_dac(struct snd_ad1843 *ad1843,
38 unsigned int id);
39void ad1843_setup_adc(struct snd_ad1843 *ad1843,
40 unsigned int framerate,
41 snd_pcm_format_t fmt,
42 unsigned int channels);
43void ad1843_shutdown_adc(struct snd_ad1843 *ad1843);
44int ad1843_init(struct snd_ad1843 *ad1843);
45
46#endif /* __SOUND_AD1843_H */
diff --git a/include/sound/control.h b/include/sound/control.h
index 3dc1291f52db..4721b4bba053 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -129,9 +129,6 @@ int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn);
129#define snd_ctl_unregister_ioctl_compat(fcn) 129#define snd_ctl_unregister_ioctl_compat(fcn)
130#endif 130#endif
131 131
132int snd_ctl_elem_read(struct snd_card *card, struct snd_ctl_elem_value *control);
133int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, struct snd_ctl_elem_value *control);
134
135static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id) 132static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
136{ 133{
137 return id->numid - kctl->id.numid; 134 return id->numid - kctl->id.numid;
diff --git a/include/sound/core.h b/include/sound/core.h
index 695ee53488a3..558b96284bd2 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -412,13 +412,13 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
412 412
413#endif /* CONFIG_SND_DEBUG */ 413#endif /* CONFIG_SND_DEBUG */
414 414
415#ifdef CONFIG_SND_DEBUG_DETECT 415#ifdef CONFIG_SND_DEBUG_VERBOSE
416/** 416/**
417 * snd_printdd - debug printk 417 * snd_printdd - debug printk
418 * @format: format string 418 * @format: format string
419 * 419 *
420 * Works like snd_printk() for debugging purposes. 420 * Works like snd_printk() for debugging purposes.
421 * Ignored when CONFIG_SND_DEBUG_DETECT is not set. 421 * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set.
422 */ 422 */
423#define snd_printdd(format, args...) snd_printk(format, ##args) 423#define snd_printdd(format, args...) snd_printk(format, ##args)
424#else 424#else
@@ -442,7 +442,7 @@ struct snd_pci_quirk {
442 unsigned short subvendor; /* PCI subvendor ID */ 442 unsigned short subvendor; /* PCI subvendor ID */
443 unsigned short subdevice; /* PCI subdevice ID */ 443 unsigned short subdevice; /* PCI subdevice ID */
444 int value; /* value */ 444 int value; /* value */
445#ifdef CONFIG_SND_DEBUG_DETECT 445#ifdef CONFIG_SND_DEBUG_VERBOSE
446 const char *name; /* name of the device (optional) */ 446 const char *name; /* name of the device (optional) */
447#endif 447#endif
448}; 448};
@@ -450,7 +450,7 @@ struct snd_pci_quirk {
450#define _SND_PCI_QUIRK_ID(vend,dev) \ 450#define _SND_PCI_QUIRK_ID(vend,dev) \
451 .subvendor = (vend), .subdevice = (dev) 451 .subvendor = (vend), .subdevice = (dev)
452#define SND_PCI_QUIRK_ID(vend,dev) {_SND_PCI_QUIRK_ID(vend, dev)} 452#define SND_PCI_QUIRK_ID(vend,dev) {_SND_PCI_QUIRK_ID(vend, dev)}
453#ifdef CONFIG_SND_DEBUG_DETECT 453#ifdef CONFIG_SND_DEBUG_VERBOSE
454#define SND_PCI_QUIRK(vend,dev,xname,val) \ 454#define SND_PCI_QUIRK(vend,dev,xname,val) \
455 {_SND_PCI_QUIRK_ID(vend, dev), .value = (val), .name = (xname)} 455 {_SND_PCI_QUIRK_ID(vend, dev), .value = (val), .name = (xname)}
456#else 456#else
diff --git a/include/sound/cs4231-regs.h b/include/sound/cs4231-regs.h
index e8d1f3e31f9e..92647532c454 100644
--- a/include/sound/cs4231-regs.h
+++ b/include/sound/cs4231-regs.h
@@ -177,4 +177,12 @@
177#define CS4236_RIGHT_WAVE 0x1c /* right wavetable serial port volume */ 177#define CS4236_RIGHT_WAVE 0x1c /* right wavetable serial port volume */
178#define CS4236_VERSION 0x9c /* chip version and ID */ 178#define CS4236_VERSION 0x9c /* chip version and ID */
179 179
180/* definitions for extended registers - OPTI93X */
181#define OPTi931_AUX_LEFT_INPUT 0x10
182#define OPTi931_AUX_RIGHT_INPUT 0x11
183#define OPTi93X_MIC_LEFT_INPUT 0x14
184#define OPTi93X_MIC_RIGHT_INPUT 0x15
185#define OPTi93X_OUT_LEFT 0x16
186#define OPTi93X_OUT_RIGHT 0x17
187
180#endif /* __SOUND_CS4231_REGS_H */ 188#endif /* __SOUND_CS4231_REGS_H */
diff --git a/include/sound/cs4231.h b/include/sound/cs4231.h
index 66055d702aa3..f0785f9f4ae4 100644
--- a/include/sound/cs4231.h
+++ b/include/sound/cs4231.h
@@ -58,6 +58,7 @@
58/* compatible, but clones */ 58/* compatible, but clones */
59#define CS4231_HW_INTERWAVE 0x1000 /* InterWave chip */ 59#define CS4231_HW_INTERWAVE 0x1000 /* InterWave chip */
60#define CS4231_HW_OPL3SA2 0x1101 /* OPL3-SA2 chip, similar to cs4231 */ 60#define CS4231_HW_OPL3SA2 0x1101 /* OPL3-SA2 chip, similar to cs4231 */
61#define CS4231_HW_OPTI93X 0x1102 /* Opti 930/931/933 */
61 62
62/* defines for codec.hwshare */ 63/* defines for codec.hwshare */
63#define CS4231_HWSHARE_IRQ (1<<0) 64#define CS4231_HWSHARE_IRQ (1<<0)
@@ -120,6 +121,8 @@ unsigned char snd_cs4236_ext_in(struct snd_cs4231 *chip, unsigned char reg);
120void snd_cs4231_mce_up(struct snd_cs4231 *chip); 121void snd_cs4231_mce_up(struct snd_cs4231 *chip);
121void snd_cs4231_mce_down(struct snd_cs4231 *chip); 122void snd_cs4231_mce_down(struct snd_cs4231 *chip);
122 123
124void snd_cs4231_overrange(struct snd_cs4231 *chip);
125
123irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id); 126irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id);
124 127
125const char *snd_cs4231_chip_id(struct snd_cs4231 *chip); 128const char *snd_cs4231_chip_id(struct snd_cs4231 *chip);
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 7b7b9b13b4dd..10ee28eac018 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -1670,6 +1670,7 @@ struct snd_emu_chip_details {
1670 unsigned char spi_dac; /* SPI interface for DAC */ 1670 unsigned char spi_dac; /* SPI interface for DAC */
1671 unsigned char i2c_adc; /* I2C interface for ADC */ 1671 unsigned char i2c_adc; /* I2C interface for ADC */
1672 unsigned char adc_1361t; /* Use Philips 1361T ADC */ 1672 unsigned char adc_1361t; /* Use Philips 1361T ADC */
1673 unsigned char invert_shared_spdif; /* analog/digital switch inverted */
1673 const char *driver; 1674 const char *driver;
1674 const char *name; 1675 const char *name;
1675 const char *id; /* for backward compatibility - can be NULL if not needed */ 1676 const char *id; /* for backward compatibility - can be NULL if not needed */
diff --git a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h
index f023c1b97f8c..3d9afb6a8c9c 100644
--- a/include/sound/seq_kernel.h
+++ b/include/sound/seq_kernel.h
@@ -105,7 +105,7 @@ int snd_seq_event_port_attach(int client, struct snd_seq_port_callback *pcbp,
105 int cap, int type, int midi_channels, int midi_voices, char *portname); 105 int cap, int type, int midi_channels, int midi_voices, char *portname);
106int snd_seq_event_port_detach(int client, int port); 106int snd_seq_event_port_detach(int client, int port);
107 107
108#ifdef CONFIG_KMOD 108#ifdef CONFIG_MODULES
109void snd_seq_autoload_lock(void); 109void snd_seq_autoload_lock(void);
110void snd_seq_autoload_unlock(void); 110void snd_seq_autoload_unlock(void);
111#else 111#else
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index a105b01e06d5..3030fdc6981d 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -130,6 +130,13 @@
130{ .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \ 130{ .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \
131 .shift = wshift, .invert = winvert} 131 .shift = wshift, .invert = winvert}
132 132
133/* generic register modifier widget */
134#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
135{ .id = wid, .name = wname, .kcontrols = NULL, .num_kcontrols = 0, \
136 .reg = -((wreg) + 1), .shift = wshift, .mask = wmask, \
137 .on_val = won_val, .off_val = woff_val, .event = dapm_reg_event, \
138 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}
139
133/* dapm kcontrol types */ 140/* dapm kcontrol types */
134#define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \ 141#define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
135{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 142{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -193,6 +200,7 @@ struct snd_soc_dapm_widget;
193enum snd_soc_dapm_type; 200enum snd_soc_dapm_type;
194struct snd_soc_dapm_path; 201struct snd_soc_dapm_path;
195struct snd_soc_dapm_pin; 202struct snd_soc_dapm_pin;
203struct snd_soc_dapm_route;
196 204
197/* dapm controls */ 205/* dapm controls */
198int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, 206int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
@@ -205,25 +213,32 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
205 struct snd_ctl_elem_value *ucontrol); 213 struct snd_ctl_elem_value *ucontrol);
206int snd_soc_dapm_new_control(struct snd_soc_codec *codec, 214int snd_soc_dapm_new_control(struct snd_soc_codec *codec,
207 const struct snd_soc_dapm_widget *widget); 215 const struct snd_soc_dapm_widget *widget);
216int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
217 const struct snd_soc_dapm_widget *widget,
218 int num);
208 219
209/* dapm path setup */ 220/* dapm path setup */
210int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, 221int __deprecated snd_soc_dapm_connect_input(struct snd_soc_codec *codec,
211 const char *sink_name, const char *control_name, const char *src_name); 222 const char *sink_name, const char *control_name, const char *src_name);
212int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec); 223int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec);
213void snd_soc_dapm_free(struct snd_soc_device *socdev); 224void snd_soc_dapm_free(struct snd_soc_device *socdev);
225int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
226 const struct snd_soc_dapm_route *route, int num);
214 227
215/* dapm events */ 228/* dapm events */
216int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream, 229int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream,
217 int event); 230 int event);
218int snd_soc_dapm_device_event(struct snd_soc_device *socdev, int event); 231int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
232 enum snd_soc_bias_level level);
219 233
220/* dapm sys fs - used by the core */ 234/* dapm sys fs - used by the core */
221int snd_soc_dapm_sys_add(struct device *dev); 235int snd_soc_dapm_sys_add(struct device *dev);
222 236
223/* dapm audio endpoint control */ 237/* dapm audio pin control and status */
224int snd_soc_dapm_set_endpoint(struct snd_soc_codec *codec, 238int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, char *pin);
225 char *pin, int status); 239int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, char *pin);
226int snd_soc_dapm_sync_endpoints(struct snd_soc_codec *codec); 240int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, char *pin);
241int snd_soc_dapm_sync(struct snd_soc_codec *codec);
227 242
228/* dapm widget types */ 243/* dapm widget types */
229enum snd_soc_dapm_type { 244enum snd_soc_dapm_type {
@@ -245,6 +260,18 @@ enum snd_soc_dapm_type {
245 snd_soc_dapm_post, /* machine specific post widget - exec last */ 260 snd_soc_dapm_post, /* machine specific post widget - exec last */
246}; 261};
247 262
263/*
264 * DAPM audio route definition.
265 *
266 * Defines an audio route originating at source via control and finishing
267 * at sink.
268 */
269struct snd_soc_dapm_route {
270 const char *sink;
271 const char *control;
272 const char *source;
273};
274
248/* dapm audio path between two widgets */ 275/* dapm audio path between two widgets */
249struct snd_soc_dapm_path { 276struct snd_soc_dapm_path {
250 char *name; 277 char *name;
@@ -277,6 +304,9 @@ struct snd_soc_dapm_widget {
277 unsigned char shift; /* bits to shift */ 304 unsigned char shift; /* bits to shift */
278 unsigned int saved_value; /* widget saved value */ 305 unsigned int saved_value; /* widget saved value */
279 unsigned int value; /* widget current value */ 306 unsigned int value; /* widget current value */
307 unsigned int mask; /* non-shifted mask */
308 unsigned int on_val; /* on state value */
309 unsigned int off_val; /* off state value */
280 unsigned char power:1; /* block power status */ 310 unsigned char power:1; /* block power status */
281 unsigned char invert:1; /* invert the power bit */ 311 unsigned char invert:1; /* invert the power bit */
282 unsigned char active:1; /* active stream on DAC, ADC's */ 312 unsigned char active:1; /* active stream on DAC, ADC's */
diff --git a/include/sound/soc.h b/include/sound/soc.h
index d3c8c033dff8..1890d87c5204 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -73,6 +73,15 @@
73 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ 73 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \
74 .private_value = (reg_left) | ((shift) << 8) | \ 74 .private_value = (reg_left) | ((shift) << 8) | \
75 ((max) << 12) | ((invert) << 20) | ((reg_right) << 24) } 75 ((max) << 12) | ((invert) << 20) | ((reg_right) << 24) }
76#define SOC_DOUBLE_S8_TLV(xname, reg, min, max, tlv_array) \
77{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
78 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
79 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
80 .tlv.p = (tlv_array), \
81 .info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \
82 .put = snd_soc_put_volsw_s8, \
83 .private_value = (reg) | (((signed char)max) << 16) | \
84 (((signed char)min) << 24) }
76#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ 85#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
77{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ 86{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
78 .mask = xmask, .texts = xtexts } 87 .mask = xmask, .texts = xtexts }
@@ -91,6 +100,15 @@
91 .info = snd_soc_info_volsw, \ 100 .info = snd_soc_info_volsw, \
92 .get = xhandler_get, .put = xhandler_put, \ 101 .get = xhandler_get, .put = xhandler_put, \
93 .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmask, xinvert) } 102 .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmask, xinvert) }
103#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmask, xinvert,\
104 xhandler_get, xhandler_put, tlv_array) \
105{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
106 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
107 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
108 .tlv.p = (tlv_array), \
109 .info = snd_soc_info_volsw, \
110 .get = xhandler_get, .put = xhandler_put, \
111 .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmask, xinvert) }
94#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \ 112#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
95{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 113{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
96 .info = snd_soc_info_bool_ext, \ 114 .info = snd_soc_info_bool_ext, \
@@ -103,6 +121,24 @@
103 .private_value = (unsigned long)&xenum } 121 .private_value = (unsigned long)&xenum }
104 122
105/* 123/*
124 * Bias levels
125 *
126 * @ON: Bias is fully on for audio playback and capture operations.
127 * @PREPARE: Prepare for audio operations. Called before DAPM switching for
128 * stream start and stop operations.
129 * @STANDBY: Low power standby state when no playback/capture operations are
130 * in progress. NOTE: The transition time between STANDBY and ON
131 * should be as fast as possible and no longer than 10ms.
132 * @OFF: Power Off. No restrictions on transition times.
133 */
134enum snd_soc_bias_level {
135 SND_SOC_BIAS_ON,
136 SND_SOC_BIAS_PREPARE,
137 SND_SOC_BIAS_STANDBY,
138 SND_SOC_BIAS_OFF,
139};
140
141/*
106 * Digital Audio Interface (DAI) types 142 * Digital Audio Interface (DAI) types
107 */ 143 */
108#define SND_SOC_DAI_AC97 0x1 144#define SND_SOC_DAI_AC97 0x1
@@ -185,8 +221,7 @@ struct snd_soc_pcm_stream;
185struct snd_soc_ops; 221struct snd_soc_ops;
186struct snd_soc_dai_mode; 222struct snd_soc_dai_mode;
187struct snd_soc_pcm_runtime; 223struct snd_soc_pcm_runtime;
188struct snd_soc_codec_dai; 224struct snd_soc_dai;
189struct snd_soc_cpu_dai;
190struct snd_soc_codec; 225struct snd_soc_codec;
191struct snd_soc_machine_config; 226struct snd_soc_machine_config;
192struct soc_enum; 227struct soc_enum;
@@ -221,6 +256,27 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
221 struct snd_ac97_bus_ops *ops, int num); 256 struct snd_ac97_bus_ops *ops, int num);
222void snd_soc_free_ac97_codec(struct snd_soc_codec *codec); 257void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);
223 258
259/* Digital Audio Interface clocking API.*/
260int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
261 unsigned int freq, int dir);
262
263int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
264 int div_id, int div);
265
266int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
267 int pll_id, unsigned int freq_in, unsigned int freq_out);
268
269/* Digital Audio interface formatting */
270int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
271
272int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
273 unsigned int mask, int slots);
274
275int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
276
277/* Digital Audio Interface mute */
278int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute);
279
224/* 280/*
225 *Controls 281 *Controls
226 */ 282 */
@@ -249,6 +305,12 @@ int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
249 struct snd_ctl_elem_value *ucontrol); 305 struct snd_ctl_elem_value *ucontrol);
250int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, 306int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
251 struct snd_ctl_elem_value *ucontrol); 307 struct snd_ctl_elem_value *ucontrol);
308int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
309 struct snd_ctl_elem_info *uinfo);
310int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
311 struct snd_ctl_elem_value *ucontrol);
312int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
313 struct snd_ctl_elem_value *ucontrol);
252 314
253/* SoC PCM stream information */ 315/* SoC PCM stream information */
254struct snd_soc_pcm_stream { 316struct snd_soc_pcm_stream {
@@ -272,87 +334,45 @@ struct snd_soc_ops {
272 int (*trigger)(struct snd_pcm_substream *, int); 334 int (*trigger)(struct snd_pcm_substream *, int);
273}; 335};
274 336
275/* ASoC codec DAI ops */ 337/* ASoC DAI ops */
276struct snd_soc_codec_ops { 338struct snd_soc_dai_ops {
277 /* codec DAI clocking configuration */ 339 /* DAI clocking configuration */
278 int (*set_sysclk)(struct snd_soc_codec_dai *codec_dai, 340 int (*set_sysclk)(struct snd_soc_dai *dai,
279 int clk_id, unsigned int freq, int dir); 341 int clk_id, unsigned int freq, int dir);
280 int (*set_pll)(struct snd_soc_codec_dai *codec_dai, 342 int (*set_pll)(struct snd_soc_dai *dai,
281 int pll_id, unsigned int freq_in, unsigned int freq_out); 343 int pll_id, unsigned int freq_in, unsigned int freq_out);
282 int (*set_clkdiv)(struct snd_soc_codec_dai *codec_dai, 344 int (*set_clkdiv)(struct snd_soc_dai *dai, int div_id, int div);
283 int div_id, int div);
284 345
285 /* CPU DAI format configuration */ 346 /* DAI format configuration */
286 int (*set_fmt)(struct snd_soc_codec_dai *codec_dai, 347 int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
287 unsigned int fmt); 348 int (*set_tdm_slot)(struct snd_soc_dai *dai,
288 int (*set_tdm_slot)(struct snd_soc_codec_dai *codec_dai,
289 unsigned int mask, int slots); 349 unsigned int mask, int slots);
290 int (*set_tristate)(struct snd_soc_codec_dai *, int tristate); 350 int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
291 351
292 /* digital mute */ 352 /* digital mute */
293 int (*digital_mute)(struct snd_soc_codec_dai *, int mute); 353 int (*digital_mute)(struct snd_soc_dai *dai, int mute);
294};
295
296/* ASoC cpu DAI ops */
297struct snd_soc_cpu_ops {
298 /* CPU DAI clocking configuration */
299 int (*set_sysclk)(struct snd_soc_cpu_dai *cpu_dai,
300 int clk_id, unsigned int freq, int dir);
301 int (*set_clkdiv)(struct snd_soc_cpu_dai *cpu_dai,
302 int div_id, int div);
303 int (*set_pll)(struct snd_soc_cpu_dai *cpu_dai,
304 int pll_id, unsigned int freq_in, unsigned int freq_out);
305
306 /* CPU DAI format configuration */
307 int (*set_fmt)(struct snd_soc_cpu_dai *cpu_dai,
308 unsigned int fmt);
309 int (*set_tdm_slot)(struct snd_soc_cpu_dai *cpu_dai,
310 unsigned int mask, int slots);
311 int (*set_tristate)(struct snd_soc_cpu_dai *, int tristate);
312};
313
314/* SoC Codec DAI */
315struct snd_soc_codec_dai {
316 char *name;
317 int id;
318 unsigned char type;
319
320 /* DAI capabilities */
321 struct snd_soc_pcm_stream playback;
322 struct snd_soc_pcm_stream capture;
323
324 /* DAI runtime info */
325 struct snd_soc_codec *codec;
326 unsigned int active;
327 unsigned char pop_wait:1;
328
329 /* ops */
330 struct snd_soc_ops ops;
331 struct snd_soc_codec_ops dai_ops;
332
333 /* DAI private data */
334 void *private_data;
335}; 354};
336 355
337/* SoC CPU DAI */ 356/* SoC DAI (Digital Audio Interface) */
338struct snd_soc_cpu_dai { 357struct snd_soc_dai {
339
340 /* DAI description */ 358 /* DAI description */
341 char *name; 359 char *name;
342 unsigned int id; 360 unsigned int id;
343 unsigned char type; 361 unsigned char type;
344 362
345 /* DAI callbacks */ 363 /* DAI callbacks */
346 int (*probe)(struct platform_device *pdev); 364 int (*probe)(struct platform_device *pdev,
347 void (*remove)(struct platform_device *pdev); 365 struct snd_soc_dai *dai);
366 void (*remove)(struct platform_device *pdev,
367 struct snd_soc_dai *dai);
348 int (*suspend)(struct platform_device *pdev, 368 int (*suspend)(struct platform_device *pdev,
349 struct snd_soc_cpu_dai *cpu_dai); 369 struct snd_soc_dai *dai);
350 int (*resume)(struct platform_device *pdev, 370 int (*resume)(struct platform_device *pdev,
351 struct snd_soc_cpu_dai *cpu_dai); 371 struct snd_soc_dai *dai);
352 372
353 /* ops */ 373 /* ops */
354 struct snd_soc_ops ops; 374 struct snd_soc_ops ops;
355 struct snd_soc_cpu_ops dai_ops; 375 struct snd_soc_dai_ops dai_ops;
356 376
357 /* DAI capabilities */ 377 /* DAI capabilities */
358 struct snd_soc_pcm_stream capture; 378 struct snd_soc_pcm_stream capture;
@@ -360,7 +380,9 @@ struct snd_soc_cpu_dai {
360 380
361 /* DAI runtime info */ 381 /* DAI runtime info */
362 struct snd_pcm_runtime *runtime; 382 struct snd_pcm_runtime *runtime;
363 unsigned char active:1; 383 struct snd_soc_codec *codec;
384 unsigned int active;
385 unsigned char pop_wait:1;
364 void *dma_data; 386 void *dma_data;
365 387
366 /* DAI private data */ 388 /* DAI private data */
@@ -374,7 +396,8 @@ struct snd_soc_codec {
374 struct mutex mutex; 396 struct mutex mutex;
375 397
376 /* callbacks */ 398 /* callbacks */
377 int (*dapm_event)(struct snd_soc_codec *codec, int event); 399 int (*set_bias_level)(struct snd_soc_codec *,
400 enum snd_soc_bias_level level);
378 401
379 /* runtime */ 402 /* runtime */
380 struct snd_card *card; 403 struct snd_card *card;
@@ -396,12 +419,12 @@ struct snd_soc_codec {
396 /* dapm */ 419 /* dapm */
397 struct list_head dapm_widgets; 420 struct list_head dapm_widgets;
398 struct list_head dapm_paths; 421 struct list_head dapm_paths;
399 unsigned int dapm_state; 422 enum snd_soc_bias_level bias_level;
400 unsigned int suspend_dapm_state; 423 enum snd_soc_bias_level suspend_bias_level;
401 struct delayed_work delayed_work; 424 struct delayed_work delayed_work;
402 425
403 /* codec DAI's */ 426 /* codec DAI's */
404 struct snd_soc_codec_dai *dai; 427 struct snd_soc_dai *dai;
405 unsigned int num_dai; 428 unsigned int num_dai;
406}; 429};
407 430
@@ -420,12 +443,12 @@ struct snd_soc_platform {
420 int (*probe)(struct platform_device *pdev); 443 int (*probe)(struct platform_device *pdev);
421 int (*remove)(struct platform_device *pdev); 444 int (*remove)(struct platform_device *pdev);
422 int (*suspend)(struct platform_device *pdev, 445 int (*suspend)(struct platform_device *pdev,
423 struct snd_soc_cpu_dai *cpu_dai); 446 struct snd_soc_dai *dai);
424 int (*resume)(struct platform_device *pdev, 447 int (*resume)(struct platform_device *pdev,
425 struct snd_soc_cpu_dai *cpu_dai); 448 struct snd_soc_dai *dai);
426 449
427 /* pcm creation and destruction */ 450 /* pcm creation and destruction */
428 int (*pcm_new)(struct snd_card *, struct snd_soc_codec_dai *, 451 int (*pcm_new)(struct snd_card *, struct snd_soc_dai *,
429 struct snd_pcm *); 452 struct snd_pcm *);
430 void (*pcm_free)(struct snd_pcm *); 453 void (*pcm_free)(struct snd_pcm *);
431 454
@@ -439,8 +462,8 @@ struct snd_soc_dai_link {
439 char *stream_name; /* Stream name */ 462 char *stream_name; /* Stream name */
440 463
441 /* DAI */ 464 /* DAI */
442 struct snd_soc_codec_dai *codec_dai; 465 struct snd_soc_dai *codec_dai;
443 struct snd_soc_cpu_dai *cpu_dai; 466 struct snd_soc_dai *cpu_dai;
444 467
445 /* machine stream operations */ 468 /* machine stream operations */
446 struct snd_soc_ops *ops; 469 struct snd_soc_ops *ops;
@@ -467,7 +490,8 @@ struct snd_soc_machine {
467 int (*resume_post)(struct platform_device *pdev); 490 int (*resume_post)(struct platform_device *pdev);
468 491
469 /* callbacks */ 492 /* callbacks */
470 int (*dapm_event)(struct snd_soc_machine *, int event); 493 int (*set_bias_level)(struct snd_soc_machine *,
494 enum snd_soc_bias_level level);
471 495
472 /* CPU <--> Codec DAI links */ 496 /* CPU <--> Codec DAI links */
473 struct snd_soc_dai_link *dai_link; 497 struct snd_soc_dai_link *dai_link;
@@ -482,6 +506,7 @@ struct snd_soc_device {
482 struct snd_soc_codec *codec; 506 struct snd_soc_codec *codec;
483 struct snd_soc_codec_device *codec_dev; 507 struct snd_soc_codec_device *codec_dev;
484 struct delayed_work delayed_work; 508 struct delayed_work delayed_work;
509 struct work_struct deferred_resume_work;
485 void *codec_data; 510 void *codec_data;
486}; 511};
487 512
diff --git a/include/sound/uda1341.h b/include/sound/uda1341.h
index 2e564bfb37fe..110d5dc3a2be 100644
--- a/include/sound/uda1341.h
+++ b/include/sound/uda1341.h
@@ -15,8 +15,6 @@
15 * features support 15 * features support
16 */ 16 */
17 17
18/* $Id: uda1341.h,v 1.8 2005/11/17 14:17:21 tiwai Exp $ */
19
20#define UDA1341_ALSA_NAME "snd-uda1341" 18#define UDA1341_ALSA_NAME "snd-uda1341"
21 19
22/* 20/*
diff --git a/include/sound/version.h b/include/sound/version.h
index ed6fb2eb1eac..6b78aff273a8 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
1/* include/version.h. Generated by alsa/ksync script. */ 1/* include/version.h */
2#define CONFIG_SND_VERSION "1.0.16" 2#define CONFIG_SND_VERSION "1.0.17"
3#define CONFIG_SND_DATE "" 3#define CONFIG_SND_DATE ""
diff --git a/sound/Kconfig b/sound/Kconfig
index 4247406160e7..a37bee094eba 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -1,11 +1,9 @@
1# sound/Config.in 1# sound/Config.in
2# 2#
3 3
4menu "Sound" 4menuconfig SOUND
5 depends on HAS_IOMEM
6
7config SOUND
8 tristate "Sound card support" 5 tristate "Sound card support"
6 depends on HAS_IOMEM
9 help 7 help
10 If you have a sound card in your computer, i.e. if it can say more 8 If you have a sound card in your computer, i.e. if it can say more
11 than an occasional beep, say Y. Be sure to have all the information 9 than an occasional beep, say Y. Be sure to have all the information
@@ -28,22 +26,22 @@ config SOUND
28 and read <file:Documentation/sound/oss/README.modules>; the module 26 and read <file:Documentation/sound/oss/README.modules>; the module
29 will be called soundcore. 27 will be called soundcore.
30 28
29if SOUND
30
31source "sound/oss/dmasound/Kconfig" 31source "sound/oss/dmasound/Kconfig"
32 32
33if !M68K 33if !M68K
34 34
35menu "Advanced Linux Sound Architecture" 35menuconfig SND
36 depends on SOUND!=n
37
38config SND
39 tristate "Advanced Linux Sound Architecture" 36 tristate "Advanced Linux Sound Architecture"
40 depends on SOUND
41 help 37 help
42 Say 'Y' or 'M' to enable ALSA (Advanced Linux Sound Architecture), 38 Say 'Y' or 'M' to enable ALSA (Advanced Linux Sound Architecture),
43 the new base sound system. 39 the new base sound system.
44 40
45 For more information, see <http://www.alsa-project.org/> 41 For more information, see <http://www.alsa-project.org/>
46 42
43if SND
44
47source "sound/core/Kconfig" 45source "sound/core/Kconfig"
48 46
49source "sound/drivers/Kconfig" 47source "sound/drivers/Kconfig"
@@ -58,9 +56,7 @@ source "sound/aoa/Kconfig"
58 56
59source "sound/arm/Kconfig" 57source "sound/arm/Kconfig"
60 58
61if SPI
62source "sound/spi/Kconfig" 59source "sound/spi/Kconfig"
63endif
64 60
65source "sound/mips/Kconfig" 61source "sound/mips/Kconfig"
66 62
@@ -80,22 +76,20 @@ source "sound/parisc/Kconfig"
80 76
81source "sound/soc/Kconfig" 77source "sound/soc/Kconfig"
82 78
83endmenu 79endif # SND
84 80
85menu "Open Sound System" 81menuconfig SOUND_PRIME
86 depends on SOUND!=n
87
88config SOUND_PRIME
89 tristate "Open Sound System (DEPRECATED)" 82 tristate "Open Sound System (DEPRECATED)"
90 depends on SOUND
91 help 83 help
92 Say 'Y' or 'M' to enable Open Sound System drivers. 84 Say 'Y' or 'M' to enable Open Sound System drivers.
93 85
86if SOUND_PRIME
87
94source "sound/oss/Kconfig" 88source "sound/oss/Kconfig"
95 89
96endmenu 90endif # SOUND_PRIME
97 91
98endif 92endif # !M68K
99 93
100config AC97_BUS 94config AC97_BUS
101 tristate 95 tristate
@@ -105,4 +99,4 @@ config AC97_BUS
105 sound although they're sharing the AC97 bus. Concerned drivers 99 sound although they're sharing the AC97 bus. Concerned drivers
106 should "select" this. 100 should "select" this.
107 101
108endmenu 102endif # SOUND
diff --git a/sound/aoa/Kconfig b/sound/aoa/Kconfig
index 5d5813cec4c8..c081e18b9540 100644
--- a/sound/aoa/Kconfig
+++ b/sound/aoa/Kconfig
@@ -1,18 +1,17 @@
1menu "Apple Onboard Audio driver" 1menuconfig SND_AOA
2 depends on SND!=n && PPC_PMAC
3
4config SND_AOA
5 tristate "Apple Onboard Audio driver" 2 tristate "Apple Onboard Audio driver"
6 depends on SND 3 depends on PPC_PMAC
7 select SND_PCM 4 select SND_PCM
8 ---help--- 5 ---help---
9 This option enables the new driver for the various 6 This option enables the new driver for the various
10 Apple Onboard Audio components. 7 Apple Onboard Audio components.
11 8
9if SND_AOA
10
12source "sound/aoa/fabrics/Kconfig" 11source "sound/aoa/fabrics/Kconfig"
13 12
14source "sound/aoa/codecs/Kconfig" 13source "sound/aoa/codecs/Kconfig"
15 14
16source "sound/aoa/soundbus/Kconfig" 15source "sound/aoa/soundbus/Kconfig"
17 16
18endmenu 17endif # SND_AOA
diff --git a/sound/aoa/codecs/Kconfig b/sound/aoa/codecs/Kconfig
index d5fbd6016e93..808eb11ebacd 100644
--- a/sound/aoa/codecs/Kconfig
+++ b/sound/aoa/codecs/Kconfig
@@ -1,6 +1,5 @@
1config SND_AOA_ONYX 1config SND_AOA_ONYX
2 tristate "support Onyx chip" 2 tristate "support Onyx chip"
3 depends on SND_AOA
4 select I2C 3 select I2C
5 select I2C_POWERMAC 4 select I2C_POWERMAC
6 ---help--- 5 ---help---
@@ -10,7 +9,6 @@ config SND_AOA_ONYX
10 9
11#config SND_AOA_TOPAZ 10#config SND_AOA_TOPAZ
12# tristate "support Topaz chips" 11# tristate "support Topaz chips"
13# depends on SND_AOA
14# ---help--- 12# ---help---
15# This option enables support for the Topaz (CS84xx) 13# This option enables support for the Topaz (CS84xx)
16# codec chips found in the latest Apple machines, 14# codec chips found in the latest Apple machines,
@@ -19,7 +17,6 @@ config SND_AOA_ONYX
19 17
20config SND_AOA_TAS 18config SND_AOA_TAS
21 tristate "support TAS chips" 19 tristate "support TAS chips"
22 depends on SND_AOA
23 select I2C 20 select I2C
24 select I2C_POWERMAC 21 select I2C_POWERMAC
25 ---help--- 22 ---help---
@@ -29,7 +26,6 @@ config SND_AOA_TAS
29 26
30config SND_AOA_TOONIE 27config SND_AOA_TOONIE
31 tristate "support Toonie chip" 28 tristate "support Toonie chip"
32 depends on SND_AOA
33 ---help--- 29 ---help---
34 This option enables support for the toonie codec 30 This option enables support for the toonie codec
35 found in the Mac Mini. If you have a Mac Mini and 31 found in the Mac Mini. If you have a Mac Mini and
diff --git a/sound/aoa/fabrics/Kconfig b/sound/aoa/fabrics/Kconfig
index 50d7021ff677..3ca475a886b1 100644
--- a/sound/aoa/fabrics/Kconfig
+++ b/sound/aoa/fabrics/Kconfig
@@ -1,6 +1,5 @@
1config SND_AOA_FABRIC_LAYOUT 1config SND_AOA_FABRIC_LAYOUT
2 tristate "layout-id fabric" 2 tristate "layout-id fabric"
3 depends on SND_AOA
4 select SND_AOA_SOUNDBUS 3 select SND_AOA_SOUNDBUS
5 select SND_AOA_SOUNDBUS_I2S 4 select SND_AOA_SOUNDBUS_I2S
6 ---help--- 5 ---help---
diff --git a/sound/aoa/soundbus/Kconfig b/sound/aoa/soundbus/Kconfig
index 7368b7ddfe0d..839d1137b9b2 100644
--- a/sound/aoa/soundbus/Kconfig
+++ b/sound/aoa/soundbus/Kconfig
@@ -1,6 +1,5 @@
1config SND_AOA_SOUNDBUS 1config SND_AOA_SOUNDBUS
2 tristate "Apple Soundbus support" 2 tristate "Apple Soundbus support"
3 depends on SOUND
4 select SND_PCM 3 select SND_PCM
5 ---help--- 4 ---help---
6 This option enables the generic driver for the soundbus 5 This option enables the generic driver for the soundbus
diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig
index 2e4a5e0d16db..351e19ea3785 100644
--- a/sound/arm/Kconfig
+++ b/sound/arm/Kconfig
@@ -1,11 +1,19 @@
1# ALSA ARM drivers 1# ALSA ARM drivers
2 2
3menu "ALSA ARM devices" 3menuconfig SND_ARM
4 depends on SND!=n && ARM 4 bool "ARM sound devices"
5 depends on ARM
6 default y
7 help
8 Support for sound devices specific to ARM architectures.
9 Drivers that are implemented on ASoC can be found in
10 "ALSA for SoC audio support" section.
11
12if SND_ARM
5 13
6config SND_SA11XX_UDA1341 14config SND_SA11XX_UDA1341
7 tristate "SA11xx UDA1341TS driver (iPaq H3600)" 15 tristate "SA11xx UDA1341TS driver (iPaq H3600)"
8 depends on ARCH_SA1100 && SND && L3 16 depends on ARCH_SA1100 && L3
9 select SND_PCM 17 select SND_PCM
10 help 18 help
11 Say Y here if you have a Compaq iPaq H3x00 handheld computer 19 Say Y here if you have a Compaq iPaq H3x00 handheld computer
@@ -16,7 +24,7 @@ config SND_SA11XX_UDA1341
16 24
17config SND_ARMAACI 25config SND_ARMAACI
18 tristate "ARM PrimeCell PL041 AC Link support" 26 tristate "ARM PrimeCell PL041 AC Link support"
19 depends on SND && ARM_AMBA 27 depends on ARM_AMBA
20 select SND_PCM 28 select SND_PCM
21 select SND_AC97_CODEC 29 select SND_AC97_CODEC
22 30
@@ -26,11 +34,12 @@ config SND_PXA2XX_PCM
26 34
27config SND_PXA2XX_AC97 35config SND_PXA2XX_AC97
28 tristate "AC97 driver for the Intel PXA2xx chip" 36 tristate "AC97 driver for the Intel PXA2xx chip"
29 depends on ARCH_PXA && SND 37 depends on ARCH_PXA
30 select SND_PXA2XX_PCM 38 select SND_PXA2XX_PCM
31 select SND_AC97_CODEC 39 select SND_AC97_CODEC
32 help 40 help
33 Say Y or M if you want to support any AC97 codec attached to 41 Say Y or M if you want to support any AC97 codec attached to
34 the PXA2xx AC97 interface. 42 the PXA2xx AC97 interface.
35 43
36endmenu 44endif # SND_ARM
45
diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c
index 0eff33ca0f79..faeddf3ecedb 100644
--- a/sound/arm/sa11xx-uda1341.c
+++ b/sound/arm/sa11xx-uda1341.c
@@ -21,8 +21,6 @@
21 * merged HAL layer (patches from Brian) 21 * merged HAL layer (patches from Brian)
22 */ 22 */
23 23
24/* $Id: sa11xx-uda1341.c,v 1.27 2005/12/07 09:13:42 cladisch Exp $ */
25
26/*************************************************************************************************** 24/***************************************************************************************************
27* 25*
28* To understand what Alsa Drivers should be doing look at "Writing an Alsa Driver" by Takashi Iwai 26* To understand what Alsa Drivers should be doing look at "Writing an Alsa Driver" by Takashi Iwai
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index a8d71c6c8e75..335d45ecde6a 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -1,24 +1,19 @@
1# ALSA soundcard-configuration 1# ALSA soundcard-configuration
2config SND_TIMER 2config SND_TIMER
3 tristate 3 tristate
4 depends on SND
5 4
6config SND_PCM 5config SND_PCM
7 tristate 6 tristate
8 select SND_TIMER 7 select SND_TIMER
9 depends on SND
10 8
11config SND_HWDEP 9config SND_HWDEP
12 tristate 10 tristate
13 depends on SND
14 11
15config SND_RAWMIDI 12config SND_RAWMIDI
16 tristate 13 tristate
17 depends on SND
18 14
19config SND_SEQUENCER 15config SND_SEQUENCER
20 tristate "Sequencer support" 16 tristate "Sequencer support"
21 depends on SND
22 select SND_TIMER 17 select SND_TIMER
23 help 18 help
24 Say Y or M to enable MIDI sequencer and router support. This 19 Say Y or M to enable MIDI sequencer and router support. This
@@ -44,11 +39,9 @@ config SND_SEQ_DUMMY
44 39
45config SND_OSSEMUL 40config SND_OSSEMUL
46 bool 41 bool
47 depends on SND
48 42
49config SND_MIXER_OSS 43config SND_MIXER_OSS
50 tristate "OSS Mixer API" 44 tristate "OSS Mixer API"
51 depends on SND
52 select SND_OSSEMUL 45 select SND_OSSEMUL
53 help 46 help
54 To enable OSS mixer API emulation (/dev/mixer*), say Y here 47 To enable OSS mixer API emulation (/dev/mixer*), say Y here
@@ -61,7 +54,6 @@ config SND_MIXER_OSS
61 54
62config SND_PCM_OSS 55config SND_PCM_OSS
63 tristate "OSS PCM (digital audio) API" 56 tristate "OSS PCM (digital audio) API"
64 depends on SND
65 select SND_OSSEMUL 57 select SND_OSSEMUL
66 select SND_PCM 58 select SND_PCM
67 help 59 help
@@ -84,7 +76,7 @@ config SND_PCM_OSS_PLUGINS
84 76
85config SND_SEQUENCER_OSS 77config SND_SEQUENCER_OSS
86 bool "OSS Sequencer API" 78 bool "OSS Sequencer API"
87 depends on SND && SND_SEQUENCER 79 depends on SND_SEQUENCER
88 select SND_OSSEMUL 80 select SND_OSSEMUL
89 help 81 help
90 Say Y here to enable OSS sequencer emulation (both 82 Say Y here to enable OSS sequencer emulation (both
@@ -98,7 +90,7 @@ config SND_SEQUENCER_OSS
98 90
99config SND_RTCTIMER 91config SND_RTCTIMER
100 tristate "RTC Timer support" 92 tristate "RTC Timer support"
101 depends on SND && RTC 93 depends on RTC
102 select SND_TIMER 94 select SND_TIMER
103 help 95 help
104 Say Y here to enable RTC timer support for ALSA. ALSA uses 96 Say Y here to enable RTC timer support for ALSA. ALSA uses
@@ -123,7 +115,6 @@ config SND_SEQ_RTCTIMER_DEFAULT
123 115
124config SND_DYNAMIC_MINORS 116config SND_DYNAMIC_MINORS
125 bool "Dynamic device file minor numbers" 117 bool "Dynamic device file minor numbers"
126 depends on SND
127 help 118 help
128 If you say Y here, the minor numbers of ALSA device files in 119 If you say Y here, the minor numbers of ALSA device files in
129 /dev/snd/ are allocated dynamically. This allows you to have 120 /dev/snd/ are allocated dynamically. This allows you to have
@@ -134,7 +125,6 @@ config SND_DYNAMIC_MINORS
134 125
135config SND_SUPPORT_OLD_API 126config SND_SUPPORT_OLD_API
136 bool "Support old ALSA API" 127 bool "Support old ALSA API"
137 depends on SND
138 default y 128 default y
139 help 129 help
140 Say Y here to support the obsolete ALSA PCM API (ver.0.9.0 rc3 130 Say Y here to support the obsolete ALSA PCM API (ver.0.9.0 rc3
@@ -142,7 +132,7 @@ config SND_SUPPORT_OLD_API
142 132
143config SND_VERBOSE_PROCFS 133config SND_VERBOSE_PROCFS
144 bool "Verbose procfs contents" 134 bool "Verbose procfs contents"
145 depends on SND && PROC_FS 135 depends on PROC_FS
146 default y 136 default y
147 help 137 help
148 Say Y here to include code for verbose procfs contents (provides 138 Say Y here to include code for verbose procfs contents (provides
@@ -151,7 +141,6 @@ config SND_VERBOSE_PROCFS
151 141
152config SND_VERBOSE_PRINTK 142config SND_VERBOSE_PRINTK
153 bool "Verbose printk" 143 bool "Verbose printk"
154 depends on SND
155 help 144 help
156 Say Y here to enable verbose log messages. These messages 145 Say Y here to enable verbose log messages. These messages
157 will help to identify source file and position containing 146 will help to identify source file and position containing
@@ -161,16 +150,17 @@ config SND_VERBOSE_PRINTK
161 150
162config SND_DEBUG 151config SND_DEBUG
163 bool "Debug" 152 bool "Debug"
164 depends on SND
165 help 153 help
166 Say Y here to enable ALSA debug code. 154 Say Y here to enable ALSA debug code.
167 155
168config SND_DEBUG_DETECT 156config SND_DEBUG_VERBOSE
169 bool "Debug detection" 157 bool "More verbose debug"
170 depends on SND_DEBUG 158 depends on SND_DEBUG
171 help 159 help
172 Say Y here to enable extra-verbose log messages printed when 160 Say Y here to enable extra-verbose debugging messages.
173 detecting devices. 161
162 Let me repeat: it enables EXTRA-VERBOSE DEBUGGING messages.
163 So, say Y only if you are ready to be annoyed.
174 164
175config SND_PCM_XRUN_DEBUG 165config SND_PCM_XRUN_DEBUG
176 bool "Enable PCM ring buffer overrun/underrun debugging" 166 bool "Enable PCM ring buffer overrun/underrun debugging"
@@ -184,4 +174,3 @@ config SND_PCM_XRUN_DEBUG
184 174
185config SND_VMASTER 175config SND_VMASTER
186 bool 176 bool
187 depends on SND
diff --git a/sound/core/control.c b/sound/core/control.c
index 01a1a5af47bb..281b2e2ef0ea 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -684,7 +684,8 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
684 return result; 684 return result;
685} 685}
686 686
687int snd_ctl_elem_read(struct snd_card *card, struct snd_ctl_elem_value *control) 687static int snd_ctl_elem_read(struct snd_card *card,
688 struct snd_ctl_elem_value *control)
688{ 689{
689 struct snd_kcontrol *kctl; 690 struct snd_kcontrol *kctl;
690 struct snd_kcontrol_volatile *vd; 691 struct snd_kcontrol_volatile *vd;
@@ -734,8 +735,8 @@ static int snd_ctl_elem_read_user(struct snd_card *card,
734 return result; 735 return result;
735} 736}
736 737
737int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, 738static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
738 struct snd_ctl_elem_value *control) 739 struct snd_ctl_elem_value *control)
739{ 740{
740 struct snd_kcontrol *kctl; 741 struct snd_kcontrol *kctl;
741 struct snd_kcontrol_volatile *vd; 742 struct snd_kcontrol_volatile *vd;
diff --git a/sound/core/init.c b/sound/core/init.c
index ac0573416130..5c254d498ae0 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -46,17 +46,24 @@ static char *slots[SNDRV_CARDS];
46module_param_array(slots, charp, NULL, 0444); 46module_param_array(slots, charp, NULL, 0444);
47MODULE_PARM_DESC(slots, "Module names assigned to the slots."); 47MODULE_PARM_DESC(slots, "Module names assigned to the slots.");
48 48
49/* return non-zero if the given index is already reserved for another 49/* return non-zero if the given index is reserved for the given
50 * module via slots option 50 * module via slots option
51 */ 51 */
52static int module_slot_mismatch(struct module *module, int idx) 52static int module_slot_match(struct module *module, int idx)
53{ 53{
54 int match = 1;
54#ifdef MODULE 55#ifdef MODULE
55 char *s1, *s2; 56 const char *s1, *s2;
57
56 if (!module || !module->name || !slots[idx]) 58 if (!module || !module->name || !slots[idx])
57 return 0; 59 return 0;
58 s1 = slots[idx]; 60
59 s2 = module->name; 61 s1 = module->name;
62 s2 = slots[idx];
63 if (*s2 == '!') {
64 match = 0; /* negative match */
65 s2++;
66 }
60 /* compare module name strings 67 /* compare module name strings
61 * hyphens are handled as equivalent with underscore 68 * hyphens are handled as equivalent with underscore
62 */ 69 */
@@ -68,12 +75,12 @@ static int module_slot_mismatch(struct module *module, int idx)
68 if (c2 == '-') 75 if (c2 == '-')
69 c2 = '_'; 76 c2 = '_';
70 if (c1 != c2) 77 if (c1 != c2)
71 return 1; 78 return !match;
72 if (!c1) 79 if (!c1)
73 break; 80 break;
74 } 81 }
75#endif 82#endif /* MODULE */
76 return 0; 83 return match;
77} 84}
78 85
79#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 86#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
@@ -129,7 +136,7 @@ struct snd_card *snd_card_new(int idx, const char *xid,
129 struct module *module, int extra_size) 136 struct module *module, int extra_size)
130{ 137{
131 struct snd_card *card; 138 struct snd_card *card;
132 int err; 139 int err, idx2;
133 140
134 if (extra_size < 0) 141 if (extra_size < 0)
135 extra_size = 0; 142 extra_size = 0;
@@ -144,35 +151,41 @@ struct snd_card *snd_card_new(int idx, const char *xid,
144 err = 0; 151 err = 0;
145 mutex_lock(&snd_card_mutex); 152 mutex_lock(&snd_card_mutex);
146 if (idx < 0) { 153 if (idx < 0) {
147 int idx2;
148 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) 154 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
149 /* idx == -1 == 0xffff means: take any free slot */ 155 /* idx == -1 == 0xffff means: take any free slot */
150 if (~snd_cards_lock & idx & 1<<idx2) { 156 if (~snd_cards_lock & idx & 1<<idx2) {
151 if (module_slot_mismatch(module, idx2)) 157 if (module_slot_match(module, idx2)) {
152 continue; 158 idx = idx2;
153 idx = idx2; 159 break;
154 if (idx >= snd_ecards_limit) 160 }
155 snd_ecards_limit = idx + 1; 161 }
156 break; 162 }
163 if (idx < 0) {
164 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
165 /* idx == -1 == 0xffff means: take any free slot */
166 if (~snd_cards_lock & idx & 1<<idx2) {
167 if (!slots[idx2] || !*slots[idx2]) {
168 idx = idx2;
169 break;
170 }
157 } 171 }
158 } else {
159 if (idx < snd_ecards_limit) {
160 if (snd_cards_lock & (1 << idx))
161 err = -EBUSY; /* invalid */
162 } else {
163 if (idx < SNDRV_CARDS)
164 snd_ecards_limit = idx + 1; /* increase the limit */
165 else
166 err = -ENODEV;
167 }
168 } 172 }
169 if (idx < 0 || err < 0) { 173 if (idx < 0)
174 err = -ENODEV;
175 else if (idx < snd_ecards_limit) {
176 if (snd_cards_lock & (1 << idx))
177 err = -EBUSY; /* invalid */
178 } else if (idx >= SNDRV_CARDS)
179 err = -ENODEV;
180 if (err < 0) {
170 mutex_unlock(&snd_card_mutex); 181 mutex_unlock(&snd_card_mutex);
171 snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i), error: %d\n", 182 snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i), error: %d\n",
172 idx, snd_ecards_limit - 1, err); 183 idx, snd_ecards_limit - 1, err);
173 goto __error; 184 goto __error;
174 } 185 }
175 snd_cards_lock |= 1 << idx; /* lock it */ 186 snd_cards_lock |= 1 << idx; /* lock it */
187 if (idx >= snd_ecards_limit)
188 snd_ecards_limit = idx + 1; /* increase the limit */
176 mutex_unlock(&snd_card_mutex); 189 mutex_unlock(&snd_card_mutex);
177 card->number = idx; 190 card->number = idx;
178 card->module = module; 191 card->module = module;
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 23b7bc02728b..f5d6d8d12979 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -80,68 +80,6 @@ struct snd_mem_list {
80#endif 80#endif
81 81
82/* 82/*
83 * Hacks
84 */
85
86#if defined(__i386__)
87/*
88 * A hack to allocate large buffers via dma_alloc_coherent()
89 *
90 * since dma_alloc_coherent always tries GFP_DMA when the requested
91 * pci memory region is below 32bit, it happens quite often that even
92 * 2 order of pages cannot be allocated.
93 *
94 * so in the following, we allocate at first without dma_mask, so that
95 * allocation will be done without GFP_DMA. if the area doesn't match
96 * with the requested region, then realloate with the original dma_mask
97 * again.
98 *
99 * Really, we want to move this type of thing into dma_alloc_coherent()
100 * so dma_mask doesn't have to be messed with.
101 */
102
103static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size,
104 dma_addr_t *dma_handle,
105 gfp_t flags)
106{
107 void *ret;
108 u64 dma_mask, coherent_dma_mask;
109
110 if (dev == NULL || !dev->dma_mask)
111 return dma_alloc_coherent(dev, size, dma_handle, flags);
112 dma_mask = *dev->dma_mask;
113 coherent_dma_mask = dev->coherent_dma_mask;
114 *dev->dma_mask = 0xffffffff; /* do without masking */
115 dev->coherent_dma_mask = 0xffffffff; /* do without masking */
116 ret = dma_alloc_coherent(dev, size, dma_handle, flags);
117 *dev->dma_mask = dma_mask; /* restore */
118 dev->coherent_dma_mask = coherent_dma_mask; /* restore */
119 if (ret) {
120 /* obtained address is out of range? */
121 if (((unsigned long)*dma_handle + size - 1) & ~dma_mask) {
122 /* reallocate with the proper mask */
123 dma_free_coherent(dev, size, ret, *dma_handle);
124 ret = dma_alloc_coherent(dev, size, dma_handle, flags);
125 }
126 } else {
127 /* wish to success now with the proper mask... */
128 if (dma_mask != 0xffffffffUL) {
129 /* allocation with GFP_ATOMIC to avoid the long stall */
130 flags &= ~GFP_KERNEL;
131 flags |= GFP_ATOMIC;
132 ret = dma_alloc_coherent(dev, size, dma_handle, flags);
133 }
134 }
135 return ret;
136}
137
138/* redefine dma_alloc_coherent for some architectures */
139#undef dma_alloc_coherent
140#define dma_alloc_coherent snd_dma_hack_alloc_coherent
141
142#endif /* arch */
143
144/*
145 * 83 *
146 * Generic memory allocators 84 * Generic memory allocators
147 * 85 *
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 47cfa5186e34..7a1545d2d953 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -148,7 +148,7 @@ struct snd_seq_client *snd_seq_client_use_ptr(int clientid)
148 return NULL; 148 return NULL;
149 } 149 }
150 spin_unlock_irqrestore(&clients_lock, flags); 150 spin_unlock_irqrestore(&clients_lock, flags);
151#ifdef CONFIG_KMOD 151#ifdef CONFIG_MODULES
152 if (!in_interrupt()) { 152 if (!in_interrupt()) {
153 static char client_requested[SNDRV_SEQ_GLOBAL_CLIENTS]; 153 static char client_requested[SNDRV_SEQ_GLOBAL_CLIENTS];
154 static char card_requested[SNDRV_CARDS]; 154 static char card_requested[SNDRV_CARDS];
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c
index 2f00ad28a2b7..05410e536a4f 100644
--- a/sound/core/seq/seq_device.c
+++ b/sound/core/seq/seq_device.c
@@ -124,7 +124,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry,
124 * load all registered drivers (called from seq_clientmgr.c) 124 * load all registered drivers (called from seq_clientmgr.c)
125 */ 125 */
126 126
127#ifdef CONFIG_KMOD 127#ifdef CONFIG_MODULES
128/* avoid auto-loading during module_init() */ 128/* avoid auto-loading during module_init() */
129static int snd_seq_in_init; 129static int snd_seq_in_init;
130void snd_seq_autoload_lock(void) 130void snd_seq_autoload_lock(void)
@@ -140,7 +140,7 @@ void snd_seq_autoload_unlock(void)
140 140
141void snd_seq_device_load_drivers(void) 141void snd_seq_device_load_drivers(void)
142{ 142{
143#ifdef CONFIG_KMOD 143#ifdef CONFIG_MODULES
144 struct ops_list *ops; 144 struct ops_list *ops;
145 145
146 /* Calling request_module during module_init() 146 /* Calling request_module during module_init()
@@ -566,7 +566,5 @@ EXPORT_SYMBOL(snd_seq_device_load_drivers);
566EXPORT_SYMBOL(snd_seq_device_new); 566EXPORT_SYMBOL(snd_seq_device_new);
567EXPORT_SYMBOL(snd_seq_device_register_driver); 567EXPORT_SYMBOL(snd_seq_device_register_driver);
568EXPORT_SYMBOL(snd_seq_device_unregister_driver); 568EXPORT_SYMBOL(snd_seq_device_unregister_driver);
569#ifdef CONFIG_KMOD
570EXPORT_SYMBOL(snd_seq_autoload_lock); 569EXPORT_SYMBOL(snd_seq_autoload_lock);
571EXPORT_SYMBOL(snd_seq_autoload_unlock); 570EXPORT_SYMBOL(snd_seq_autoload_unlock);
572#endif
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 6c8ab48c689a..09a94953745a 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -60,14 +60,14 @@ EXPORT_SYMBOL(snd_ecards_limit);
60static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; 60static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
61static DEFINE_MUTEX(sound_mutex); 61static DEFINE_MUTEX(sound_mutex);
62 62
63#ifdef CONFIG_KMOD 63#ifdef CONFIG_MODULES
64 64
65/** 65/**
66 * snd_request_card - try to load the card module 66 * snd_request_card - try to load the card module
67 * @card: the card number 67 * @card: the card number
68 * 68 *
69 * Tries to load the module "snd-card-X" for the given card number 69 * Tries to load the module "snd-card-X" for the given card number
70 * via KMOD. Returns immediately if already loaded. 70 * via request_module. Returns immediately if already loaded.
71 */ 71 */
72void snd_request_card(int card) 72void snd_request_card(int card)
73{ 73{
@@ -92,7 +92,7 @@ static void snd_request_other(int minor)
92 request_module(str); 92 request_module(str);
93} 93}
94 94
95#endif /* request_module support */ 95#endif /* modular kernel */
96 96
97/** 97/**
98 * snd_lookup_minor_data - get user data of a registered device 98 * snd_lookup_minor_data - get user data of a registered device
@@ -132,7 +132,7 @@ static int snd_open(struct inode *inode, struct file *file)
132 return -ENODEV; 132 return -ENODEV;
133 mptr = snd_minors[minor]; 133 mptr = snd_minors[minor];
134 if (mptr == NULL) { 134 if (mptr == NULL) {
135#ifdef CONFIG_KMOD 135#ifdef CONFIG_MODULES
136 int dev = SNDRV_MINOR_DEVICE(minor); 136 int dev = SNDRV_MINOR_DEVICE(minor);
137 if (dev == SNDRV_MINOR_CONTROL) { 137 if (dev == SNDRV_MINOR_CONTROL) {
138 /* /dev/aloadC? */ 138 /* /dev/aloadC? */
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 9d8184a2c2d0..0af337efc64e 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -146,7 +146,7 @@ static struct snd_timer *snd_timer_find(struct snd_timer_id *tid)
146 return NULL; 146 return NULL;
147} 147}
148 148
149#ifdef CONFIG_KMOD 149#ifdef CONFIG_MODULES
150 150
151static void snd_timer_request(struct snd_timer_id *tid) 151static void snd_timer_request(struct snd_timer_id *tid)
152{ 152{
@@ -259,8 +259,8 @@ int snd_timer_open(struct snd_timer_instance **ti,
259 /* open a master instance */ 259 /* open a master instance */
260 mutex_lock(&register_mutex); 260 mutex_lock(&register_mutex);
261 timer = snd_timer_find(tid); 261 timer = snd_timer_find(tid);
262#ifdef CONFIG_KMOD 262#ifdef CONFIG_MODULES
263 if (timer == NULL) { 263 if (!timer) {
264 mutex_unlock(&register_mutex); 264 mutex_unlock(&register_mutex);
265 snd_timer_request(tid); 265 snd_timer_request(tid);
266 mutex_lock(&register_mutex); 266 mutex_lock(&register_mutex);
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index 602b58e3b55d..255fd18b9aec 100644
--- a/sound/drivers/Kconfig
+++ b/sound/drivers/Kconfig
@@ -1,15 +1,41 @@
1# ALSA generic drivers 1config SND_MPU401_UART
2 tristate
3 select SND_RAWMIDI
2 4
3menu "Generic devices" 5config SND_OPL3_LIB
4 depends on SND!=n 6 tristate
7 select SND_TIMER
8 select SND_HWDEP
5 9
10config SND_OPL4_LIB
11 tristate
12 select SND_TIMER
13 select SND_HWDEP
14
15config SND_VX_LIB
16 tristate
17 select SND_HWDEP
18 select SND_PCM
19
20config SND_AC97_CODEC
21 tristate
22 select SND_PCM
23 select AC97_BUS
24 select SND_VMASTER
25
26menuconfig SND_DRIVERS
27 bool "Generic sound devices"
28 default y
29 help
30 Support for generic sound devices.
31
32if SND_DRIVERS
6 33
7config SND_PCSP 34config SND_PCSP
8 tristate "PC-Speaker support (READ HELP!)" 35 tristate "PC-Speaker support (READ HELP!)"
9 depends on PCSPKR_PLATFORM && X86_PC && HIGH_RES_TIMERS 36 depends on PCSPKR_PLATFORM && X86_PC && HIGH_RES_TIMERS
10 depends on INPUT 37 depends on INPUT
11 depends on EXPERIMENTAL 38 depends on EXPERIMENTAL
12 depends on SND
13 select SND_PCM 39 select SND_PCM
14 help 40 help
15 If you don't have a sound card in your computer, you can include a 41 If you don't have a sound card in your computer, you can include a
@@ -35,33 +61,8 @@ config SND_PCSP
35 Say M if you don't. 61 Say M if you don't.
36 Say Y only if you really know what you do. 62 Say Y only if you really know what you do.
37 63
38config SND_MPU401_UART
39 tristate
40 select SND_RAWMIDI
41
42config SND_OPL3_LIB
43 tristate
44 select SND_TIMER
45 select SND_HWDEP
46
47config SND_OPL4_LIB
48 tristate
49 select SND_TIMER
50 select SND_HWDEP
51
52config SND_VX_LIB
53 tristate
54 select SND_HWDEP
55 select SND_PCM
56
57config SND_AC97_CODEC
58 tristate
59 select SND_PCM
60 select AC97_BUS
61
62config SND_DUMMY 64config SND_DUMMY
63 tristate "Dummy (/dev/null) soundcard" 65 tristate "Dummy (/dev/null) soundcard"
64 depends on SND
65 select SND_PCM 66 select SND_PCM
66 help 67 help
67 Say Y here to include the dummy driver. This driver does 68 Say Y here to include the dummy driver. This driver does
@@ -90,7 +91,6 @@ config SND_VIRMIDI
90 91
91config SND_MTPAV 92config SND_MTPAV
92 tristate "MOTU MidiTimePiece AV multiport MIDI" 93 tristate "MOTU MidiTimePiece AV multiport MIDI"
93 depends on SND
94 select SND_RAWMIDI 94 select SND_RAWMIDI
95 help 95 help
96 To use a MOTU MidiTimePiece AV multiport MIDI adapter 96 To use a MOTU MidiTimePiece AV multiport MIDI adapter
@@ -102,7 +102,7 @@ config SND_MTPAV
102 102
103config SND_MTS64 103config SND_MTS64
104 tristate "ESI Miditerminal 4140 driver" 104 tristate "ESI Miditerminal 4140 driver"
105 depends on SND && PARPORT 105 depends on PARPORT
106 select SND_RAWMIDI 106 select SND_RAWMIDI
107 help 107 help
108 The ESI Miditerminal 4140 is a 4 In 4 Out MIDI Interface with 108 The ESI Miditerminal 4140 is a 4 In 4 Out MIDI Interface with
@@ -115,7 +115,6 @@ config SND_MTS64
115 115
116config SND_SERIAL_U16550 116config SND_SERIAL_U16550
117 tristate "UART16550 serial MIDI driver" 117 tristate "UART16550 serial MIDI driver"
118 depends on SND
119 select SND_RAWMIDI 118 select SND_RAWMIDI
120 help 119 help
121 To include support for MIDI serial port interfaces, say Y here 120 To include support for MIDI serial port interfaces, say Y here
@@ -131,7 +130,6 @@ config SND_SERIAL_U16550
131 130
132config SND_MPU401 131config SND_MPU401
133 tristate "Generic MPU-401 UART driver" 132 tristate "Generic MPU-401 UART driver"
134 depends on SND
135 select SND_MPU401_UART 133 select SND_MPU401_UART
136 help 134 help
137 Say Y here to include support for MIDI ports compatible with 135 Say Y here to include support for MIDI ports compatible with
@@ -142,7 +140,7 @@ config SND_MPU401
142 140
143config SND_PORTMAN2X4 141config SND_PORTMAN2X4
144 tristate "Portman 2x4 driver" 142 tristate "Portman 2x4 driver"
145 depends on SND && PARPORT 143 depends on PARPORT
146 select SND_RAWMIDI 144 select SND_RAWMIDI
147 help 145 help
148 Say Y here to include support for Midiman Portman 2x4 parallel 146 Say Y here to include support for Midiman Portman 2x4 parallel
@@ -153,7 +151,7 @@ config SND_PORTMAN2X4
153 151
154config SND_ML403_AC97CR 152config SND_ML403_AC97CR
155 tristate "Xilinx ML403 AC97 Controller Reference" 153 tristate "Xilinx ML403 AC97 Controller Reference"
156 depends on SND && XILINX_VIRTEX 154 depends on XILINX_VIRTEX
157 select SND_AC97_CODEC 155 select SND_AC97_CODEC
158 help 156 help
159 Say Y here to include support for the 157 Say Y here to include support for the
@@ -163,4 +161,25 @@ config SND_ML403_AC97CR
163 To compile this driver as a module, choose M here: the module 161 To compile this driver as a module, choose M here: the module
164 will be called snd-ml403_ac97cr. 162 will be called snd-ml403_ac97cr.
165 163
166endmenu 164config SND_AC97_POWER_SAVE
165 bool "AC97 Power-Saving Mode"
166 depends on SND_AC97_CODEC && EXPERIMENTAL
167 default n
168 help
169 Say Y here to enable the aggressive power-saving support of
170 AC97 codecs. In this mode, the power-mode is dynamically
171 controlled at each open/close.
172
173 The mode is activated by passing power_save=1 option to
174 snd-ac97-codec driver. You can toggle it dynamically over
175 sysfs, too.
176
177config SND_AC97_POWER_SAVE_DEFAULT
178 int "Default time-out for AC97 power-save mode"
179 depends on SND_AC97_POWER_SAVE
180 default 0
181 help
182 The default time-out value in seconds for AC97 automatic
183 power-save mode. 0 means to disable the power-save mode.
184
185endif # SND_DRIVERS
diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c
index 1dfe6948e6ff..efd22e92bced 100644
--- a/sound/drivers/vx/vx_hwdep.c
+++ b/sound/drivers/vx/vx_hwdep.c
@@ -183,7 +183,7 @@ static int vx_hwdep_dsp_load(struct snd_hwdep *hw,
183 kfree(fw); 183 kfree(fw);
184 return -ENOMEM; 184 return -ENOMEM;
185 } 185 }
186 if (copy_from_user(fw->data, dsp->image, dsp->length)) { 186 if (copy_from_user((void *)fw->data, dsp->image, dsp->length)) {
187 free_fw(fw); 187 free_fw(fw);
188 return -EFAULT; 188 return -EFAULT;
189 } 189 }
diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c
index e57e9cbe6a0f..9c3d361accfb 100644
--- a/sound/i2c/cs8427.c
+++ b/sound/i2c/cs8427.c
@@ -23,6 +23,7 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/init.h> 25#include <linux/init.h>
26#include <asm/unaligned.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/control.h> 28#include <sound/control.h>
28#include <sound/pcm.h> 29#include <sound/pcm.h>
@@ -264,10 +265,7 @@ int snd_cs8427_create(struct snd_i2c_bus *bus,
264 goto __fail; 265 goto __fail;
265 } 266 }
266 /* write default channel status bytes */ 267 /* write default channel status bytes */
267 buf[0] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 0)); 268 put_unaligned_le32(SNDRV_PCM_DEFAULT_CON_SPDIF, buf);
268 buf[1] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 8));
269 buf[2] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 16));
270 buf[3] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 24));
271 memset(buf + 4, 0, 24 - 4); 269 memset(buf + 4, 0, 24 - 4);
272 if (snd_cs8427_send_corudata(device, 0, buf, 24) < 0) 270 if (snd_cs8427_send_corudata(device, 0, buf, 24) < 0)
273 goto __fail; 271 goto __fail;
diff --git a/sound/i2c/l3/uda1341.c b/sound/i2c/l3/uda1341.c
index bfa5d2c3608b..1f4942ea1414 100644
--- a/sound/i2c/l3/uda1341.c
+++ b/sound/i2c/l3/uda1341.c
@@ -17,8 +17,6 @@
17 * 2002-05-12 Tomas Kasparek another code cleanup 17 * 2002-05-12 Tomas Kasparek another code cleanup
18 */ 18 */
19 19
20/* $Id: uda1341.c,v 1.18 2005/11/17 14:17:21 tiwai Exp $ */
21
22#include <linux/module.h> 20#include <linux/module.h>
23#include <linux/init.h> 21#include <linux/init.h>
24#include <linux/types.h> 22#include <linux/types.h>
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 2639a6ab8f2e..25347a25d63c 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -21,12 +21,17 @@ config SND_SB16_DSP
21 select SND_PCM 21 select SND_PCM
22 select SND_SB_COMMON 22 select SND_SB_COMMON
23 23
24menu "ISA devices" 24menuconfig SND_ISA
25 depends on SND!=n && ISA && ISA_DMA_API 25 bool "ISA sound devices"
26 depends on ISA && ISA_DMA_API
27 default y
28 help
29 Support for sound devices connected via the ISA bus.
30
31if SND_ISA
26 32
27config SND_ADLIB 33config SND_ADLIB
28 tristate "AdLib FM card" 34 tristate "AdLib FM card"
29 depends on SND
30 select SND_OPL3_LIB 35 select SND_OPL3_LIB
31 help 36 help
32 Say Y here to include support for AdLib FM cards. 37 Say Y here to include support for AdLib FM cards.
@@ -36,7 +41,7 @@ config SND_ADLIB
36 41
37config SND_AD1816A 42config SND_AD1816A
38 tristate "Analog Devices SoundPort AD1816A" 43 tristate "Analog Devices SoundPort AD1816A"
39 depends on SND && PNP && ISA 44 depends on PNP
40 select ISAPNP 45 select ISAPNP
41 select SND_OPL3_LIB 46 select SND_OPL3_LIB
42 select SND_MPU401_UART 47 select SND_MPU401_UART
@@ -50,7 +55,6 @@ config SND_AD1816A
50 55
51config SND_AD1848 56config SND_AD1848
52 tristate "Generic AD1848/CS4248 driver" 57 tristate "Generic AD1848/CS4248 driver"
53 depends on SND
54 select SND_AD1848_LIB 58 select SND_AD1848_LIB
55 help 59 help
56 Say Y here to include support for AD1848 (Analog Devices) or 60 Say Y here to include support for AD1848 (Analog Devices) or
@@ -64,7 +68,7 @@ config SND_AD1848
64 68
65config SND_ALS100 69config SND_ALS100
66 tristate "Avance Logic ALS100/ALS120" 70 tristate "Avance Logic ALS100/ALS120"
67 depends on SND && PNP && ISA 71 depends on PNP
68 select ISAPNP 72 select ISAPNP
69 select SND_OPL3_LIB 73 select SND_OPL3_LIB
70 select SND_MPU401_UART 74 select SND_MPU401_UART
@@ -78,7 +82,7 @@ config SND_ALS100
78 82
79config SND_AZT2320 83config SND_AZT2320
80 tristate "Aztech Systems AZT2320" 84 tristate "Aztech Systems AZT2320"
81 depends on SND && PNP && ISA 85 depends on PNP
82 select ISAPNP 86 select ISAPNP
83 select SND_OPL3_LIB 87 select SND_OPL3_LIB
84 select SND_MPU401_UART 88 select SND_MPU401_UART
@@ -92,7 +96,6 @@ config SND_AZT2320
92 96
93config SND_CMI8330 97config SND_CMI8330
94 tristate "C-Media CMI8330" 98 tristate "C-Media CMI8330"
95 depends on SND
96 select SND_AD1848_LIB 99 select SND_AD1848_LIB
97 select SND_SB16_DSP 100 select SND_SB16_DSP
98 help 101 help
@@ -104,7 +107,6 @@ config SND_CMI8330
104 107
105config SND_CS4231 108config SND_CS4231
106 tristate "Generic Cirrus Logic CS4231 driver" 109 tristate "Generic Cirrus Logic CS4231 driver"
107 depends on SND
108 select SND_MPU401_UART 110 select SND_MPU401_UART
109 select SND_CS4231_LIB 111 select SND_CS4231_LIB
110 help 112 help
@@ -116,7 +118,6 @@ config SND_CS4231
116 118
117config SND_CS4232 119config SND_CS4232
118 tristate "Generic Cirrus Logic CS4232 driver" 120 tristate "Generic Cirrus Logic CS4232 driver"
119 depends on SND
120 select SND_OPL3_LIB 121 select SND_OPL3_LIB
121 select SND_MPU401_UART 122 select SND_MPU401_UART
122 select SND_CS4231_LIB 123 select SND_CS4231_LIB
@@ -129,7 +130,6 @@ config SND_CS4232
129 130
130config SND_CS4236 131config SND_CS4236
131 tristate "Generic Cirrus Logic CS4236+ driver" 132 tristate "Generic Cirrus Logic CS4236+ driver"
132 depends on SND
133 select SND_OPL3_LIB 133 select SND_OPL3_LIB
134 select SND_MPU401_UART 134 select SND_MPU401_UART
135 select SND_CS4231_LIB 135 select SND_CS4231_LIB
@@ -142,7 +142,7 @@ config SND_CS4236
142 142
143config SND_DT019X 143config SND_DT019X
144 tristate "Diamond Technologies DT-019X, Avance Logic ALS-007" 144 tristate "Diamond Technologies DT-019X, Avance Logic ALS-007"
145 depends on SND && PNP && ISA 145 depends on PNP
146 select ISAPNP 146 select ISAPNP
147 select SND_OPL3_LIB 147 select SND_OPL3_LIB
148 select SND_MPU401_UART 148 select SND_MPU401_UART
@@ -156,7 +156,7 @@ config SND_DT019X
156 156
157config SND_ES968 157config SND_ES968
158 tristate "Generic ESS ES968 driver" 158 tristate "Generic ESS ES968 driver"
159 depends on SND && PNP && ISA 159 depends on PNP
160 select ISAPNP 160 select ISAPNP
161 select SND_MPU401_UART 161 select SND_MPU401_UART
162 select SND_SB8_DSP 162 select SND_SB8_DSP
@@ -168,7 +168,6 @@ config SND_ES968
168 168
169config SND_ES1688 169config SND_ES1688
170 tristate "Generic ESS ES688/ES1688 driver" 170 tristate "Generic ESS ES688/ES1688 driver"
171 depends on SND
172 select SND_OPL3_LIB 171 select SND_OPL3_LIB
173 select SND_MPU401_UART 172 select SND_MPU401_UART
174 select SND_PCM 173 select SND_PCM
@@ -181,7 +180,6 @@ config SND_ES1688
181 180
182config SND_ES18XX 181config SND_ES18XX
183 tristate "Generic ESS ES18xx driver" 182 tristate "Generic ESS ES18xx driver"
184 depends on SND
185 select SND_OPL3_LIB 183 select SND_OPL3_LIB
186 select SND_MPU401_UART 184 select SND_MPU401_UART
187 select SND_PCM 185 select SND_PCM
@@ -193,7 +191,7 @@ config SND_ES18XX
193 191
194config SND_SC6000 192config SND_SC6000
195 tristate "Gallant SC-6000, Audio Excel DSP 16" 193 tristate "Gallant SC-6000, Audio Excel DSP 16"
196 depends on SND && HAS_IOPORT 194 depends on HAS_IOPORT
197 select SND_AD1848_LIB 195 select SND_AD1848_LIB
198 select SND_OPL3_LIB 196 select SND_OPL3_LIB
199 select SND_MPU401_UART 197 select SND_MPU401_UART
@@ -204,15 +202,10 @@ config SND_SC6000
204 To compile this driver as a module, choose M here: the module 202 To compile this driver as a module, choose M here: the module
205 will be called snd-sc6000. 203 will be called snd-sc6000.
206 204
207config SND_GUS_SYNTH
208 tristate
209
210config SND_GUSCLASSIC 205config SND_GUSCLASSIC
211 tristate "Gravis UltraSound Classic" 206 tristate "Gravis UltraSound Classic"
212 depends on SND
213 select SND_RAWMIDI 207 select SND_RAWMIDI
214 select SND_PCM 208 select SND_PCM
215 select SND_GUS_SYNTH
216 help 209 help
217 Say Y here to include support for Gravis UltraSound Classic 210 Say Y here to include support for Gravis UltraSound Classic
218 soundcards. 211 soundcards.
@@ -222,11 +215,9 @@ config SND_GUSCLASSIC
222 215
223config SND_GUSEXTREME 216config SND_GUSEXTREME
224 tristate "Gravis UltraSound Extreme" 217 tristate "Gravis UltraSound Extreme"
225 depends on SND
226 select SND_HWDEP 218 select SND_HWDEP
227 select SND_MPU401_UART 219 select SND_MPU401_UART
228 select SND_PCM 220 select SND_PCM
229 select SND_GUS_SYNTH
230 help 221 help
231 Say Y here to include support for Gravis UltraSound Extreme 222 Say Y here to include support for Gravis UltraSound Extreme
232 soundcards. 223 soundcards.
@@ -236,10 +227,8 @@ config SND_GUSEXTREME
236 227
237config SND_GUSMAX 228config SND_GUSMAX
238 tristate "Gravis UltraSound MAX" 229 tristate "Gravis UltraSound MAX"
239 depends on SND
240 select SND_RAWMIDI 230 select SND_RAWMIDI
241 select SND_CS4231_LIB 231 select SND_CS4231_LIB
242 select SND_GUS_SYNTH
243 help 232 help
244 Say Y here to include support for Gravis UltraSound MAX 233 Say Y here to include support for Gravis UltraSound MAX
245 soundcards. 234 soundcards.
@@ -249,10 +238,9 @@ config SND_GUSMAX
249 238
250config SND_INTERWAVE 239config SND_INTERWAVE
251 tristate "AMD InterWave, Gravis UltraSound PnP" 240 tristate "AMD InterWave, Gravis UltraSound PnP"
252 depends on SND && PNP && ISA 241 depends on PNP
253 select SND_RAWMIDI 242 select SND_RAWMIDI
254 select SND_CS4231_LIB 243 select SND_CS4231_LIB
255 select SND_GUS_SYNTH
256 help 244 help
257 Say Y here to include support for AMD InterWave based 245 Say Y here to include support for AMD InterWave based
258 soundcards (Gravis UltraSound Plug & Play, STB SoundRage32, 246 soundcards (Gravis UltraSound Plug & Play, STB SoundRage32,
@@ -263,10 +251,9 @@ config SND_INTERWAVE
263 251
264config SND_INTERWAVE_STB 252config SND_INTERWAVE_STB
265 tristate "AMD InterWave + TEA6330T (UltraSound 32-Pro)" 253 tristate "AMD InterWave + TEA6330T (UltraSound 32-Pro)"
266 depends on SND && PNP && ISA 254 depends on PNP
267 select SND_RAWMIDI 255 select SND_RAWMIDI
268 select SND_CS4231_LIB 256 select SND_CS4231_LIB
269 select SND_GUS_SYNTH
270 help 257 help
271 Say Y here to include support for AMD InterWave based 258 Say Y here to include support for AMD InterWave based
272 soundcards with a TEA6330T bass and treble regulator 259 soundcards with a TEA6330T bass and treble regulator
@@ -277,7 +264,6 @@ config SND_INTERWAVE_STB
277 264
278config SND_OPL3SA2 265config SND_OPL3SA2
279 tristate "Yamaha OPL3-SA2/SA3" 266 tristate "Yamaha OPL3-SA2/SA3"
280 depends on SND
281 select SND_OPL3_LIB 267 select SND_OPL3_LIB
282 select SND_MPU401_UART 268 select SND_MPU401_UART
283 select SND_CS4231_LIB 269 select SND_CS4231_LIB
@@ -290,7 +276,6 @@ config SND_OPL3SA2
290 276
291config SND_OPTI92X_AD1848 277config SND_OPTI92X_AD1848
292 tristate "OPTi 82C92x - AD1848" 278 tristate "OPTi 82C92x - AD1848"
293 depends on SND
294 select SND_OPL3_LIB 279 select SND_OPL3_LIB
295 select SND_OPL4_LIB 280 select SND_OPL4_LIB
296 select SND_MPU401_UART 281 select SND_MPU401_UART
@@ -304,7 +289,6 @@ config SND_OPTI92X_AD1848
304 289
305config SND_OPTI92X_CS4231 290config SND_OPTI92X_CS4231
306 tristate "OPTi 82C92x - CS4231" 291 tristate "OPTi 82C92x - CS4231"
307 depends on SND
308 select SND_OPL3_LIB 292 select SND_OPL3_LIB
309 select SND_OPL4_LIB 293 select SND_OPL4_LIB
310 select SND_MPU401_UART 294 select SND_MPU401_UART
@@ -318,10 +302,9 @@ config SND_OPTI92X_CS4231
318 302
319config SND_OPTI93X 303config SND_OPTI93X
320 tristate "OPTi 82C93x" 304 tristate "OPTi 82C93x"
321 depends on SND
322 select SND_OPL3_LIB 305 select SND_OPL3_LIB
323 select SND_MPU401_UART 306 select SND_MPU401_UART
324 select SND_PCM 307 select SND_CS4231_LIB
325 help 308 help
326 Say Y here to include support for soundcards based on Opti 309 Say Y here to include support for soundcards based on Opti
327 82C93x chips. 310 82C93x chips.
@@ -331,7 +314,6 @@ config SND_OPTI93X
331 314
332config SND_MIRO 315config SND_MIRO
333 tristate "Miro miroSOUND PCM1pro/PCM12/PCM20radio driver" 316 tristate "Miro miroSOUND PCM1pro/PCM12/PCM20radio driver"
334 depends on SND
335 select SND_OPL4_LIB 317 select SND_OPL4_LIB
336 select SND_CS4231_LIB 318 select SND_CS4231_LIB
337 select SND_MPU401_UART 319 select SND_MPU401_UART
@@ -345,7 +327,6 @@ config SND_MIRO
345 327
346config SND_SB8 328config SND_SB8
347 tristate "Sound Blaster 1.0/2.0/Pro (8-bit)" 329 tristate "Sound Blaster 1.0/2.0/Pro (8-bit)"
348 depends on SND
349 select SND_OPL3_LIB 330 select SND_OPL3_LIB
350 select SND_RAWMIDI 331 select SND_RAWMIDI
351 select SND_SB8_DSP 332 select SND_SB8_DSP
@@ -358,7 +339,6 @@ config SND_SB8
358 339
359config SND_SB16 340config SND_SB16
360 tristate "Sound Blaster 16 (PnP)" 341 tristate "Sound Blaster 16 (PnP)"
361 depends on SND
362 select SND_OPL3_LIB 342 select SND_OPL3_LIB
363 select SND_MPU401_UART 343 select SND_MPU401_UART
364 select SND_SB16_DSP 344 select SND_SB16_DSP
@@ -371,7 +351,6 @@ config SND_SB16
371 351
372config SND_SBAWE 352config SND_SBAWE
373 tristate "Sound Blaster AWE (32,64) (PnP)" 353 tristate "Sound Blaster AWE (32,64) (PnP)"
374 depends on SND
375 select SND_OPL3_LIB 354 select SND_OPL3_LIB
376 select SND_MPU401_UART 355 select SND_MPU401_UART
377 select SND_SB16_DSP 356 select SND_SB16_DSP
@@ -402,7 +381,6 @@ config SND_SB16_CSP_FIRMWARE_IN_KERNEL
402 381
403config SND_SGALAXY 382config SND_SGALAXY
404 tristate "Aztech Sound Galaxy" 383 tristate "Aztech Sound Galaxy"
405 depends on SND
406 select SND_AD1848_LIB 384 select SND_AD1848_LIB
407 help 385 help
408 Say Y here to include support for Aztech Sound Galaxy 386 Say Y here to include support for Aztech Sound Galaxy
@@ -413,7 +391,6 @@ config SND_SGALAXY
413 391
414config SND_SSCAPE 392config SND_SSCAPE
415 tristate "Ensoniq SoundScape PnP driver" 393 tristate "Ensoniq SoundScape PnP driver"
416 depends on SND
417 select SND_HWDEP 394 select SND_HWDEP
418 select SND_MPU401_UART 395 select SND_MPU401_UART
419 select SND_CS4231_LIB 396 select SND_CS4231_LIB
@@ -426,7 +403,6 @@ config SND_SSCAPE
426 403
427config SND_WAVEFRONT 404config SND_WAVEFRONT
428 tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)" 405 tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)"
429 depends on SND
430 select FW_LOADER 406 select FW_LOADER
431 select SND_OPL3_LIB 407 select SND_OPL3_LIB
432 select SND_MPU401_UART 408 select SND_MPU401_UART
@@ -448,4 +424,5 @@ config SND_WAVEFRONT_FIRMWARE_IN_KERNEL
448 you need to install the firmware files from the 424 you need to install the firmware files from the
449 alsa-firmware package. 425 alsa-firmware package.
450 426
451endmenu 427endif # SND_ISA
428
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
index 0aa8649e5c7f..521db705d179 100644
--- a/sound/isa/cs423x/cs4231_lib.c
+++ b/sound/isa/cs423x/cs4231_lib.c
@@ -119,6 +119,42 @@ static unsigned char snd_cs4231_original_image[32] =
119 0x00, /* 1f/31 - cbrl */ 119 0x00, /* 1f/31 - cbrl */
120}; 120};
121 121
122static unsigned char snd_opti93x_original_image[32] =
123{
124 0x00, /* 00/00 - l_mixout_outctrl */
125 0x00, /* 01/01 - r_mixout_outctrl */
126 0x88, /* 02/02 - l_cd_inctrl */
127 0x88, /* 03/03 - r_cd_inctrl */
128 0x88, /* 04/04 - l_a1/fm_inctrl */
129 0x88, /* 05/05 - r_a1/fm_inctrl */
130 0x80, /* 06/06 - l_dac_inctrl */
131 0x80, /* 07/07 - r_dac_inctrl */
132 0x00, /* 08/08 - ply_dataform_reg */
133 0x00, /* 09/09 - if_conf */
134 0x00, /* 0a/10 - pin_ctrl */
135 0x00, /* 0b/11 - err_init_reg */
136 0x0a, /* 0c/12 - id_reg */
137 0x00, /* 0d/13 - reserved */
138 0x00, /* 0e/14 - ply_upcount_reg */
139 0x00, /* 0f/15 - ply_lowcount_reg */
140 0x88, /* 10/16 - reserved/l_a1_inctrl */
141 0x88, /* 11/17 - reserved/r_a1_inctrl */
142 0x88, /* 12/18 - l_line_inctrl */
143 0x88, /* 13/19 - r_line_inctrl */
144 0x88, /* 14/20 - l_mic_inctrl */
145 0x88, /* 15/21 - r_mic_inctrl */
146 0x80, /* 16/22 - l_out_outctrl */
147 0x80, /* 17/23 - r_out_outctrl */
148 0x00, /* 18/24 - reserved */
149 0x00, /* 19/25 - reserved */
150 0x00, /* 1a/26 - reserved */
151 0x00, /* 1b/27 - reserved */
152 0x00, /* 1c/28 - cap_dataform_reg */
153 0x00, /* 1d/29 - reserved */
154 0x00, /* 1e/30 - cap_upcount_reg */
155 0x00 /* 1f/31 - cap_lowcount_reg */
156};
157
122/* 158/*
123 * Basic I/O functions 159 * Basic I/O functions
124 */ 160 */
@@ -895,7 +931,7 @@ static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream)
895 return 0; 931 return 0;
896} 932}
897 933
898static void snd_cs4231_overrange(struct snd_cs4231 *chip) 934void snd_cs4231_overrange(struct snd_cs4231 *chip)
899{ 935{
900 unsigned long flags; 936 unsigned long flags;
901 unsigned char res; 937 unsigned char res;
@@ -1054,8 +1090,11 @@ static int snd_cs4231_probe(struct snd_cs4231 *chip)
1054 chip->image[CS4231_IFACE_CTRL] = 1090 chip->image[CS4231_IFACE_CTRL] =
1055 (chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA) | 1091 (chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA) |
1056 (chip->single_dma ? CS4231_SINGLE_DMA : 0); 1092 (chip->single_dma ? CS4231_SINGLE_DMA : 0);
1057 chip->image[CS4231_ALT_FEATURE_1] = 0x80; 1093 if (chip->hardware != CS4231_HW_OPTI93X) {
1058 chip->image[CS4231_ALT_FEATURE_2] = chip->hardware == CS4231_HW_INTERWAVE ? 0xc2 : 0x01; 1094 chip->image[CS4231_ALT_FEATURE_1] = 0x80;
1095 chip->image[CS4231_ALT_FEATURE_2] =
1096 chip->hardware == CS4231_HW_INTERWAVE ? 0xc2 : 0x01;
1097 }
1059 ptr = (unsigned char *) &chip->image; 1098 ptr = (unsigned char *) &chip->image;
1060 snd_cs4231_mce_down(chip); 1099 snd_cs4231_mce_down(chip);
1061 spin_lock_irqsave(&chip->reg_lock, flags); 1100 spin_lock_irqsave(&chip->reg_lock, flags);
@@ -1376,6 +1415,7 @@ const char *snd_cs4231_chip_id(struct snd_cs4231 *chip)
1376 case CS4231_HW_INTERWAVE: return "AMD InterWave"; 1415 case CS4231_HW_INTERWAVE: return "AMD InterWave";
1377 case CS4231_HW_OPL3SA2: return chip->card->shortname; 1416 case CS4231_HW_OPL3SA2: return chip->card->shortname;
1378 case CS4231_HW_AD1845: return "AD1845"; 1417 case CS4231_HW_AD1845: return "AD1845";
1418 case CS4231_HW_OPTI93X: return "OPTi 93x";
1379 default: return "???"; 1419 default: return "???";
1380 } 1420 }
1381} 1421}
@@ -1401,8 +1441,13 @@ static int snd_cs4231_new(struct snd_card *card,
1401 chip->rate_constraint = snd_cs4231_xrate; 1441 chip->rate_constraint = snd_cs4231_xrate;
1402 chip->set_playback_format = snd_cs4231_playback_format; 1442 chip->set_playback_format = snd_cs4231_playback_format;
1403 chip->set_capture_format = snd_cs4231_capture_format; 1443 chip->set_capture_format = snd_cs4231_capture_format;
1404 memcpy(&chip->image, &snd_cs4231_original_image, sizeof(snd_cs4231_original_image)); 1444 if (chip->hardware == CS4231_HW_OPTI93X)
1405 1445 memcpy(&chip->image, &snd_opti93x_original_image,
1446 sizeof(snd_opti93x_original_image));
1447 else
1448 memcpy(&chip->image, &snd_cs4231_original_image,
1449 sizeof(snd_cs4231_original_image));
1450
1406 *rchip = chip; 1451 *rchip = chip;
1407 return 0; 1452 return 0;
1408} 1453}
@@ -1790,6 +1835,48 @@ CS4231_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
1790CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1) 1835CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1)
1791}; 1836};
1792 1837
1838static struct snd_kcontrol_new snd_opti93x_controls[] = {
1839CS4231_DOUBLE("Master Playback Switch", 0,
1840 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
1841CS4231_DOUBLE("Master Playback Volume", 0,
1842 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1),
1843CS4231_DOUBLE("PCM Playback Switch", 0,
1844 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
1845CS4231_DOUBLE("PCM Playback Volume", 0,
1846 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1),
1847CS4231_DOUBLE("FM Playback Switch", 0,
1848 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
1849CS4231_DOUBLE("FM Playback Volume", 0,
1850 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1),
1851CS4231_DOUBLE("Line Playback Switch", 0,
1852 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
1853CS4231_DOUBLE("Line Playback Volume", 0,
1854 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1),
1855CS4231_DOUBLE("Mic Playback Switch", 0,
1856 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
1857CS4231_DOUBLE("Mic Playback Volume", 0,
1858 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1),
1859CS4231_DOUBLE("Mic Boost", 0,
1860 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
1861CS4231_DOUBLE("CD Playback Switch", 0,
1862 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
1863CS4231_DOUBLE("CD Playback Volume", 0,
1864 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1),
1865CS4231_DOUBLE("Aux Playback Switch", 0,
1866 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
1867CS4231_DOUBLE("Aux Playback Volume", 0,
1868 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1),
1869CS4231_DOUBLE("Capture Volume", 0,
1870 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
1871{
1872 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1873 .name = "Capture Source",
1874 .info = snd_cs4231_info_mux,
1875 .get = snd_cs4231_get_mux,
1876 .put = snd_cs4231_put_mux,
1877}
1878};
1879
1793int snd_cs4231_mixer(struct snd_cs4231 *chip) 1880int snd_cs4231_mixer(struct snd_cs4231 *chip)
1794{ 1881{
1795 struct snd_card *card; 1882 struct snd_card *card;
@@ -1802,10 +1889,22 @@ int snd_cs4231_mixer(struct snd_cs4231 *chip)
1802 1889
1803 strcpy(card->mixername, chip->pcm->name); 1890 strcpy(card->mixername, chip->pcm->name);
1804 1891
1805 for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) { 1892 if (chip->hardware == CS4231_HW_OPTI93X)
1806 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4231_controls[idx], chip))) < 0) 1893 for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
1807 return err; 1894 err = snd_ctl_add(card,
1808 } 1895 snd_ctl_new1(&snd_opti93x_controls[idx],
1896 chip));
1897 if (err < 0)
1898 return err;
1899 }
1900 else
1901 for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) {
1902 err = snd_ctl_add(card,
1903 snd_ctl_new1(&snd_cs4231_controls[idx],
1904 chip));
1905 if (err < 0)
1906 return err;
1907 }
1809 return 0; 1908 return 0;
1810} 1909}
1811 1910
@@ -1815,6 +1914,7 @@ EXPORT_SYMBOL(snd_cs4236_ext_out);
1815EXPORT_SYMBOL(snd_cs4236_ext_in); 1914EXPORT_SYMBOL(snd_cs4236_ext_in);
1816EXPORT_SYMBOL(snd_cs4231_mce_up); 1915EXPORT_SYMBOL(snd_cs4231_mce_up);
1817EXPORT_SYMBOL(snd_cs4231_mce_down); 1916EXPORT_SYMBOL(snd_cs4231_mce_down);
1917EXPORT_SYMBOL(snd_cs4231_overrange);
1818EXPORT_SYMBOL(snd_cs4231_interrupt); 1918EXPORT_SYMBOL(snd_cs4231_interrupt);
1819EXPORT_SYMBOL(snd_cs4231_chip_id); 1919EXPORT_SYMBOL(snd_cs4231_chip_id);
1820EXPORT_SYMBOL(snd_cs4231_create); 1920EXPORT_SYMBOL(snd_cs4231_create);
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index fe1afc13a01d..41c047e665ec 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -33,15 +33,10 @@
33#include <asm/io.h> 33#include <asm/io.h>
34#include <asm/dma.h> 34#include <asm/dma.h>
35#include <sound/core.h> 35#include <sound/core.h>
36#ifdef CS4231 36#if defined(CS4231) || defined(OPTi93X)
37#include <sound/cs4231.h> 37#include <sound/cs4231.h>
38#else 38#else
39#ifndef OPTi93X
40#include <sound/ad1848.h> 39#include <sound/ad1848.h>
41#else
42#include <sound/control.h>
43#include <sound/pcm.h>
44#endif /* OPTi93X */
45#endif /* CS4231 */ 40#endif /* CS4231 */
46#include <sound/mpu401.h> 41#include <sound/mpu401.h>
47#include <sound/opl3.h> 42#include <sound/opl3.h>
@@ -109,7 +104,6 @@ module_param(dma2, int, 0444);
109MODULE_PARM_DESC(dma2, "2nd dma # for opti9xx driver."); 104MODULE_PARM_DESC(dma2, "2nd dma # for opti9xx driver.");
110#endif /* CS4231 || OPTi93X */ 105#endif /* CS4231 || OPTi93X */
111 106
112#define OPTi9XX_HW_DETECT 0
113#define OPTi9XX_HW_82C928 1 107#define OPTi9XX_HW_82C928 1
114#define OPTi9XX_HW_82C929 2 108#define OPTi9XX_HW_82C929 2
115#define OPTi9XX_HW_82C924 3 109#define OPTi9XX_HW_82C924 3
@@ -123,105 +117,12 @@ MODULE_PARM_DESC(dma2, "2nd dma # for opti9xx driver.");
123 117
124#ifdef OPTi93X 118#ifdef OPTi93X
125 119
126#define OPTi93X_INDEX 0x00
127#define OPTi93X_DATA 0x01
128#define OPTi93X_STATUS 0x02 120#define OPTi93X_STATUS 0x02
129#define OPTi93X_DDATA 0x03
130#define OPTi93X_PORT(chip, r) ((chip)->port + OPTi93X_##r) 121#define OPTi93X_PORT(chip, r) ((chip)->port + OPTi93X_##r)
131 122
132#define OPTi93X_MIXOUT_LEFT 0x00
133#define OPTi93X_MIXOUT_RIGHT 0x01
134#define OPTi93X_CD_LEFT_INPUT 0x02
135#define OPTi93X_CD_RIGHT_INPUT 0x03
136#define OPTi930_AUX_LEFT_INPUT 0x04
137#define OPTi930_AUX_RIGHT_INPUT 0x05
138#define OPTi931_FM_LEFT_INPUT 0x04
139#define OPTi931_FM_RIGHT_INPUT 0x05
140#define OPTi93X_DAC_LEFT 0x06
141#define OPTi93X_DAC_RIGHT 0x07
142#define OPTi93X_PLAY_FORMAT 0x08
143#define OPTi93X_IFACE_CONF 0x09
144#define OPTi93X_PIN_CTRL 0x0a
145#define OPTi93X_ERR_INIT 0x0b
146#define OPTi93X_ID 0x0c
147#define OPTi93X_PLAY_UPR_CNT 0x0e
148#define OPTi93X_PLAY_LWR_CNT 0x0f
149#define OPTi931_AUX_LEFT_INPUT 0x10
150#define OPTi931_AUX_RIGHT_INPUT 0x11
151#define OPTi93X_LINE_LEFT_INPUT 0x12
152#define OPTi93X_LINE_RIGHT_INPUT 0x13
153#define OPTi93X_MIC_LEFT_INPUT 0x14
154#define OPTi93X_MIC_RIGHT_INPUT 0x15
155#define OPTi93X_OUT_LEFT 0x16
156#define OPTi93X_OUT_RIGHT 0x17
157#define OPTi93X_CAPT_FORMAT 0x1c
158#define OPTi93X_CAPT_UPR_CNT 0x1e
159#define OPTi93X_CAPT_LWR_CNT 0x1f
160
161#define OPTi93X_TRD 0x20
162#define OPTi93X_MCE 0x40
163#define OPTi93X_INIT 0x80
164
165#define OPTi93X_MIXOUT_MIC_GAIN 0x20
166#define OPTi93X_MIXOUT_LINE 0x00
167#define OPTi93X_MIXOUT_CD 0x40
168#define OPTi93X_MIXOUT_MIC 0x80
169#define OPTi93X_MIXOUT_MIXER 0xc0
170
171#define OPTi93X_STEREO 0x10
172#define OPTi93X_LINEAR_8 0x00
173#define OPTi93X_ULAW_8 0x20
174#define OPTi93X_LINEAR_16_LIT 0x40
175#define OPTi93X_ALAW_8 0x60
176#define OPTi93X_ADPCM_16 0xa0
177#define OPTi93X_LINEAR_16_BIG 0xc0
178
179#define OPTi93X_CAPTURE_PIO 0x80
180#define OPTi93X_PLAYBACK_PIO 0x40
181#define OPTi93X_AUTOCALIB 0x08
182#define OPTi93X_SINGLE_DMA 0x04
183#define OPTi93X_CAPTURE_ENABLE 0x02
184#define OPTi93X_PLAYBACK_ENABLE 0x01
185
186#define OPTi93X_IRQ_ENABLE 0x02
187
188#define OPTi93X_DMA_REQUEST 0x10
189#define OPTi93X_CALIB_IN_PROGRESS 0x20
190
191#define OPTi93X_IRQ_PLAYBACK 0x04 123#define OPTi93X_IRQ_PLAYBACK 0x04
192#define OPTi93X_IRQ_CAPTURE 0x08 124#define OPTi93X_IRQ_CAPTURE 0x08
193 125
194
195struct snd_opti93x {
196 unsigned long port;
197 struct resource *res_port;
198 int irq;
199 int dma1;
200 int dma2;
201
202 struct snd_opti9xx *chip;
203 unsigned short hardware;
204 unsigned char image[32];
205
206 unsigned char mce_bit;
207 unsigned short mode;
208 int mute;
209
210 spinlock_t lock;
211
212 struct snd_card *card;
213 struct snd_pcm *pcm;
214 struct snd_pcm_substream *playback_substream;
215 struct snd_pcm_substream *capture_substream;
216 unsigned int p_dma_size;
217 unsigned int c_dma_size;
218};
219
220#define OPTi93X_MODE_NONE 0x00
221#define OPTi93X_MODE_PLAY 0x01
222#define OPTi93X_MODE_CAPTURE 0x02
223#define OPTi93X_MODE_OPEN (OPTi93X_MODE_PLAY | OPTi93X_MODE_CAPTURE)
224
225#endif /* OPTi93X */ 126#endif /* OPTi93X */
226 127
227struct snd_opti9xx { 128struct snd_opti9xx {
@@ -234,6 +135,7 @@ struct snd_opti9xx {
234 unsigned long mc_base_size; 135 unsigned long mc_base_size;
235#ifdef OPTi93X 136#ifdef OPTi93X
236 unsigned long mc_indir_index; 137 unsigned long mc_indir_index;
138 struct snd_cs4231 *codec;
237#endif /* OPTi93X */ 139#endif /* OPTi93X */
238 unsigned long pwd_reg; 140 unsigned long pwd_reg;
239 141
@@ -491,16 +393,9 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
491 break; 393 break;
492 394
493#else /* OPTi93X */ 395#else /* OPTi93X */
494 case OPTi9XX_HW_82C930:
495 case OPTi9XX_HW_82C931: 396 case OPTi9XX_HW_82C931:
496 case OPTi9XX_HW_82C933: 397 case OPTi9XX_HW_82C933:
497 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x03); 398 /*
498 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0x00, 0xff);
499 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0x10 |
500 (chip->hardware == OPTi9XX_HW_82C930 ? 0x00 : 0x04),
501 0x34);
502 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x20, 0xbf);
503 /*
504 * The BTC 1817DW has QS1000 wavetable which is connected 399 * The BTC 1817DW has QS1000 wavetable which is connected
505 * to the serial digital input of the OPTI931. 400 * to the serial digital input of the OPTI931.
506 */ 401 */
@@ -510,6 +405,13 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
510 * or digital input signal. 405 * or digital input signal.
511 */ 406 */
512 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(26), 0x01, 0x01); 407 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(26), 0x01, 0x01);
408 case OPTi9XX_HW_82C930: /* FALL THROUGH */
409 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x03);
410 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0x00, 0xff);
411 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0x10 |
412 (chip->hardware == OPTi9XX_HW_82C930 ? 0x00 : 0x04),
413 0x34);
414 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x20, 0xbf);
513 break; 415 break;
514#endif /* OPTi93X */ 416#endif /* OPTi93X */
515 417
@@ -654,979 +556,23 @@ __skip_mpu:
654 556
655#ifdef OPTi93X 557#ifdef OPTi93X
656 558
657static unsigned char snd_opti93x_default_image[32] =
658{
659 0x00, /* 00/00 - l_mixout_outctrl */
660 0x00, /* 01/01 - r_mixout_outctrl */
661 0x88, /* 02/02 - l_cd_inctrl */
662 0x88, /* 03/03 - r_cd_inctrl */
663 0x88, /* 04/04 - l_a1/fm_inctrl */
664 0x88, /* 05/05 - r_a1/fm_inctrl */
665 0x80, /* 06/06 - l_dac_inctrl */
666 0x80, /* 07/07 - r_dac_inctrl */
667 0x00, /* 08/08 - ply_dataform_reg */
668 0x00, /* 09/09 - if_conf */
669 0x00, /* 0a/10 - pin_ctrl */
670 0x00, /* 0b/11 - err_init_reg */
671 0x0a, /* 0c/12 - id_reg */
672 0x00, /* 0d/13 - reserved */
673 0x00, /* 0e/14 - ply_upcount_reg */
674 0x00, /* 0f/15 - ply_lowcount_reg */
675 0x88, /* 10/16 - reserved/l_a1_inctrl */
676 0x88, /* 11/17 - reserved/r_a1_inctrl */
677 0x88, /* 12/18 - l_line_inctrl */
678 0x88, /* 13/19 - r_line_inctrl */
679 0x88, /* 14/20 - l_mic_inctrl */
680 0x88, /* 15/21 - r_mic_inctrl */
681 0x80, /* 16/22 - l_out_outctrl */
682 0x80, /* 17/23 - r_out_outctrl */
683 0x00, /* 18/24 - reserved */
684 0x00, /* 19/25 - reserved */
685 0x00, /* 1a/26 - reserved */
686 0x00, /* 1b/27 - reserved */
687 0x00, /* 1c/28 - cap_dataform_reg */
688 0x00, /* 1d/29 - reserved */
689 0x00, /* 1e/30 - cap_upcount_reg */
690 0x00 /* 1f/31 - cap_lowcount_reg */
691};
692
693
694static int snd_opti93x_busy_wait(struct snd_opti93x *chip)
695{
696 int timeout;
697
698 for (timeout = 250; timeout-- > 0; udelay(10))
699 if (!(inb(OPTi93X_PORT(chip, INDEX)) & OPTi93X_INIT))
700 return 0;
701
702 snd_printk("chip still busy.\n");
703 return -EBUSY;
704}
705
706static unsigned char snd_opti93x_in(struct snd_opti93x *chip, unsigned char reg)
707{
708 snd_opti93x_busy_wait(chip);
709 outb(chip->mce_bit | (reg & 0x1f), OPTi93X_PORT(chip, INDEX));
710 return inb(OPTi93X_PORT(chip, DATA));
711}
712
713static void snd_opti93x_out(struct snd_opti93x *chip, unsigned char reg,
714 unsigned char value)
715{
716 snd_opti93x_busy_wait(chip);
717 outb(chip->mce_bit | (reg & 0x1f), OPTi93X_PORT(chip, INDEX));
718 outb(value, OPTi93X_PORT(chip, DATA));
719}
720
721static void snd_opti93x_out_image(struct snd_opti93x *chip, unsigned char reg,
722 unsigned char value)
723{
724 snd_opti93x_out(chip, reg, chip->image[reg] = value);
725}
726
727static void snd_opti93x_out_mask(struct snd_opti93x *chip, unsigned char reg,
728 unsigned char mask, unsigned char value)
729{
730 snd_opti93x_out_image(chip, reg,
731 (chip->image[reg] & ~mask) | (value & mask));
732}
733
734
735static void snd_opti93x_mce_up(struct snd_opti93x *chip)
736{
737 snd_opti93x_busy_wait(chip);
738
739 chip->mce_bit = OPTi93X_MCE;
740 if (!(inb(OPTi93X_PORT(chip, INDEX)) & OPTi93X_MCE))
741 outb(chip->mce_bit, OPTi93X_PORT(chip, INDEX));
742}
743
744static void snd_opti93x_mce_down(struct snd_opti93x *chip)
745{
746 snd_opti93x_busy_wait(chip);
747
748 chip->mce_bit = 0;
749 if (inb(OPTi93X_PORT(chip, INDEX)) & OPTi93X_MCE)
750 outb(chip->mce_bit, OPTi93X_PORT(chip, INDEX));
751}
752
753#define snd_opti93x_mute_reg(chip, reg, mute) \
754 snd_opti93x_out(chip, reg, mute ? 0x80 : chip->image[reg]);
755
756static void snd_opti93x_mute(struct snd_opti93x *chip, int mute)
757{
758 mute = mute ? 1 : 0;
759 if (chip->mute == mute)
760 return;
761
762 chip->mute = mute;
763
764 snd_opti93x_mute_reg(chip, OPTi93X_CD_LEFT_INPUT, mute);
765 snd_opti93x_mute_reg(chip, OPTi93X_CD_RIGHT_INPUT, mute);
766 switch (chip->hardware) {
767 case OPTi9XX_HW_82C930:
768 snd_opti93x_mute_reg(chip, OPTi930_AUX_LEFT_INPUT, mute);
769 snd_opti93x_mute_reg(chip, OPTi930_AUX_RIGHT_INPUT, mute);
770 break;
771 case OPTi9XX_HW_82C931:
772 case OPTi9XX_HW_82C933:
773 snd_opti93x_mute_reg(chip, OPTi931_FM_LEFT_INPUT, mute);
774 snd_opti93x_mute_reg(chip, OPTi931_FM_RIGHT_INPUT, mute);
775 snd_opti93x_mute_reg(chip, OPTi931_AUX_LEFT_INPUT, mute);
776 snd_opti93x_mute_reg(chip, OPTi931_AUX_RIGHT_INPUT, mute);
777 }
778 snd_opti93x_mute_reg(chip, OPTi93X_DAC_LEFT, mute);
779 snd_opti93x_mute_reg(chip, OPTi93X_DAC_RIGHT, mute);
780 snd_opti93x_mute_reg(chip, OPTi93X_LINE_LEFT_INPUT, mute);
781 snd_opti93x_mute_reg(chip, OPTi93X_LINE_RIGHT_INPUT, mute);
782 snd_opti93x_mute_reg(chip, OPTi93X_MIC_LEFT_INPUT, mute);
783 snd_opti93x_mute_reg(chip, OPTi93X_MIC_RIGHT_INPUT, mute);
784 snd_opti93x_mute_reg(chip, OPTi93X_OUT_LEFT, mute);
785 snd_opti93x_mute_reg(chip, OPTi93X_OUT_RIGHT, mute);
786}
787
788
789static unsigned int snd_opti93x_get_count(unsigned char format,
790 unsigned int size)
791{
792 switch (format & 0xe0) {
793 case OPTi93X_LINEAR_16_LIT:
794 case OPTi93X_LINEAR_16_BIG:
795 size >>= 1;
796 break;
797 case OPTi93X_ADPCM_16:
798 return size >> 2;
799 }
800 return (format & OPTi93X_STEREO) ? (size >> 1) : size;
801}
802
803static unsigned int rates[] = { 5512, 6615, 8000, 9600, 11025, 16000,
804 18900, 22050, 27428, 32000, 33075, 37800,
805 44100, 48000 };
806#define RATES ARRAY_SIZE(rates)
807
808static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
809 .count = RATES,
810 .list = rates,
811 .mask = 0,
812};
813
814static unsigned char bits[] = { 0x01, 0x0f, 0x00, 0x0e, 0x03, 0x02,
815 0x05, 0x07, 0x04, 0x06, 0x0d, 0x09,
816 0x0b, 0x0c};
817
818static unsigned char snd_opti93x_get_freq(unsigned int rate)
819{
820 unsigned int i;
821
822 for (i = 0; i < RATES; i++) {
823 if (rate == rates[i])
824 return bits[i];
825 }
826 snd_BUG();
827 return bits[RATES-1];
828}
829
830static unsigned char snd_opti93x_get_format(struct snd_opti93x *chip,
831 unsigned int format, int channels)
832{
833 unsigned char retval = OPTi93X_LINEAR_8;
834
835 switch (format) {
836 case SNDRV_PCM_FORMAT_MU_LAW:
837 retval = OPTi93X_ULAW_8;
838 break;
839 case SNDRV_PCM_FORMAT_A_LAW:
840 retval = OPTi93X_ALAW_8;
841 break;
842 case SNDRV_PCM_FORMAT_S16_LE:
843 retval = OPTi93X_LINEAR_16_LIT;
844 break;
845 case SNDRV_PCM_FORMAT_S16_BE:
846 retval = OPTi93X_LINEAR_16_BIG;
847 break;
848 case SNDRV_PCM_FORMAT_IMA_ADPCM:
849 retval = OPTi93X_ADPCM_16;
850 }
851 return (channels > 1) ? (retval | OPTi93X_STEREO) : retval;
852}
853
854
855static void snd_opti93x_playback_format(struct snd_opti93x *chip, unsigned char fmt)
856{
857 unsigned char mask;
858
859 snd_opti93x_mute(chip, 1);
860
861 snd_opti93x_mce_up(chip);
862 mask = (chip->mode & OPTi93X_MODE_CAPTURE) ? 0xf0 : 0xff;
863 snd_opti93x_out_mask(chip, OPTi93X_PLAY_FORMAT, mask, fmt);
864 snd_opti93x_mce_down(chip);
865
866 snd_opti93x_mute(chip, 0);
867}
868
869static void snd_opti93x_capture_format(struct snd_opti93x *chip, unsigned char fmt)
870{
871 snd_opti93x_mute(chip, 1);
872
873 snd_opti93x_mce_up(chip);
874 if (!(chip->mode & OPTi93X_MODE_PLAY))
875 snd_opti93x_out_mask(chip, OPTi93X_PLAY_FORMAT, 0x0f, fmt);
876 else
877 fmt = chip->image[OPTi93X_PLAY_FORMAT] & 0xf0;
878 snd_opti93x_out_image(chip, OPTi93X_CAPT_FORMAT, fmt);
879 snd_opti93x_mce_down(chip);
880
881 snd_opti93x_mute(chip, 0);
882}
883
884
885static int snd_opti93x_open(struct snd_opti93x *chip, unsigned int mode)
886{
887 unsigned long flags;
888
889 spin_lock_irqsave(&chip->lock, flags);
890
891 if (chip->mode & mode) {
892 spin_unlock_irqrestore(&chip->lock, flags);
893 return -EAGAIN;
894 }
895
896 if (!(chip->mode & OPTi93X_MODE_OPEN)) {
897 outb(0x00, OPTi93X_PORT(chip, STATUS));
898 snd_opti93x_out_mask(chip, OPTi93X_PIN_CTRL,
899 OPTi93X_IRQ_ENABLE, OPTi93X_IRQ_ENABLE);
900 chip->mode = mode;
901 }
902 else
903 chip->mode |= mode;
904
905 spin_unlock_irqrestore(&chip->lock, flags);
906 return 0;
907}
908
909static void snd_opti93x_close(struct snd_opti93x *chip, unsigned int mode)
910{
911 unsigned long flags;
912
913 spin_lock_irqsave(&chip->lock, flags);
914
915 chip->mode &= ~mode;
916 if (chip->mode & OPTi93X_MODE_OPEN) {
917 spin_unlock_irqrestore(&chip->lock, flags);
918 return;
919 }
920
921 snd_opti93x_mute(chip, 1);
922
923 outb(0, OPTi93X_PORT(chip, STATUS));
924 snd_opti93x_out_mask(chip, OPTi93X_PIN_CTRL, OPTi93X_IRQ_ENABLE,
925 ~OPTi93X_IRQ_ENABLE);
926
927 snd_opti93x_mce_up(chip);
928 snd_opti93x_out_image(chip, OPTi93X_IFACE_CONF, 0x00);
929 snd_opti93x_mce_down(chip);
930 chip->mode = 0;
931
932 snd_opti93x_mute(chip, 0);
933 spin_unlock_irqrestore(&chip->lock, flags);
934}
935
936static int snd_opti93x_trigger(struct snd_pcm_substream *substream,
937 unsigned char what, int cmd)
938{
939 struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
940
941 switch (cmd) {
942 case SNDRV_PCM_TRIGGER_START:
943 case SNDRV_PCM_TRIGGER_STOP:
944 {
945 unsigned int what = 0;
946 struct snd_pcm_substream *s;
947 snd_pcm_group_for_each_entry(s, substream) {
948 if (s == chip->playback_substream) {
949 what |= OPTi93X_PLAYBACK_ENABLE;
950 snd_pcm_trigger_done(s, substream);
951 } else if (s == chip->capture_substream) {
952 what |= OPTi93X_CAPTURE_ENABLE;
953 snd_pcm_trigger_done(s, substream);
954 }
955 }
956 spin_lock(&chip->lock);
957 if (cmd == SNDRV_PCM_TRIGGER_START) {
958 snd_opti93x_out_mask(chip, OPTi93X_IFACE_CONF, what, what);
959 if (what & OPTi93X_CAPTURE_ENABLE)
960 udelay(50);
961 } else
962 snd_opti93x_out_mask(chip, OPTi93X_IFACE_CONF, what, 0x00);
963 spin_unlock(&chip->lock);
964 break;
965 }
966 default:
967 return -EINVAL;
968 }
969 return 0;
970}
971
972static int snd_opti93x_playback_trigger(struct snd_pcm_substream *substream, int cmd)
973{
974 return snd_opti93x_trigger(substream,
975 OPTi93X_PLAYBACK_ENABLE, cmd);
976}
977
978static int snd_opti93x_capture_trigger(struct snd_pcm_substream *substream, int cmd)
979{
980 return snd_opti93x_trigger(substream,
981 OPTi93X_CAPTURE_ENABLE, cmd);
982}
983
984static int snd_opti93x_hw_params(struct snd_pcm_substream *substream,
985 struct snd_pcm_hw_params *hw_params)
986{
987 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
988}
989
990
991static int snd_opti93x_hw_free(struct snd_pcm_substream *substream)
992{
993 snd_pcm_lib_free_pages(substream);
994 return 0;
995}
996
997
998static int snd_opti93x_playback_prepare(struct snd_pcm_substream *substream)
999{
1000 struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
1001 struct snd_pcm_runtime *runtime = substream->runtime;
1002 unsigned long flags;
1003 unsigned char format;
1004 unsigned int count = snd_pcm_lib_period_bytes(substream);
1005 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1006
1007 spin_lock_irqsave(&chip->lock, flags);
1008
1009 chip->p_dma_size = size;
1010 snd_opti93x_out_mask(chip, OPTi93X_IFACE_CONF,
1011 OPTi93X_PLAYBACK_ENABLE | OPTi93X_PLAYBACK_PIO,
1012 ~(OPTi93X_PLAYBACK_ENABLE | OPTi93X_PLAYBACK_PIO));
1013
1014 snd_dma_program(chip->dma1, runtime->dma_addr, size,
1015 DMA_MODE_WRITE | DMA_AUTOINIT);
1016
1017 format = snd_opti93x_get_freq(runtime->rate);
1018 format |= snd_opti93x_get_format(chip, runtime->format,
1019 runtime->channels);
1020 snd_opti93x_playback_format(chip, format);
1021 format = chip->image[OPTi93X_PLAY_FORMAT];
1022
1023 count = snd_opti93x_get_count(format, count) - 1;
1024 snd_opti93x_out_image(chip, OPTi93X_PLAY_LWR_CNT, count);
1025 snd_opti93x_out_image(chip, OPTi93X_PLAY_UPR_CNT, count >> 8);
1026
1027 spin_unlock_irqrestore(&chip->lock, flags);
1028 return 0;
1029}
1030
1031static int snd_opti93x_capture_prepare(struct snd_pcm_substream *substream)
1032{
1033 struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
1034 struct snd_pcm_runtime *runtime = substream->runtime;
1035 unsigned long flags;
1036 unsigned char format;
1037 unsigned int count = snd_pcm_lib_period_bytes(substream);
1038 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1039
1040 spin_lock_irqsave(&chip->lock, flags);
1041
1042 chip->c_dma_size = size;
1043 snd_opti93x_out_mask(chip, OPTi93X_IFACE_CONF,
1044 OPTi93X_CAPTURE_ENABLE | OPTi93X_CAPTURE_PIO, 0);
1045
1046 snd_dma_program(chip->dma2, runtime->dma_addr, size,
1047 DMA_MODE_READ | DMA_AUTOINIT);
1048
1049 format = snd_opti93x_get_freq(runtime->rate);
1050 format |= snd_opti93x_get_format(chip, runtime->format,
1051 runtime->channels);
1052 snd_opti93x_capture_format(chip, format);
1053 format = chip->image[OPTi93X_CAPT_FORMAT];
1054
1055 count = snd_opti93x_get_count(format, count) - 1;
1056 snd_opti93x_out_image(chip, OPTi93X_CAPT_LWR_CNT, count);
1057 snd_opti93x_out_image(chip, OPTi93X_CAPT_UPR_CNT, count >> 8);
1058
1059 spin_unlock_irqrestore(&chip->lock, flags);
1060 return 0;
1061}
1062
1063static snd_pcm_uframes_t snd_opti93x_playback_pointer(struct snd_pcm_substream *substream)
1064{
1065 struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
1066 size_t ptr;
1067
1068 if (!(chip->image[OPTi93X_IFACE_CONF] & OPTi93X_PLAYBACK_ENABLE))
1069 return 0;
1070
1071 ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
1072 return bytes_to_frames(substream->runtime, ptr);
1073}
1074
1075static snd_pcm_uframes_t snd_opti93x_capture_pointer(struct snd_pcm_substream *substream)
1076{
1077 struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
1078 size_t ptr;
1079
1080 if (!(chip->image[OPTi93X_IFACE_CONF] & OPTi93X_CAPTURE_ENABLE))
1081 return 0;
1082
1083 ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
1084 return bytes_to_frames(substream->runtime, ptr);
1085}
1086
1087
1088static void snd_opti93x_overrange(struct snd_opti93x *chip)
1089{
1090 unsigned long flags;
1091
1092 spin_lock_irqsave(&chip->lock, flags);
1093
1094 if (snd_opti93x_in(chip, OPTi93X_ERR_INIT) & (0x08 | 0x02))
1095 chip->capture_substream->runtime->overrange++;
1096
1097 spin_unlock_irqrestore(&chip->lock, flags);
1098}
1099
1100static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id) 559static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
1101{ 560{
1102 struct snd_opti93x *codec = dev_id; 561 struct snd_cs4231 *codec = dev_id;
562 struct snd_opti9xx *chip = codec->card->private_data;
1103 unsigned char status; 563 unsigned char status;
1104 564
1105 status = snd_opti9xx_read(codec->chip, OPTi9XX_MC_REG(11)); 565 status = snd_opti9xx_read(chip, OPTi9XX_MC_REG(11));
1106 if ((status & OPTi93X_IRQ_PLAYBACK) && codec->playback_substream) 566 if ((status & OPTi93X_IRQ_PLAYBACK) && codec->playback_substream)
1107 snd_pcm_period_elapsed(codec->playback_substream); 567 snd_pcm_period_elapsed(codec->playback_substream);
1108 if ((status & OPTi93X_IRQ_CAPTURE) && codec->capture_substream) { 568 if ((status & OPTi93X_IRQ_CAPTURE) && codec->capture_substream) {
1109 snd_opti93x_overrange(codec); 569 snd_cs4231_overrange(codec);
1110 snd_pcm_period_elapsed(codec->capture_substream); 570 snd_pcm_period_elapsed(codec->capture_substream);
1111 } 571 }
1112 outb(0x00, OPTi93X_PORT(codec, STATUS)); 572 outb(0x00, OPTi93X_PORT(codec, STATUS));
1113 return IRQ_HANDLED; 573 return IRQ_HANDLED;
1114} 574}
1115 575
1116
1117static struct snd_pcm_hardware snd_opti93x_playback = {
1118 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1119 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
1120 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1121 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1122 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1123 .rate_min = 5512,
1124 .rate_max = 48000,
1125 .channels_min = 1,
1126 .channels_max = 2,
1127 .buffer_bytes_max = (128*1024),
1128 .period_bytes_min = 64,
1129 .period_bytes_max = (128*1024),
1130 .periods_min = 1,
1131 .periods_max = 1024,
1132 .fifo_size = 0,
1133};
1134
1135static struct snd_pcm_hardware snd_opti93x_capture = {
1136 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1137 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
1138 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1139 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1140 .rates = SNDRV_PCM_RATE_8000_48000,
1141 .rate_min = 5512,
1142 .rate_max = 48000,
1143 .channels_min = 1,
1144 .channels_max = 2,
1145 .buffer_bytes_max = (128*1024),
1146 .period_bytes_min = 64,
1147 .period_bytes_max = (128*1024),
1148 .periods_min = 1,
1149 .periods_max = 1024,
1150 .fifo_size = 0,
1151};
1152
1153static int snd_opti93x_playback_open(struct snd_pcm_substream *substream)
1154{
1155 int error;
1156 struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
1157 struct snd_pcm_runtime *runtime = substream->runtime;
1158
1159 if ((error = snd_opti93x_open(chip, OPTi93X_MODE_PLAY)) < 0)
1160 return error;
1161 snd_pcm_set_sync(substream);
1162 chip->playback_substream = substream;
1163 runtime->hw = snd_opti93x_playback;
1164 snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
1165 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
1166 return error;
1167}
1168
1169static int snd_opti93x_capture_open(struct snd_pcm_substream *substream)
1170{
1171 int error;
1172 struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
1173 struct snd_pcm_runtime *runtime = substream->runtime;
1174
1175 if ((error = snd_opti93x_open(chip, OPTi93X_MODE_CAPTURE)) < 0)
1176 return error;
1177 runtime->hw = snd_opti93x_capture;
1178 snd_pcm_set_sync(substream);
1179 chip->capture_substream = substream;
1180 snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
1181 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
1182 return error;
1183}
1184
1185static int snd_opti93x_playback_close(struct snd_pcm_substream *substream)
1186{
1187 struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
1188
1189 chip->playback_substream = NULL;
1190 snd_opti93x_close(chip, OPTi93X_MODE_PLAY);
1191 return 0;
1192}
1193
1194static int snd_opti93x_capture_close(struct snd_pcm_substream *substream)
1195{
1196 struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
1197
1198 chip->capture_substream = NULL;
1199 snd_opti93x_close(chip, OPTi93X_MODE_CAPTURE);
1200 return 0;
1201}
1202
1203
1204static void snd_opti93x_init(struct snd_opti93x *chip)
1205{
1206 unsigned long flags;
1207 int i;
1208
1209 spin_lock_irqsave(&chip->lock, flags);
1210 snd_opti93x_mce_up(chip);
1211
1212 for (i = 0; i < 32; i++)
1213 snd_opti93x_out_image(chip, i, snd_opti93x_default_image[i]);
1214
1215 snd_opti93x_mce_down(chip);
1216 spin_unlock_irqrestore(&chip->lock, flags);
1217}
1218
1219static int snd_opti93x_probe(struct snd_opti93x *chip)
1220{
1221 unsigned long flags;
1222 unsigned char val;
1223
1224 spin_lock_irqsave(&chip->lock, flags);
1225 val = snd_opti93x_in(chip, OPTi93X_ID) & 0x0f;
1226 spin_unlock_irqrestore(&chip->lock, flags);
1227
1228 return (val == 0x0a) ? 0 : -ENODEV;
1229}
1230
1231static int snd_opti93x_free(struct snd_opti93x *chip)
1232{
1233 release_and_free_resource(chip->res_port);
1234 if (chip->dma1 >= 0) {
1235 disable_dma(chip->dma1);
1236 free_dma(chip->dma1);
1237 }
1238 if (chip->dma2 >= 0) {
1239 disable_dma(chip->dma2);
1240 free_dma(chip->dma2);
1241 }
1242 if (chip->irq >= 0) {
1243 free_irq(chip->irq, chip);
1244 }
1245 kfree(chip);
1246 return 0;
1247}
1248
1249static int snd_opti93x_dev_free(struct snd_device *device)
1250{
1251 struct snd_opti93x *chip = device->device_data;
1252 return snd_opti93x_free(chip);
1253}
1254
1255static const char *snd_opti93x_chip_id(struct snd_opti93x *codec)
1256{
1257 switch (codec->hardware) {
1258 case OPTi9XX_HW_82C930: return "82C930";
1259 case OPTi9XX_HW_82C931: return "82C931";
1260 case OPTi9XX_HW_82C933: return "82C933";
1261 default: return "???";
1262 }
1263}
1264
1265static int snd_opti93x_create(struct snd_card *card, struct snd_opti9xx *chip,
1266 int dma1, int dma2,
1267 struct snd_opti93x **rcodec)
1268{
1269 static struct snd_device_ops ops = {
1270 .dev_free = snd_opti93x_dev_free,
1271 };
1272 int error;
1273 struct snd_opti93x *codec;
1274
1275 *rcodec = NULL;
1276 codec = kzalloc(sizeof(*codec), GFP_KERNEL);
1277 if (codec == NULL)
1278 return -ENOMEM;
1279 codec->irq = -1;
1280 codec->dma1 = -1;
1281 codec->dma2 = -1;
1282
1283 if ((codec->res_port = request_region(chip->wss_base + 4, 4, "OPTI93x CODEC")) == NULL) {
1284 snd_printk(KERN_ERR "opti9xx: can't grab port 0x%lx\n", chip->wss_base + 4);
1285 snd_opti93x_free(codec);
1286 return -EBUSY;
1287 }
1288 if (request_dma(dma1, "OPTI93x - 1")) {
1289 snd_printk(KERN_ERR "opti9xx: can't grab DMA1 %d\n", dma1);
1290 snd_opti93x_free(codec);
1291 return -EBUSY;
1292 }
1293 codec->dma1 = chip->dma1;
1294 if (request_dma(dma2, "OPTI93x - 2")) {
1295 snd_printk(KERN_ERR "opti9xx: can't grab DMA2 %d\n", dma2);
1296 snd_opti93x_free(codec);
1297 return -EBUSY;
1298 }
1299 codec->dma2 = chip->dma2;
1300
1301 if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DEV_NAME" - WSS", codec)) {
1302 snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq);
1303 snd_opti93x_free(codec);
1304 return -EBUSY;
1305 }
1306
1307 codec->card = card;
1308 codec->port = chip->wss_base + 4;
1309 codec->irq = chip->irq;
1310
1311 spin_lock_init(&codec->lock);
1312 codec->hardware = chip->hardware;
1313 codec->chip = chip;
1314
1315 if ((error = snd_opti93x_probe(codec))) {
1316 snd_opti93x_free(codec);
1317 return error;
1318 }
1319
1320 snd_opti93x_init(codec);
1321
1322 /* Register device */
1323 if ((error = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops)) < 0) {
1324 snd_opti93x_free(codec);
1325 return error;
1326 }
1327
1328 *rcodec = codec;
1329 return 0;
1330}
1331
1332static struct snd_pcm_ops snd_opti93x_playback_ops = {
1333 .open = snd_opti93x_playback_open,
1334 .close = snd_opti93x_playback_close,
1335 .ioctl = snd_pcm_lib_ioctl,
1336 .hw_params = snd_opti93x_hw_params,
1337 .hw_free = snd_opti93x_hw_free,
1338 .prepare = snd_opti93x_playback_prepare,
1339 .trigger = snd_opti93x_playback_trigger,
1340 .pointer = snd_opti93x_playback_pointer,
1341};
1342
1343static struct snd_pcm_ops snd_opti93x_capture_ops = {
1344 .open = snd_opti93x_capture_open,
1345 .close = snd_opti93x_capture_close,
1346 .ioctl = snd_pcm_lib_ioctl,
1347 .hw_params = snd_opti93x_hw_params,
1348 .hw_free = snd_opti93x_hw_free,
1349 .prepare = snd_opti93x_capture_prepare,
1350 .trigger = snd_opti93x_capture_trigger,
1351 .pointer = snd_opti93x_capture_pointer,
1352};
1353
1354static int snd_opti93x_pcm(struct snd_opti93x *codec, int device, struct snd_pcm **rpcm)
1355{
1356 int error;
1357 struct snd_pcm *pcm;
1358
1359 if ((error = snd_pcm_new(codec->card, "OPTi 82C93X", device, 1, 1, &pcm)) < 0)
1360 return error;
1361
1362 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_opti93x_playback_ops);
1363 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_opti93x_capture_ops);
1364
1365 pcm->private_data = codec;
1366 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
1367
1368 strcpy(pcm->name, snd_opti93x_chip_id(codec));
1369
1370 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1371 snd_dma_isa_data(),
1372 64*1024, codec->dma1 > 3 || codec->dma2 > 3 ? 128*1024 : 64*1024);
1373
1374 codec->pcm = pcm;
1375 if (rpcm)
1376 *rpcm = pcm;
1377 return 0;
1378}
1379
1380/*
1381 * MIXER part
1382 */
1383
1384static int snd_opti93x_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1385{
1386 static char *texts[4] = {
1387 "Line1", "Aux", "Mic", "Mix"
1388 };
1389
1390 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1391 uinfo->count = 2;
1392 uinfo->value.enumerated.items = 4;
1393 if (uinfo->value.enumerated.item > 3)
1394 uinfo->value.enumerated.item = 3;
1395 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1396 return 0;
1397}
1398
1399static int snd_opti93x_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1400{
1401 struct snd_opti93x *chip = snd_kcontrol_chip(kcontrol);
1402 unsigned long flags;
1403
1404 spin_lock_irqsave(&chip->lock, flags);
1405 ucontrol->value.enumerated.item[0] = (chip->image[OPTi93X_MIXOUT_LEFT] & OPTi93X_MIXOUT_MIXER) >> 6;
1406 ucontrol->value.enumerated.item[1] = (chip->image[OPTi93X_MIXOUT_RIGHT] & OPTi93X_MIXOUT_MIXER) >> 6;
1407 spin_unlock_irqrestore(&chip->lock, flags);
1408 return 0;
1409}
1410
1411static int snd_opti93x_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1412{
1413 struct snd_opti93x *chip = snd_kcontrol_chip(kcontrol);
1414 unsigned long flags;
1415 unsigned short left, right;
1416 int change;
1417
1418 if (ucontrol->value.enumerated.item[0] > 3 ||
1419 ucontrol->value.enumerated.item[1] > 3)
1420 return -EINVAL;
1421 left = ucontrol->value.enumerated.item[0] << 6;
1422 right = ucontrol->value.enumerated.item[1] << 6;
1423 spin_lock_irqsave(&chip->lock, flags);
1424 left = (chip->image[OPTi93X_MIXOUT_LEFT] & ~OPTi93X_MIXOUT_MIXER) | left;
1425 right = (chip->image[OPTi93X_MIXOUT_RIGHT] & ~OPTi93X_MIXOUT_MIXER) | right;
1426 change = left != chip->image[OPTi93X_MIXOUT_LEFT] ||
1427 right != chip->image[OPTi93X_MIXOUT_RIGHT];
1428 snd_opti93x_out_image(chip, OPTi93X_MIXOUT_LEFT, left);
1429 snd_opti93x_out_image(chip, OPTi93X_MIXOUT_RIGHT, right);
1430 spin_unlock_irqrestore(&chip->lock, flags);
1431 return change;
1432}
1433
1434#if 0
1435
1436#define OPTi93X_SINGLE(xname, xindex, reg, shift, mask, invert) \
1437{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1438 .info = snd_opti93x_info_single, \
1439 .get = snd_opti93x_get_single, .put = snd_opti93x_put_single, \
1440 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
1441
1442static int snd_opti93x_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1443{
1444 int mask = (kcontrol->private_value >> 16) & 0xff;
1445
1446 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1447 uinfo->count = 1;
1448 uinfo->value.integer.min = 0;
1449 uinfo->value.integer.max = mask;
1450 return 0;
1451}
1452
1453static int snd_opti93x_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1454{
1455 struct snd_opti93x *chip = snd_kcontrol_chip(kcontrol);
1456 unsigned long flags;
1457 int reg = kcontrol->private_value & 0xff;
1458 int shift = (kcontrol->private_value >> 8) & 0xff;
1459 int mask = (kcontrol->private_value >> 16) & 0xff;
1460 int invert = (kcontrol->private_value >> 24) & 0xff;
1461
1462 spin_lock_irqsave(&chip->lock, flags);
1463 ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
1464 spin_unlock_irqrestore(&chip->lock, flags);
1465 if (invert)
1466 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1467 return 0;
1468}
1469
1470static int snd_opti93x_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1471{
1472 struct snd_opti93x *chip = snd_kcontrol_chip(kcontrol);
1473 unsigned long flags;
1474 int reg = kcontrol->private_value & 0xff;
1475 int shift = (kcontrol->private_value >> 8) & 0xff;
1476 int mask = (kcontrol->private_value >> 16) & 0xff;
1477 int invert = (kcontrol->private_value >> 24) & 0xff;
1478 int change;
1479 unsigned short val;
1480
1481 val = (ucontrol->value.integer.value[0] & mask);
1482 if (invert)
1483 val = mask - val;
1484 val <<= shift;
1485 spin_lock_irqsave(&chip->lock, flags);
1486 val = (chip->image[reg] & ~(mask << shift)) | val;
1487 change = val != chip->image[reg];
1488 snd_opti93x_out(chip, reg, val);
1489 spin_unlock_irqrestore(&chip->lock, flags);
1490 return change;
1491}
1492
1493#endif /* single */
1494
1495#define OPTi93X_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
1496{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1497 .info = snd_opti93x_info_double, \
1498 .get = snd_opti93x_get_double, .put = snd_opti93x_put_double, \
1499 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
1500
1501#define OPTi93X_DOUBLE_INVERT_INVERT(xctl) \
1502 do { xctl.private_value ^= 22; } while (0)
1503#define OPTi93X_DOUBLE_CHANGE_REGS(xctl, left_reg, right_reg) \
1504 do { xctl.private_value &= ~0x0000ffff; \
1505 xctl.private_value |= left_reg | (right_reg << 8); } while (0)
1506
1507static int snd_opti93x_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1508{
1509 int mask = (kcontrol->private_value >> 24) & 0xff;
1510
1511 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1512 uinfo->count = 2;
1513 uinfo->value.integer.min = 0;
1514 uinfo->value.integer.max = mask;
1515 return 0;
1516}
1517
1518static int snd_opti93x_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1519{
1520 struct snd_opti93x *chip = snd_kcontrol_chip(kcontrol);
1521 unsigned long flags;
1522 int left_reg = kcontrol->private_value & 0xff;
1523 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1524 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1525 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1526 int mask = (kcontrol->private_value >> 24) & 0xff;
1527 int invert = (kcontrol->private_value >> 22) & 1;
1528
1529 spin_lock_irqsave(&chip->lock, flags);
1530 ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
1531 ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
1532 spin_unlock_irqrestore(&chip->lock, flags);
1533 if (invert) {
1534 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1535 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
1536 }
1537 return 0;
1538}
1539
1540static int snd_opti93x_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1541{
1542 struct snd_opti93x *chip = snd_kcontrol_chip(kcontrol);
1543 unsigned long flags;
1544 int left_reg = kcontrol->private_value & 0xff;
1545 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1546 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1547 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1548 int mask = (kcontrol->private_value >> 24) & 0xff;
1549 int invert = (kcontrol->private_value >> 22) & 1;
1550 int change;
1551 unsigned short val1, val2;
1552
1553 val1 = ucontrol->value.integer.value[0] & mask;
1554 val2 = ucontrol->value.integer.value[1] & mask;
1555 if (invert) {
1556 val1 = mask - val1;
1557 val2 = mask - val2;
1558 }
1559 val1 <<= shift_left;
1560 val2 <<= shift_right;
1561 spin_lock_irqsave(&chip->lock, flags);
1562 val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
1563 val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
1564 change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg];
1565 snd_opti93x_out_image(chip, left_reg, val1);
1566 snd_opti93x_out_image(chip, right_reg, val2);
1567 spin_unlock_irqrestore(&chip->lock, flags);
1568 return change;
1569}
1570
1571static struct snd_kcontrol_new snd_opti93x_controls[] __devinitdata = {
1572OPTi93X_DOUBLE("Master Playback Switch", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
1573OPTi93X_DOUBLE("Master Playback Volume", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1),
1574OPTi93X_DOUBLE("PCM Playback Switch", 0, OPTi93X_DAC_LEFT, OPTi93X_DAC_RIGHT, 7, 7, 1, 1),
1575OPTi93X_DOUBLE("PCM Playback Volume", 0, OPTi93X_DAC_LEFT, OPTi93X_DAC_RIGHT, 0, 0, 31, 1),
1576OPTi93X_DOUBLE("FM Playback Switch", 0, OPTi931_FM_LEFT_INPUT, OPTi931_FM_RIGHT_INPUT, 7, 7, 1, 1),
1577OPTi93X_DOUBLE("FM Playback Volume", 0, OPTi931_FM_LEFT_INPUT, OPTi931_FM_RIGHT_INPUT, 1, 1, 15, 1),
1578OPTi93X_DOUBLE("Line Playback Switch", 0, OPTi93X_LINE_LEFT_INPUT, OPTi93X_LINE_RIGHT_INPUT, 7, 7, 1, 1),
1579OPTi93X_DOUBLE("Line Playback Volume", 0, OPTi93X_LINE_LEFT_INPUT, OPTi93X_LINE_RIGHT_INPUT, 1, 1, 15, 1),
1580OPTi93X_DOUBLE("Mic Playback Switch", 0, OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
1581OPTi93X_DOUBLE("Mic Playback Volume", 0, OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1),
1582OPTi93X_DOUBLE("Mic Boost", 0, OPTi93X_MIXOUT_LEFT, OPTi93X_MIXOUT_RIGHT, 5, 5, 1, 1),
1583OPTi93X_DOUBLE("CD Playback Switch", 0, OPTi93X_CD_LEFT_INPUT, OPTi93X_CD_RIGHT_INPUT, 7, 7, 1, 1),
1584OPTi93X_DOUBLE("CD Playback Volume", 0, OPTi93X_CD_LEFT_INPUT, OPTi93X_CD_RIGHT_INPUT, 1, 1, 15, 1),
1585OPTi93X_DOUBLE("Aux Playback Switch", 0, OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
1586OPTi93X_DOUBLE("Aux Playback Volume", 0, OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1),
1587OPTi93X_DOUBLE("Capture Volume", 0, OPTi93X_MIXOUT_LEFT, OPTi93X_MIXOUT_RIGHT, 0, 0, 15, 0),
1588{
1589 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1590 .name = "Capture Source",
1591 .info = snd_opti93x_info_mux,
1592 .get = snd_opti93x_get_mux,
1593 .put = snd_opti93x_put_mux,
1594}
1595};
1596
1597static int __devinit snd_opti93x_mixer(struct snd_opti93x *chip)
1598{
1599 struct snd_card *card;
1600 struct snd_kcontrol_new knew;
1601 int err;
1602 unsigned int idx;
1603
1604 snd_assert(chip != NULL && chip->card != NULL, return -EINVAL);
1605
1606 card = chip->card;
1607
1608 strcpy(card->mixername, snd_opti93x_chip_id(chip));
1609
1610 for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
1611 knew = snd_opti93x_controls[idx];
1612 if (chip->hardware == OPTi9XX_HW_82C930) {
1613 if (strstr(knew.name, "FM")) /* skip FM controls */
1614 continue;
1615 else if (strcmp(knew.name, "Mic Playback Volume"))
1616 OPTi93X_DOUBLE_INVERT_INVERT(knew);
1617 else if (strstr(knew.name, "Aux"))
1618 OPTi93X_DOUBLE_CHANGE_REGS(knew, OPTi930_AUX_LEFT_INPUT, OPTi930_AUX_RIGHT_INPUT);
1619 else if (strcmp(knew.name, "PCM Playback Volume"))
1620 OPTi93X_DOUBLE_INVERT_INVERT(knew);
1621 else if (strcmp(knew.name, "Master Playback Volume"))
1622 OPTi93X_DOUBLE_INVERT_INVERT(knew);
1623 }
1624 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_opti93x_controls[idx], chip))) < 0)
1625 return err;
1626 }
1627 return 0;
1628}
1629
1630#endif /* OPTi93X */ 576#endif /* OPTi93X */
1631 577
1632static int __devinit snd_card_opti9xx_detect(struct snd_card *card, 578static int __devinit snd_card_opti9xx_detect(struct snd_card *card,
@@ -1739,8 +685,16 @@ static void snd_card_opti9xx_free(struct snd_card *card)
1739{ 685{
1740 struct snd_opti9xx *chip = card->private_data; 686 struct snd_opti9xx *chip = card->private_data;
1741 687
1742 if (chip) 688 if (chip) {
689#ifdef OPTi93X
690 struct snd_cs4231 *codec = chip->codec;
691 if (codec->irq > 0) {
692 disable_irq(codec->irq);
693 free_irq(codec->irq, codec);
694 }
695#endif
1743 release_and_free_resource(chip->res_mc_base); 696 release_and_free_resource(chip->res_mc_base);
697 }
1744} 698}
1745 699
1746static int __devinit snd_opti9xx_probe(struct snd_card *card) 700static int __devinit snd_opti9xx_probe(struct snd_card *card)
@@ -1748,11 +702,11 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
1748 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; 702 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
1749 int error; 703 int error;
1750 struct snd_opti9xx *chip = card->private_data; 704 struct snd_opti9xx *chip = card->private_data;
1751#if defined(OPTi93X) 705#if defined(CS4231) || defined(OPTi93X)
1752 struct snd_opti93x *codec;
1753#elif defined(CS4231)
1754 struct snd_cs4231 *codec; 706 struct snd_cs4231 *codec;
707#ifdef CS4231
1755 struct snd_timer *timer; 708 struct snd_timer *timer;
709#endif
1756#else 710#else
1757 struct snd_ad1848 *codec; 711 struct snd_ad1848 *codec;
1758#endif 712#endif
@@ -1784,26 +738,34 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
1784 if ((error = snd_opti9xx_configure(chip))) 738 if ((error = snd_opti9xx_configure(chip)))
1785 return error; 739 return error;
1786 740
1787#if defined(OPTi93X) 741#if defined(CS4231) || defined(OPTi93X)
1788 if ((error = snd_opti93x_create(card, chip, chip->dma1, chip->dma2, &codec)))
1789 return error;
1790 if ((error = snd_opti93x_pcm(codec, 0, &pcm)) < 0)
1791 return error;
1792 if ((error = snd_opti93x_mixer(codec)) < 0)
1793 return error;
1794#elif defined(CS4231)
1795 if ((error = snd_cs4231_create(card, chip->wss_base + 4, -1, 742 if ((error = snd_cs4231_create(card, chip->wss_base + 4, -1,
1796 chip->irq, chip->dma1, chip->dma2, 743 chip->irq, chip->dma1, chip->dma2,
1797 CS4231_HW_DETECT, 744#ifdef CS4231
1798 0, 745 CS4231_HW_DETECT, 0,
746#else /* OPTi93x */
747 CS4231_HW_OPTI93X, CS4231_HWSHARE_IRQ,
748#endif
1799 &codec)) < 0) 749 &codec)) < 0)
1800 return error; 750 return error;
751#ifdef OPTi93X
752 chip->codec = codec;
753#endif
1801 if ((error = snd_cs4231_pcm(codec, 0, &pcm)) < 0) 754 if ((error = snd_cs4231_pcm(codec, 0, &pcm)) < 0)
1802 return error; 755 return error;
1803 if ((error = snd_cs4231_mixer(codec)) < 0) 756 if ((error = snd_cs4231_mixer(codec)) < 0)
1804 return error; 757 return error;
758#ifdef CS4231
1805 if ((error = snd_cs4231_timer(codec, 0, &timer)) < 0) 759 if ((error = snd_cs4231_timer(codec, 0, &timer)) < 0)
1806 return error; 760 return error;
761#else /* OPTI93X */
762 error = request_irq(chip->irq, snd_opti93x_interrupt,
763 IRQF_DISABLED, DEV_NAME" - WSS", codec);
764 if (error < 0) {
765 snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq);
766 return error;
767 }
768#endif
1807#else 769#else
1808 if ((error = snd_ad1848_create(card, chip->wss_base + 4, 770 if ((error = snd_ad1848_create(card, chip->wss_base + 4,
1809 chip->irq, chip->dma1, 771 chip->irq, chip->dma1,
diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile
index c9d1c986d70e..1098a56b2f4b 100644
--- a/sound/isa/sb/Makefile
+++ b/sound/isa/sb/Makefile
@@ -34,5 +34,3 @@ ifeq ($(CONFIG_SND_SB16_CSP),y)
34 obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o 34 obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o
35endif 35endif
36obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-emu8000-synth.o 36obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-emu8000-synth.o
37
38obj-m := $(sort $(obj-m))
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index 95eeca163354..0bb9b9256601 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -1939,7 +1939,7 @@ static int __devinit
1939wavefront_download_firmware (snd_wavefront_t *dev, char *path) 1939wavefront_download_firmware (snd_wavefront_t *dev, char *path)
1940 1940
1941{ 1941{
1942 unsigned char *buf; 1942 const unsigned char *buf;
1943 int len, err; 1943 int len, err;
1944 int section_cnt_downloaded = 0; 1944 int section_cnt_downloaded = 0;
1945 const struct firmware *firmware; 1945 const struct firmware *firmware;
diff --git a/sound/mips/Kconfig b/sound/mips/Kconfig
index 531f8ba96a71..a9823fad85c2 100644
--- a/sound/mips/Kconfig
+++ b/sound/mips/Kconfig
@@ -1,15 +1,34 @@
1# ALSA MIPS drivers 1# ALSA MIPS drivers
2 2
3menu "ALSA MIPS devices" 3menuconfig SND_MIPS
4 depends on SND!=n && MIPS 4 bool "MIPS sound devices"
5 depends on MIPS
6 default y
7 help
8 Support for sound devices of MIPS architectures.
9
10if SND_MIPS
11
12config SND_SGI_O2
13 tristate "SGI O2 Audio"
14 depends on SGI_IP32
15 help
16 Sound support for the SGI O2 Workstation.
17
18config SND_SGI_HAL2
19 tristate "SGI HAL2 Audio"
20 depends on SGI_HAS_HAL2
21 help
22 Sound support for the SGI Indy and Indigo2 Workstation.
23
5 24
6config SND_AU1X00 25config SND_AU1X00
7 tristate "Au1x00 AC97 Port Driver" 26 tristate "Au1x00 AC97 Port Driver"
8 depends on (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && SND 27 depends on SOC_AU1000 || SOC_AU1100 || SOC_AU1500
9 select SND_PCM 28 select SND_PCM
10 select SND_AC97_CODEC 29 select SND_AC97_CODEC
11 help 30 help
12 ALSA Sound driver for the Au1x00's AC97 port. 31 ALSA Sound driver for the Au1x00's AC97 port.
13 32
14endmenu 33endif # SND_MIPS
15 34
diff --git a/sound/mips/Makefile b/sound/mips/Makefile
index 47afed971fba..861ec0a574b4 100644
--- a/sound/mips/Makefile
+++ b/sound/mips/Makefile
@@ -3,6 +3,10 @@
3# 3#
4 4
5snd-au1x00-objs := au1x00.o 5snd-au1x00-objs := au1x00.o
6snd-sgi-o2-objs := sgio2audio.o ad1843.o
7snd-sgi-hal2-objs := hal2.o
6 8
7# Toplevel Module Dependency 9# Toplevel Module Dependency
8obj-$(CONFIG_SND_AU1X00) += snd-au1x00.o 10obj-$(CONFIG_SND_AU1X00) += snd-au1x00.o
11obj-$(CONFIG_SND_SGI_O2) += snd-sgi-o2.o
12obj-$(CONFIG_SND_SGI_HAL2) += snd-sgi-hal2.o
diff --git a/sound/mips/ad1843.c b/sound/mips/ad1843.c
new file mode 100644
index 000000000000..c624510ec374
--- /dev/null
+++ b/sound/mips/ad1843.c
@@ -0,0 +1,561 @@
1/*
2 * AD1843 low level driver
3 *
4 * Copyright 2003 Vivien Chappelier <vivien.chappelier@linux-mips.org>
5 * Copyright 2008 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
6 *
7 * inspired from vwsnd.c (SGI VW audio driver)
8 * Copyright 1999 Silicon Graphics, Inc. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26#include <linux/init.h>
27#include <linux/sched.h>
28#include <linux/errno.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/ad1843.h>
32
33/*
34 * AD1843 bitfield definitions. All are named as in the AD1843 data
35 * sheet, with ad1843_ prepended and individual bit numbers removed.
36 *
37 * E.g., bits LSS0 through LSS2 become ad1843_LSS.
38 *
39 * Only the bitfields we need are defined.
40 */
41
42struct ad1843_bitfield {
43 char reg;
44 char lo_bit;
45 char nbits;
46};
47
48static const struct ad1843_bitfield
49 ad1843_PDNO = { 0, 14, 1 }, /* Converter Power-Down Flag */
50 ad1843_INIT = { 0, 15, 1 }, /* Clock Initialization Flag */
51 ad1843_RIG = { 2, 0, 4 }, /* Right ADC Input Gain */
52 ad1843_RMGE = { 2, 4, 1 }, /* Right ADC Mic Gain Enable */
53 ad1843_RSS = { 2, 5, 3 }, /* Right ADC Source Select */
54 ad1843_LIG = { 2, 8, 4 }, /* Left ADC Input Gain */
55 ad1843_LMGE = { 2, 12, 1 }, /* Left ADC Mic Gain Enable */
56 ad1843_LSS = { 2, 13, 3 }, /* Left ADC Source Select */
57 ad1843_RD2M = { 3, 0, 5 }, /* Right DAC 2 Mix Gain/Atten */
58 ad1843_RD2MM = { 3, 7, 1 }, /* Right DAC 2 Mix Mute */
59 ad1843_LD2M = { 3, 8, 5 }, /* Left DAC 2 Mix Gain/Atten */
60 ad1843_LD2MM = { 3, 15, 1 }, /* Left DAC 2 Mix Mute */
61 ad1843_RX1M = { 4, 0, 5 }, /* Right Aux 1 Mix Gain/Atten */
62 ad1843_RX1MM = { 4, 7, 1 }, /* Right Aux 1 Mix Mute */
63 ad1843_LX1M = { 4, 8, 5 }, /* Left Aux 1 Mix Gain/Atten */
64 ad1843_LX1MM = { 4, 15, 1 }, /* Left Aux 1 Mix Mute */
65 ad1843_RX2M = { 5, 0, 5 }, /* Right Aux 2 Mix Gain/Atten */
66 ad1843_RX2MM = { 5, 7, 1 }, /* Right Aux 2 Mix Mute */
67 ad1843_LX2M = { 5, 8, 5 }, /* Left Aux 2 Mix Gain/Atten */
68 ad1843_LX2MM = { 5, 15, 1 }, /* Left Aux 2 Mix Mute */
69 ad1843_RMCM = { 7, 0, 5 }, /* Right Mic Mix Gain/Atten */
70 ad1843_RMCMM = { 7, 7, 1 }, /* Right Mic Mix Mute */
71 ad1843_LMCM = { 7, 8, 5 }, /* Left Mic Mix Gain/Atten */
72 ad1843_LMCMM = { 7, 15, 1 }, /* Left Mic Mix Mute */
73 ad1843_HPOS = { 8, 4, 1 }, /* Headphone Output Voltage Swing */
74 ad1843_HPOM = { 8, 5, 1 }, /* Headphone Output Mute */
75 ad1843_MPOM = { 8, 6, 1 }, /* Mono Output Mute */
76 ad1843_RDA1G = { 9, 0, 6 }, /* Right DAC1 Analog/Digital Gain */
77 ad1843_RDA1GM = { 9, 7, 1 }, /* Right DAC1 Analog Mute */
78 ad1843_LDA1G = { 9, 8, 6 }, /* Left DAC1 Analog/Digital Gain */
79 ad1843_LDA1GM = { 9, 15, 1 }, /* Left DAC1 Analog Mute */
80 ad1843_RDA2G = { 10, 0, 6 }, /* Right DAC2 Analog/Digital Gain */
81 ad1843_RDA2GM = { 10, 7, 1 }, /* Right DAC2 Analog Mute */
82 ad1843_LDA2G = { 10, 8, 6 }, /* Left DAC2 Analog/Digital Gain */
83 ad1843_LDA2GM = { 10, 15, 1 }, /* Left DAC2 Analog Mute */
84 ad1843_RDA1AM = { 11, 7, 1 }, /* Right DAC1 Digital Mute */
85 ad1843_LDA1AM = { 11, 15, 1 }, /* Left DAC1 Digital Mute */
86 ad1843_RDA2AM = { 12, 7, 1 }, /* Right DAC2 Digital Mute */
87 ad1843_LDA2AM = { 12, 15, 1 }, /* Left DAC2 Digital Mute */
88 ad1843_ADLC = { 15, 0, 2 }, /* ADC Left Sample Rate Source */
89 ad1843_ADRC = { 15, 2, 2 }, /* ADC Right Sample Rate Source */
90 ad1843_DA1C = { 15, 8, 2 }, /* DAC1 Sample Rate Source */
91 ad1843_DA2C = { 15, 10, 2 }, /* DAC2 Sample Rate Source */
92 ad1843_C1C = { 17, 0, 16 }, /* Clock 1 Sample Rate Select */
93 ad1843_C2C = { 20, 0, 16 }, /* Clock 2 Sample Rate Select */
94 ad1843_C3C = { 23, 0, 16 }, /* Clock 3 Sample Rate Select */
95 ad1843_DAADL = { 25, 4, 2 }, /* Digital ADC Left Source Select */
96 ad1843_DAADR = { 25, 6, 2 }, /* Digital ADC Right Source Select */
97 ad1843_DAMIX = { 25, 14, 1 }, /* DAC Digital Mix Enable */
98 ad1843_DRSFLT = { 25, 15, 1 }, /* Digital Reampler Filter Mode */
99 ad1843_ADLF = { 26, 0, 2 }, /* ADC Left Channel Data Format */
100 ad1843_ADRF = { 26, 2, 2 }, /* ADC Right Channel Data Format */
101 ad1843_ADTLK = { 26, 4, 1 }, /* ADC Transmit Lock Mode Select */
102 ad1843_SCF = { 26, 7, 1 }, /* SCLK Frequency Select */
103 ad1843_DA1F = { 26, 8, 2 }, /* DAC1 Data Format Select */
104 ad1843_DA2F = { 26, 10, 2 }, /* DAC2 Data Format Select */
105 ad1843_DA1SM = { 26, 14, 1 }, /* DAC1 Stereo/Mono Mode Select */
106 ad1843_DA2SM = { 26, 15, 1 }, /* DAC2 Stereo/Mono Mode Select */
107 ad1843_ADLEN = { 27, 0, 1 }, /* ADC Left Channel Enable */
108 ad1843_ADREN = { 27, 1, 1 }, /* ADC Right Channel Enable */
109 ad1843_AAMEN = { 27, 4, 1 }, /* Analog to Analog Mix Enable */
110 ad1843_ANAEN = { 27, 7, 1 }, /* Analog Channel Enable */
111 ad1843_DA1EN = { 27, 8, 1 }, /* DAC1 Enable */
112 ad1843_DA2EN = { 27, 9, 1 }, /* DAC2 Enable */
113 ad1843_DDMEN = { 27, 12, 1 }, /* DAC2 to DAC1 Mix Enable */
114 ad1843_C1EN = { 28, 11, 1 }, /* Clock Generator 1 Enable */
115 ad1843_C2EN = { 28, 12, 1 }, /* Clock Generator 2 Enable */
116 ad1843_C3EN = { 28, 13, 1 }, /* Clock Generator 3 Enable */
117 ad1843_PDNI = { 28, 15, 1 }; /* Converter Power Down */
118
119/*
120 * The various registers of the AD1843 use three different formats for
121 * specifying gain. The ad1843_gain structure parameterizes the
122 * formats.
123 */
124
125struct ad1843_gain {
126 int negative; /* nonzero if gain is negative. */
127 const struct ad1843_bitfield *lfield;
128 const struct ad1843_bitfield *rfield;
129 const struct ad1843_bitfield *lmute;
130 const struct ad1843_bitfield *rmute;
131};
132
133static const struct ad1843_gain ad1843_gain_RECLEV = {
134 .negative = 0,
135 .lfield = &ad1843_LIG,
136 .rfield = &ad1843_RIG
137};
138static const struct ad1843_gain ad1843_gain_LINE = {
139 .negative = 1,
140 .lfield = &ad1843_LX1M,
141 .rfield = &ad1843_RX1M,
142 .lmute = &ad1843_LX1MM,
143 .rmute = &ad1843_RX1MM
144};
145static const struct ad1843_gain ad1843_gain_LINE_2 = {
146 .negative = 1,
147 .lfield = &ad1843_LDA2G,
148 .rfield = &ad1843_RDA2G,
149 .lmute = &ad1843_LDA2GM,
150 .rmute = &ad1843_RDA2GM
151};
152static const struct ad1843_gain ad1843_gain_MIC = {
153 .negative = 1,
154 .lfield = &ad1843_LMCM,
155 .rfield = &ad1843_RMCM,
156 .lmute = &ad1843_LMCMM,
157 .rmute = &ad1843_RMCMM
158};
159static const struct ad1843_gain ad1843_gain_PCM_0 = {
160 .negative = 1,
161 .lfield = &ad1843_LDA1G,
162 .rfield = &ad1843_RDA1G,
163 .lmute = &ad1843_LDA1GM,
164 .rmute = &ad1843_RDA1GM
165};
166static const struct ad1843_gain ad1843_gain_PCM_1 = {
167 .negative = 1,
168 .lfield = &ad1843_LD2M,
169 .rfield = &ad1843_RD2M,
170 .lmute = &ad1843_LD2MM,
171 .rmute = &ad1843_RD2MM
172};
173
174static const struct ad1843_gain *ad1843_gain[AD1843_GAIN_SIZE] =
175{
176 &ad1843_gain_RECLEV,
177 &ad1843_gain_LINE,
178 &ad1843_gain_LINE_2,
179 &ad1843_gain_MIC,
180 &ad1843_gain_PCM_0,
181 &ad1843_gain_PCM_1,
182};
183
184/* read the current value of an AD1843 bitfield. */
185
186static int ad1843_read_bits(struct snd_ad1843 *ad1843,
187 const struct ad1843_bitfield *field)
188{
189 int w;
190
191 w = ad1843->read(ad1843->chip, field->reg);
192 return w >> field->lo_bit & ((1 << field->nbits) - 1);
193}
194
195/*
196 * write a new value to an AD1843 bitfield and return the old value.
197 */
198
199static int ad1843_write_bits(struct snd_ad1843 *ad1843,
200 const struct ad1843_bitfield *field,
201 int newval)
202{
203 int w, mask, oldval, newbits;
204
205 w = ad1843->read(ad1843->chip, field->reg);
206 mask = ((1 << field->nbits) - 1) << field->lo_bit;
207 oldval = (w & mask) >> field->lo_bit;
208 newbits = (newval << field->lo_bit) & mask;
209 w = (w & ~mask) | newbits;
210 ad1843->write(ad1843->chip, field->reg, w);
211
212 return oldval;
213}
214
215/*
216 * ad1843_read_multi reads multiple bitfields from the same AD1843
217 * register. It uses a single read cycle to do it. (Reading the
218 * ad1843 requires 256 bit times at 12.288 MHz, or nearly 20
219 * microseconds.)
220 *
221 * Called like this.
222 *
223 * ad1843_read_multi(ad1843, nfields,
224 * &ad1843_FIELD1, &val1,
225 * &ad1843_FIELD2, &val2, ...);
226 */
227
228static void ad1843_read_multi(struct snd_ad1843 *ad1843, int argcount, ...)
229{
230 va_list ap;
231 const struct ad1843_bitfield *fp;
232 int w = 0, mask, *value, reg = -1;
233
234 va_start(ap, argcount);
235 while (--argcount >= 0) {
236 fp = va_arg(ap, const struct ad1843_bitfield *);
237 value = va_arg(ap, int *);
238 if (reg == -1) {
239 reg = fp->reg;
240 w = ad1843->read(ad1843->chip, reg);
241 }
242
243 mask = (1 << fp->nbits) - 1;
244 *value = w >> fp->lo_bit & mask;
245 }
246 va_end(ap);
247}
248
249/*
250 * ad1843_write_multi stores multiple bitfields into the same AD1843
251 * register. It uses one read and one write cycle to do it.
252 *
253 * Called like this.
254 *
255 * ad1843_write_multi(ad1843, nfields,
256 * &ad1843_FIELD1, val1,
257 * &ad1843_FIELF2, val2, ...);
258 */
259
260static void ad1843_write_multi(struct snd_ad1843 *ad1843, int argcount, ...)
261{
262 va_list ap;
263 int reg;
264 const struct ad1843_bitfield *fp;
265 int value;
266 int w, m, mask, bits;
267
268 mask = 0;
269 bits = 0;
270 reg = -1;
271
272 va_start(ap, argcount);
273 while (--argcount >= 0) {
274 fp = va_arg(ap, const struct ad1843_bitfield *);
275 value = va_arg(ap, int);
276 if (reg == -1)
277 reg = fp->reg;
278 else
279 BUG_ON(reg != fp->reg);
280 m = ((1 << fp->nbits) - 1) << fp->lo_bit;
281 mask |= m;
282 bits |= (value << fp->lo_bit) & m;
283 }
284 va_end(ap);
285
286 if (~mask & 0xFFFF)
287 w = ad1843->read(ad1843->chip, reg);
288 else
289 w = 0;
290 w = (w & ~mask) | bits;
291 ad1843->write(ad1843->chip, reg, w);
292}
293
294int ad1843_get_gain_max(struct snd_ad1843 *ad1843, int id)
295{
296 const struct ad1843_gain *gp = ad1843_gain[id];
297 int ret;
298
299 ret = (1 << gp->lfield->nbits);
300 if (!gp->lmute)
301 ret -= 1;
302 return ret;
303}
304
305/*
306 * ad1843_get_gain reads the specified register and extracts the gain value
307 * using the supplied gain type.
308 */
309
310int ad1843_get_gain(struct snd_ad1843 *ad1843, int id)
311{
312 int lg, rg, lm, rm;
313 const struct ad1843_gain *gp = ad1843_gain[id];
314 unsigned short mask = (1 << gp->lfield->nbits) - 1;
315
316 ad1843_read_multi(ad1843, 2, gp->lfield, &lg, gp->rfield, &rg);
317 if (gp->negative) {
318 lg = mask - lg;
319 rg = mask - rg;
320 }
321 if (gp->lmute) {
322 ad1843_read_multi(ad1843, 2, gp->lmute, &lm, gp->rmute, &rm);
323 if (lm)
324 lg = 0;
325 if (rm)
326 rg = 0;
327 }
328 return lg << 0 | rg << 8;
329}
330
331/*
332 * Set an audio channel's gain.
333 *
334 * Returns the new gain, which may be lower than the old gain.
335 */
336
337int ad1843_set_gain(struct snd_ad1843 *ad1843, int id, int newval)
338{
339 const struct ad1843_gain *gp = ad1843_gain[id];
340 unsigned short mask = (1 << gp->lfield->nbits) - 1;
341
342 int lg = (newval >> 0) & mask;
343 int rg = (newval >> 8) & mask;
344 int lm = (lg == 0) ? 1 : 0;
345 int rm = (rg == 0) ? 1 : 0;
346
347 if (gp->negative) {
348 lg = mask - lg;
349 rg = mask - rg;
350 }
351 if (gp->lmute)
352 ad1843_write_multi(ad1843, 2, gp->lmute, lm, gp->rmute, rm);
353 ad1843_write_multi(ad1843, 2, gp->lfield, lg, gp->rfield, rg);
354 return ad1843_get_gain(ad1843, id);
355}
356
357/* Returns the current recording source */
358
359int ad1843_get_recsrc(struct snd_ad1843 *ad1843)
360{
361 int val = ad1843_read_bits(ad1843, &ad1843_LSS);
362
363 if (val < 0 || val > 2) {
364 val = 2;
365 ad1843_write_multi(ad1843, 2,
366 &ad1843_LSS, val, &ad1843_RSS, val);
367 }
368 return val;
369}
370
371/*
372 * Set recording source.
373 *
374 * Returns newsrc on success, -errno on failure.
375 */
376
377int ad1843_set_recsrc(struct snd_ad1843 *ad1843, int newsrc)
378{
379 if (newsrc < 0 || newsrc > 2)
380 return -EINVAL;
381
382 ad1843_write_multi(ad1843, 2, &ad1843_LSS, newsrc, &ad1843_RSS, newsrc);
383 return newsrc;
384}
385
386/* Setup ad1843 for D/A conversion. */
387
388void ad1843_setup_dac(struct snd_ad1843 *ad1843,
389 unsigned int id,
390 unsigned int framerate,
391 snd_pcm_format_t fmt,
392 unsigned int channels)
393{
394 int ad_fmt = 0, ad_mode = 0;
395
396 switch (fmt) {
397 case SNDRV_PCM_FORMAT_S8:
398 ad_fmt = 0;
399 break;
400 case SNDRV_PCM_FORMAT_U8:
401 ad_fmt = 0;
402 break;
403 case SNDRV_PCM_FORMAT_S16_LE:
404 ad_fmt = 1;
405 break;
406 case SNDRV_PCM_FORMAT_MU_LAW:
407 ad_fmt = 2;
408 break;
409 case SNDRV_PCM_FORMAT_A_LAW:
410 ad_fmt = 3;
411 break;
412 default:
413 break;
414 }
415
416 switch (channels) {
417 case 2:
418 ad_mode = 0;
419 break;
420 case 1:
421 ad_mode = 1;
422 break;
423 default:
424 break;
425 }
426
427 if (id) {
428 ad1843_write_bits(ad1843, &ad1843_C2C, framerate);
429 ad1843_write_multi(ad1843, 2,
430 &ad1843_DA2SM, ad_mode,
431 &ad1843_DA2F, ad_fmt);
432 } else {
433 ad1843_write_bits(ad1843, &ad1843_C1C, framerate);
434 ad1843_write_multi(ad1843, 2,
435 &ad1843_DA1SM, ad_mode,
436 &ad1843_DA1F, ad_fmt);
437 }
438}
439
440void ad1843_shutdown_dac(struct snd_ad1843 *ad1843, unsigned int id)
441{
442 if (id)
443 ad1843_write_bits(ad1843, &ad1843_DA2F, 1);
444 else
445 ad1843_write_bits(ad1843, &ad1843_DA1F, 1);
446}
447
448void ad1843_setup_adc(struct snd_ad1843 *ad1843,
449 unsigned int framerate,
450 snd_pcm_format_t fmt,
451 unsigned int channels)
452{
453 int da_fmt = 0;
454
455 switch (fmt) {
456 case SNDRV_PCM_FORMAT_S8: da_fmt = 0; break;
457 case SNDRV_PCM_FORMAT_U8: da_fmt = 0; break;
458 case SNDRV_PCM_FORMAT_S16_LE: da_fmt = 1; break;
459 case SNDRV_PCM_FORMAT_MU_LAW: da_fmt = 2; break;
460 case SNDRV_PCM_FORMAT_A_LAW: da_fmt = 3; break;
461 default: break;
462 }
463
464 ad1843_write_bits(ad1843, &ad1843_C3C, framerate);
465 ad1843_write_multi(ad1843, 2,
466 &ad1843_ADLF, da_fmt, &ad1843_ADRF, da_fmt);
467}
468
469void ad1843_shutdown_adc(struct snd_ad1843 *ad1843)
470{
471 /* nothing to do */
472}
473
474/*
475 * Fully initialize the ad1843. As described in the AD1843 data
476 * sheet, section "START-UP SEQUENCE". The numbered comments are
477 * subsection headings from the data sheet. See the data sheet, pages
478 * 52-54, for more info.
479 *
480 * return 0 on success, -errno on failure. */
481
482int ad1843_init(struct snd_ad1843 *ad1843)
483{
484 unsigned long later;
485
486 if (ad1843_read_bits(ad1843, &ad1843_INIT) != 0) {
487 printk(KERN_ERR "ad1843: AD1843 won't initialize\n");
488 return -EIO;
489 }
490
491 ad1843_write_bits(ad1843, &ad1843_SCF, 1);
492
493 /* 4. Put the conversion resources into standby. */
494 ad1843_write_bits(ad1843, &ad1843_PDNI, 0);
495 later = jiffies + msecs_to_jiffies(500);
496
497 while (ad1843_read_bits(ad1843, &ad1843_PDNO)) {
498 if (time_after(jiffies, later)) {
499 printk(KERN_ERR
500 "ad1843: AD1843 won't power up\n");
501 return -EIO;
502 }
503 schedule_timeout_interruptible(5);
504 }
505
506 /* 5. Power up the clock generators and enable clock output pins. */
507 ad1843_write_multi(ad1843, 3,
508 &ad1843_C1EN, 1,
509 &ad1843_C2EN, 1,
510 &ad1843_C3EN, 1);
511
512 /* 6. Configure conversion resources while they are in standby. */
513
514 /* DAC1/2 use clock 1/2 as source, ADC uses clock 3. Always. */
515 ad1843_write_multi(ad1843, 4,
516 &ad1843_DA1C, 1,
517 &ad1843_DA2C, 2,
518 &ad1843_ADLC, 3,
519 &ad1843_ADRC, 3);
520
521 /* 7. Enable conversion resources. */
522 ad1843_write_bits(ad1843, &ad1843_ADTLK, 1);
523 ad1843_write_multi(ad1843, 7,
524 &ad1843_ANAEN, 1,
525 &ad1843_AAMEN, 1,
526 &ad1843_DA1EN, 1,
527 &ad1843_DA2EN, 1,
528 &ad1843_DDMEN, 1,
529 &ad1843_ADLEN, 1,
530 &ad1843_ADREN, 1);
531
532 /* 8. Configure conversion resources while they are enabled. */
533
534 /* set gain to 0 for all channels */
535 ad1843_set_gain(ad1843, AD1843_GAIN_RECLEV, 0);
536 ad1843_set_gain(ad1843, AD1843_GAIN_LINE, 0);
537 ad1843_set_gain(ad1843, AD1843_GAIN_LINE_2, 0);
538 ad1843_set_gain(ad1843, AD1843_GAIN_MIC, 0);
539 ad1843_set_gain(ad1843, AD1843_GAIN_PCM_0, 0);
540 ad1843_set_gain(ad1843, AD1843_GAIN_PCM_1, 0);
541
542 /* Unmute all channels. */
543 /* DAC1 */
544 ad1843_write_multi(ad1843, 2, &ad1843_LDA1GM, 0, &ad1843_RDA1GM, 0);
545 /* DAC2 */
546 ad1843_write_multi(ad1843, 2, &ad1843_LDA2GM, 0, &ad1843_RDA2GM, 0);
547
548 /* Set default recording source to Line In and set
549 * mic gain to +20 dB.
550 */
551 ad1843_set_recsrc(ad1843, 2);
552 ad1843_write_multi(ad1843, 2, &ad1843_LMGE, 1, &ad1843_RMGE, 1);
553
554 /* Set Speaker Out level to +/- 4V and unmute it. */
555 ad1843_write_multi(ad1843, 3,
556 &ad1843_HPOS, 1,
557 &ad1843_HPOM, 0,
558 &ad1843_MPOM, 0);
559
560 return 0;
561}
diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c
new file mode 100644
index 000000000000..db495be01861
--- /dev/null
+++ b/sound/mips/hal2.c
@@ -0,0 +1,947 @@
1/*
2 * Driver for A2 audio system used in SGI machines
3 * Copyright (c) 2008 Thomas Bogendoerfer <tsbogend@alpha.fanken.de>
4 *
5 * Based on OSS code from Ladislav Michl <ladis@linux-mips.org>, which
6 * was based on code from Ulf Carlsson
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 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/interrupt.h>
25#include <linux/dma-mapping.h>
26#include <linux/platform_device.h>
27#include <linux/io.h>
28
29#include <asm/sgi/hpc3.h>
30#include <asm/sgi/ip22.h>
31
32#include <sound/core.h>
33#include <sound/control.h>
34#include <sound/pcm.h>
35#include <sound/pcm-indirect.h>
36#include <sound/initval.h>
37
38#include "hal2.h"
39
40static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
41static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
42
43module_param(index, int, 0444);
44MODULE_PARM_DESC(index, "Index value for SGI HAL2 soundcard.");
45module_param(id, charp, 0444);
46MODULE_PARM_DESC(id, "ID string for SGI HAL2 soundcard.");
47MODULE_DESCRIPTION("ALSA driver for SGI HAL2 audio");
48MODULE_AUTHOR("Thomas Bogendoerfer");
49MODULE_LICENSE("GPL");
50
51
52#define H2_BLOCK_SIZE 1024
53#define H2_BUF_SIZE 16384
54
55struct hal2_pbus {
56 struct hpc3_pbus_dmacregs *pbus;
57 int pbusnr;
58 unsigned int ctrl; /* Current state of pbus->pbdma_ctrl */
59};
60
61struct hal2_desc {
62 struct hpc_dma_desc desc;
63 u32 pad; /* padding */
64};
65
66struct hal2_codec {
67 struct snd_pcm_indirect pcm_indirect;
68 struct snd_pcm_substream *substream;
69
70 unsigned char *buffer;
71 dma_addr_t buffer_dma;
72 struct hal2_desc *desc;
73 dma_addr_t desc_dma;
74 int desc_count;
75 struct hal2_pbus pbus;
76 int voices; /* mono/stereo */
77 unsigned int sample_rate;
78 unsigned int master; /* Master frequency */
79 unsigned short mod; /* MOD value */
80 unsigned short inc; /* INC value */
81};
82
83#define H2_MIX_OUTPUT_ATT 0
84#define H2_MIX_INPUT_GAIN 1
85
86struct snd_hal2 {
87 struct snd_card *card;
88
89 struct hal2_ctl_regs *ctl_regs; /* HAL2 ctl registers */
90 struct hal2_aes_regs *aes_regs; /* HAL2 aes registers */
91 struct hal2_vol_regs *vol_regs; /* HAL2 vol registers */
92 struct hal2_syn_regs *syn_regs; /* HAL2 syn registers */
93
94 struct hal2_codec dac;
95 struct hal2_codec adc;
96};
97
98#define H2_INDIRECT_WAIT(regs) while (hal2_read(&regs->isr) & H2_ISR_TSTATUS);
99
100#define H2_READ_ADDR(addr) (addr | (1<<7))
101#define H2_WRITE_ADDR(addr) (addr)
102
103static inline u32 hal2_read(u32 *reg)
104{
105 return __raw_readl(reg);
106}
107
108static inline void hal2_write(u32 val, u32 *reg)
109{
110 __raw_writel(val, reg);
111}
112
113
114static u32 hal2_i_read32(struct snd_hal2 *hal2, u16 addr)
115{
116 u32 ret;
117 struct hal2_ctl_regs *regs = hal2->ctl_regs;
118
119 hal2_write(H2_READ_ADDR(addr), &regs->iar);
120 H2_INDIRECT_WAIT(regs);
121 ret = hal2_read(&regs->idr0) & 0xffff;
122 hal2_write(H2_READ_ADDR(addr) | 0x1, &regs->iar);
123 H2_INDIRECT_WAIT(regs);
124 ret |= (hal2_read(&regs->idr0) & 0xffff) << 16;
125 return ret;
126}
127
128static void hal2_i_write16(struct snd_hal2 *hal2, u16 addr, u16 val)
129{
130 struct hal2_ctl_regs *regs = hal2->ctl_regs;
131
132 hal2_write(val, &regs->idr0);
133 hal2_write(0, &regs->idr1);
134 hal2_write(0, &regs->idr2);
135 hal2_write(0, &regs->idr3);
136 hal2_write(H2_WRITE_ADDR(addr), &regs->iar);
137 H2_INDIRECT_WAIT(regs);
138}
139
140static void hal2_i_write32(struct snd_hal2 *hal2, u16 addr, u32 val)
141{
142 struct hal2_ctl_regs *regs = hal2->ctl_regs;
143
144 hal2_write(val & 0xffff, &regs->idr0);
145 hal2_write(val >> 16, &regs->idr1);
146 hal2_write(0, &regs->idr2);
147 hal2_write(0, &regs->idr3);
148 hal2_write(H2_WRITE_ADDR(addr), &regs->iar);
149 H2_INDIRECT_WAIT(regs);
150}
151
152static void hal2_i_setbit16(struct snd_hal2 *hal2, u16 addr, u16 bit)
153{
154 struct hal2_ctl_regs *regs = hal2->ctl_regs;
155
156 hal2_write(H2_READ_ADDR(addr), &regs->iar);
157 H2_INDIRECT_WAIT(regs);
158 hal2_write((hal2_read(&regs->idr0) & 0xffff) | bit, &regs->idr0);
159 hal2_write(0, &regs->idr1);
160 hal2_write(0, &regs->idr2);
161 hal2_write(0, &regs->idr3);
162 hal2_write(H2_WRITE_ADDR(addr), &regs->iar);
163 H2_INDIRECT_WAIT(regs);
164}
165
166static void hal2_i_clearbit16(struct snd_hal2 *hal2, u16 addr, u16 bit)
167{
168 struct hal2_ctl_regs *regs = hal2->ctl_regs;
169
170 hal2_write(H2_READ_ADDR(addr), &regs->iar);
171 H2_INDIRECT_WAIT(regs);
172 hal2_write((hal2_read(&regs->idr0) & 0xffff) & ~bit, &regs->idr0);
173 hal2_write(0, &regs->idr1);
174 hal2_write(0, &regs->idr2);
175 hal2_write(0, &regs->idr3);
176 hal2_write(H2_WRITE_ADDR(addr), &regs->iar);
177 H2_INDIRECT_WAIT(regs);
178}
179
180static int hal2_gain_info(struct snd_kcontrol *kcontrol,
181 struct snd_ctl_elem_info *uinfo)
182{
183 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
184 uinfo->count = 2;
185 uinfo->value.integer.min = 0;
186 switch ((int)kcontrol->private_value) {
187 case H2_MIX_OUTPUT_ATT:
188 uinfo->value.integer.max = 31;
189 break;
190 case H2_MIX_INPUT_GAIN:
191 uinfo->value.integer.max = 15;
192 break;
193 }
194 return 0;
195}
196
197static int hal2_gain_get(struct snd_kcontrol *kcontrol,
198 struct snd_ctl_elem_value *ucontrol)
199{
200 struct snd_hal2 *hal2 = snd_kcontrol_chip(kcontrol);
201 u32 tmp;
202 int l, r;
203
204 switch ((int)kcontrol->private_value) {
205 case H2_MIX_OUTPUT_ATT:
206 tmp = hal2_i_read32(hal2, H2I_DAC_C2);
207 if (tmp & H2I_C2_MUTE) {
208 l = 0;
209 r = 0;
210 } else {
211 l = 31 - ((tmp >> H2I_C2_L_ATT_SHIFT) & 31);
212 r = 31 - ((tmp >> H2I_C2_R_ATT_SHIFT) & 31);
213 }
214 break;
215 case H2_MIX_INPUT_GAIN:
216 tmp = hal2_i_read32(hal2, H2I_ADC_C2);
217 l = (tmp >> H2I_C2_L_GAIN_SHIFT) & 15;
218 r = (tmp >> H2I_C2_R_GAIN_SHIFT) & 15;
219 break;
220 }
221 ucontrol->value.integer.value[0] = l;
222 ucontrol->value.integer.value[1] = r;
223
224 return 0;
225}
226
227static int hal2_gain_put(struct snd_kcontrol *kcontrol,
228 struct snd_ctl_elem_value *ucontrol)
229{
230 struct snd_hal2 *hal2 = snd_kcontrol_chip(kcontrol);
231 u32 old, new;
232 int l, r;
233
234 l = ucontrol->value.integer.value[0];
235 r = ucontrol->value.integer.value[1];
236
237 switch ((int)kcontrol->private_value) {
238 case H2_MIX_OUTPUT_ATT:
239 old = hal2_i_read32(hal2, H2I_DAC_C2);
240 new = old & ~(H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE);
241 if (l | r) {
242 l = 31 - l;
243 r = 31 - r;
244 new |= (l << H2I_C2_L_ATT_SHIFT);
245 new |= (r << H2I_C2_R_ATT_SHIFT);
246 } else
247 new |= H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE;
248 hal2_i_write32(hal2, H2I_DAC_C2, new);
249 break;
250 case H2_MIX_INPUT_GAIN:
251 old = hal2_i_read32(hal2, H2I_ADC_C2);
252 new = old & ~(H2I_C2_L_GAIN_M | H2I_C2_R_GAIN_M);
253 new |= (l << H2I_C2_L_GAIN_SHIFT);
254 new |= (r << H2I_C2_R_GAIN_SHIFT);
255 hal2_i_write32(hal2, H2I_ADC_C2, new);
256 break;
257 }
258 return old != new;
259}
260
261static struct snd_kcontrol_new hal2_ctrl_headphone __devinitdata = {
262 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
263 .name = "Headphone Playback Volume",
264 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
265 .private_value = H2_MIX_OUTPUT_ATT,
266 .info = hal2_gain_info,
267 .get = hal2_gain_get,
268 .put = hal2_gain_put,
269};
270
271static struct snd_kcontrol_new hal2_ctrl_mic __devinitdata = {
272 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
273 .name = "Mic Capture Volume",
274 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
275 .private_value = H2_MIX_INPUT_GAIN,
276 .info = hal2_gain_info,
277 .get = hal2_gain_get,
278 .put = hal2_gain_put,
279};
280
281static int __devinit hal2_mixer_create(struct snd_hal2 *hal2)
282{
283 int err;
284
285 /* mute DAC */
286 hal2_i_write32(hal2, H2I_DAC_C2,
287 H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE);
288 /* mute ADC */
289 hal2_i_write32(hal2, H2I_ADC_C2, 0);
290
291 err = snd_ctl_add(hal2->card,
292 snd_ctl_new1(&hal2_ctrl_headphone, hal2));
293 if (err < 0)
294 return err;
295
296 err = snd_ctl_add(hal2->card,
297 snd_ctl_new1(&hal2_ctrl_mic, hal2));
298 if (err < 0)
299 return err;
300
301 return 0;
302}
303
304static irqreturn_t hal2_interrupt(int irq, void *dev_id)
305{
306 struct snd_hal2 *hal2 = dev_id;
307 irqreturn_t ret = IRQ_NONE;
308
309 /* decide what caused this interrupt */
310 if (hal2->dac.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) {
311 snd_pcm_period_elapsed(hal2->dac.substream);
312 ret = IRQ_HANDLED;
313 }
314 if (hal2->adc.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) {
315 snd_pcm_period_elapsed(hal2->adc.substream);
316 ret = IRQ_HANDLED;
317 }
318 return ret;
319}
320
321static int hal2_compute_rate(struct hal2_codec *codec, unsigned int rate)
322{
323 unsigned short mod;
324
325 if (44100 % rate < 48000 % rate) {
326 mod = 4 * 44100 / rate;
327 codec->master = 44100;
328 } else {
329 mod = 4 * 48000 / rate;
330 codec->master = 48000;
331 }
332
333 codec->inc = 4;
334 codec->mod = mod;
335 rate = 4 * codec->master / mod;
336
337 return rate;
338}
339
340static void hal2_set_dac_rate(struct snd_hal2 *hal2)
341{
342 unsigned int master = hal2->dac.master;
343 int inc = hal2->dac.inc;
344 int mod = hal2->dac.mod;
345
346 hal2_i_write16(hal2, H2I_BRES1_C1, (master == 44100) ? 1 : 0);
347 hal2_i_write32(hal2, H2I_BRES1_C2,
348 ((0xffff & (inc - mod - 1)) << 16) | inc);
349}
350
351static void hal2_set_adc_rate(struct snd_hal2 *hal2)
352{
353 unsigned int master = hal2->adc.master;
354 int inc = hal2->adc.inc;
355 int mod = hal2->adc.mod;
356
357 hal2_i_write16(hal2, H2I_BRES2_C1, (master == 44100) ? 1 : 0);
358 hal2_i_write32(hal2, H2I_BRES2_C2,
359 ((0xffff & (inc - mod - 1)) << 16) | inc);
360}
361
362static void hal2_setup_dac(struct snd_hal2 *hal2)
363{
364 unsigned int fifobeg, fifoend, highwater, sample_size;
365 struct hal2_pbus *pbus = &hal2->dac.pbus;
366
367 /* Now we set up some PBUS information. The PBUS needs information about
368 * what portion of the fifo it will use. If it's receiving or
369 * transmitting, and finally whether the stream is little endian or big
370 * endian. The information is written later, on the start call.
371 */
372 sample_size = 2 * hal2->dac.voices;
373 /* Fifo should be set to hold exactly four samples. Highwater mark
374 * should be set to two samples. */
375 highwater = (sample_size * 2) >> 1; /* halfwords */
376 fifobeg = 0; /* playback is first */
377 fifoend = (sample_size * 4) >> 3; /* doublewords */
378 pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_LD |
379 (highwater << 8) | (fifobeg << 16) | (fifoend << 24);
380 /* We disable everything before we do anything at all */
381 pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
382 hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX);
383 /* Setup the HAL2 for playback */
384 hal2_set_dac_rate(hal2);
385 /* Set endianess */
386 hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECTX);
387 /* Set DMA bus */
388 hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
389 /* We are using 1st Bresenham clock generator for playback */
390 hal2_i_write16(hal2, H2I_DAC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT)
391 | (1 << H2I_C1_CLKID_SHIFT)
392 | (hal2->dac.voices << H2I_C1_DATAT_SHIFT));
393}
394
395static void hal2_setup_adc(struct snd_hal2 *hal2)
396{
397 unsigned int fifobeg, fifoend, highwater, sample_size;
398 struct hal2_pbus *pbus = &hal2->adc.pbus;
399
400 sample_size = 2 * hal2->adc.voices;
401 highwater = (sample_size * 2) >> 1; /* halfwords */
402 fifobeg = (4 * 4) >> 3; /* record is second */
403 fifoend = (4 * 4 + sample_size * 4) >> 3; /* doublewords */
404 pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_RCV | HPC3_PDMACTRL_LD |
405 (highwater << 8) | (fifobeg << 16) | (fifoend << 24);
406 pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
407 hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR);
408 /* Setup the HAL2 for record */
409 hal2_set_adc_rate(hal2);
410 /* Set endianess */
411 hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECR);
412 /* Set DMA bus */
413 hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
414 /* We are using 2nd Bresenham clock generator for record */
415 hal2_i_write16(hal2, H2I_ADC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT)
416 | (2 << H2I_C1_CLKID_SHIFT)
417 | (hal2->adc.voices << H2I_C1_DATAT_SHIFT));
418}
419
420static void hal2_start_dac(struct snd_hal2 *hal2)
421{
422 struct hal2_pbus *pbus = &hal2->dac.pbus;
423
424 pbus->pbus->pbdma_dptr = hal2->dac.desc_dma;
425 pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT;
426 /* enable DAC */
427 hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX);
428}
429
430static void hal2_start_adc(struct snd_hal2 *hal2)
431{
432 struct hal2_pbus *pbus = &hal2->adc.pbus;
433
434 pbus->pbus->pbdma_dptr = hal2->adc.desc_dma;
435 pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT;
436 /* enable ADC */
437 hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR);
438}
439
440static inline void hal2_stop_dac(struct snd_hal2 *hal2)
441{
442 hal2->dac.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
443 /* The HAL2 itself may remain enabled safely */
444}
445
446static inline void hal2_stop_adc(struct snd_hal2 *hal2)
447{
448 hal2->adc.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
449}
450
451static int hal2_alloc_dmabuf(struct hal2_codec *codec)
452{
453 struct hal2_desc *desc;
454 dma_addr_t desc_dma, buffer_dma;
455 int count = H2_BUF_SIZE / H2_BLOCK_SIZE;
456 int i;
457
458 codec->buffer = dma_alloc_noncoherent(NULL, H2_BUF_SIZE,
459 &buffer_dma, GFP_KERNEL);
460 if (!codec->buffer)
461 return -ENOMEM;
462 desc = dma_alloc_noncoherent(NULL, count * sizeof(struct hal2_desc),
463 &desc_dma, GFP_KERNEL);
464 if (!desc) {
465 dma_free_noncoherent(NULL, H2_BUF_SIZE,
466 codec->buffer, buffer_dma);
467 return -ENOMEM;
468 }
469 codec->buffer_dma = buffer_dma;
470 codec->desc_dma = desc_dma;
471 codec->desc = desc;
472 for (i = 0; i < count; i++) {
473 desc->desc.pbuf = buffer_dma + i * H2_BLOCK_SIZE;
474 desc->desc.cntinfo = HPCDMA_XIE | H2_BLOCK_SIZE;
475 desc->desc.pnext = (i == count - 1) ?
476 desc_dma : desc_dma + (i + 1) * sizeof(struct hal2_desc);
477 desc++;
478 }
479 dma_cache_sync(NULL, codec->desc, count * sizeof(struct hal2_desc),
480 DMA_TO_DEVICE);
481 codec->desc_count = count;
482 return 0;
483}
484
485static void hal2_free_dmabuf(struct hal2_codec *codec)
486{
487 dma_free_noncoherent(NULL, codec->desc_count * sizeof(struct hal2_desc),
488 codec->desc, codec->desc_dma);
489 dma_free_noncoherent(NULL, H2_BUF_SIZE, codec->buffer,
490 codec->buffer_dma);
491}
492
493static struct snd_pcm_hardware hal2_pcm_hw = {
494 .info = (SNDRV_PCM_INFO_MMAP |
495 SNDRV_PCM_INFO_MMAP_VALID |
496 SNDRV_PCM_INFO_INTERLEAVED |
497 SNDRV_PCM_INFO_BLOCK_TRANSFER),
498 .formats = SNDRV_PCM_FMTBIT_S16_BE,
499 .rates = SNDRV_PCM_RATE_8000_48000,
500 .rate_min = 8000,
501 .rate_max = 48000,
502 .channels_min = 2,
503 .channels_max = 2,
504 .buffer_bytes_max = 65536,
505 .period_bytes_min = 1024,
506 .period_bytes_max = 65536,
507 .periods_min = 2,
508 .periods_max = 1024,
509};
510
511static int hal2_pcm_hw_params(struct snd_pcm_substream *substream,
512 struct snd_pcm_hw_params *params)
513{
514 int err;
515
516 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
517 if (err < 0)
518 return err;
519
520 return 0;
521}
522
523static int hal2_pcm_hw_free(struct snd_pcm_substream *substream)
524{
525 return snd_pcm_lib_free_pages(substream);
526}
527
528static int hal2_playback_open(struct snd_pcm_substream *substream)
529{
530 struct snd_pcm_runtime *runtime = substream->runtime;
531 struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
532 int err;
533
534 runtime->hw = hal2_pcm_hw;
535
536 err = hal2_alloc_dmabuf(&hal2->dac);
537 if (err)
538 return err;
539 return 0;
540}
541
542static int hal2_playback_close(struct snd_pcm_substream *substream)
543{
544 struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
545
546 hal2_free_dmabuf(&hal2->dac);
547 return 0;
548}
549
550static int hal2_playback_prepare(struct snd_pcm_substream *substream)
551{
552 struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
553 struct snd_pcm_runtime *runtime = substream->runtime;
554 struct hal2_codec *dac = &hal2->dac;
555
556 dac->voices = runtime->channels;
557 dac->sample_rate = hal2_compute_rate(dac, runtime->rate);
558 memset(&dac->pcm_indirect, 0, sizeof(dac->pcm_indirect));
559 dac->pcm_indirect.hw_buffer_size = H2_BUF_SIZE;
560 dac->pcm_indirect.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
561 dac->substream = substream;
562 hal2_setup_dac(hal2);
563 return 0;
564}
565
566static int hal2_playback_trigger(struct snd_pcm_substream *substream, int cmd)
567{
568 struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
569
570 switch (cmd) {
571 case SNDRV_PCM_TRIGGER_START:
572 hal2->dac.pcm_indirect.hw_io = hal2->dac.buffer_dma;
573 hal2->dac.pcm_indirect.hw_data = 0;
574 substream->ops->ack(substream);
575 hal2_start_dac(hal2);
576 break;
577 case SNDRV_PCM_TRIGGER_STOP:
578 hal2_stop_dac(hal2);
579 break;
580 default:
581 return -EINVAL;
582 }
583 return 0;
584}
585
586static snd_pcm_uframes_t
587hal2_playback_pointer(struct snd_pcm_substream *substream)
588{
589 struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
590 struct hal2_codec *dac = &hal2->dac;
591
592 return snd_pcm_indirect_playback_pointer(substream, &dac->pcm_indirect,
593 dac->pbus.pbus->pbdma_bptr);
594}
595
596static void hal2_playback_transfer(struct snd_pcm_substream *substream,
597 struct snd_pcm_indirect *rec, size_t bytes)
598{
599 struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
600 unsigned char *buf = hal2->dac.buffer + rec->hw_data;
601
602 memcpy(buf, substream->runtime->dma_area + rec->sw_data, bytes);
603 dma_cache_sync(NULL, buf, bytes, DMA_TO_DEVICE);
604
605}
606
607static int hal2_playback_ack(struct snd_pcm_substream *substream)
608{
609 struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
610 struct hal2_codec *dac = &hal2->dac;
611
612 dac->pcm_indirect.hw_queue_size = H2_BUF_SIZE / 2;
613 snd_pcm_indirect_playback_transfer(substream,
614 &dac->pcm_indirect,
615 hal2_playback_transfer);
616 return 0;
617}
618
619static int hal2_capture_open(struct snd_pcm_substream *substream)
620{
621 struct snd_pcm_runtime *runtime = substream->runtime;
622 struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
623 struct hal2_codec *adc = &hal2->adc;
624 int err;
625
626 runtime->hw = hal2_pcm_hw;
627
628 err = hal2_alloc_dmabuf(adc);
629 if (err)
630 return err;
631 return 0;
632}
633
634static int hal2_capture_close(struct snd_pcm_substream *substream)
635{
636 struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
637
638 hal2_free_dmabuf(&hal2->adc);
639 return 0;
640}
641
642static int hal2_capture_prepare(struct snd_pcm_substream *substream)
643{
644 struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
645 struct snd_pcm_runtime *runtime = substream->runtime;
646 struct hal2_codec *adc = &hal2->adc;
647
648 adc->voices = runtime->channels;
649 adc->sample_rate = hal2_compute_rate(adc, runtime->rate);
650 memset(&adc->pcm_indirect, 0, sizeof(adc->pcm_indirect));
651 adc->pcm_indirect.hw_buffer_size = H2_BUF_SIZE;
652 adc->pcm_indirect.hw_queue_size = H2_BUF_SIZE / 2;
653 adc->pcm_indirect.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
654 adc->substream = substream;
655 hal2_setup_adc(hal2);
656 return 0;
657}
658
659static int hal2_capture_trigger(struct snd_pcm_substream *substream, int cmd)
660{
661 struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
662
663 switch (cmd) {
664 case SNDRV_PCM_TRIGGER_START:
665 hal2->adc.pcm_indirect.hw_io = hal2->adc.buffer_dma;
666 hal2->adc.pcm_indirect.hw_data = 0;
667 printk(KERN_DEBUG "buffer_dma %x\n", hal2->adc.buffer_dma);
668 hal2_start_adc(hal2);
669 break;
670 case SNDRV_PCM_TRIGGER_STOP:
671 hal2_stop_adc(hal2);
672 break;
673 default:
674 return -EINVAL;
675 }
676 return 0;
677}
678
679static snd_pcm_uframes_t
680hal2_capture_pointer(struct snd_pcm_substream *substream)
681{
682 struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
683 struct hal2_codec *adc = &hal2->adc;
684
685 return snd_pcm_indirect_capture_pointer(substream, &adc->pcm_indirect,
686 adc->pbus.pbus->pbdma_bptr);
687}
688
689static void hal2_capture_transfer(struct snd_pcm_substream *substream,
690 struct snd_pcm_indirect *rec, size_t bytes)
691{
692 struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
693 unsigned char *buf = hal2->adc.buffer + rec->hw_data;
694
695 dma_cache_sync(NULL, buf, bytes, DMA_FROM_DEVICE);
696 memcpy(substream->runtime->dma_area + rec->sw_data, buf, bytes);
697}
698
699static int hal2_capture_ack(struct snd_pcm_substream *substream)
700{
701 struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
702 struct hal2_codec *adc = &hal2->adc;
703
704 snd_pcm_indirect_capture_transfer(substream,
705 &adc->pcm_indirect,
706 hal2_capture_transfer);
707 return 0;
708}
709
710static struct snd_pcm_ops hal2_playback_ops = {
711 .open = hal2_playback_open,
712 .close = hal2_playback_close,
713 .ioctl = snd_pcm_lib_ioctl,
714 .hw_params = hal2_pcm_hw_params,
715 .hw_free = hal2_pcm_hw_free,
716 .prepare = hal2_playback_prepare,
717 .trigger = hal2_playback_trigger,
718 .pointer = hal2_playback_pointer,
719 .ack = hal2_playback_ack,
720};
721
722static struct snd_pcm_ops hal2_capture_ops = {
723 .open = hal2_capture_open,
724 .close = hal2_capture_close,
725 .ioctl = snd_pcm_lib_ioctl,
726 .hw_params = hal2_pcm_hw_params,
727 .hw_free = hal2_pcm_hw_free,
728 .prepare = hal2_capture_prepare,
729 .trigger = hal2_capture_trigger,
730 .pointer = hal2_capture_pointer,
731 .ack = hal2_capture_ack,
732};
733
734static int __devinit hal2_pcm_create(struct snd_hal2 *hal2)
735{
736 struct snd_pcm *pcm;
737 int err;
738
739 /* create first pcm device with one outputs and one input */
740 err = snd_pcm_new(hal2->card, "SGI HAL2 Audio", 0, 1, 1, &pcm);
741 if (err < 0)
742 return err;
743
744 pcm->private_data = hal2;
745 strcpy(pcm->name, "SGI HAL2");
746
747 /* set operators */
748 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
749 &hal2_playback_ops);
750 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
751 &hal2_capture_ops);
752 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
753 snd_dma_continuous_data(GFP_KERNEL),
754 0, 1024 * 1024);
755
756 return 0;
757}
758
759static int hal2_dev_free(struct snd_device *device)
760{
761 struct snd_hal2 *hal2 = device->device_data;
762
763 free_irq(SGI_HPCDMA_IRQ, hal2);
764 kfree(hal2);
765 return 0;
766}
767
768static struct snd_device_ops hal2_ops = {
769 .dev_free = hal2_dev_free,
770};
771
772static void hal2_init_codec(struct hal2_codec *codec, struct hpc3_regs *hpc3,
773 int index)
774{
775 codec->pbus.pbusnr = index;
776 codec->pbus.pbus = &hpc3->pbdma[index];
777}
778
779static int hal2_detect(struct snd_hal2 *hal2)
780{
781 unsigned short board, major, minor;
782 unsigned short rev;
783
784 /* reset HAL2 */
785 hal2_write(0, &hal2->ctl_regs->isr);
786
787 /* release reset */
788 hal2_write(H2_ISR_GLOBAL_RESET_N | H2_ISR_CODEC_RESET_N,
789 &hal2->ctl_regs->isr);
790
791
792 hal2_i_write16(hal2, H2I_RELAY_C, H2I_RELAY_C_STATE);
793 rev = hal2_read(&hal2->ctl_regs->rev);
794 if (rev & H2_REV_AUDIO_PRESENT)
795 return -ENODEV;
796
797 board = (rev & H2_REV_BOARD_M) >> 12;
798 major = (rev & H2_REV_MAJOR_CHIP_M) >> 4;
799 minor = (rev & H2_REV_MINOR_CHIP_M);
800
801 printk(KERN_INFO "SGI HAL2 revision %i.%i.%i\n",
802 board, major, minor);
803
804 return 0;
805}
806
807static int hal2_create(struct snd_card *card, struct snd_hal2 **rchip)
808{
809 struct snd_hal2 *hal2;
810 struct hpc3_regs *hpc3 = hpc3c0;
811 int err;
812
813 hal2 = kzalloc(sizeof(struct snd_hal2), GFP_KERNEL);
814 if (!hal2)
815 return -ENOMEM;
816
817 hal2->card = card;
818
819 if (request_irq(SGI_HPCDMA_IRQ, hal2_interrupt, IRQF_SHARED,
820 "SGI HAL2", hal2)) {
821 printk(KERN_ERR "HAL2: Can't get irq %d\n", SGI_HPCDMA_IRQ);
822 kfree(hal2);
823 return -EAGAIN;
824 }
825
826 hal2->ctl_regs = (struct hal2_ctl_regs *)hpc3->pbus_extregs[0];
827 hal2->aes_regs = (struct hal2_aes_regs *)hpc3->pbus_extregs[1];
828 hal2->vol_regs = (struct hal2_vol_regs *)hpc3->pbus_extregs[2];
829 hal2->syn_regs = (struct hal2_syn_regs *)hpc3->pbus_extregs[3];
830
831 if (hal2_detect(hal2) < 0) {
832 kfree(hal2);
833 return -ENODEV;
834 }
835
836 hal2_init_codec(&hal2->dac, hpc3, 0);
837 hal2_init_codec(&hal2->adc, hpc3, 1);
838
839 /*
840 * All DMA channel interfaces in HAL2 are designed to operate with
841 * PBUS programmed for 2 cycles in D3, 2 cycles in D4 and 2 cycles
842 * in D5. HAL2 is a 16-bit device which can accept both big and little
843 * endian format. It assumes that even address bytes are on high
844 * portion of PBUS (15:8) and assumes that HPC3 is programmed to
845 * accept a live (unsynchronized) version of P_DREQ_N from HAL2.
846 */
847#define HAL2_PBUS_DMACFG ((0 << HPC3_DMACFG_D3R_SHIFT) | \
848 (2 << HPC3_DMACFG_D4R_SHIFT) | \
849 (2 << HPC3_DMACFG_D5R_SHIFT) | \
850 (0 << HPC3_DMACFG_D3W_SHIFT) | \
851 (2 << HPC3_DMACFG_D4W_SHIFT) | \
852 (2 << HPC3_DMACFG_D5W_SHIFT) | \
853 HPC3_DMACFG_DS16 | \
854 HPC3_DMACFG_EVENHI | \
855 HPC3_DMACFG_RTIME | \
856 (8 << HPC3_DMACFG_BURST_SHIFT) | \
857 HPC3_DMACFG_DRQLIVE)
858 /*
859 * Ignore what's mentioned in the specification and write value which
860 * works in The Real World (TM)
861 */
862 hpc3->pbus_dmacfg[hal2->dac.pbus.pbusnr][0] = 0x8208844;
863 hpc3->pbus_dmacfg[hal2->adc.pbus.pbusnr][0] = 0x8208844;
864
865 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, hal2, &hal2_ops);
866 if (err < 0) {
867 free_irq(SGI_HPCDMA_IRQ, hal2);
868 kfree(hal2);
869 return err;
870 }
871 *rchip = hal2;
872 return 0;
873}
874
875static int __devinit hal2_probe(struct platform_device *pdev)
876{
877 struct snd_card *card;
878 struct snd_hal2 *chip;
879 int err;
880
881 card = snd_card_new(index, id, THIS_MODULE, 0);
882 if (card == NULL)
883 return -ENOMEM;
884
885 err = hal2_create(card, &chip);
886 if (err < 0) {
887 snd_card_free(card);
888 return err;
889 }
890 snd_card_set_dev(card, &pdev->dev);
891
892 err = hal2_pcm_create(chip);
893 if (err < 0) {
894 snd_card_free(card);
895 return err;
896 }
897 err = hal2_mixer_create(chip);
898 if (err < 0) {
899 snd_card_free(card);
900 return err;
901 }
902
903 strcpy(card->driver, "SGI HAL2 Audio");
904 strcpy(card->shortname, "SGI HAL2 Audio");
905 sprintf(card->longname, "%s irq %i",
906 card->shortname,
907 SGI_HPCDMA_IRQ);
908
909 err = snd_card_register(card);
910 if (err < 0) {
911 snd_card_free(card);
912 return err;
913 }
914 platform_set_drvdata(pdev, card);
915 return 0;
916}
917
918static int __exit hal2_remove(struct platform_device *pdev)
919{
920 struct snd_card *card = platform_get_drvdata(pdev);
921
922 snd_card_free(card);
923 platform_set_drvdata(pdev, NULL);
924 return 0;
925}
926
927static struct platform_driver hal2_driver = {
928 .probe = hal2_probe,
929 .remove = __devexit_p(hal2_remove),
930 .driver = {
931 .name = "sgihal2",
932 .owner = THIS_MODULE,
933 }
934};
935
936static int __init alsa_card_hal2_init(void)
937{
938 return platform_driver_register(&hal2_driver);
939}
940
941static void __exit alsa_card_hal2_exit(void)
942{
943 platform_driver_unregister(&hal2_driver);
944}
945
946module_init(alsa_card_hal2_init);
947module_exit(alsa_card_hal2_exit);
diff --git a/sound/mips/hal2.h b/sound/mips/hal2.h
new file mode 100644
index 000000000000..f19828bc64e0
--- /dev/null
+++ b/sound/mips/hal2.h
@@ -0,0 +1,245 @@
1#ifndef __HAL2_H
2#define __HAL2_H
3
4/*
5 * Driver for HAL2 sound processors
6 * Copyright (c) 1999 Ulf Carlsson <ulfc@bun.falkenberg.se>
7 * Copyright (c) 2001, 2002, 2003 Ladislav Michl <ladis@linux-mips.org>
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 * 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#include <linux/types.h>
25
26/* Indirect status register */
27
28#define H2_ISR_TSTATUS 0x01 /* RO: transaction status 1=busy */
29#define H2_ISR_USTATUS 0x02 /* RO: utime status bit 1=armed */
30#define H2_ISR_QUAD_MODE 0x04 /* codec mode 0=indigo 1=quad */
31#define H2_ISR_GLOBAL_RESET_N 0x08 /* chip global reset 0=reset */
32#define H2_ISR_CODEC_RESET_N 0x10 /* codec/synth reset 0=reset */
33
34/* Revision register */
35
36#define H2_REV_AUDIO_PRESENT 0x8000 /* RO: audio present 0=present */
37#define H2_REV_BOARD_M 0x7000 /* RO: bits 14:12, board revision */
38#define H2_REV_MAJOR_CHIP_M 0x00F0 /* RO: bits 7:4, major chip revision */
39#define H2_REV_MINOR_CHIP_M 0x000F /* RO: bits 3:0, minor chip revision */
40
41/* Indirect address register */
42
43/*
44 * Address of indirect internal register to be accessed. A write to this
45 * register initiates read or write access to the indirect registers in the
46 * HAL2. Note that there af four indirect data registers for write access to
47 * registers larger than 16 byte.
48 */
49
50#define H2_IAR_TYPE_M 0xF000 /* bits 15:12, type of functional */
51 /* block the register resides in */
52 /* 1=DMA Port */
53 /* 9=Global DMA Control */
54 /* 2=Bresenham */
55 /* 3=Unix Timer */
56#define H2_IAR_NUM_M 0x0F00 /* bits 11:8 instance of the */
57 /* blockin which the indirect */
58 /* register resides */
59 /* If IAR_TYPE_M=DMA Port: */
60 /* 1=Synth In */
61 /* 2=AES In */
62 /* 3=AES Out */
63 /* 4=DAC Out */
64 /* 5=ADC Out */
65 /* 6=Synth Control */
66 /* If IAR_TYPE_M=Global DMA Control: */
67 /* 1=Control */
68 /* If IAR_TYPE_M=Bresenham: */
69 /* 1=Bresenham Clock Gen 1 */
70 /* 2=Bresenham Clock Gen 2 */
71 /* 3=Bresenham Clock Gen 3 */
72 /* If IAR_TYPE_M=Unix Timer: */
73 /* 1=Unix Timer */
74#define H2_IAR_ACCESS_SELECT 0x0080 /* 1=read 0=write */
75#define H2_IAR_PARAM 0x000C /* Parameter Select */
76#define H2_IAR_RB_INDEX_M 0x0003 /* Read Back Index */
77 /* 00:word0 */
78 /* 01:word1 */
79 /* 10:word2 */
80 /* 11:word3 */
81/*
82 * HAL2 internal addressing
83 *
84 * The HAL2 has "indirect registers" (idr) which are accessed by writing to the
85 * Indirect Data registers. Write the address to the Indirect Address register
86 * to transfer the data.
87 *
88 * We define the H2IR_* to the read address and H2IW_* to the write address and
89 * H2I_* to be fields in whatever register is referred to.
90 *
91 * When we write to indirect registers which are larger than one word (16 bit)
92 * we have to fill more than one indirect register before writing. When we read
93 * back however we have to read several times, each time with different Read
94 * Back Indexes (there are defs for doing this easily).
95 */
96
97/*
98 * Relay Control
99 */
100#define H2I_RELAY_C 0x9100
101#define H2I_RELAY_C_STATE 0x01 /* state of RELAY pin signal */
102
103/* DMA port enable */
104
105#define H2I_DMA_PORT_EN 0x9104
106#define H2I_DMA_PORT_EN_SY_IN 0x01 /* Synth_in DMA port */
107#define H2I_DMA_PORT_EN_AESRX 0x02 /* AES receiver DMA port */
108#define H2I_DMA_PORT_EN_AESTX 0x04 /* AES transmitter DMA port */
109#define H2I_DMA_PORT_EN_CODECTX 0x08 /* CODEC transmit DMA port */
110#define H2I_DMA_PORT_EN_CODECR 0x10 /* CODEC receive DMA port */
111
112#define H2I_DMA_END 0x9108 /* global dma endian select */
113#define H2I_DMA_END_SY_IN 0x01 /* Synth_in DMA port */
114#define H2I_DMA_END_AESRX 0x02 /* AES receiver DMA port */
115#define H2I_DMA_END_AESTX 0x04 /* AES transmitter DMA port */
116#define H2I_DMA_END_CODECTX 0x08 /* CODEC transmit DMA port */
117#define H2I_DMA_END_CODECR 0x10 /* CODEC receive DMA port */
118 /* 0=b_end 1=l_end */
119
120#define H2I_DMA_DRV 0x910C /* global PBUS DMA enable */
121
122#define H2I_SYNTH_C 0x1104 /* Synth DMA control */
123
124#define H2I_AESRX_C 0x1204 /* AES RX dma control */
125
126#define H2I_C_TS_EN 0x20 /* Timestamp enable */
127#define H2I_C_TS_FRMT 0x40 /* Timestamp format */
128#define H2I_C_NAUDIO 0x80 /* Sign extend */
129
130/* AESRX CTL, 16 bit */
131
132#define H2I_AESTX_C 0x1304 /* AES TX DMA control */
133#define H2I_AESTX_C_CLKID_SHIFT 3 /* Bresenham Clock Gen 1-3 */
134#define H2I_AESTX_C_CLKID_M 0x18
135#define H2I_AESTX_C_DATAT_SHIFT 8 /* 1=mono 2=stereo (3=quad) */
136#define H2I_AESTX_C_DATAT_M 0x300
137
138/* CODEC registers */
139
140#define H2I_DAC_C1 0x1404 /* DAC DMA control, 16 bit */
141#define H2I_DAC_C2 0x1408 /* DAC DMA control, 32 bit */
142#define H2I_ADC_C1 0x1504 /* ADC DMA control, 16 bit */
143#define H2I_ADC_C2 0x1508 /* ADC DMA control, 32 bit */
144
145/* Bits in CTL1 register */
146
147#define H2I_C1_DMA_SHIFT 0 /* DMA channel */
148#define H2I_C1_DMA_M 0x7
149#define H2I_C1_CLKID_SHIFT 3 /* Bresenham Clock Gen 1-3 */
150#define H2I_C1_CLKID_M 0x18
151#define H2I_C1_DATAT_SHIFT 8 /* 1=mono 2=stereo (3=quad) */
152#define H2I_C1_DATAT_M 0x300
153
154/* Bits in CTL2 register */
155
156#define H2I_C2_R_GAIN_SHIFT 0 /* right a/d input gain */
157#define H2I_C2_R_GAIN_M 0xf
158#define H2I_C2_L_GAIN_SHIFT 4 /* left a/d input gain */
159#define H2I_C2_L_GAIN_M 0xf0
160#define H2I_C2_R_SEL 0x100 /* right input select */
161#define H2I_C2_L_SEL 0x200 /* left input select */
162#define H2I_C2_MUTE 0x400 /* mute */
163#define H2I_C2_DO1 0x00010000 /* digital output port bit 0 */
164#define H2I_C2_DO2 0x00020000 /* digital output port bit 1 */
165#define H2I_C2_R_ATT_SHIFT 18 /* right d/a output - */
166#define H2I_C2_R_ATT_M 0x007c0000 /* attenuation */
167#define H2I_C2_L_ATT_SHIFT 23 /* left d/a output - */
168#define H2I_C2_L_ATT_M 0x0f800000 /* attenuation */
169
170#define H2I_SYNTH_MAP_C 0x1104 /* synth dma handshake ctrl */
171
172/* Clock generator CTL 1, 16 bit */
173
174#define H2I_BRES1_C1 0x2104
175#define H2I_BRES2_C1 0x2204
176#define H2I_BRES3_C1 0x2304
177
178#define H2I_BRES_C1_SHIFT 0 /* 0=48.0 1=44.1 2=aes_rx */
179#define H2I_BRES_C1_M 0x03
180
181/* Clock generator CTL 2, 32 bit */
182
183#define H2I_BRES1_C2 0x2108
184#define H2I_BRES2_C2 0x2208
185#define H2I_BRES3_C2 0x2308
186
187#define H2I_BRES_C2_INC_SHIFT 0 /* increment value */
188#define H2I_BRES_C2_INC_M 0xffff
189#define H2I_BRES_C2_MOD_SHIFT 16 /* modcontrol value */
190#define H2I_BRES_C2_MOD_M 0xffff0000 /* modctrl=0xffff&(modinc-1) */
191
192/* Unix timer, 64 bit */
193
194#define H2I_UTIME 0x3104
195#define H2I_UTIME_0_LD 0xffff /* microseconds, LSB's */
196#define H2I_UTIME_1_LD0 0x0f /* microseconds, MSB's */
197#define H2I_UTIME_1_LD1 0xf0 /* tenths of microseconds */
198#define H2I_UTIME_2_LD 0xffff /* seconds, LSB's */
199#define H2I_UTIME_3_LD 0xffff /* seconds, MSB's */
200
201struct hal2_ctl_regs {
202 u32 _unused0[4];
203 u32 isr; /* 0x10 Status Register */
204 u32 _unused1[3];
205 u32 rev; /* 0x20 Revision Register */
206 u32 _unused2[3];
207 u32 iar; /* 0x30 Indirect Address Register */
208 u32 _unused3[3];
209 u32 idr0; /* 0x40 Indirect Data Register 0 */
210 u32 _unused4[3];
211 u32 idr1; /* 0x50 Indirect Data Register 1 */
212 u32 _unused5[3];
213 u32 idr2; /* 0x60 Indirect Data Register 2 */
214 u32 _unused6[3];
215 u32 idr3; /* 0x70 Indirect Data Register 3 */
216};
217
218struct hal2_aes_regs {
219 u32 rx_stat[2]; /* Status registers */
220 u32 rx_cr[2]; /* Control registers */
221 u32 rx_ud[4]; /* User data window */
222 u32 rx_st[24]; /* Channel status data */
223
224 u32 tx_stat[1]; /* Status register */
225 u32 tx_cr[3]; /* Control registers */
226 u32 tx_ud[4]; /* User data window */
227 u32 tx_st[24]; /* Channel status data */
228};
229
230struct hal2_vol_regs {
231 u32 right; /* Right volume */
232 u32 left; /* Left volume */
233};
234
235struct hal2_syn_regs {
236 u32 _unused0[2];
237 u32 page; /* DOC Page register */
238 u32 regsel; /* DOC Register selection */
239 u32 dlow; /* DOC Data low */
240 u32 dhigh; /* DOC Data high */
241 u32 irq; /* IRQ Status */
242 u32 dram; /* DRAM Access */
243};
244
245#endif /* __HAL2_H */
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c
new file mode 100644
index 000000000000..4c63504348dc
--- /dev/null
+++ b/sound/mips/sgio2audio.c
@@ -0,0 +1,1006 @@
1/*
2 * Sound driver for Silicon Graphics O2 Workstations A/V board audio.
3 *
4 * Copyright 2003 Vivien Chappelier <vivien.chappelier@linux-mips.org>
5 * Copyright 2008 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
6 * Mxier part taken from mace_audio.c:
7 * Copyright 2007 Thorben Jändling <tj.trevelyan@gmail.com>
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 as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/spinlock.h>
28#include <linux/gfp.h>
29#include <linux/vmalloc.h>
30#include <linux/interrupt.h>
31#include <linux/dma-mapping.h>
32#include <linux/platform_device.h>
33#include <linux/io.h>
34
35#include <asm/ip32/ip32_ints.h>
36#include <asm/ip32/mace.h>
37
38#include <sound/core.h>
39#include <sound/control.h>
40#include <sound/pcm.h>
41#define SNDRV_GET_ID
42#include <sound/initval.h>
43#include <sound/ad1843.h>
44
45
46MODULE_AUTHOR("Vivien Chappelier <vivien.chappelier@linux-mips.org>");
47MODULE_DESCRIPTION("SGI O2 Audio");
48MODULE_LICENSE("GPL");
49MODULE_SUPPORTED_DEVICE("{{Silicon Graphics, O2 Audio}}");
50
51static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
52static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
53
54module_param(index, int, 0444);
55MODULE_PARM_DESC(index, "Index value for SGI O2 soundcard.");
56module_param(id, charp, 0444);
57MODULE_PARM_DESC(id, "ID string for SGI O2 soundcard.");
58
59
60#define AUDIO_CONTROL_RESET BIT(0) /* 1: reset audio interface */
61#define AUDIO_CONTROL_CODEC_PRESENT BIT(1) /* 1: codec detected */
62
63#define CODEC_CONTROL_WORD_SHIFT 0
64#define CODEC_CONTROL_READ BIT(16)
65#define CODEC_CONTROL_ADDRESS_SHIFT 17
66
67#define CHANNEL_CONTROL_RESET BIT(10) /* 1: reset channel */
68#define CHANNEL_DMA_ENABLE BIT(9) /* 1: enable DMA transfer */
69#define CHANNEL_INT_THRESHOLD_DISABLED (0 << 5) /* interrupt disabled */
70#define CHANNEL_INT_THRESHOLD_25 (1 << 5) /* int on buffer >25% full */
71#define CHANNEL_INT_THRESHOLD_50 (2 << 5) /* int on buffer >50% full */
72#define CHANNEL_INT_THRESHOLD_75 (3 << 5) /* int on buffer >75% full */
73#define CHANNEL_INT_THRESHOLD_EMPTY (4 << 5) /* int on buffer empty */
74#define CHANNEL_INT_THRESHOLD_NOT_EMPTY (5 << 5) /* int on buffer !empty */
75#define CHANNEL_INT_THRESHOLD_FULL (6 << 5) /* int on buffer empty */
76#define CHANNEL_INT_THRESHOLD_NOT_FULL (7 << 5) /* int on buffer !empty */
77
78#define CHANNEL_RING_SHIFT 12
79#define CHANNEL_RING_SIZE (1 << CHANNEL_RING_SHIFT)
80#define CHANNEL_RING_MASK (CHANNEL_RING_SIZE - 1)
81
82#define CHANNEL_LEFT_SHIFT 40
83#define CHANNEL_RIGHT_SHIFT 8
84
85struct snd_sgio2audio_chan {
86 int idx;
87 struct snd_pcm_substream *substream;
88 int pos;
89 snd_pcm_uframes_t size;
90 spinlock_t lock;
91};
92
93/* definition of the chip-specific record */
94struct snd_sgio2audio {
95 struct snd_card *card;
96
97 /* codec */
98 struct snd_ad1843 ad1843;
99 spinlock_t ad1843_lock;
100
101 /* channels */
102 struct snd_sgio2audio_chan channel[3];
103
104 /* resources */
105 void *ring_base;
106 dma_addr_t ring_base_dma;
107};
108
109/* AD1843 access */
110
111/*
112 * read_ad1843_reg returns the current contents of a 16 bit AD1843 register.
113 *
114 * Returns unsigned register value on success, -errno on failure.
115 */
116static int read_ad1843_reg(void *priv, int reg)
117{
118 struct snd_sgio2audio *chip = priv;
119 int val;
120 unsigned long flags;
121
122 spin_lock_irqsave(&chip->ad1843_lock, flags);
123
124 writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) |
125 CODEC_CONTROL_READ, &mace->perif.audio.codec_control);
126 wmb();
127 val = readq(&mace->perif.audio.codec_control); /* flush bus */
128 udelay(200);
129
130 val = readq(&mace->perif.audio.codec_read);
131
132 spin_unlock_irqrestore(&chip->ad1843_lock, flags);
133 return val;
134}
135
136/*
137 * write_ad1843_reg writes the specified value to a 16 bit AD1843 register.
138 */
139static int write_ad1843_reg(void *priv, int reg, int word)
140{
141 struct snd_sgio2audio *chip = priv;
142 int val;
143 unsigned long flags;
144
145 spin_lock_irqsave(&chip->ad1843_lock, flags);
146
147 writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) |
148 (word << CODEC_CONTROL_WORD_SHIFT),
149 &mace->perif.audio.codec_control);
150 wmb();
151 val = readq(&mace->perif.audio.codec_control); /* flush bus */
152 udelay(200);
153
154 spin_unlock_irqrestore(&chip->ad1843_lock, flags);
155 return 0;
156}
157
158static int sgio2audio_gain_info(struct snd_kcontrol *kcontrol,
159 struct snd_ctl_elem_info *uinfo)
160{
161 struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
162
163 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
164 uinfo->count = 2;
165 uinfo->value.integer.min = 0;
166 uinfo->value.integer.max = ad1843_get_gain_max(&chip->ad1843,
167 (int)kcontrol->private_value);
168 return 0;
169}
170
171static int sgio2audio_gain_get(struct snd_kcontrol *kcontrol,
172 struct snd_ctl_elem_value *ucontrol)
173{
174 struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
175 int vol;
176
177 vol = ad1843_get_gain(&chip->ad1843, (int)kcontrol->private_value);
178
179 ucontrol->value.integer.value[0] = (vol >> 8) & 0xFF;
180 ucontrol->value.integer.value[1] = vol & 0xFF;
181
182 return 0;
183}
184
185static int sgio2audio_gain_put(struct snd_kcontrol *kcontrol,
186 struct snd_ctl_elem_value *ucontrol)
187{
188 struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
189 int newvol, oldvol;
190
191 oldvol = ad1843_get_gain(&chip->ad1843, kcontrol->private_value);
192 newvol = (ucontrol->value.integer.value[0] << 8) |
193 ucontrol->value.integer.value[1];
194
195 newvol = ad1843_set_gain(&chip->ad1843, kcontrol->private_value,
196 newvol);
197
198 return newvol != oldvol;
199}
200
201static int sgio2audio_source_info(struct snd_kcontrol *kcontrol,
202 struct snd_ctl_elem_info *uinfo)
203{
204 static const char *texts[3] = {
205 "Cam Mic", "Mic", "Line"
206 };
207 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
208 uinfo->count = 1;
209 uinfo->value.enumerated.items = 3;
210 if (uinfo->value.enumerated.item >= 3)
211 uinfo->value.enumerated.item = 1;
212 strcpy(uinfo->value.enumerated.name,
213 texts[uinfo->value.enumerated.item]);
214 return 0;
215}
216
217static int sgio2audio_source_get(struct snd_kcontrol *kcontrol,
218 struct snd_ctl_elem_value *ucontrol)
219{
220 struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
221
222 ucontrol->value.enumerated.item[0] = ad1843_get_recsrc(&chip->ad1843);
223 return 0;
224}
225
226static int sgio2audio_source_put(struct snd_kcontrol *kcontrol,
227 struct snd_ctl_elem_value *ucontrol)
228{
229 struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
230 int newsrc, oldsrc;
231
232 oldsrc = ad1843_get_recsrc(&chip->ad1843);
233 newsrc = ad1843_set_recsrc(&chip->ad1843,
234 ucontrol->value.enumerated.item[0]);
235
236 return newsrc != oldsrc;
237}
238
239/* dac1/pcm0 mixer control */
240static struct snd_kcontrol_new sgio2audio_ctrl_pcm0 __devinitdata = {
241 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
242 .name = "PCM Playback Volume",
243 .index = 0,
244 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
245 .private_value = AD1843_GAIN_PCM_0,
246 .info = sgio2audio_gain_info,
247 .get = sgio2audio_gain_get,
248 .put = sgio2audio_gain_put,
249};
250
251/* dac2/pcm1 mixer control */
252static struct snd_kcontrol_new sgio2audio_ctrl_pcm1 __devinitdata = {
253 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
254 .name = "PCM Playback Volume",
255 .index = 1,
256 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
257 .private_value = AD1843_GAIN_PCM_1,
258 .info = sgio2audio_gain_info,
259 .get = sgio2audio_gain_get,
260 .put = sgio2audio_gain_put,
261};
262
263/* record level mixer control */
264static struct snd_kcontrol_new sgio2audio_ctrl_reclevel __devinitdata = {
265 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
266 .name = "Capture Volume",
267 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
268 .private_value = AD1843_GAIN_RECLEV,
269 .info = sgio2audio_gain_info,
270 .get = sgio2audio_gain_get,
271 .put = sgio2audio_gain_put,
272};
273
274/* record level source control */
275static struct snd_kcontrol_new sgio2audio_ctrl_recsource __devinitdata = {
276 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
277 .name = "Capture Source",
278 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
279 .info = sgio2audio_source_info,
280 .get = sgio2audio_source_get,
281 .put = sgio2audio_source_put,
282};
283
284/* line mixer control */
285static struct snd_kcontrol_new sgio2audio_ctrl_line __devinitdata = {
286 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
287 .name = "Line Playback Volume",
288 .index = 0,
289 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
290 .private_value = AD1843_GAIN_LINE,
291 .info = sgio2audio_gain_info,
292 .get = sgio2audio_gain_get,
293 .put = sgio2audio_gain_put,
294};
295
296/* cd mixer control */
297static struct snd_kcontrol_new sgio2audio_ctrl_cd __devinitdata = {
298 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
299 .name = "Line Playback Volume",
300 .index = 1,
301 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
302 .private_value = AD1843_GAIN_LINE_2,
303 .info = sgio2audio_gain_info,
304 .get = sgio2audio_gain_get,
305 .put = sgio2audio_gain_put,
306};
307
308/* mic mixer control */
309static struct snd_kcontrol_new sgio2audio_ctrl_mic __devinitdata = {
310 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
311 .name = "Mic Playback Volume",
312 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
313 .private_value = AD1843_GAIN_MIC,
314 .info = sgio2audio_gain_info,
315 .get = sgio2audio_gain_get,
316 .put = sgio2audio_gain_put,
317};
318
319
320static int __devinit snd_sgio2audio_new_mixer(struct snd_sgio2audio *chip)
321{
322 int err;
323
324 err = snd_ctl_add(chip->card,
325 snd_ctl_new1(&sgio2audio_ctrl_pcm0, chip));
326 if (err < 0)
327 return err;
328
329 err = snd_ctl_add(chip->card,
330 snd_ctl_new1(&sgio2audio_ctrl_pcm1, chip));
331 if (err < 0)
332 return err;
333
334 err = snd_ctl_add(chip->card,
335 snd_ctl_new1(&sgio2audio_ctrl_reclevel, chip));
336 if (err < 0)
337 return err;
338
339 err = snd_ctl_add(chip->card,
340 snd_ctl_new1(&sgio2audio_ctrl_recsource, chip));
341 if (err < 0)
342 return err;
343 err = snd_ctl_add(chip->card,
344 snd_ctl_new1(&sgio2audio_ctrl_line, chip));
345 if (err < 0)
346 return err;
347
348 err = snd_ctl_add(chip->card,
349 snd_ctl_new1(&sgio2audio_ctrl_cd, chip));
350 if (err < 0)
351 return err;
352
353 err = snd_ctl_add(chip->card,
354 snd_ctl_new1(&sgio2audio_ctrl_mic, chip));
355 if (err < 0)
356 return err;
357
358 return 0;
359}
360
361/* low-level audio interface DMA */
362
363/* get data out of bounce buffer, count must be a multiple of 32 */
364/* returns 1 if a period has elapsed */
365static int snd_sgio2audio_dma_pull_frag(struct snd_sgio2audio *chip,
366 unsigned int ch, unsigned int count)
367{
368 int ret;
369 unsigned long src_base, src_pos, dst_mask;
370 unsigned char *dst_base;
371 int dst_pos;
372 u64 *src;
373 s16 *dst;
374 u64 x;
375 unsigned long flags;
376 struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime;
377
378 spin_lock_irqsave(&chip->channel[ch].lock, flags);
379
380 src_base = (unsigned long) chip->ring_base | (ch << CHANNEL_RING_SHIFT);
381 src_pos = readq(&mace->perif.audio.chan[ch].read_ptr);
382 dst_base = runtime->dma_area;
383 dst_pos = chip->channel[ch].pos;
384 dst_mask = frames_to_bytes(runtime, runtime->buffer_size) - 1;
385
386 /* check if a period has elapsed */
387 chip->channel[ch].size += (count >> 3); /* in frames */
388 ret = chip->channel[ch].size >= runtime->period_size;
389 chip->channel[ch].size %= runtime->period_size;
390
391 while (count) {
392 src = (u64 *)(src_base + src_pos);
393 dst = (s16 *)(dst_base + dst_pos);
394
395 x = *src;
396 dst[0] = (x >> CHANNEL_LEFT_SHIFT) & 0xffff;
397 dst[1] = (x >> CHANNEL_RIGHT_SHIFT) & 0xffff;
398
399 src_pos = (src_pos + sizeof(u64)) & CHANNEL_RING_MASK;
400 dst_pos = (dst_pos + 2 * sizeof(s16)) & dst_mask;
401 count -= sizeof(u64);
402 }
403
404 writeq(src_pos, &mace->perif.audio.chan[ch].read_ptr); /* in bytes */
405 chip->channel[ch].pos = dst_pos;
406
407 spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
408 return ret;
409}
410
411/* put some DMA data in bounce buffer, count must be a multiple of 32 */
412/* returns 1 if a period has elapsed */
413static int snd_sgio2audio_dma_push_frag(struct snd_sgio2audio *chip,
414 unsigned int ch, unsigned int count)
415{
416 int ret;
417 s64 l, r;
418 unsigned long dst_base, dst_pos, src_mask;
419 unsigned char *src_base;
420 int src_pos;
421 u64 *dst;
422 s16 *src;
423 unsigned long flags;
424 struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime;
425
426 spin_lock_irqsave(&chip->channel[ch].lock, flags);
427
428 dst_base = (unsigned long)chip->ring_base | (ch << CHANNEL_RING_SHIFT);
429 dst_pos = readq(&mace->perif.audio.chan[ch].write_ptr);
430 src_base = runtime->dma_area;
431 src_pos = chip->channel[ch].pos;
432 src_mask = frames_to_bytes(runtime, runtime->buffer_size) - 1;
433
434 /* check if a period has elapsed */
435 chip->channel[ch].size += (count >> 3); /* in frames */
436 ret = chip->channel[ch].size >= runtime->period_size;
437 chip->channel[ch].size %= runtime->period_size;
438
439 while (count) {
440 src = (s16 *)(src_base + src_pos);
441 dst = (u64 *)(dst_base + dst_pos);
442
443 l = src[0]; /* sign extend */
444 r = src[1]; /* sign extend */
445
446 *dst = ((l & 0x00ffffff) << CHANNEL_LEFT_SHIFT) |
447 ((r & 0x00ffffff) << CHANNEL_RIGHT_SHIFT);
448
449 dst_pos = (dst_pos + sizeof(u64)) & CHANNEL_RING_MASK;
450 src_pos = (src_pos + 2 * sizeof(s16)) & src_mask;
451 count -= sizeof(u64);
452 }
453
454 writeq(dst_pos, &mace->perif.audio.chan[ch].write_ptr); /* in bytes */
455 chip->channel[ch].pos = src_pos;
456
457 spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
458 return ret;
459}
460
461static int snd_sgio2audio_dma_start(struct snd_pcm_substream *substream)
462{
463 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
464 struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
465 int ch = chan->idx;
466
467 /* reset DMA channel */
468 writeq(CHANNEL_CONTROL_RESET, &mace->perif.audio.chan[ch].control);
469 udelay(10);
470 writeq(0, &mace->perif.audio.chan[ch].control);
471
472 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
473 /* push a full buffer */
474 snd_sgio2audio_dma_push_frag(chip, ch, CHANNEL_RING_SIZE - 32);
475 }
476 /* set DMA to wake on 50% empty and enable interrupt */
477 writeq(CHANNEL_DMA_ENABLE | CHANNEL_INT_THRESHOLD_50,
478 &mace->perif.audio.chan[ch].control);
479 return 0;
480}
481
482static int snd_sgio2audio_dma_stop(struct snd_pcm_substream *substream)
483{
484 struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
485
486 writeq(0, &mace->perif.audio.chan[chan->idx].control);
487 return 0;
488}
489
490static irqreturn_t snd_sgio2audio_dma_in_isr(int irq, void *dev_id)
491{
492 struct snd_sgio2audio_chan *chan = dev_id;
493 struct snd_pcm_substream *substream;
494 struct snd_sgio2audio *chip;
495 int count, ch;
496
497 substream = chan->substream;
498 chip = snd_pcm_substream_chip(substream);
499 ch = chan->idx;
500
501 /* empty the ring */
502 count = CHANNEL_RING_SIZE -
503 readq(&mace->perif.audio.chan[ch].depth) - 32;
504 if (snd_sgio2audio_dma_pull_frag(chip, ch, count))
505 snd_pcm_period_elapsed(substream);
506
507 return IRQ_HANDLED;
508}
509
510static irqreturn_t snd_sgio2audio_dma_out_isr(int irq, void *dev_id)
511{
512 struct snd_sgio2audio_chan *chan = dev_id;
513 struct snd_pcm_substream *substream;
514 struct snd_sgio2audio *chip;
515 int count, ch;
516
517 substream = chan->substream;
518 chip = snd_pcm_substream_chip(substream);
519 ch = chan->idx;
520 /* fill the ring */
521 count = CHANNEL_RING_SIZE -
522 readq(&mace->perif.audio.chan[ch].depth) - 32;
523 if (snd_sgio2audio_dma_push_frag(chip, ch, count))
524 snd_pcm_period_elapsed(substream);
525
526 return IRQ_HANDLED;
527}
528
529static irqreturn_t snd_sgio2audio_error_isr(int irq, void *dev_id)
530{
531 struct snd_sgio2audio_chan *chan = dev_id;
532 struct snd_pcm_substream *substream;
533
534 substream = chan->substream;
535 snd_sgio2audio_dma_stop(substream);
536 snd_sgio2audio_dma_start(substream);
537 return IRQ_HANDLED;
538}
539
540/* PCM part */
541/* PCM hardware definition */
542static struct snd_pcm_hardware snd_sgio2audio_pcm_hw = {
543 .info = (SNDRV_PCM_INFO_MMAP |
544 SNDRV_PCM_INFO_MMAP_VALID |
545 SNDRV_PCM_INFO_INTERLEAVED |
546 SNDRV_PCM_INFO_BLOCK_TRANSFER),
547 .formats = SNDRV_PCM_FMTBIT_S16_BE,
548 .rates = SNDRV_PCM_RATE_8000_48000,
549 .rate_min = 8000,
550 .rate_max = 48000,
551 .channels_min = 2,
552 .channels_max = 2,
553 .buffer_bytes_max = 65536,
554 .period_bytes_min = 32768,
555 .period_bytes_max = 65536,
556 .periods_min = 1,
557 .periods_max = 1024,
558};
559
560/* PCM playback open callback */
561static int snd_sgio2audio_playback1_open(struct snd_pcm_substream *substream)
562{
563 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
564 struct snd_pcm_runtime *runtime = substream->runtime;
565
566 runtime->hw = snd_sgio2audio_pcm_hw;
567 runtime->private_data = &chip->channel[1];
568 return 0;
569}
570
571static int snd_sgio2audio_playback2_open(struct snd_pcm_substream *substream)
572{
573 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
574 struct snd_pcm_runtime *runtime = substream->runtime;
575
576 runtime->hw = snd_sgio2audio_pcm_hw;
577 runtime->private_data = &chip->channel[2];
578 return 0;
579}
580
581/* PCM capture open callback */
582static int snd_sgio2audio_capture_open(struct snd_pcm_substream *substream)
583{
584 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
585 struct snd_pcm_runtime *runtime = substream->runtime;
586
587 runtime->hw = snd_sgio2audio_pcm_hw;
588 runtime->private_data = &chip->channel[0];
589 return 0;
590}
591
592/* PCM close callback */
593static int snd_sgio2audio_pcm_close(struct snd_pcm_substream *substream)
594{
595 struct snd_pcm_runtime *runtime = substream->runtime;
596
597 runtime->private_data = NULL;
598 return 0;
599}
600
601
602/* hw_params callback */
603static int snd_sgio2audio_pcm_hw_params(struct snd_pcm_substream *substream,
604 struct snd_pcm_hw_params *hw_params)
605{
606 struct snd_pcm_runtime *runtime = substream->runtime;
607 int size = params_buffer_bytes(hw_params);
608
609 /* alloc virtual 'dma' area */
610 if (runtime->dma_area)
611 vfree(runtime->dma_area);
612 runtime->dma_area = vmalloc(size);
613 if (runtime->dma_area == NULL)
614 return -ENOMEM;
615 runtime->dma_bytes = size;
616 return 0;
617}
618
619/* hw_free callback */
620static int snd_sgio2audio_pcm_hw_free(struct snd_pcm_substream *substream)
621{
622 if (substream->runtime->dma_area)
623 vfree(substream->runtime->dma_area);
624 substream->runtime->dma_area = NULL;
625 return 0;
626}
627
628/* prepare callback */
629static int snd_sgio2audio_pcm_prepare(struct snd_pcm_substream *substream)
630{
631 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
632 struct snd_pcm_runtime *runtime = substream->runtime;
633 struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
634 int ch = chan->idx;
635 unsigned long flags;
636
637 spin_lock_irqsave(&chip->channel[ch].lock, flags);
638
639 /* Setup the pseudo-dma transfer pointers. */
640 chip->channel[ch].pos = 0;
641 chip->channel[ch].size = 0;
642 chip->channel[ch].substream = substream;
643
644 /* set AD1843 format */
645 /* hardware format is always S16_LE */
646 switch (substream->stream) {
647 case SNDRV_PCM_STREAM_PLAYBACK:
648 ad1843_setup_dac(&chip->ad1843,
649 ch - 1,
650 runtime->rate,
651 SNDRV_PCM_FORMAT_S16_LE,
652 runtime->channels);
653 break;
654 case SNDRV_PCM_STREAM_CAPTURE:
655 ad1843_setup_adc(&chip->ad1843,
656 runtime->rate,
657 SNDRV_PCM_FORMAT_S16_LE,
658 runtime->channels);
659 break;
660 }
661 spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
662 return 0;
663}
664
665/* trigger callback */
666static int snd_sgio2audio_pcm_trigger(struct snd_pcm_substream *substream,
667 int cmd)
668{
669 switch (cmd) {
670 case SNDRV_PCM_TRIGGER_START:
671 /* start the PCM engine */
672 snd_sgio2audio_dma_start(substream);
673 break;
674 case SNDRV_PCM_TRIGGER_STOP:
675 /* stop the PCM engine */
676 snd_sgio2audio_dma_stop(substream);
677 break;
678 default:
679 return -EINVAL;
680 }
681 return 0;
682}
683
684/* pointer callback */
685static snd_pcm_uframes_t
686snd_sgio2audio_pcm_pointer(struct snd_pcm_substream *substream)
687{
688 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
689 struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
690
691 /* get the current hardware pointer */
692 return bytes_to_frames(substream->runtime,
693 chip->channel[chan->idx].pos);
694}
695
696/* get the physical page pointer on the given offset */
697static struct page *snd_sgio2audio_page(struct snd_pcm_substream *substream,
698 unsigned long offset)
699{
700 return vmalloc_to_page(substream->runtime->dma_area + offset);
701}
702
703/* operators */
704static struct snd_pcm_ops snd_sgio2audio_playback1_ops = {
705 .open = snd_sgio2audio_playback1_open,
706 .close = snd_sgio2audio_pcm_close,
707 .ioctl = snd_pcm_lib_ioctl,
708 .hw_params = snd_sgio2audio_pcm_hw_params,
709 .hw_free = snd_sgio2audio_pcm_hw_free,
710 .prepare = snd_sgio2audio_pcm_prepare,
711 .trigger = snd_sgio2audio_pcm_trigger,
712 .pointer = snd_sgio2audio_pcm_pointer,
713 .page = snd_sgio2audio_page,
714};
715
716static struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
717 .open = snd_sgio2audio_playback2_open,
718 .close = snd_sgio2audio_pcm_close,
719 .ioctl = snd_pcm_lib_ioctl,
720 .hw_params = snd_sgio2audio_pcm_hw_params,
721 .hw_free = snd_sgio2audio_pcm_hw_free,
722 .prepare = snd_sgio2audio_pcm_prepare,
723 .trigger = snd_sgio2audio_pcm_trigger,
724 .pointer = snd_sgio2audio_pcm_pointer,
725 .page = snd_sgio2audio_page,
726};
727
728static struct snd_pcm_ops snd_sgio2audio_capture_ops = {
729 .open = snd_sgio2audio_capture_open,
730 .close = snd_sgio2audio_pcm_close,
731 .ioctl = snd_pcm_lib_ioctl,
732 .hw_params = snd_sgio2audio_pcm_hw_params,
733 .hw_free = snd_sgio2audio_pcm_hw_free,
734 .prepare = snd_sgio2audio_pcm_prepare,
735 .trigger = snd_sgio2audio_pcm_trigger,
736 .pointer = snd_sgio2audio_pcm_pointer,
737 .page = snd_sgio2audio_page,
738};
739
740/*
741 * definitions of capture are omitted here...
742 */
743
744/* create a pcm device */
745static int __devinit snd_sgio2audio_new_pcm(struct snd_sgio2audio *chip)
746{
747 struct snd_pcm *pcm;
748 int err;
749
750 /* create first pcm device with one outputs and one input */
751 err = snd_pcm_new(chip->card, "SGI O2 Audio", 0, 1, 1, &pcm);
752 if (err < 0)
753 return err;
754
755 pcm->private_data = chip;
756 strcpy(pcm->name, "SGI O2 DAC1");
757
758 /* set operators */
759 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
760 &snd_sgio2audio_playback1_ops);
761 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
762 &snd_sgio2audio_capture_ops);
763
764 /* create second pcm device with one outputs and no input */
765 err = snd_pcm_new(chip->card, "SGI O2 Audio", 1, 1, 0, &pcm);
766 if (err < 0)
767 return err;
768
769 pcm->private_data = chip;
770 strcpy(pcm->name, "SGI O2 DAC2");
771
772 /* set operators */
773 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
774 &snd_sgio2audio_playback2_ops);
775
776 return 0;
777}
778
779static struct {
780 int idx;
781 int irq;
782 irqreturn_t (*isr)(int, void *);
783 const char *desc;
784} snd_sgio2_isr_table[] = {
785 {
786 .idx = 0,
787 .irq = MACEISA_AUDIO1_DMAT_IRQ,
788 .isr = snd_sgio2audio_dma_in_isr,
789 .desc = "Capture DMA Channel 0"
790 }, {
791 .idx = 0,
792 .irq = MACEISA_AUDIO1_OF_IRQ,
793 .isr = snd_sgio2audio_error_isr,
794 .desc = "Capture Overflow"
795 }, {
796 .idx = 1,
797 .irq = MACEISA_AUDIO2_DMAT_IRQ,
798 .isr = snd_sgio2audio_dma_out_isr,
799 .desc = "Playback DMA Channel 1"
800 }, {
801 .idx = 1,
802 .irq = MACEISA_AUDIO2_MERR_IRQ,
803 .isr = snd_sgio2audio_error_isr,
804 .desc = "Memory Error Channel 1"
805 }, {
806 .idx = 2,
807 .irq = MACEISA_AUDIO3_DMAT_IRQ,
808 .isr = snd_sgio2audio_dma_out_isr,
809 .desc = "Playback DMA Channel 2"
810 }, {
811 .idx = 2,
812 .irq = MACEISA_AUDIO3_MERR_IRQ,
813 .isr = snd_sgio2audio_error_isr,
814 .desc = "Memory Error Channel 2"
815 }
816};
817
818/* ALSA driver */
819
820static int snd_sgio2audio_free(struct snd_sgio2audio *chip)
821{
822 int i;
823
824 /* reset interface */
825 writeq(AUDIO_CONTROL_RESET, &mace->perif.audio.control);
826 udelay(1);
827 writeq(0, &mace->perif.audio.control);
828
829 /* release IRQ's */
830 for (i = 0; i < ARRAY_SIZE(snd_sgio2_isr_table); i++)
831 free_irq(snd_sgio2_isr_table[i].irq,
832 &chip->channel[snd_sgio2_isr_table[i].idx]);
833
834 dma_free_coherent(NULL, MACEISA_RINGBUFFERS_SIZE,
835 chip->ring_base, chip->ring_base_dma);
836
837 /* release card data */
838 kfree(chip);
839 return 0;
840}
841
842static int snd_sgio2audio_dev_free(struct snd_device *device)
843{
844 struct snd_sgio2audio *chip = device->device_data;
845
846 return snd_sgio2audio_free(chip);
847}
848
849static struct snd_device_ops ops = {
850 .dev_free = snd_sgio2audio_dev_free,
851};
852
853static int __devinit snd_sgio2audio_create(struct snd_card *card,
854 struct snd_sgio2audio **rchip)
855{
856 struct snd_sgio2audio *chip;
857 int i, err;
858
859 *rchip = NULL;
860
861 /* check if a codec is attached to the interface */
862 /* (Audio or Audio/Video board present) */
863 if (!(readq(&mace->perif.audio.control) & AUDIO_CONTROL_CODEC_PRESENT))
864 return -ENOENT;
865
866 chip = kzalloc(sizeof(struct snd_sgio2audio), GFP_KERNEL);
867 if (chip == NULL)
868 return -ENOMEM;
869
870 chip->card = card;
871
872 chip->ring_base = dma_alloc_coherent(NULL, MACEISA_RINGBUFFERS_SIZE,
873 &chip->ring_base_dma, GFP_USER);
874 if (chip->ring_base == NULL) {
875 printk(KERN_ERR
876 "sgio2audio: could not allocate ring buffers\n");
877 kfree(chip);
878 return -ENOMEM;
879 }
880
881 spin_lock_init(&chip->ad1843_lock);
882
883 /* initialize channels */
884 for (i = 0; i < 3; i++) {
885 spin_lock_init(&chip->channel[i].lock);
886 chip->channel[i].idx = i;
887 }
888
889 /* allocate IRQs */
890 for (i = 0; i < ARRAY_SIZE(snd_sgio2_isr_table); i++) {
891 if (request_irq(snd_sgio2_isr_table[i].irq,
892 snd_sgio2_isr_table[i].isr,
893 0,
894 snd_sgio2_isr_table[i].desc,
895 &chip->channel[snd_sgio2_isr_table[i].idx])) {
896 snd_sgio2audio_free(chip);
897 printk(KERN_ERR "sgio2audio: cannot allocate irq %d\n",
898 snd_sgio2_isr_table[i].irq);
899 return -EBUSY;
900 }
901 }
902
903 /* reset the interface */
904 writeq(AUDIO_CONTROL_RESET, &mace->perif.audio.control);
905 udelay(1);
906 writeq(0, &mace->perif.audio.control);
907 msleep_interruptible(1); /* give time to recover */
908
909 /* set ring base */
910 writeq(chip->ring_base_dma, &mace->perif.ctrl.ringbase);
911
912 /* attach the AD1843 codec */
913 chip->ad1843.read = read_ad1843_reg;
914 chip->ad1843.write = write_ad1843_reg;
915 chip->ad1843.chip = chip;
916
917 /* initialize the AD1843 codec */
918 err = ad1843_init(&chip->ad1843);
919 if (err < 0) {
920 snd_sgio2audio_free(chip);
921 return err;
922 }
923
924 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
925 if (err < 0) {
926 snd_sgio2audio_free(chip);
927 return err;
928 }
929 *rchip = chip;
930 return 0;
931}
932
933static int __devinit snd_sgio2audio_probe(struct platform_device *pdev)
934{
935 struct snd_card *card;
936 struct snd_sgio2audio *chip;
937 int err;
938
939 card = snd_card_new(index, id, THIS_MODULE, 0);
940 if (card == NULL)
941 return -ENOMEM;
942
943 err = snd_sgio2audio_create(card, &chip);
944 if (err < 0) {
945 snd_card_free(card);
946 return err;
947 }
948 snd_card_set_dev(card, &pdev->dev);
949
950 err = snd_sgio2audio_new_pcm(chip);
951 if (err < 0) {
952 snd_card_free(card);
953 return err;
954 }
955 err = snd_sgio2audio_new_mixer(chip);
956 if (err < 0) {
957 snd_card_free(card);
958 return err;
959 }
960
961 strcpy(card->driver, "SGI O2 Audio");
962 strcpy(card->shortname, "SGI O2 Audio");
963 sprintf(card->longname, "%s irq %i-%i",
964 card->shortname,
965 MACEISA_AUDIO1_DMAT_IRQ,
966 MACEISA_AUDIO3_MERR_IRQ);
967
968 err = snd_card_register(card);
969 if (err < 0) {
970 snd_card_free(card);
971 return err;
972 }
973 platform_set_drvdata(pdev, card);
974 return 0;
975}
976
977static int __exit snd_sgio2audio_remove(struct platform_device *pdev)
978{
979 struct snd_card *card = platform_get_drvdata(pdev);
980
981 snd_card_free(card);
982 platform_set_drvdata(pdev, NULL);
983 return 0;
984}
985
986static struct platform_driver sgio2audio_driver = {
987 .probe = snd_sgio2audio_probe,
988 .remove = __devexit_p(snd_sgio2audio_remove),
989 .driver = {
990 .name = "sgio2audio",
991 .owner = THIS_MODULE,
992 }
993};
994
995static int __init alsa_card_sgio2audio_init(void)
996{
997 return platform_driver_register(&sgio2audio_driver);
998}
999
1000static void __exit alsa_card_sgio2audio_exit(void)
1001{
1002 platform_driver_unregister(&sgio2audio_driver);
1003}
1004
1005module_init(alsa_card_sgio2audio_init)
1006module_exit(alsa_card_sgio2audio_exit)
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 3be2dc1025b5..33940139844b 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -7,7 +7,7 @@
7 7
8config SOUND_BCM_CS4297A 8config SOUND_BCM_CS4297A
9 tristate "Crystal Sound CS4297a (for Swarm)" 9 tristate "Crystal Sound CS4297a (for Swarm)"
10 depends on SOUND_PRIME && SIBYTE_SWARM 10 depends on SIBYTE_SWARM
11 help 11 help
12 The BCM91250A has a Crystal CS4297a on synchronous serial 12 The BCM91250A has a Crystal CS4297a on synchronous serial
13 port B (in addition to the DB-9 serial port). Say Y or M 13 port B (in addition to the DB-9 serial port). Say Y or M
@@ -17,7 +17,7 @@ config SOUND_BCM_CS4297A
17 17
18config SOUND_VWSND 18config SOUND_VWSND
19 tristate "SGI Visual Workstation Sound" 19 tristate "SGI Visual Workstation Sound"
20 depends on SOUND_PRIME && X86_VISWS 20 depends on X86_VISWS
21 help 21 help
22 Say Y or M if you have an SGI Visual Workstation and you want to be 22 Say Y or M if you have an SGI Visual Workstation and you want to be
23 able to use its on-board audio. Read 23 able to use its on-board audio. Read
@@ -26,19 +26,18 @@ config SOUND_VWSND
26 26
27config SOUND_HAL2 27config SOUND_HAL2
28 tristate "SGI HAL2 sound (EXPERIMENTAL)" 28 tristate "SGI HAL2 sound (EXPERIMENTAL)"
29 depends on SOUND_PRIME && SGI_IP22 && EXPERIMENTAL 29 depends on SGI_IP22 && EXPERIMENTAL
30 help 30 help
31 Say Y or M if you have an SGI Indy or Indigo2 system and want to be able to 31 Say Y or M if you have an SGI Indy or Indigo2 system and want to be able to
32 use its on-board A2 audio system. 32 use its on-board A2 audio system.
33 33
34config SOUND_AU1550_AC97 34config SOUND_AU1550_AC97
35 tristate "Au1550/Au1200 AC97 Sound" 35 tristate "Au1550/Au1200 AC97 Sound"
36 select SND_AC97_CODEC 36 depends on SOC_AU1550 || SOC_AU1200
37 depends on SOUND_PRIME && (SOC_AU1550 || SOC_AU1200)
38 37
39config SOUND_TRIDENT 38config SOUND_TRIDENT
40 tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core" 39 tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core"
41 depends on SOUND_PRIME && PCI 40 depends on PCI
42 ---help--- 41 ---help---
43 Say Y or M if you have a PCI sound card utilizing the Trident 42 Say Y or M if you have a PCI sound card utilizing the Trident
44 4DWave-DX/NX chipset or your mother board chipset has SiS 7018 43 4DWave-DX/NX chipset or your mother board chipset has SiS 7018
@@ -79,7 +78,7 @@ config SOUND_TRIDENT
79 78
80config SOUND_MSNDCLAS 79config SOUND_MSNDCLAS
81 tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey" 80 tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey"
82 depends on SOUND_PRIME && (m || !STANDALONE) && ISA 81 depends on (m || !STANDALONE) && ISA
83 help 82 help
84 Say M here if you have a Turtle Beach MultiSound Classic, Tahiti or 83 Say M here if you have a Turtle Beach MultiSound Classic, Tahiti or
85 Monterey (not for the Pinnacle or Fiji). 84 Monterey (not for the Pinnacle or Fiji).
@@ -143,7 +142,7 @@ config MSNDCLAS_IO
143 142
144config SOUND_MSNDPIN 143config SOUND_MSNDPIN
145 tristate "Support for Turtle Beach MultiSound Pinnacle, Fiji" 144 tristate "Support for Turtle Beach MultiSound Pinnacle, Fiji"
146 depends on SOUND_PRIME && (m || !STANDALONE) && ISA 145 depends on (m || !STANDALONE) && ISA
147 help 146 help
148 Say M here if you have a Turtle Beach MultiSound Pinnacle or Fiji. 147 Say M here if you have a Turtle Beach MultiSound Pinnacle or Fiji.
149 See <file:Documentation/sound/oss/MultiSound> for important information 148 See <file:Documentation/sound/oss/MultiSound> for important information
@@ -229,7 +228,7 @@ config MSNDPIN_NONPNP
229 configure the card's resources. 228 configure the card's resources.
230 229
231comment "MSND Pinnacle DSP section will be configured to above parameters." 230comment "MSND Pinnacle DSP section will be configured to above parameters."
232 depends on SOUND_PRIME && SOUND_MSNDPIN=y && MSNDPIN_NONPNP 231 depends on SOUND_MSNDPIN=y && MSNDPIN_NONPNP
233 232
234config MSNDPIN_CFG 233config MSNDPIN_CFG
235 hex "MSND Pinnacle config port 250,260,270" 234 hex "MSND Pinnacle config port 250,260,270"
@@ -242,7 +241,7 @@ config MSNDPIN_CFG
242 Mode". 241 Mode".
243 242
244comment "Pinnacle-specific Device Configuration (0 disables)" 243comment "Pinnacle-specific Device Configuration (0 disables)"
245 depends on SOUND_PRIME && SOUND_MSNDPIN=y && MSNDPIN_NONPNP 244 depends on SOUND_MSNDPIN=y && MSNDPIN_NONPNP
246 245
247config MSNDPIN_MPU_IO 246config MSNDPIN_MPU_IO
248 hex "MSND Pinnacle MPU I/O (e.g. 330)" 247 hex "MSND Pinnacle MPU I/O (e.g. 330)"
@@ -294,7 +293,7 @@ config MSNDPIN_JOYSTICK_IO
294 293
295config MSND_FIFOSIZE 294config MSND_FIFOSIZE
296 int "MSND buffer size (kB)" 295 int "MSND buffer size (kB)"
297 depends on SOUND_PRIME && (SOUND_MSNDPIN=y || SOUND_MSNDCLAS=y) 296 depends on SOUND_MSNDPIN=y || SOUND_MSNDCLAS=y
298 default "128" 297 default "128"
299 help 298 help
300 Configures the size of each audio buffer, in kilobytes, for 299 Configures the size of each audio buffer, in kilobytes, for
@@ -302,9 +301,9 @@ config MSND_FIFOSIZE
302 and Pinnacle). Larger values reduce the chance of data overruns at 301 and Pinnacle). Larger values reduce the chance of data overruns at
303 the expense of overall latency. If unsure, use the default. 302 the expense of overall latency. If unsure, use the default.
304 303
305config SOUND_OSS 304menuconfig SOUND_OSS
306 tristate "OSS sound modules" 305 tristate "OSS sound modules"
307 depends on SOUND_PRIME && ISA_DMA_API && VIRT_TO_BUS 306 depends on ISA_DMA_API && VIRT_TO_BUS
308 help 307 help
309 OSS is the Open Sound System suite of sound card drivers. They make 308 OSS is the Open Sound System suite of sound card drivers. They make
310 sound programming easier since they provide a common API. Say Y or 309 sound programming easier since they provide a common API. Say Y or
@@ -312,16 +311,16 @@ config SOUND_OSS
312 driver for your sound card above, then pick your driver from the 311 driver for your sound card above, then pick your driver from the
313 list below. 312 list below.
314 313
314if SOUND_OSS
315
315config SOUND_TRACEINIT 316config SOUND_TRACEINIT
316 bool "Verbose initialisation" 317 bool "Verbose initialisation"
317 depends on SOUND_OSS
318 help 318 help
319 Verbose soundcard initialization -- affects the format of autoprobe 319 Verbose soundcard initialization -- affects the format of autoprobe
320 and initialization messages at boot time. 320 and initialization messages at boot time.
321 321
322config SOUND_DMAP 322config SOUND_DMAP
323 bool "Persistent DMA buffers" 323 bool "Persistent DMA buffers"
324 depends on SOUND_OSS
325 ---help--- 324 ---help---
326 Linux can often have problems allocating DMA buffers for ISA sound 325 Linux can often have problems allocating DMA buffers for ISA sound
327 cards on machines with more than 16MB of RAM. This is because ISA 326 cards on machines with more than 16MB of RAM. This is because ISA
@@ -338,8 +337,6 @@ config SOUND_DMAP
338 337
339config SOUND_SSCAPE 338config SOUND_SSCAPE
340 tristate "Ensoniq SoundScape support" 339 tristate "Ensoniq SoundScape support"
341 depends on SOUND_OSS
342 depends on VIRT_TO_BUS
343 help 340 help
344 Answer Y if you have a sound card based on the Ensoniq SoundScape 341 Answer Y if you have a sound card based on the Ensoniq SoundScape
345 chipset. Such cards are being manufactured at least by Ensoniq, Spea 342 chipset. Such cards are being manufactured at least by Ensoniq, Spea
@@ -352,13 +349,11 @@ config SOUND_SSCAPE
352 349
353config SOUND_VMIDI 350config SOUND_VMIDI
354 tristate "Loopback MIDI device support" 351 tristate "Loopback MIDI device support"
355 depends on SOUND_OSS
356 help 352 help
357 Support for MIDI loopback on port 1 or 2. 353 Support for MIDI loopback on port 1 or 2.
358 354
359config SOUND_TRIX 355config SOUND_TRIX
360 tristate "MediaTrix AudioTrix Pro support" 356 tristate "MediaTrix AudioTrix Pro support"
361 depends on SOUND_OSS
362 help 357 help
363 Answer Y if you have the AudioTriX Pro sound card manufactured 358 Answer Y if you have the AudioTriX Pro sound card manufactured
364 by MediaTrix. 359 by MediaTrix.
@@ -382,7 +377,6 @@ config TRIX_BOOT_FILE
382 377
383config SOUND_MSS 378config SOUND_MSS
384 tristate "Microsoft Sound System support" 379 tristate "Microsoft Sound System support"
385 depends on SOUND_OSS
386 ---help--- 380 ---help---
387 Again think carefully before answering Y to this question. It's 381 Again think carefully before answering Y to this question. It's
388 safe to answer Y if you have the original Windows Sound System card 382 safe to answer Y if you have the original Windows Sound System card
@@ -414,7 +408,6 @@ config SOUND_MSS
414 408
415config SOUND_MPU401 409config SOUND_MPU401
416 tristate "MPU-401 support (NOT for SB16)" 410 tristate "MPU-401 support (NOT for SB16)"
417 depends on SOUND_OSS
418 ---help--- 411 ---help---
419 Be careful with this question. The MPU401 interface is supported by 412 Be careful with this question. The MPU401 interface is supported by
420 all sound cards. However, some natively supported cards have their 413 all sound cards. However, some natively supported cards have their
@@ -430,7 +423,6 @@ config SOUND_MPU401
430 423
431config SOUND_PAS 424config SOUND_PAS
432 tristate "ProAudioSpectrum 16 support" 425 tristate "ProAudioSpectrum 16 support"
433 depends on SOUND_OSS
434 ---help--- 426 ---help---
435 Answer Y only if you have a Pro Audio Spectrum 16, ProAudio Studio 427 Answer Y only if you have a Pro Audio Spectrum 16, ProAudio Studio
436 16 or Logitech SoundMan 16 sound card. Answer N if you have some 428 16 or Logitech SoundMan 16 sound card. Answer N if you have some
@@ -452,7 +444,6 @@ config PAS_JOYSTICK
452 444
453config SOUND_PSS 445config SOUND_PSS
454 tristate "PSS (AD1848, ADSP-2115, ESC614) support" 446 tristate "PSS (AD1848, ADSP-2115, ESC614) support"
455 depends on SOUND_OSS
456 help 447 help
457 Answer Y or M if you have an Orchid SW32, Cardinal DSP16, Beethoven 448 Answer Y or M if you have an Orchid SW32, Cardinal DSP16, Beethoven
458 ADSP-16 or some other card based on the PSS chipset (AD1848 codec + 449 ADSP-16 or some other card based on the PSS chipset (AD1848 codec +
@@ -495,7 +486,6 @@ config PSS_BOOT_FILE
495 486
496config SOUND_SB 487config SOUND_SB
497 tristate "100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support" 488 tristate "100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support"
498 depends on SOUND_OSS
499 ---help--- 489 ---help---
500 Answer Y if you have an original Sound Blaster card made by Creative 490 Answer Y if you have an original Sound Blaster card made by Creative
501 Labs or a 100% hardware compatible clone (like the Thunderboard or 491 Labs or a 100% hardware compatible clone (like the Thunderboard or
@@ -522,7 +512,6 @@ config SOUND_SB
522 512
523config SOUND_YM3812 513config SOUND_YM3812
524 tristate "Yamaha FM synthesizer (YM3812/OPL-3) support" 514 tristate "Yamaha FM synthesizer (YM3812/OPL-3) support"
525 depends on SOUND_OSS
526 ---help--- 515 ---help---
527 Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4). 516 Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4).
528 Answering Y is usually a safe and recommended choice, however some 517 Answering Y is usually a safe and recommended choice, however some
@@ -538,7 +527,6 @@ config SOUND_YM3812
538 527
539config SOUND_UART6850 528config SOUND_UART6850
540 tristate "6850 UART support" 529 tristate "6850 UART support"
541 depends on SOUND_OSS
542 help 530 help
543 This option enables support for MIDI interfaces based on the 6850 531 This option enables support for MIDI interfaces based on the 6850
544 UART chip. This interface is rarely found on sound cards. It's safe 532 UART chip. This interface is rarely found on sound cards. It's safe
@@ -549,7 +537,6 @@ config SOUND_UART6850
549 537
550config SOUND_AEDSP16 538config SOUND_AEDSP16
551 tristate "Gallant Audio Cards (SC-6000 and SC-6600 based)" 539 tristate "Gallant Audio Cards (SC-6000 and SC-6600 based)"
552 depends on SOUND_OSS
553 ---help--- 540 ---help---
554 Answer Y if you have a Gallant's Audio Excel DSP 16 card. This 541 Answer Y if you have a Gallant's Audio Excel DSP 16 card. This
555 driver supports Audio Excel DSP 16 but not the III nor PnP versions 542 driver supports Audio Excel DSP 16 but not the III nor PnP versions
@@ -630,14 +617,14 @@ endchoice
630 617
631config SOUND_VIDC 618config SOUND_VIDC
632 tristate "VIDC 16-bit sound" 619 tristate "VIDC 16-bit sound"
633 depends on ARM && (ARCH_ACORN || ARCH_CLPS7500) && SOUND_OSS 620 depends on ARM && (ARCH_ACORN || ARCH_CLPS7500)
634 help 621 help
635 16-bit support for the VIDC onboard sound hardware found on Acorn 622 16-bit support for the VIDC onboard sound hardware found on Acorn
636 machines. 623 machines.
637 624
638config SOUND_WAVEARTIST 625config SOUND_WAVEARTIST
639 tristate "Netwinder WaveArtist" 626 tristate "Netwinder WaveArtist"
640 depends on ARM && SOUND_OSS && ARCH_NETWINDER 627 depends on ARM && ARCH_NETWINDER
641 help 628 help
642 Say Y here to include support for the Rockwell WaveArtist sound 629 Say Y here to include support for the Rockwell WaveArtist sound
643 system. This driver is mainly for the NetWinder. 630 system. This driver is mainly for the NetWinder.
@@ -646,9 +633,11 @@ config SOUND_KAHLUA
646 tristate "XpressAudio Sound Blaster emulation" 633 tristate "XpressAudio Sound Blaster emulation"
647 depends on SOUND_SB 634 depends on SOUND_SB
648 635
636endif # SOUND_OSS
637
649config SOUND_SH_DAC_AUDIO 638config SOUND_SH_DAC_AUDIO
650 tristate "SuperH DAC audio support" 639 tristate "SuperH DAC audio support"
651 depends on SOUND_PRIME && CPU_SH3 640 depends on CPU_SH3
652 641
653config SOUND_SH_DAC_AUDIO_CHANNEL 642config SOUND_SH_DAC_AUDIO_CHANNEL
654 int "DAC channel" 643 int "DAC channel"
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
index a003c0ea9303..95fc5c681755 100644
--- a/sound/oss/dmasound/dmasound_core.c
+++ b/sound/oss/dmasound/dmasound_core.c
@@ -211,10 +211,6 @@ static int state_unit = -1;
211static int irq_installed; 211static int irq_installed;
212#endif /* MODULE */ 212#endif /* MODULE */
213 213
214/* software implemented recording volume! */
215uint software_input_volume = SW_INPUT_VOLUME_SCALE * SW_INPUT_VOLUME_DEFAULT;
216EXPORT_SYMBOL(software_input_volume);
217
218/* control over who can modify resources shared between play/record */ 214/* control over who can modify resources shared between play/record */
219static mode_t shared_resource_owner; 215static mode_t shared_resource_owner;
220static int shared_resources_initialised; 216static int shared_resources_initialised;
@@ -1188,7 +1184,7 @@ static struct {
1188 1184
1189/* publish this function for use by low-level code, if required */ 1185/* publish this function for use by low-level code, if required */
1190 1186
1191char *get_afmt_string(int afmt) 1187static char *get_afmt_string(int afmt)
1192{ 1188{
1193 switch(afmt) { 1189 switch(afmt) {
1194 case AFMT_MU_LAW: 1190 case AFMT_MU_LAW:
@@ -1551,4 +1547,3 @@ EXPORT_SYMBOL(dmasound_catchRadius);
1551EXPORT_SYMBOL(dmasound_ulaw2dma8); 1547EXPORT_SYMBOL(dmasound_ulaw2dma8);
1552EXPORT_SYMBOL(dmasound_alaw2dma8); 1548EXPORT_SYMBOL(dmasound_alaw2dma8);
1553#endif 1549#endif
1554EXPORT_SYMBOL(get_afmt_string) ;
diff --git a/sound/oss/dmasound/dmasound_paula.c b/sound/oss/dmasound/dmasound_paula.c
index 202e8103dc4d..06e9e88e4c05 100644
--- a/sound/oss/dmasound/dmasound_paula.c
+++ b/sound/oss/dmasound/dmasound_paula.c
@@ -710,7 +710,7 @@ static MACHINE machAmiga = {
710/*** Config & Setup **********************************************************/ 710/*** Config & Setup **********************************************************/
711 711
712 712
713int __init dmasound_paula_init(void) 713static int __init dmasound_paula_init(void)
714{ 714{
715 int err; 715 int err;
716 716
diff --git a/sound/oss/dmasound/dmasound_q40.c b/sound/oss/dmasound/dmasound_q40.c
index b3379dd7ca5e..1855b14d90c3 100644
--- a/sound/oss/dmasound/dmasound_q40.c
+++ b/sound/oss/dmasound/dmasound_q40.c
@@ -611,7 +611,7 @@ static MACHINE machQ40 = {
611/*** Config & Setup **********************************************************/ 611/*** Config & Setup **********************************************************/
612 612
613 613
614int __init dmasound_q40_init(void) 614static int __init dmasound_q40_init(void)
615{ 615{
616 if (MACH_IS_Q40) { 616 if (MACH_IS_Q40) {
617 dmasound.mach = machQ40; 617 dmasound.mach = machQ40;
diff --git a/sound/oss/msnd.c b/sound/oss/msnd.c
index ba38d6200099..e4282d93a1aa 100644
--- a/sound/oss/msnd.c
+++ b/sound/oss/msnd.c
@@ -20,8 +20,6 @@
20 * along with this program; if not, write to the Free Software 20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * 22 *
23 * $Id: msnd.c,v 1.17 1999/03/21 16:50:09 andrewtv Exp $
24 *
25 ********************************************************************/ 23 ********************************************************************/
26 24
27#include <linux/module.h> 25#include <linux/module.h>
diff --git a/sound/oss/msnd.h b/sound/oss/msnd.h
index d0ca582c4583..61b3955481c5 100644
--- a/sound/oss/msnd.h
+++ b/sound/oss/msnd.h
@@ -24,8 +24,6 @@
24 * along with this program; if not, write to the Free Software 24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * 26 *
27 * $Id: msnd.h,v 1.36 1999/03/21 17:05:42 andrewtv Exp $
28 *
29 ********************************************************************/ 27 ********************************************************************/
30#ifndef __MSND_H 28#ifndef __MSND_H
31#define __MSND_H 29#define __MSND_H
diff --git a/sound/oss/msnd_classic.h b/sound/oss/msnd_classic.h
index 7ffea5267f96..1a17dde2f650 100644
--- a/sound/oss/msnd_classic.h
+++ b/sound/oss/msnd_classic.h
@@ -24,8 +24,6 @@
24 * along with this program; if not, write to the Free Software 24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * 26 *
27 * $Id: msnd_classic.h,v 1.10 1999/03/21 17:36:09 andrewtv Exp $
28 *
29 ********************************************************************/ 27 ********************************************************************/
30#ifndef __MSND_CLASSIC_H 28#ifndef __MSND_CLASSIC_H
31#define __MSND_CLASSIC_H 29#define __MSND_CLASSIC_H
diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c
index f1f49ebf752e..bf27e008f465 100644
--- a/sound/oss/msnd_pinnacle.c
+++ b/sound/oss/msnd_pinnacle.c
@@ -29,13 +29,8 @@
29 * along with this program; if not, write to the Free Software 29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 * 31 *
32 * $Id: msnd_pinnacle.c,v 1.8 2000/12/30 00:33:21 sycamore Exp $
33 *
34 * 12-3-2000 Modified IO port validation Steve Sycamore 32 * 12-3-2000 Modified IO port validation Steve Sycamore
35 * 33 *
36 *
37 * $$$: msnd_pinnacle.c,v 1.75 1999/03/21 16:50:09 andrewtv $$$ $
38 *
39 ********************************************************************/ 34 ********************************************************************/
40 35
41#include <linux/kernel.h> 36#include <linux/kernel.h>
diff --git a/sound/oss/msnd_pinnacle.h b/sound/oss/msnd_pinnacle.h
index cce911487004..c18d66cbbe3f 100644
--- a/sound/oss/msnd_pinnacle.h
+++ b/sound/oss/msnd_pinnacle.h
@@ -24,8 +24,6 @@
24 * along with this program; if not, write to the Free Software 24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * 26 *
27 * $Id: msnd_pinnacle.h,v 1.11 1999/03/21 17:36:09 andrewtv Exp $
28 *
29 ********************************************************************/ 27 ********************************************************************/
30#ifndef __MSND_PINNACLE_H 28#ifndef __MSND_PINNACLE_H
31#define __MSND_PINNACLE_H 29#define __MSND_PINNACLE_H
diff --git a/sound/parisc/Kconfig b/sound/parisc/Kconfig
index a5a7f9d75d05..9b61d95010f0 100644
--- a/sound/parisc/Kconfig
+++ b/sound/parisc/Kconfig
@@ -1,15 +1,20 @@
1# ALSA PA-RISC drivers 1# ALSA PA-RISC drivers
2 2
3menu "GSC devices" 3menuconfig SND_GSC
4 depends on SND!=n && GSC 4 bool "GSC sound devices"
5 depends on GSC
6 default y
7 help
8 Support for GSC sound devices on PA-RISC architectures.
9
10if SND_GSC
5 11
6config SND_HARMONY 12config SND_HARMONY
7 tristate "Harmony/Vivace sound chip" 13 tristate "Harmony/Vivace sound chip"
8 depends on SND
9 select SND_PCM 14 select SND_PCM
10 help 15 help
11 Say 'Y' or 'M' to include support for the Harmony/Vivace sound 16 Say 'Y' or 'M' to include support for the Harmony/Vivace sound
12 chip found in most GSC-based PA-RISC workstations. It's frequently 17 chip found in most GSC-based PA-RISC workstations. It's frequently
13 provided as part of the Lasi multi-function IC. 18 provided as part of the Lasi multi-function IC.
14 19
15endmenu 20endif # SND_GSC
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 7e4742109572..8fe5dac39428 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -1,11 +1,16 @@
1# ALSA PCI drivers 1# ALSA PCI drivers
2 2
3menu "PCI devices" 3menuconfig SND_PCI
4 depends on SND!=n && PCI 4 bool "PCI sound devices"
5 depends on PCI
6 default y
7 help
8 Support for sound devices connected via the PCI bus.
9
10if SND_PCI
5 11
6config SND_AD1889 12config SND_AD1889
7 tristate "Analog Devices AD1889" 13 tristate "Analog Devices AD1889"
8 depends on SND
9 select SND_AC97_CODEC 14 select SND_AC97_CODEC
10 help 15 help
11 Say Y here to include support for the integrated AC97 sound 16 Say Y here to include support for the integrated AC97 sound
@@ -17,7 +22,6 @@ config SND_AD1889
17 22
18config SND_ALS300 23config SND_ALS300
19 tristate "Avance Logic ALS300/ALS300+" 24 tristate "Avance Logic ALS300/ALS300+"
20 depends on SND
21 select SND_PCM 25 select SND_PCM
22 select SND_AC97_CODEC 26 select SND_AC97_CODEC
23 select SND_OPL3_LIB 27 select SND_OPL3_LIB
@@ -29,7 +33,7 @@ config SND_ALS300
29 33
30config SND_ALS4000 34config SND_ALS4000
31 tristate "Avance Logic ALS4000" 35 tristate "Avance Logic ALS4000"
32 depends on SND && ISA_DMA_API 36 depends on ISA_DMA_API
33 select SND_OPL3_LIB 37 select SND_OPL3_LIB
34 select SND_MPU401_UART 38 select SND_MPU401_UART
35 select SND_PCM 39 select SND_PCM
@@ -43,7 +47,6 @@ config SND_ALS4000
43 47
44config SND_ALI5451 48config SND_ALI5451
45 tristate "ALi M5451 PCI Audio Controller" 49 tristate "ALi M5451 PCI Audio Controller"
46 depends on SND
47 select SND_MPU401_UART 50 select SND_MPU401_UART
48 select SND_AC97_CODEC 51 select SND_AC97_CODEC
49 help 52 help
@@ -57,7 +60,6 @@ config SND_ALI5451
57 60
58config SND_ATIIXP 61config SND_ATIIXP
59 tristate "ATI IXP AC97 Controller" 62 tristate "ATI IXP AC97 Controller"
60 depends on SND
61 select SND_AC97_CODEC 63 select SND_AC97_CODEC
62 help 64 help
63 Say Y here to include support for the integrated AC97 sound 65 Say Y here to include support for the integrated AC97 sound
@@ -69,7 +71,6 @@ config SND_ATIIXP
69 71
70config SND_ATIIXP_MODEM 72config SND_ATIIXP_MODEM
71 tristate "ATI IXP Modem" 73 tristate "ATI IXP Modem"
72 depends on SND
73 select SND_AC97_CODEC 74 select SND_AC97_CODEC
74 help 75 help
75 Say Y here to include support for the integrated MC97 modem on 76 Say Y here to include support for the integrated MC97 modem on
@@ -80,7 +81,6 @@ config SND_ATIIXP_MODEM
80 81
81config SND_AU8810 82config SND_AU8810
82 tristate "Aureal Advantage" 83 tristate "Aureal Advantage"
83 depends on SND
84 select SND_MPU401_UART 84 select SND_MPU401_UART
85 select SND_AC97_CODEC 85 select SND_AC97_CODEC
86 help 86 help
@@ -95,7 +95,6 @@ config SND_AU8810
95 95
96config SND_AU8820 96config SND_AU8820
97 tristate "Aureal Vortex" 97 tristate "Aureal Vortex"
98 depends on SND
99 select SND_MPU401_UART 98 select SND_MPU401_UART
100 select SND_AC97_CODEC 99 select SND_AC97_CODEC
101 help 100 help
@@ -109,7 +108,6 @@ config SND_AU8820
109 108
110config SND_AU8830 109config SND_AU8830
111 tristate "Aureal Vortex 2" 110 tristate "Aureal Vortex 2"
112 depends on SND
113 select SND_MPU401_UART 111 select SND_MPU401_UART
114 select SND_AC97_CODEC 112 select SND_AC97_CODEC
115 help 113 help
@@ -124,7 +122,6 @@ config SND_AU8830
124 122
125config SND_AW2 123config SND_AW2
126 tristate "Emagic Audiowerk 2" 124 tristate "Emagic Audiowerk 2"
127 depends on SND
128 help 125 help
129 Say Y here to include support for Emagic Audiowerk 2 soundcards. 126 Say Y here to include support for Emagic Audiowerk 2 soundcards.
130 127
@@ -139,7 +136,7 @@ config SND_AW2
139 136
140config SND_AZT3328 137config SND_AZT3328
141 tristate "Aztech AZF3328 / PCI168 (EXPERIMENTAL)" 138 tristate "Aztech AZF3328 / PCI168 (EXPERIMENTAL)"
142 depends on SND && EXPERIMENTAL 139 depends on EXPERIMENTAL
143 select SND_OPL3_LIB 140 select SND_OPL3_LIB
144 select SND_MPU401_UART 141 select SND_MPU401_UART
145 select SND_PCM 142 select SND_PCM
@@ -152,7 +149,6 @@ config SND_AZT3328
152 149
153config SND_BT87X 150config SND_BT87X
154 tristate "Bt87x Audio Capture" 151 tristate "Bt87x Audio Capture"
155 depends on SND
156 select SND_PCM 152 select SND_PCM
157 help 153 help
158 If you want to record audio from TV cards based on 154 If you want to record audio from TV cards based on
@@ -174,7 +170,6 @@ config SND_BT87X_OVERCLOCK
174 170
175config SND_CA0106 171config SND_CA0106
176 tristate "SB Audigy LS / Live 24bit" 172 tristate "SB Audigy LS / Live 24bit"
177 depends on SND
178 select SND_AC97_CODEC 173 select SND_AC97_CODEC
179 select SND_RAWMIDI 174 select SND_RAWMIDI
180 select SND_VMASTER 175 select SND_VMASTER
@@ -187,7 +182,6 @@ config SND_CA0106
187 182
188config SND_CMIPCI 183config SND_CMIPCI
189 tristate "C-Media 8338, 8738, 8768, 8770" 184 tristate "C-Media 8338, 8738, 8768, 8770"
190 depends on SND
191 select SND_OPL3_LIB 185 select SND_OPL3_LIB
192 select SND_MPU401_UART 186 select SND_MPU401_UART
193 select SND_PCM 187 select SND_PCM
@@ -201,13 +195,11 @@ config SND_CMIPCI
201 195
202config SND_OXYGEN_LIB 196config SND_OXYGEN_LIB
203 tristate 197 tristate
204 depends on SND
205 select SND_PCM 198 select SND_PCM
206 select SND_MPU401_UART 199 select SND_MPU401_UART
207 200
208config SND_OXYGEN 201config SND_OXYGEN
209 tristate "C-Media 8788 (Oxygen)" 202 tristate "C-Media 8788 (Oxygen)"
210 depends on SND
211 select SND_OXYGEN_LIB 203 select SND_OXYGEN_LIB
212 help 204 help
213 Say Y here to include support for sound cards based on the 205 Say Y here to include support for sound cards based on the
@@ -225,7 +217,6 @@ config SND_OXYGEN
225 217
226config SND_CS4281 218config SND_CS4281
227 tristate "Cirrus Logic (Sound Fusion) CS4281" 219 tristate "Cirrus Logic (Sound Fusion) CS4281"
228 depends on SND
229 select SND_OPL3_LIB 220 select SND_OPL3_LIB
230 select SND_RAWMIDI 221 select SND_RAWMIDI
231 select SND_AC97_CODEC 222 select SND_AC97_CODEC
@@ -237,7 +228,6 @@ config SND_CS4281
237 228
238config SND_CS46XX 229config SND_CS46XX
239 tristate "Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x" 230 tristate "Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x"
240 depends on SND
241 select SND_RAWMIDI 231 select SND_RAWMIDI
242 select SND_AC97_CODEC 232 select SND_AC97_CODEC
243 help 233 help
@@ -258,7 +248,7 @@ config SND_CS46XX_NEW_DSP
258 248
259config SND_CS5530 249config SND_CS5530
260 tristate "CS5530 Audio" 250 tristate "CS5530 Audio"
261 depends on SND && ISA_DMA_API 251 depends on ISA_DMA_API
262 select SND_SB16_DSP 252 select SND_SB16_DSP
263 help 253 help
264 Say Y here to include support for audio on Cyrix/NatSemi CS5530 chips. 254 Say Y here to include support for audio on Cyrix/NatSemi CS5530 chips.
@@ -268,7 +258,7 @@ config SND_CS5530
268 258
269config SND_CS5535AUDIO 259config SND_CS5535AUDIO
270 tristate "CS5535/CS5536 Audio" 260 tristate "CS5535/CS5536 Audio"
271 depends on SND && X86 && !X86_64 261 depends on X86 && !X86_64
272 select SND_PCM 262 select SND_PCM
273 select SND_AC97_CODEC 263 select SND_AC97_CODEC
274 help 264 help
@@ -286,7 +276,6 @@ config SND_CS5535AUDIO
286 276
287config SND_DARLA20 277config SND_DARLA20
288 tristate "(Echoaudio) Darla20" 278 tristate "(Echoaudio) Darla20"
289 depends on SND
290 select FW_LOADER 279 select FW_LOADER
291 select SND_PCM 280 select SND_PCM
292 help 281 help
@@ -297,7 +286,6 @@ config SND_DARLA20
297 286
298config SND_GINA20 287config SND_GINA20
299 tristate "(Echoaudio) Gina20" 288 tristate "(Echoaudio) Gina20"
300 depends on SND
301 select FW_LOADER 289 select FW_LOADER
302 select SND_PCM 290 select SND_PCM
303 help 291 help
@@ -308,7 +296,6 @@ config SND_GINA20
308 296
309config SND_LAYLA20 297config SND_LAYLA20
310 tristate "(Echoaudio) Layla20" 298 tristate "(Echoaudio) Layla20"
311 depends on SND
312 select FW_LOADER 299 select FW_LOADER
313 select SND_RAWMIDI 300 select SND_RAWMIDI
314 select SND_PCM 301 select SND_PCM
@@ -320,7 +307,6 @@ config SND_LAYLA20
320 307
321config SND_DARLA24 308config SND_DARLA24
322 tristate "(Echoaudio) Darla24" 309 tristate "(Echoaudio) Darla24"
323 depends on SND
324 select FW_LOADER 310 select FW_LOADER
325 select SND_PCM 311 select SND_PCM
326 help 312 help
@@ -331,7 +317,6 @@ config SND_DARLA24
331 317
332config SND_GINA24 318config SND_GINA24
333 tristate "(Echoaudio) Gina24" 319 tristate "(Echoaudio) Gina24"
334 depends on SND
335 select FW_LOADER 320 select FW_LOADER
336 select SND_PCM 321 select SND_PCM
337 help 322 help
@@ -342,7 +327,6 @@ config SND_GINA24
342 327
343config SND_LAYLA24 328config SND_LAYLA24
344 tristate "(Echoaudio) Layla24" 329 tristate "(Echoaudio) Layla24"
345 depends on SND
346 select FW_LOADER 330 select FW_LOADER
347 select SND_RAWMIDI 331 select SND_RAWMIDI
348 select SND_PCM 332 select SND_PCM
@@ -354,7 +338,6 @@ config SND_LAYLA24
354 338
355config SND_MONA 339config SND_MONA
356 tristate "(Echoaudio) Mona" 340 tristate "(Echoaudio) Mona"
357 depends on SND
358 select FW_LOADER 341 select FW_LOADER
359 select SND_RAWMIDI 342 select SND_RAWMIDI
360 select SND_PCM 343 select SND_PCM
@@ -366,7 +349,6 @@ config SND_MONA
366 349
367config SND_MIA 350config SND_MIA
368 tristate "(Echoaudio) Mia" 351 tristate "(Echoaudio) Mia"
369 depends on SND
370 select FW_LOADER 352 select FW_LOADER
371 select SND_RAWMIDI 353 select SND_RAWMIDI
372 select SND_PCM 354 select SND_PCM
@@ -378,7 +360,6 @@ config SND_MIA
378 360
379config SND_ECHO3G 361config SND_ECHO3G
380 tristate "(Echoaudio) 3G cards" 362 tristate "(Echoaudio) 3G cards"
381 depends on SND
382 select FW_LOADER 363 select FW_LOADER
383 select SND_RAWMIDI 364 select SND_RAWMIDI
384 select SND_PCM 365 select SND_PCM
@@ -390,7 +371,6 @@ config SND_ECHO3G
390 371
391config SND_INDIGO 372config SND_INDIGO
392 tristate "(Echoaudio) Indigo" 373 tristate "(Echoaudio) Indigo"
393 depends on SND
394 select FW_LOADER 374 select FW_LOADER
395 select SND_PCM 375 select SND_PCM
396 help 376 help
@@ -401,7 +381,6 @@ config SND_INDIGO
401 381
402config SND_INDIGOIO 382config SND_INDIGOIO
403 tristate "(Echoaudio) Indigo IO" 383 tristate "(Echoaudio) Indigo IO"
404 depends on SND
405 select FW_LOADER 384 select FW_LOADER
406 select SND_PCM 385 select SND_PCM
407 help 386 help
@@ -412,7 +391,6 @@ config SND_INDIGOIO
412 391
413config SND_INDIGODJ 392config SND_INDIGODJ
414 tristate "(Echoaudio) Indigo DJ" 393 tristate "(Echoaudio) Indigo DJ"
415 depends on SND
416 select FW_LOADER 394 select FW_LOADER
417 select SND_PCM 395 select SND_PCM
418 help 396 help
@@ -423,7 +401,6 @@ config SND_INDIGODJ
423 401
424config SND_EMU10K1 402config SND_EMU10K1
425 tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)" 403 tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)"
426 depends on SND
427 select FW_LOADER 404 select FW_LOADER
428 select SND_HWDEP 405 select SND_HWDEP
429 select SND_RAWMIDI 406 select SND_RAWMIDI
@@ -441,7 +418,6 @@ config SND_EMU10K1
441 418
442config SND_EMU10K1X 419config SND_EMU10K1X
443 tristate "Emu10k1X (Dell OEM Version)" 420 tristate "Emu10k1X (Dell OEM Version)"
444 depends on SND
445 select SND_AC97_CODEC 421 select SND_AC97_CODEC
446 select SND_RAWMIDI 422 select SND_RAWMIDI
447 help 423 help
@@ -453,7 +429,6 @@ config SND_EMU10K1X
453 429
454config SND_ENS1370 430config SND_ENS1370
455 tristate "(Creative) Ensoniq AudioPCI 1370" 431 tristate "(Creative) Ensoniq AudioPCI 1370"
456 depends on SND
457 select SND_RAWMIDI 432 select SND_RAWMIDI
458 select SND_PCM 433 select SND_PCM
459 help 434 help
@@ -464,7 +439,6 @@ config SND_ENS1370
464 439
465config SND_ENS1371 440config SND_ENS1371
466 tristate "(Creative) Ensoniq AudioPCI 1371/1373" 441 tristate "(Creative) Ensoniq AudioPCI 1371/1373"
467 depends on SND
468 select SND_RAWMIDI 442 select SND_RAWMIDI
469 select SND_AC97_CODEC 443 select SND_AC97_CODEC
470 help 444 help
@@ -476,7 +450,6 @@ config SND_ENS1371
476 450
477config SND_ES1938 451config SND_ES1938
478 tristate "ESS ES1938/1946/1969 (Solo-1)" 452 tristate "ESS ES1938/1946/1969 (Solo-1)"
479 depends on SND
480 select SND_OPL3_LIB 453 select SND_OPL3_LIB
481 select SND_MPU401_UART 454 select SND_MPU401_UART
482 select SND_AC97_CODEC 455 select SND_AC97_CODEC
@@ -489,7 +462,6 @@ config SND_ES1938
489 462
490config SND_ES1968 463config SND_ES1968
491 tristate "ESS ES1968/1978 (Maestro-1/2/2E)" 464 tristate "ESS ES1968/1978 (Maestro-1/2/2E)"
492 depends on SND
493 select SND_MPU401_UART 465 select SND_MPU401_UART
494 select SND_AC97_CODEC 466 select SND_AC97_CODEC
495 help 467 help
@@ -501,7 +473,6 @@ config SND_ES1968
501 473
502config SND_FM801 474config SND_FM801
503 tristate "ForteMedia FM801" 475 tristate "ForteMedia FM801"
504 depends on SND
505 select SND_OPL3_LIB 476 select SND_OPL3_LIB
506 select SND_MPU401_UART 477 select SND_MPU401_UART
507 select SND_AC97_CODEC 478 select SND_AC97_CODEC
@@ -528,7 +499,6 @@ config SND_FM801_TEA575X
528 499
529config SND_HDA_INTEL 500config SND_HDA_INTEL
530 tristate "Intel HD Audio" 501 tristate "Intel HD Audio"
531 depends on SND
532 select SND_PCM 502 select SND_PCM
533 select SND_VMASTER 503 select SND_VMASTER
534 help 504 help
@@ -637,7 +607,6 @@ config SND_HDA_POWER_SAVE_DEFAULT
637 607
638config SND_HDSP 608config SND_HDSP
639 tristate "RME Hammerfall DSP Audio" 609 tristate "RME Hammerfall DSP Audio"
640 depends on SND
641 select SND_HWDEP 610 select SND_HWDEP
642 select SND_RAWMIDI 611 select SND_RAWMIDI
643 select SND_PCM 612 select SND_PCM
@@ -650,7 +619,6 @@ config SND_HDSP
650 619
651config SND_HDSPM 620config SND_HDSPM
652 tristate "RME Hammerfall DSP MADI" 621 tristate "RME Hammerfall DSP MADI"
653 depends on SND
654 select SND_HWDEP 622 select SND_HWDEP
655 select SND_RAWMIDI 623 select SND_RAWMIDI
656 select SND_PCM 624 select SND_PCM
@@ -663,7 +631,6 @@ config SND_HDSPM
663 631
664config SND_HIFIER 632config SND_HIFIER
665 tristate "TempoTec HiFier Fantasia" 633 tristate "TempoTec HiFier Fantasia"
666 depends on SND
667 select SND_OXYGEN_LIB 634 select SND_OXYGEN_LIB
668 help 635 help
669 Say Y here to include support for the MediaTek/TempoTec HiFier 636 Say Y here to include support for the MediaTek/TempoTec HiFier
@@ -674,7 +641,6 @@ config SND_HIFIER
674 641
675config SND_ICE1712 642config SND_ICE1712
676 tristate "ICEnsemble ICE1712 (Envy24)" 643 tristate "ICEnsemble ICE1712 (Envy24)"
677 depends on SND
678 select SND_MPU401_UART 644 select SND_MPU401_UART
679 select SND_AC97_CODEC 645 select SND_AC97_CODEC
680 help 646 help
@@ -691,8 +657,7 @@ config SND_ICE1712
691 657
692config SND_ICE1724 658config SND_ICE1724
693 tristate "ICE/VT1724/1720 (Envy24HT/PT)" 659 tristate "ICE/VT1724/1720 (Envy24HT/PT)"
694 depends on SND 660 select SND_RAWMIDI
695 select SND_MPU401_UART
696 select SND_AC97_CODEC 661 select SND_AC97_CODEC
697 select SND_VMASTER 662 select SND_VMASTER
698 help 663 help
@@ -709,7 +674,6 @@ config SND_ICE1724
709 674
710config SND_INTEL8X0 675config SND_INTEL8X0
711 tristate "Intel/SiS/nVidia/AMD/ALi AC97 Controller" 676 tristate "Intel/SiS/nVidia/AMD/ALi AC97 Controller"
712 depends on SND
713 select SND_AC97_CODEC 677 select SND_AC97_CODEC
714 help 678 help
715 Say Y here to include support for the integrated AC97 sound 679 Say Y here to include support for the integrated AC97 sound
@@ -722,7 +686,6 @@ config SND_INTEL8X0
722 686
723config SND_INTEL8X0M 687config SND_INTEL8X0M
724 tristate "Intel/SiS/nVidia/AMD MC97 Modem" 688 tristate "Intel/SiS/nVidia/AMD MC97 Modem"
725 depends on SND
726 select SND_AC97_CODEC 689 select SND_AC97_CODEC
727 help 690 help
728 Say Y here to include support for the integrated MC97 modem on 691 Say Y here to include support for the integrated MC97 modem on
@@ -733,7 +696,6 @@ config SND_INTEL8X0M
733 696
734config SND_KORG1212 697config SND_KORG1212
735 tristate "Korg 1212 IO" 698 tristate "Korg 1212 IO"
736 depends on SND
737 select FW_LOADER if !SND_KORG1212_FIRMWARE_IN_KERNEL 699 select FW_LOADER if !SND_KORG1212_FIRMWARE_IN_KERNEL
738 select SND_PCM 700 select SND_PCM
739 help 701 help
@@ -753,7 +715,6 @@ config SND_KORG1212_FIRMWARE_IN_KERNEL
753 715
754config SND_MAESTRO3 716config SND_MAESTRO3
755 tristate "ESS Allegro/Maestro3" 717 tristate "ESS Allegro/Maestro3"
756 depends on SND
757 select FW_LOADER if !SND_MAESTRO3_FIRMWARE_IN_KERNEL 718 select FW_LOADER if !SND_MAESTRO3_FIRMWARE_IN_KERNEL
758 select SND_AC97_CODEC 719 select SND_AC97_CODEC
759 help 720 help
@@ -774,7 +735,6 @@ config SND_MAESTRO3_FIRMWARE_IN_KERNEL
774 735
775config SND_MIXART 736config SND_MIXART
776 tristate "Digigram miXart" 737 tristate "Digigram miXart"
777 depends on SND
778 select SND_HWDEP 738 select SND_HWDEP
779 select SND_PCM 739 select SND_PCM
780 help 740 help
@@ -786,7 +746,6 @@ config SND_MIXART
786 746
787config SND_NM256 747config SND_NM256
788 tristate "NeoMagic NM256AV/ZX" 748 tristate "NeoMagic NM256AV/ZX"
789 depends on SND
790 select SND_AC97_CODEC 749 select SND_AC97_CODEC
791 help 750 help
792 Say Y here to include support for NeoMagic NM256AV/ZX chips. 751 Say Y here to include support for NeoMagic NM256AV/ZX chips.
@@ -796,7 +755,6 @@ config SND_NM256
796 755
797config SND_PCXHR 756config SND_PCXHR
798 tristate "Digigram PCXHR" 757 tristate "Digigram PCXHR"
799 depends on SND
800 select SND_PCM 758 select SND_PCM
801 select SND_HWDEP 759 select SND_HWDEP
802 help 760 help
@@ -807,7 +765,6 @@ config SND_PCXHR
807 765
808config SND_RIPTIDE 766config SND_RIPTIDE
809 tristate "Conexant Riptide" 767 tristate "Conexant Riptide"
810 depends on SND
811 select FW_LOADER 768 select FW_LOADER
812 select SND_OPL3_LIB 769 select SND_OPL3_LIB
813 select SND_MPU401_UART 770 select SND_MPU401_UART
@@ -820,7 +777,6 @@ config SND_RIPTIDE
820 777
821config SND_RME32 778config SND_RME32
822 tristate "RME Digi32, 32/8, 32 PRO" 779 tristate "RME Digi32, 32/8, 32 PRO"
823 depends on SND
824 select SND_PCM 780 select SND_PCM
825 help 781 help
826 Say Y to include support for RME Digi32, Digi32 PRO and 782 Say Y to include support for RME Digi32, Digi32 PRO and
@@ -832,7 +788,6 @@ config SND_RME32
832 788
833config SND_RME96 789config SND_RME96
834 tristate "RME Digi96, 96/8, 96/8 PRO" 790 tristate "RME Digi96, 96/8, 96/8 PRO"
835 depends on SND
836 select SND_PCM 791 select SND_PCM
837 help 792 help
838 Say Y here to include support for RME Digi96, Digi96/8 and 793 Say Y here to include support for RME Digi96, Digi96/8 and
@@ -843,7 +798,6 @@ config SND_RME96
843 798
844config SND_RME9652 799config SND_RME9652
845 tristate "RME Digi9652 (Hammerfall)" 800 tristate "RME Digi9652 (Hammerfall)"
846 depends on SND
847 select SND_PCM 801 select SND_PCM
848 help 802 help
849 Say Y here to include support for RME Hammerfall (RME 803 Say Y here to include support for RME Hammerfall (RME
@@ -854,7 +808,7 @@ config SND_RME9652
854 808
855config SND_SIS7019 809config SND_SIS7019
856 tristate "SiS 7019 Audio Accelerator" 810 tristate "SiS 7019 Audio Accelerator"
857 depends on SND && X86 && !X86_64 811 depends on X86 && !X86_64
858 select SND_AC97_CODEC 812 select SND_AC97_CODEC
859 help 813 help
860 Say Y here to include support for the SiS 7019 Audio Accelerator. 814 Say Y here to include support for the SiS 7019 Audio Accelerator.
@@ -864,7 +818,6 @@ config SND_SIS7019
864 818
865config SND_SONICVIBES 819config SND_SONICVIBES
866 tristate "S3 SonicVibes" 820 tristate "S3 SonicVibes"
867 depends on SND
868 select SND_OPL3_LIB 821 select SND_OPL3_LIB
869 select SND_MPU401_UART 822 select SND_MPU401_UART
870 select SND_AC97_CODEC 823 select SND_AC97_CODEC
@@ -877,7 +830,6 @@ config SND_SONICVIBES
877 830
878config SND_TRIDENT 831config SND_TRIDENT
879 tristate "Trident 4D-Wave DX/NX; SiS 7018" 832 tristate "Trident 4D-Wave DX/NX; SiS 7018"
880 depends on SND
881 select SND_MPU401_UART 833 select SND_MPU401_UART
882 select SND_AC97_CODEC 834 select SND_AC97_CODEC
883 help 835 help
@@ -889,7 +841,6 @@ config SND_TRIDENT
889 841
890config SND_VIA82XX 842config SND_VIA82XX
891 tristate "VIA 82C686A/B, 8233/8235 AC97 Controller" 843 tristate "VIA 82C686A/B, 8233/8235 AC97 Controller"
892 depends on SND
893 select SND_MPU401_UART 844 select SND_MPU401_UART
894 select SND_AC97_CODEC 845 select SND_AC97_CODEC
895 help 846 help
@@ -901,7 +852,6 @@ config SND_VIA82XX
901 852
902config SND_VIA82XX_MODEM 853config SND_VIA82XX_MODEM
903 tristate "VIA 82C686A/B, 8233 based Modems" 854 tristate "VIA 82C686A/B, 8233 based Modems"
904 depends on SND
905 select SND_AC97_CODEC 855 select SND_AC97_CODEC
906 help 856 help
907 Say Y here to include support for the integrated MC97 modem on 857 Say Y here to include support for the integrated MC97 modem on
@@ -912,7 +862,6 @@ config SND_VIA82XX_MODEM
912 862
913config SND_VIRTUOSO 863config SND_VIRTUOSO
914 tristate "Asus Virtuoso 100/200 (Xonar)" 864 tristate "Asus Virtuoso 100/200 (Xonar)"
915 depends on SND
916 select SND_OXYGEN_LIB 865 select SND_OXYGEN_LIB
917 help 866 help
918 Say Y here to include support for sound cards based on the 867 Say Y here to include support for sound cards based on the
@@ -923,7 +872,6 @@ config SND_VIRTUOSO
923 872
924config SND_VX222 873config SND_VX222
925 tristate "Digigram VX222" 874 tristate "Digigram VX222"
926 depends on SND
927 select SND_VX_LIB 875 select SND_VX_LIB
928 help 876 help
929 Say Y here to include support for Digigram VX222 soundcards. 877 Say Y here to include support for Digigram VX222 soundcards.
@@ -933,7 +881,6 @@ config SND_VX222
933 881
934config SND_YMFPCI 882config SND_YMFPCI
935 tristate "Yamaha YMF724/740/744/754" 883 tristate "Yamaha YMF724/740/744/754"
936 depends on SND
937 select FW_LOADER if !SND_YMFPCI_FIRMWARE_IN_KERNEL 884 select FW_LOADER if !SND_YMFPCI_FIRMWARE_IN_KERNEL
938 select SND_OPL3_LIB 885 select SND_OPL3_LIB
939 select SND_MPU401_UART 886 select SND_MPU401_UART
@@ -954,25 +901,4 @@ config SND_YMFPCI_FIRMWARE_IN_KERNEL
954 for the YMFPCI driver. If you choose N here, you need to 901 for the YMFPCI driver. If you choose N here, you need to
955 install the firmware files from the alsa-firmware package. 902 install the firmware files from the alsa-firmware package.
956 903
957config SND_AC97_POWER_SAVE 904endif # SND_PCI
958 bool "AC97 Power-Saving Mode"
959 depends on SND_AC97_CODEC && EXPERIMENTAL
960 default n
961 help
962 Say Y here to enable the aggressive power-saving support of
963 AC97 codecs. In this mode, the power-mode is dynamically
964 controlled at each open/close.
965
966 The mode is activated by passing power_save=1 option to
967 snd-ac97-codec driver. You can toggle it dynamically over
968 sysfs, too.
969
970config SND_AC97_POWER_SAVE_DEFAULT
971 int "Default time-out for AC97 power-save mode"
972 depends on SND_AC97_POWER_SAVE
973 default 0
974 help
975 The default time-out value in seconds for AC97 automatic
976 power-save mode. 0 means to disable the power-save mode.
977
978endmenu
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index 85ef14bc8056..65b25d221cd2 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -13,7 +13,7 @@ snd-bt87x-objs := bt87x.o
13snd-cmipci-objs := cmipci.o 13snd-cmipci-objs := cmipci.o
14snd-cs4281-objs := cs4281.o 14snd-cs4281-objs := cs4281.o
15snd-cs5530-objs := cs5530.o 15snd-cs5530-objs := cs5530.o
16snd-ens1370-objs := ens1370.o 16snd-ens1370-objs := ens1370.o ak4531_codec.o
17snd-ens1371-objs := ens1371.o 17snd-ens1371-objs := ens1371.o
18snd-es1938-objs := es1938.o 18snd-es1938-objs := es1938.o
19snd-es1968-objs := es1968.o 19snd-es1968-objs := es1968.o
diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile
index 0be48b1a22d0..41fa322f0971 100644
--- a/sound/pci/ac97/Makefile
+++ b/sound/pci/ac97/Makefile
@@ -3,16 +3,8 @@
3# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz> 3# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
4# 4#
5 5
6snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o 6snd-ac97-codec-y := ac97_codec.o ac97_pcm.o
7 7snd-ac97-codec-$(CONFIG_PROC_FS) += ac97_proc.o
8ifneq ($(CONFIG_PROC_FS),)
9snd-ac97-codec-objs += ac97_proc.o
10endif
11
12snd-ak4531-codec-objs := ak4531_codec.o
13 8
14# Toplevel Module Dependency 9# Toplevel Module Dependency
15obj-$(CONFIG_SND_AC97_CODEC) += snd-ac97-codec.o 10obj-$(CONFIG_SND_AC97_CODEC) += snd-ac97-codec.o
16obj-$(CONFIG_SND_ENS1370) += snd-ak4531-codec.o
17
18obj-m := $(sort $(obj-m))
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 45fd29017ddd..07364c00768a 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -49,8 +49,9 @@ MODULE_PARM_DESC(enable_loopback, "Enable AC97 ADC/DAC Loopback Control");
49 49
50#ifdef CONFIG_SND_AC97_POWER_SAVE 50#ifdef CONFIG_SND_AC97_POWER_SAVE
51static int power_save = CONFIG_SND_AC97_POWER_SAVE_DEFAULT; 51static int power_save = CONFIG_SND_AC97_POWER_SAVE_DEFAULT;
52module_param(power_save, bool, 0644); 52module_param(power_save, int, 0644);
53MODULE_PARM_DESC(power_save, "Enable AC97 power-saving control"); 53MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
54 "(in second, 0 = disable).");
54#endif 55#endif
55/* 56/*
56 57
@@ -2294,9 +2295,11 @@ static void snd_ac97_powerdown(struct snd_ac97 *ac97)
2294 power |= AC97_PD_PR0 | AC97_PD_PR1; /* ADC & DAC powerdown */ 2295 power |= AC97_PD_PR0 | AC97_PD_PR1; /* ADC & DAC powerdown */
2295 snd_ac97_write(ac97, AC97_POWERDOWN, power); 2296 snd_ac97_write(ac97, AC97_POWERDOWN, power);
2296 udelay(100); 2297 udelay(100);
2297 power |= AC97_PD_PR2 | AC97_PD_PR3; /* Analog Mixer powerdown */ 2298 power |= AC97_PD_PR2; /* Analog Mixer powerdown (Vref on) */
2298 snd_ac97_write(ac97, AC97_POWERDOWN, power); 2299 snd_ac97_write(ac97, AC97_POWERDOWN, power);
2299 if (ac97_is_power_save_mode(ac97)) { 2300 if (ac97_is_power_save_mode(ac97)) {
2301 power |= AC97_PD_PR3; /* Analog Mixer powerdown */
2302 snd_ac97_write(ac97, AC97_POWERDOWN, power);
2300 udelay(100); 2303 udelay(100);
2301 /* AC-link powerdown, internal Clk disable */ 2304 /* AC-link powerdown, internal Clk disable */
2302 /* FIXME: this may cause click noises on some boards */ 2305 /* FIXME: this may cause click noises on some boards */
@@ -2362,7 +2365,7 @@ int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup)
2362 * that open/close frequently) 2365 * that open/close frequently)
2363 */ 2366 */
2364 schedule_delayed_work(&ac97->power_work, 2367 schedule_delayed_work(&ac97->power_work,
2365 msecs_to_jiffies(2000)); 2368 msecs_to_jiffies(power_save * 1000));
2366 else { 2369 else {
2367 cancel_delayed_work(&ac97->power_work); 2370 cancel_delayed_work(&ac97->power_work);
2368 update_power_regs(ac97); 2371 update_power_regs(ac97);
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 1292dcee072d..0746e9ccc20b 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -669,6 +669,7 @@ AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1),
669AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), 669AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
670AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), 670AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0),
671 671
672AC97_SINGLE("Master Left Inv Switch", AC97_MASTER, 6, 1, 0),
672AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0), 673AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0),
673AC97_SINGLE("Headphone ZC Switch", AC97_HEADPHONE, 7, 1, 0), 674AC97_SINGLE("Headphone ZC Switch", AC97_HEADPHONE, 7, 1, 0),
674AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO, 7, 1, 0), 675AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO, 7, 1, 0),
@@ -3352,8 +3353,66 @@ AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0),
3352AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0), 3353AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0),
3353}; 3354};
3354 3355
3356static const char *slave_vols_vt1616[] = {
3357 "Front Playback Volume",
3358 "Surround Playback Volume",
3359 "Center Playback Volume",
3360 "LFE Playback Volume",
3361 NULL
3362};
3363
3364static const char *slave_sws_vt1616[] = {
3365 "Front Playback Switch",
3366 "Surround Playback Switch",
3367 "Center Playback Switch",
3368 "LFE Playback Switch",
3369 NULL
3370};
3371
3372/* find a mixer control element with the given name */
3373static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97,
3374 const char *name)
3375{
3376 struct snd_ctl_elem_id id;
3377 memset(&id, 0, sizeof(id));
3378 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
3379 strcpy(id.name, name);
3380 return snd_ctl_find_id(ac97->bus->card, &id);
3381}
3382
3383/* create a virtual master control and add slaves */
3384int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name,
3385 const unsigned int *tlv, const char **slaves)
3386{
3387 struct snd_kcontrol *kctl;
3388 const char **s;
3389 int err;
3390
3391 kctl = snd_ctl_make_virtual_master(name, tlv);
3392 if (!kctl)
3393 return -ENOMEM;
3394 err = snd_ctl_add(ac97->bus->card, kctl);
3395 if (err < 0)
3396 return err;
3397
3398 for (s = slaves; *s; s++) {
3399 struct snd_kcontrol *sctl;
3400
3401 sctl = snd_ac97_find_mixer_ctl(ac97, *s);
3402 if (!sctl) {
3403 snd_printdd("Cannot find slave %s, skipped\n", *s);
3404 continue;
3405 }
3406 err = snd_ctl_add_slave(kctl, sctl);
3407 if (err < 0)
3408 return err;
3409 }
3410 return 0;
3411}
3412
3355static int patch_vt1616_specific(struct snd_ac97 * ac97) 3413static int patch_vt1616_specific(struct snd_ac97 * ac97)
3356{ 3414{
3415 struct snd_kcontrol *kctl;
3357 int err; 3416 int err;
3358 3417
3359 if (snd_ac97_try_bit(ac97, 0x5a, 9)) 3418 if (snd_ac97_try_bit(ac97, 0x5a, 9))
@@ -3361,6 +3420,24 @@ static int patch_vt1616_specific(struct snd_ac97 * ac97)
3361 return err; 3420 return err;
3362 if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[1], ARRAY_SIZE(snd_ac97_controls_vt1616) - 1)) < 0) 3421 if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[1], ARRAY_SIZE(snd_ac97_controls_vt1616) - 1)) < 0)
3363 return err; 3422 return err;
3423
3424 /* There is already a misnamed master switch. Rename it. */
3425 kctl = snd_ac97_find_mixer_ctl(ac97, "Master Playback Volume");
3426 if (!kctl)
3427 return -EINVAL;
3428
3429 snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Front Playback");
3430
3431 err = snd_ac97_add_vmaster(ac97, "Master Playback Volume",
3432 kctl->tlv.p, slave_vols_vt1616);
3433 if (err < 0)
3434 return err;
3435
3436 err = snd_ac97_add_vmaster(ac97, "Master Playback Switch",
3437 NULL, slave_sws_vt1616);
3438 if (err < 0)
3439 return err;
3440
3364 return 0; 3441 return 0;
3365} 3442}
3366 3443
@@ -3633,7 +3710,7 @@ static int patch_ucb1400(struct snd_ac97 * ac97)
3633{ 3710{
3634 ac97->build_ops = &patch_ucb1400_ops; 3711 ac97->build_ops = &patch_ucb1400_ops;
3635 /* enable headphone driver and smart low power mode by default */ 3712 /* enable headphone driver and smart low power mode by default */
3636 snd_ac97_write(ac97, 0x6a, 0x0050); 3713 snd_ac97_write_cache(ac97, 0x6a, 0x0050);
3637 snd_ac97_write(ac97, 0x6c, 0x0030); 3714 snd_ac97_write_cache(ac97, 0x6c, 0x0030);
3638 return 0; 3715 return 0;
3639} 3716}
diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ak4531_codec.c
index c0c1633999ea..33d37b1c42fc 100644
--- a/sound/pci/ac97/ak4531_codec.c
+++ b/sound/pci/ak4531_codec.c
@@ -28,9 +28,11 @@
28#include <sound/ak4531_codec.h> 28#include <sound/ak4531_codec.h>
29#include <sound/tlv.h> 29#include <sound/tlv.h>
30 30
31/*
31MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 32MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
32MODULE_DESCRIPTION("Universal routines for AK4531 codec"); 33MODULE_DESCRIPTION("Universal routines for AK4531 codec");
33MODULE_LICENSE("GPL"); 34MODULE_LICENSE("GPL");
35*/
34 36
35#ifdef CONFIG_PROC_FS 37#ifdef CONFIG_PROC_FS
36static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531); 38static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531);
@@ -270,7 +272,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_master, -6200, 200, 0);
270static const DECLARE_TLV_DB_SCALE(db_scale_mono, -2800, 400, 0); 272static const DECLARE_TLV_DB_SCALE(db_scale_mono, -2800, 400, 0);
271static const DECLARE_TLV_DB_SCALE(db_scale_input, -5000, 200, 0); 273static const DECLARE_TLV_DB_SCALE(db_scale_input, -5000, 200, 0);
272 274
273static struct snd_kcontrol_new snd_ak4531_controls[] = { 275static struct snd_kcontrol_new snd_ak4531_controls[] __devinitdata = {
274 276
275AK4531_DOUBLE_TLV("Master Playback Switch", 0, 277AK4531_DOUBLE_TLV("Master Playback Switch", 0,
276 AK4531_LMASTER, AK4531_RMASTER, 7, 7, 1, 1, 278 AK4531_LMASTER, AK4531_RMASTER, 7, 7, 1, 1,
@@ -379,8 +381,9 @@ static u8 snd_ak4531_initial_map[0x19 + 1] = {
379 0x01 /* 19: Mic Amp Setup */ 381 0x01 /* 19: Mic Amp Setup */
380}; 382};
381 383
382int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531, 384int __devinit snd_ak4531_mixer(struct snd_card *card,
383 struct snd_ak4531 **rak4531) 385 struct snd_ak4531 *_ak4531,
386 struct snd_ak4531 **rak4531)
384{ 387{
385 unsigned int idx; 388 unsigned int idx;
386 int err; 389 int err;
@@ -476,7 +479,8 @@ static void snd_ak4531_proc_read(struct snd_info_entry *entry,
476 ak4531->regs[AK4531_MIC_GAIN] & 1 ? "+30dB" : "+0dB"); 479 ak4531->regs[AK4531_MIC_GAIN] & 1 ? "+30dB" : "+0dB");
477} 480}
478 481
479static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531) 482static void __devinit
483snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531)
480{ 484{
481 struct snd_info_entry *entry; 485 struct snd_info_entry *entry;
482 486
@@ -484,25 +488,3 @@ static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak453
484 snd_info_set_text_ops(entry, ak4531, snd_ak4531_proc_read); 488 snd_info_set_text_ops(entry, ak4531, snd_ak4531_proc_read);
485} 489}
486#endif 490#endif
487
488EXPORT_SYMBOL(snd_ak4531_mixer);
489#ifdef CONFIG_PM
490EXPORT_SYMBOL(snd_ak4531_suspend);
491EXPORT_SYMBOL(snd_ak4531_resume);
492#endif
493
494/*
495 * INIT part
496 */
497
498static int __init alsa_ak4531_init(void)
499{
500 return 0;
501}
502
503static void __exit alsa_ak4531_exit(void)
504{
505}
506
507module_init(alsa_ak4531_init)
508module_exit(alsa_ak4531_exit)
diff --git a/sound/pci/au88x0/au88x0_game.c b/sound/pci/au88x0/au88x0_game.c
index bc212f41a38a..e291aa59742e 100644
--- a/sound/pci/au88x0/au88x0_game.c
+++ b/sound/pci/au88x0/au88x0_game.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * $Id: au88x0_game.c,v 1.9 2003/09/22 03:51:28 mjander Exp $
3 *
4 * Manuel Jander. 2 * Manuel Jander.
5 * 3 *
6 * Based on the work of: 4 * Based on the work of:
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 5f63af6b88a2..22f18f3cfbc9 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168). 2 * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
3 * Copyright (C) 2002, 2005, 2006, 2007 by Andreas Mohr <andi AT lisas.de> 3 * Copyright (C) 2002, 2005 - 2008 by Andreas Mohr <andi AT lisas.de>
4 * 4 *
5 * Framework borrowed from Bart Hartgers's als4000.c. 5 * Framework borrowed from Bart Hartgers's als4000.c.
6 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801), 6 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -35,9 +35,20 @@
35 * (3 weeks' worth of evenings filled with driver work). 35 * (3 weeks' worth of evenings filled with driver work).
36 * (and no, I did NOT go the easy way: to pick up a SB PCI128 for 9 Euros) 36 * (and no, I did NOT go the easy way: to pick up a SB PCI128 for 9 Euros)
37 * 37 *
38 * It is quite likely that the AZF3328 chip is the PCI cousin of the
39 * AZF3318 ("azt1020 pnp", "MM Pro 16") ISA chip, given very similar specs.
40 *
38 * The AZF3328 chip (note: AZF3328, *not* AZT3328, that's just the driver name 41 * The AZF3328 chip (note: AZF3328, *not* AZT3328, that's just the driver name
39 * for compatibility reasons) has the following features: 42 * for compatibility reasons) from Azfin (joint-venture of Aztech and Fincitec,
43 * Fincitec acquired by National Semiconductor in 2002, together with the
44 * Fincitec-related company ARSmikro) has the following features:
40 * 45 *
46 * - compatibility & compliance:
47 * - Microsoft PC 97 ("PC 97 Hardware Design Guide",
48 * http://www.microsoft.com/whdc/archive/pcguides.mspx)
49 * - Microsoft PC 98 Baseline Audio
50 * - MPU401 UART
51 * - Sound Blaster Emulation (DOS Box)
41 * - builtin AC97 conformant codec (SNR over 80dB) 52 * - builtin AC97 conformant codec (SNR over 80dB)
42 * Note that "conformant" != "compliant"!! this chip's mixer register layout 53 * Note that "conformant" != "compliant"!! this chip's mixer register layout
43 * *differs* from the standard AC97 layout: 54 * *differs* from the standard AC97 layout:
@@ -48,21 +59,28 @@
48 * addresses illegally. So far unfortunately it looks like the very flexible 59 * addresses illegally. So far unfortunately it looks like the very flexible
49 * ALSA AC97 support is still not enough to easily compensate for such a 60 * ALSA AC97 support is still not enough to easily compensate for such a
50 * grave layout violation despite all tweaks and quirks mechanisms it offers. 61 * grave layout violation despite all tweaks and quirks mechanisms it offers.
51 * - builtin genuine OPL3 62 * - builtin genuine OPL3 - verified to work fine, 20080506
52 * - full duplex 16bit playback/record at independent sampling rate 63 * - full duplex 16bit playback/record at independent sampling rate
53 * - MPU401 (+ legacy address support) FIXME: how to enable legacy addr?? 64 * - MPU401 (+ legacy address support, claimed by one official spec sheet)
65 * FIXME: how to enable legacy addr??
54 * - game port (legacy address support) 66 * - game port (legacy address support)
55 * - builtin 3D enhancement (said to be YAMAHA Ymersion)
56 * - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven 67 * - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven
57 * features supported) 68 * features supported). - See common term "Digital Enhanced Game Port"...
69 * (probably DirectInput 3.0 spec - confirm)
70 * - builtin 3D enhancement (said to be YAMAHA Ymersion)
58 * - built-in General DirectX timer having a 20 bits counter 71 * - built-in General DirectX timer having a 20 bits counter
59 * with 1us resolution (see below!) 72 * with 1us resolution (see below!)
60 * - I2S serial port for external DAC 73 * - I2S serial output port for external DAC
61 * - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI 74 * - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI
62 * - supports hardware volume control 75 * - supports hardware volume control
63 * - single chip low cost solution (128 pin QFP) 76 * - single chip low cost solution (128 pin QFP)
64 * - supports programmable Sub-vendor and Sub-system ID 77 * - supports programmable Sub-vendor and Sub-system ID
65 * required for Microsoft's logo compliance (FIXME: where?) 78 * required for Microsoft's logo compliance (FIXME: where?)
79 * At least the Trident 4D Wave DX has one bit somewhere
80 * to enable writes to PCI subsystem VID registers, that should be it.
81 * This might easily be in extended PCI reg space, since PCI168 also has
82 * some custom data starting at 0x80. What kind of config settings
83 * are located in our extended PCI space anyway??
66 * - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms 84 * - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms
67 * 85 *
68 * Note that this driver now is actually *better* than the Windows driver, 86 * Note that this driver now is actually *better* than the Windows driver,
@@ -74,6 +92,24 @@
74 * - "timidity -iAv -B2,8 -Os -EFreverb=0" 92 * - "timidity -iAv -B2,8 -Os -EFreverb=0"
75 * - "pmidi -p 128:0 jazz.mid" 93 * - "pmidi -p 128:0 jazz.mid"
76 * 94 *
95 * OPL3 hardware playback testing, try something like:
96 * cat /proc/asound/hwdep
97 * and
98 * aconnect -o
99 * Then use
100 * sbiload -Dhw:x,y --opl3 /usr/share/sounds/opl3/std.o3 ......./drums.o3
101 * where x,y is the xx-yy number as given in hwdep.
102 * Then try
103 * pmidi -p a:b jazz.mid
104 * where a:b is the client number plus 0 usually, as given by aconnect above.
105 * Oh, and make sure to unmute the FM mixer control (doh!)
106 * NOTE: power use during OPL3 playback is _VERY_ high (70W --> 90W!)
107 * despite no CPU activity, possibly due to hindering ACPI idling somehow.
108 * Shouldn't be a problem of the AZF3328 chip itself, I'd hope.
109 * Higher PCM / FM mixer levels seem to conflict (causes crackling),
110 * at least sometimes. Maybe even use with hardware sequencer timer above :)
111 * adplay/adplug-utils might soon offer hardware-based OPL3 playback, too.
112 *
77 * Certain PCI versions of this card are susceptible to DMA traffic underruns 113 * Certain PCI versions of this card are susceptible to DMA traffic underruns
78 * in some systems (resulting in sound crackling/clicking/popping), 114 * in some systems (resulting in sound crackling/clicking/popping),
79 * probably because they don't have a DMA FIFO buffer or so. 115 * probably because they don't have a DMA FIFO buffer or so.
@@ -87,6 +123,8 @@
87 * better than a VIA, yet ironically I still get crackling, like many other 123 * better than a VIA, yet ironically I still get crackling, like many other
88 * people with the same chipset. 124 * people with the same chipset.
89 * Possible remedies: 125 * Possible remedies:
126 * - use speaker (amplifier) output instead of headphone output
127 * (in case crackling is due to overloaded output clipping)
90 * - plug card into a different PCI slot, preferrably one that isn't shared 128 * - plug card into a different PCI slot, preferrably one that isn't shared
91 * too much (this helps a lot, but not completely!) 129 * too much (this helps a lot, but not completely!)
92 * - get rid of PCI VGA card, use AGP instead 130 * - get rid of PCI VGA card, use AGP instead
@@ -94,18 +132,23 @@
94 * - fiddle with PCI latency settings (setpci -v -s BUSID latency_timer=XX) 132 * - fiddle with PCI latency settings (setpci -v -s BUSID latency_timer=XX)
95 * Not too helpful. 133 * Not too helpful.
96 * - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS 134 * - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS
97 * 135 *
98 * BUGS 136 * BUGS
99 * - full-duplex might *still* be problematic, not fully tested recently 137 * - full-duplex might *still* be problematic, however a recent test was fine
100 * - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated 138 * - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated
101 * if you set PCM output switch to "pre 3D" instead of "post 3D". 139 * if you set PCM output switch to "pre 3D" instead of "post 3D".
102 * If this can't be set, then get a mixer application that Isn't Stupid (tm) 140 * If this can't be set, then get a mixer application that Isn't Stupid (tm)
103 * (e.g. kmix, gamix) - unfortunately several are!! 141 * (e.g. kmix, gamix) - unfortunately several are!!
104 * 142 * - locking is not entirely clean, especially the audio stream activity
143 * ints --> may be racy
144 * - an _unconnected_ secondary joystick at the gameport will be reported
145 * to be "active" (floating values, not precisely -1) due to the way we need
146 * to read the Digital Enhanced Game Port. Not sure whether it is fixable.
147 *
105 * TODO 148 * TODO
106 * - test MPU401 MIDI playback etc. 149 * - test MPU401 MIDI playback etc.
107 * - add some power micro-management (disable various units of the card 150 * - add more power micro-management (disable various units of the card
108 * as long as they're unused). However this requires I/O ports which I 151 * as long as they're unused). However this requires more I/O ports which I
109 * haven't figured out yet and which thus might not even exist... 152 * haven't figured out yet and which thus might not even exist...
110 * The standard suspend/resume functionality could probably make use of 153 * The standard suspend/resume functionality could probably make use of
111 * some improvement, too... 154 * some improvement, too...
@@ -113,6 +156,7 @@
113 * - figure out some cleverly evil scheme to possibly make ALSA AC97 code 156 * - figure out some cleverly evil scheme to possibly make ALSA AC97 code
114 * fully accept our quite incompatible ""AC97"" mixer and thus save some 157 * fully accept our quite incompatible ""AC97"" mixer and thus save some
115 * code (but I'm not too optimistic that doing this is possible at all) 158 * code (but I'm not too optimistic that doing this is possible at all)
159 * - use MMIO (memory-mapped I/O)? Slightly faster access, e.g. for gameport.
116 */ 160 */
117 161
118#include <asm/io.h> 162#include <asm/io.h>
@@ -138,7 +182,7 @@ MODULE_LICENSE("GPL");
138MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}"); 182MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
139 183
140#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) 184#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
141#define SUPPORT_JOYSTICK 1 185#define SUPPORT_GAMEPORT 1
142#endif 186#endif
143 187
144#define DEBUG_MISC 0 188#define DEBUG_MISC 0
@@ -147,13 +191,14 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
147#define DEBUG_PLAY_REC 0 191#define DEBUG_PLAY_REC 0
148#define DEBUG_IO 0 192#define DEBUG_IO 0
149#define DEBUG_TIMER 0 193#define DEBUG_TIMER 0
194#define DEBUG_GAME 0
150#define MIXER_TESTING 0 195#define MIXER_TESTING 0
151 196
152#if DEBUG_MISC 197#if DEBUG_MISC
153#define snd_azf3328_dbgmisc(format, args...) printk(KERN_ERR format, ##args) 198#define snd_azf3328_dbgmisc(format, args...) printk(KERN_ERR format, ##args)
154#else 199#else
155#define snd_azf3328_dbgmisc(format, args...) 200#define snd_azf3328_dbgmisc(format, args...)
156#endif 201#endif
157 202
158#if DEBUG_CALLS 203#if DEBUG_CALLS
159#define snd_azf3328_dbgcalls(format, args...) printk(format, ##args) 204#define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
@@ -163,25 +208,31 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
163#define snd_azf3328_dbgcalls(format, args...) 208#define snd_azf3328_dbgcalls(format, args...)
164#define snd_azf3328_dbgcallenter() 209#define snd_azf3328_dbgcallenter()
165#define snd_azf3328_dbgcallleave() 210#define snd_azf3328_dbgcallleave()
166#endif 211#endif
167 212
168#if DEBUG_MIXER 213#if DEBUG_MIXER
169#define snd_azf3328_dbgmixer(format, args...) printk(format, ##args) 214#define snd_azf3328_dbgmixer(format, args...) printk(format, ##args)
170#else 215#else
171#define snd_azf3328_dbgmixer(format, args...) 216#define snd_azf3328_dbgmixer(format, args...)
172#endif 217#endif
173 218
174#if DEBUG_PLAY_REC 219#if DEBUG_PLAY_REC
175#define snd_azf3328_dbgplay(format, args...) printk(KERN_ERR format, ##args) 220#define snd_azf3328_dbgplay(format, args...) printk(KERN_ERR format, ##args)
176#else 221#else
177#define snd_azf3328_dbgplay(format, args...) 222#define snd_azf3328_dbgplay(format, args...)
178#endif 223#endif
179 224
180#if DEBUG_MISC 225#if DEBUG_MISC
181#define snd_azf3328_dbgtimer(format, args...) printk(KERN_ERR format, ##args) 226#define snd_azf3328_dbgtimer(format, args...) printk(KERN_ERR format, ##args)
182#else 227#else
183#define snd_azf3328_dbgtimer(format, args...) 228#define snd_azf3328_dbgtimer(format, args...)
184#endif 229#endif
230
231#if DEBUG_GAME
232#define snd_azf3328_dbggame(format, args...) printk(KERN_ERR format, ##args)
233#else
234#define snd_azf3328_dbggame(format, args...)
235#endif
185 236
186static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 237static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
187module_param_array(index, int, NULL, 0444); 238module_param_array(index, int, NULL, 0444);
@@ -195,51 +246,62 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card *
195module_param_array(enable, bool, NULL, 0444); 246module_param_array(enable, bool, NULL, 0444);
196MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard."); 247MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard.");
197 248
198#ifdef SUPPORT_JOYSTICK
199static int joystick[SNDRV_CARDS];
200module_param_array(joystick, bool, NULL, 0444);
201MODULE_PARM_DESC(joystick, "Enable joystick for AZF3328 soundcard.");
202#endif
203
204static int seqtimer_scaling = 128; 249static int seqtimer_scaling = 128;
205module_param(seqtimer_scaling, int, 0444); 250module_param(seqtimer_scaling, int, 0444);
206MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128."); 251MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
207 252
253struct snd_azf3328_audio_stream {
254 struct snd_pcm_substream *substream;
255 int enabled;
256 int running;
257 unsigned long portbase;
258};
259
260enum snd_azf3328_stream_index {
261 AZF_PLAYBACK = 0,
262 AZF_CAPTURE = 1,
263};
264
208struct snd_azf3328 { 265struct snd_azf3328 {
209 /* often-used fields towards beginning, then grouped */ 266 /* often-used fields towards beginning, then grouped */
210 unsigned long codec_port; 267
211 unsigned long io2_port; 268 unsigned long codec_io; /* usually 0xb000, size 128 */
212 unsigned long mpu_port; 269 unsigned long game_io; /* usually 0xb400, size 8 */
213 unsigned long synth_port; 270 unsigned long mpu_io; /* usually 0xb800, size 4 */
214 unsigned long mixer_port; 271 unsigned long opl3_io; /* usually 0xbc00, size 8 */
272 unsigned long mixer_io; /* usually 0xc000, size 64 */
215 273
216 spinlock_t reg_lock; 274 spinlock_t reg_lock;
217 275
218 struct snd_timer *timer; 276 struct snd_timer *timer;
219 277
220 struct snd_pcm *pcm; 278 struct snd_pcm *pcm;
221 struct snd_pcm_substream *playback_substream; 279 struct snd_azf3328_audio_stream audio_stream[2];
222 struct snd_pcm_substream *capture_substream;
223 unsigned int is_playing;
224 unsigned int is_recording;
225 280
226 struct snd_card *card; 281 struct snd_card *card;
227 struct snd_rawmidi *rmidi; 282 struct snd_rawmidi *rmidi;
228 283
229#ifdef SUPPORT_JOYSTICK 284#ifdef SUPPORT_GAMEPORT
230 struct gameport *gameport; 285 struct gameport *gameport;
286 int axes[4];
231#endif 287#endif
232 288
233 struct pci_dev *pci; 289 struct pci_dev *pci;
234 int irq; 290 int irq;
235 291
292 /* register 0x6a is write-only, thus need to remember setting.
293 * If we need to add more registers here, then we might try to fold this
294 * into some transparent combined shadow register handling with
295 * CONFIG_PM register storage below, but that's slightly difficult. */
296 u16 shadow_reg_codec_6AH;
297
236#ifdef CONFIG_PM 298#ifdef CONFIG_PM
237 /* register value containers for power management 299 /* register value containers for power management
238 * Note: not always full I/O range preserved (just like Win driver!) */ 300 * Note: not always full I/O range preserved (just like Win driver!) */
239 u16 saved_regs_codec [AZF_IO_SIZE_CODEC_PM / 2]; 301 u16 saved_regs_codec[AZF_IO_SIZE_CODEC_PM / 2];
240 u16 saved_regs_io2 [AZF_IO_SIZE_IO2_PM / 2]; 302 u16 saved_regs_game [AZF_IO_SIZE_GAME_PM / 2];
241 u16 saved_regs_mpu [AZF_IO_SIZE_MPU_PM / 2]; 303 u16 saved_regs_mpu [AZF_IO_SIZE_MPU_PM / 2];
242 u16 saved_regs_synth[AZF_IO_SIZE_SYNTH_PM / 2]; 304 u16 saved_regs_opl3 [AZF_IO_SIZE_OPL3_PM / 2];
243 u16 saved_regs_mixer[AZF_IO_SIZE_MIXER_PM / 2]; 305 u16 saved_regs_mixer[AZF_IO_SIZE_MIXER_PM / 2];
244#endif 306#endif
245}; 307};
@@ -252,126 +314,166 @@ static const struct pci_device_id snd_azf3328_ids[] = {
252 314
253MODULE_DEVICE_TABLE(pci, snd_azf3328_ids); 315MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
254 316
317
318static int
319snd_azf3328_io_reg_setb(unsigned reg, u8 mask, int do_set)
320{
321 u8 prev = inb(reg), new;
322
323 new = (do_set) ? (prev|mask) : (prev & ~mask);
324 /* we need to always write the new value no matter whether it differs
325 * or not, since some register bits don't indicate their setting */
326 outb(new, reg);
327 if (new != prev)
328 return 1;
329
330 return 0;
331}
332
255static inline void 333static inline void
256snd_azf3328_codec_outb(const struct snd_azf3328 *chip, int reg, u8 value) 334snd_azf3328_codec_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
257{ 335{
258 outb(value, chip->codec_port + reg); 336 outb(value, chip->codec_io + reg);
259} 337}
260 338
261static inline u8 339static inline u8
262snd_azf3328_codec_inb(const struct snd_azf3328 *chip, int reg) 340snd_azf3328_codec_inb(const struct snd_azf3328 *chip, unsigned reg)
263{ 341{
264 return inb(chip->codec_port + reg); 342 return inb(chip->codec_io + reg);
265} 343}
266 344
267static inline void 345static inline void
268snd_azf3328_codec_outw(const struct snd_azf3328 *chip, int reg, u16 value) 346snd_azf3328_codec_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
269{ 347{
270 outw(value, chip->codec_port + reg); 348 outw(value, chip->codec_io + reg);
271} 349}
272 350
273static inline u16 351static inline u16
274snd_azf3328_codec_inw(const struct snd_azf3328 *chip, int reg) 352snd_azf3328_codec_inw(const struct snd_azf3328 *chip, unsigned reg)
353{
354 return inw(chip->codec_io + reg);
355}
356
357static inline void
358snd_azf3328_codec_outl(const struct snd_azf3328 *chip, unsigned reg, u32 value)
359{
360 outl(value, chip->codec_io + reg);
361}
362
363static inline u32
364snd_azf3328_codec_inl(const struct snd_azf3328 *chip, unsigned reg)
275{ 365{
276 return inw(chip->codec_port + reg); 366 return inl(chip->codec_io + reg);
277} 367}
278 368
279static inline void 369static inline void
280snd_azf3328_codec_outl(const struct snd_azf3328 *chip, int reg, u32 value) 370snd_azf3328_game_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
281{ 371{
282 outl(value, chip->codec_port + reg); 372 outb(value, chip->game_io + reg);
283} 373}
284 374
285static inline void 375static inline void
286snd_azf3328_io2_outb(const struct snd_azf3328 *chip, int reg, u8 value) 376snd_azf3328_game_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
287{ 377{
288 outb(value, chip->io2_port + reg); 378 outw(value, chip->game_io + reg);
289} 379}
290 380
291static inline u8 381static inline u8
292snd_azf3328_io2_inb(const struct snd_azf3328 *chip, int reg) 382snd_azf3328_game_inb(const struct snd_azf3328 *chip, unsigned reg)
293{ 383{
294 return inb(chip->io2_port + reg); 384 return inb(chip->game_io + reg);
385}
386
387static inline u16
388snd_azf3328_game_inw(const struct snd_azf3328 *chip, unsigned reg)
389{
390 return inw(chip->game_io + reg);
295} 391}
296 392
297static inline void 393static inline void
298snd_azf3328_mixer_outw(const struct snd_azf3328 *chip, int reg, u16 value) 394snd_azf3328_mixer_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
299{ 395{
300 outw(value, chip->mixer_port + reg); 396 outw(value, chip->mixer_io + reg);
301} 397}
302 398
303static inline u16 399static inline u16
304snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, int reg) 400snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, unsigned reg)
305{ 401{
306 return inw(chip->mixer_port + reg); 402 return inw(chip->mixer_io + reg);
307} 403}
308 404
309static void 405#define AZF_MUTE_BIT 0x80
310snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip, int reg, int do_mute) 406
407static int
408snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip,
409 unsigned reg, int do_mute
410)
311{ 411{
312 unsigned long portbase = chip->mixer_port + reg + 1; 412 unsigned long portbase = chip->mixer_io + reg + 1;
313 unsigned char oldval; 413 int updated;
314 414
315 /* the mute bit is on the *second* (i.e. right) register of a 415 /* the mute bit is on the *second* (i.e. right) register of a
316 * left/right channel setting */ 416 * left/right channel setting */
317 oldval = inb(portbase); 417 updated = snd_azf3328_io_reg_setb(portbase, AZF_MUTE_BIT, do_mute);
318 if (do_mute) 418
319 oldval |= 0x80; 419 /* indicate whether it was muted before */
320 else 420 return (do_mute) ? !updated : updated;
321 oldval &= ~0x80;
322 outb(oldval, portbase);
323} 421}
324 422
325static void 423static void
326snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay) 424snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip,
425 unsigned reg,
426 unsigned char dst_vol_left,
427 unsigned char dst_vol_right,
428 int chan_sel, int delay
429)
327{ 430{
328 unsigned long portbase = chip->mixer_port + reg; 431 unsigned long portbase = chip->mixer_io + reg;
329 unsigned char curr_vol_left = 0, curr_vol_right = 0; 432 unsigned char curr_vol_left = 0, curr_vol_right = 0;
330 int left_done = 0, right_done = 0; 433 int left_change = 0, right_change = 0;
331 434
332 snd_azf3328_dbgcallenter(); 435 snd_azf3328_dbgcallenter();
333 if (chan_sel & SET_CHAN_LEFT) 436
437 if (chan_sel & SET_CHAN_LEFT) {
334 curr_vol_left = inb(portbase + 1); 438 curr_vol_left = inb(portbase + 1);
335 else 439
336 left_done = 1; 440 /* take care of muting flag contained in left channel */
337 if (chan_sel & SET_CHAN_RIGHT) 441 if (curr_vol_left & AZF_MUTE_BIT)
442 dst_vol_left |= AZF_MUTE_BIT;
443 else
444 dst_vol_left &= ~AZF_MUTE_BIT;
445
446 left_change = (curr_vol_left > dst_vol_left) ? -1 : 1;
447 }
448
449 if (chan_sel & SET_CHAN_RIGHT) {
338 curr_vol_right = inb(portbase + 0); 450 curr_vol_right = inb(portbase + 0);
339 else 451
340 right_done = 1; 452 right_change = (curr_vol_right > dst_vol_right) ? -1 : 1;
341 453 }
342 /* take care of muting flag (0x80) contained in left channel */
343 if (curr_vol_left & 0x80)
344 dst_vol_left |= 0x80;
345 else
346 dst_vol_left &= ~0x80;
347 454
348 do { 455 do {
349 if (!left_done) { 456 if (left_change) {
350 if (curr_vol_left > dst_vol_left) 457 if (curr_vol_left != dst_vol_left) {
351 curr_vol_left--; 458 curr_vol_left += left_change;
352 else 459 outb(curr_vol_left, portbase + 1);
353 if (curr_vol_left < dst_vol_left) 460 } else
354 curr_vol_left++; 461 left_change = 0;
355 else
356 left_done = 1;
357 outb(curr_vol_left, portbase + 1);
358 } 462 }
359 if (!right_done) { 463 if (right_change) {
360 if (curr_vol_right > dst_vol_right) 464 if (curr_vol_right != dst_vol_right) {
361 curr_vol_right--; 465 curr_vol_right += right_change;
362 else 466
363 if (curr_vol_right < dst_vol_right)
364 curr_vol_right++;
365 else
366 right_done = 1;
367 /* during volume change, the right channel is crackling 467 /* during volume change, the right channel is crackling
368 * somewhat more than the left channel, unfortunately. 468 * somewhat more than the left channel, unfortunately.
369 * This seems to be a hardware issue. */ 469 * This seems to be a hardware issue. */
370 outb(curr_vol_right, portbase + 0); 470 outb(curr_vol_right, portbase + 0);
471 } else
472 right_change = 0;
371 } 473 }
372 if (delay) 474 if (delay)
373 mdelay(delay); 475 mdelay(delay);
374 } while ((!left_done) || (!right_done)); 476 } while ((left_change) || (right_change));
375 snd_azf3328_dbgcallleave(); 477 snd_azf3328_dbgcallleave();
376} 478}
377 479
@@ -379,7 +481,7 @@ snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, int reg
379 * general mixer element 481 * general mixer element
380 */ 482 */
381struct azf3328_mixer_reg { 483struct azf3328_mixer_reg {
382 unsigned int reg; 484 unsigned reg;
383 unsigned int lchan_shift, rchan_shift; 485 unsigned int lchan_shift, rchan_shift;
384 unsigned int mask; 486 unsigned int mask;
385 unsigned int invert: 1; 487 unsigned int invert: 1;
@@ -544,13 +646,14 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
544 "Mix", "Mic" 646 "Mix", "Mic"
545 }; 647 };
546 static const char * const texts3[] = { 648 static const char * const texts3[] = {
547 "Mic", "CD", "Video", "Aux", 649 "Mic", "CD", "Video", "Aux",
548 "Line", "Mix", "Mix Mono", "Phone" 650 "Line", "Mix", "Mix Mono", "Phone"
549 }; 651 };
550 static const char * const texts4[] = { 652 static const char * const texts4[] = {
551 "pre 3D", "post 3D" 653 "pre 3D", "post 3D"
552 }; 654 };
553 struct azf3328_mixer_reg reg; 655 struct azf3328_mixer_reg reg;
656 const char * const *p = NULL;
554 657
555 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); 658 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
556 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 659 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -561,18 +664,20 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
561 if (reg.reg == IDX_MIXER_ADVCTL2) { 664 if (reg.reg == IDX_MIXER_ADVCTL2) {
562 switch(reg.lchan_shift) { 665 switch(reg.lchan_shift) {
563 case 8: /* modem out sel */ 666 case 8: /* modem out sel */
564 strcpy(uinfo->value.enumerated.name, texts1[uinfo->value.enumerated.item]); 667 p = texts1;
565 break; 668 break;
566 case 9: /* mono sel source */ 669 case 9: /* mono sel source */
567 strcpy(uinfo->value.enumerated.name, texts2[uinfo->value.enumerated.item]); 670 p = texts2;
568 break; 671 break;
569 case 15: /* PCM Out Path */ 672 case 15: /* PCM Out Path */
570 strcpy(uinfo->value.enumerated.name, texts4[uinfo->value.enumerated.item]); 673 p = texts4;
571 break; 674 break;
572 } 675 }
573 } else 676 } else
574 strcpy(uinfo->value.enumerated.name, texts3[uinfo->value.enumerated.item] 677 if (reg.reg == IDX_MIXER_REC_SELECT)
575); 678 p = texts3;
679
680 strcpy(uinfo->value.enumerated.name, p[uinfo->value.enumerated.item]);
576 return 0; 681 return 0;
577} 682}
578 683
@@ -583,7 +688,7 @@ snd_azf3328_get_mixer_enum(struct snd_kcontrol *kcontrol,
583 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol); 688 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
584 struct azf3328_mixer_reg reg; 689 struct azf3328_mixer_reg reg;
585 unsigned short val; 690 unsigned short val;
586 691
587 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); 692 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
588 val = snd_azf3328_mixer_inw(chip, reg.reg); 693 val = snd_azf3328_mixer_inw(chip, reg.reg);
589 if (reg.reg == IDX_MIXER_REC_SELECT) { 694 if (reg.reg == IDX_MIXER_REC_SELECT) {
@@ -605,7 +710,7 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
605 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol); 710 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
606 struct azf3328_mixer_reg reg; 711 struct azf3328_mixer_reg reg;
607 unsigned int oreg, nreg, val; 712 unsigned int oreg, nreg, val;
608 713
609 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); 714 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
610 oreg = snd_azf3328_mixer_inw(chip, reg.reg); 715 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
611 val = oreg; 716 val = oreg;
@@ -631,9 +736,11 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
631static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = { 736static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
632 AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1), 737 AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
633 AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1), 738 AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
634 AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1), 739 AZF3328_MIXER_SWITCH("PCM Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
635 AZF3328_MIXER_VOL_STEREO("Wave Playback Volume", IDX_MIXER_WAVEOUT, 0x1f, 1), 740 AZF3328_MIXER_VOL_STEREO("PCM Playback Volume",
636 AZF3328_MIXER_SWITCH("Wave 3D Bypass Playback Switch", IDX_MIXER_ADVCTL2, 7, 1), 741 IDX_MIXER_WAVEOUT, 0x1f, 1),
742 AZF3328_MIXER_SWITCH("PCM 3D Bypass Playback Switch",
743 IDX_MIXER_ADVCTL2, 7, 1),
637 AZF3328_MIXER_SWITCH("FM Playback Switch", IDX_MIXER_FMSYNTH, 15, 1), 744 AZF3328_MIXER_SWITCH("FM Playback Switch", IDX_MIXER_FMSYNTH, 15, 1),
638 AZF3328_MIXER_VOL_STEREO("FM Playback Volume", IDX_MIXER_FMSYNTH, 0x1f, 1), 745 AZF3328_MIXER_VOL_STEREO("FM Playback Volume", IDX_MIXER_FMSYNTH, 0x1f, 1),
639 AZF3328_MIXER_SWITCH("CD Playback Switch", IDX_MIXER_CDAUDIO, 15, 1), 746 AZF3328_MIXER_SWITCH("CD Playback Switch", IDX_MIXER_CDAUDIO, 15, 1),
@@ -717,15 +824,16 @@ snd_azf3328_mixer_new(struct snd_azf3328 *chip)
717 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000); 824 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
718 825
719 /* mute and zero volume channels */ 826 /* mute and zero volume channels */
720 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); idx++) { 827 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); ++idx) {
721 snd_azf3328_mixer_outw(chip, 828 snd_azf3328_mixer_outw(chip,
722 snd_azf3328_init_values[idx][0], 829 snd_azf3328_init_values[idx][0],
723 snd_azf3328_init_values[idx][1]); 830 snd_azf3328_init_values[idx][1]);
724 } 831 }
725 832
726 /* add mixer controls */ 833 /* add mixer controls */
727 sw = snd_azf3328_mixer_controls; 834 sw = snd_azf3328_mixer_controls;
728 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls); idx++, sw++) { 835 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls);
836 ++idx, ++sw) {
729 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip))) < 0) 837 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip))) < 0)
730 return err; 838 return err;
731 } 839 }
@@ -757,9 +865,9 @@ snd_azf3328_hw_free(struct snd_pcm_substream *substream)
757} 865}
758 866
759static void 867static void
760snd_azf3328_setfmt(struct snd_azf3328 *chip, 868snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
761 unsigned int reg, 869 unsigned reg,
762 unsigned int bitrate, 870 enum azf_freq_t bitrate,
763 unsigned int format_width, 871 unsigned int format_width,
764 unsigned int channels 872 unsigned int channels
765) 873)
@@ -769,24 +877,25 @@ snd_azf3328_setfmt(struct snd_azf3328 *chip,
769 877
770 snd_azf3328_dbgcallenter(); 878 snd_azf3328_dbgcallenter();
771 switch (bitrate) { 879 switch (bitrate) {
772 case 4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break; 880 case AZF_FREQ_4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
773 case 4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break; 881 case AZF_FREQ_4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
774 case 5512: val |= SOUNDFORMAT_FREQ_5510; break; /* the AZF3328 names it "5510" for some strange reason */ 882 case AZF_FREQ_5512:
775 case 6620: val |= SOUNDFORMAT_FREQ_6620; break; 883 /* the AZF3328 names it "5510" for some strange reason */
776 case 8000: val |= SOUNDFORMAT_FREQ_8000; break; 884 val |= SOUNDFORMAT_FREQ_5510; break;
777 case 9600: val |= SOUNDFORMAT_FREQ_9600; break; 885 case AZF_FREQ_6620: val |= SOUNDFORMAT_FREQ_6620; break;
778 case 11025: val |= SOUNDFORMAT_FREQ_11025; break; 886 case AZF_FREQ_8000: val |= SOUNDFORMAT_FREQ_8000; break;
779 case 13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break; 887 case AZF_FREQ_9600: val |= SOUNDFORMAT_FREQ_9600; break;
780 case 16000: val |= SOUNDFORMAT_FREQ_16000; break; 888 case AZF_FREQ_11025: val |= SOUNDFORMAT_FREQ_11025; break;
781 case 22050: val |= SOUNDFORMAT_FREQ_22050; break; 889 case AZF_FREQ_13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
782 case 32000: val |= SOUNDFORMAT_FREQ_32000; break; 890 case AZF_FREQ_16000: val |= SOUNDFORMAT_FREQ_16000; break;
783 case 44100: val |= SOUNDFORMAT_FREQ_44100; break; 891 case AZF_FREQ_22050: val |= SOUNDFORMAT_FREQ_22050; break;
784 case 48000: val |= SOUNDFORMAT_FREQ_48000; break; 892 case AZF_FREQ_32000: val |= SOUNDFORMAT_FREQ_32000; break;
785 case 66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
786 default: 893 default:
787 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate); 894 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
788 val |= SOUNDFORMAT_FREQ_44100; 895 /* fall-through */
789 break; 896 case AZF_FREQ_44100: val |= SOUNDFORMAT_FREQ_44100; break;
897 case AZF_FREQ_48000: val |= SOUNDFORMAT_FREQ_48000; break;
898 case AZF_FREQ_66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
790 } 899 }
791 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */ 900 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
792 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */ 901 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
@@ -805,10 +914,10 @@ snd_azf3328_setfmt(struct snd_azf3328 *chip,
805 val |= SOUNDFORMAT_FLAG_16BIT; 914 val |= SOUNDFORMAT_FLAG_16BIT;
806 915
807 spin_lock_irqsave(&chip->reg_lock, flags); 916 spin_lock_irqsave(&chip->reg_lock, flags);
808 917
809 /* set bitrate/format */ 918 /* set bitrate/format */
810 snd_azf3328_codec_outw(chip, reg, val); 919 snd_azf3328_codec_outw(chip, reg, val);
811 920
812 /* changing the bitrate/format settings switches off the 921 /* changing the bitrate/format settings switches off the
813 * audio output with an annoying click in case of 8/16bit format change 922 * audio output with an annoying click in case of 8/16bit format change
814 * (maybe shutting down DAC/ADC?), thus immediately 923 * (maybe shutting down DAC/ADC?), thus immediately
@@ -830,31 +939,95 @@ snd_azf3328_setfmt(struct snd_azf3328 *chip,
830 snd_azf3328_dbgcallleave(); 939 snd_azf3328_dbgcallleave();
831} 940}
832 941
942static inline void
943snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip,
944 unsigned reg
945)
946{
947 /* choose lowest frequency for low power consumption.
948 * While this will cause louder noise due to rather coarse frequency,
949 * it should never matter since output should always
950 * get disabled properly when idle anyway. */
951 snd_azf3328_codec_setfmt(chip, reg, AZF_FREQ_4000, 8, 1);
952}
953
954static void
955snd_azf3328_codec_reg_6AH_update(struct snd_azf3328 *chip,
956 unsigned bitmask,
957 int enable
958)
959{
960 if (enable)
961 chip->shadow_reg_codec_6AH &= ~bitmask;
962 else
963 chip->shadow_reg_codec_6AH |= bitmask;
964 snd_azf3328_dbgplay("6AH_update mask 0x%04x enable %d: val 0x%04x\n",
965 bitmask, enable, chip->shadow_reg_codec_6AH);
966 snd_azf3328_codec_outw(chip, IDX_IO_6AH, chip->shadow_reg_codec_6AH);
967}
968
969static inline void
970snd_azf3328_codec_enable(struct snd_azf3328 *chip, int enable)
971{
972 snd_azf3328_dbgplay("codec_enable %d\n", enable);
973 /* no idea what exactly is being done here, but I strongly assume it's
974 * PM related */
975 snd_azf3328_codec_reg_6AH_update(
976 chip, IO_6A_PAUSE_PLAYBACK_BIT8, enable
977 );
978}
979
980static void
981snd_azf3328_codec_activity(struct snd_azf3328 *chip,
982 enum snd_azf3328_stream_index stream_type,
983 int enable
984)
985{
986 int need_change = (chip->audio_stream[stream_type].running != enable);
987
988 snd_azf3328_dbgplay(
989 "codec_activity: type %d, enable %d, need_change %d\n",
990 stream_type, enable, need_change
991 );
992 if (need_change) {
993 enum snd_azf3328_stream_index other =
994 (stream_type == AZF_PLAYBACK) ?
995 AZF_CAPTURE : AZF_PLAYBACK;
996 /* small check to prevent shutting down the other party
997 * in case it's active */
998 if ((enable) || !(chip->audio_stream[other].running))
999 snd_azf3328_codec_enable(chip, enable);
1000
1001 /* ...and adjust clock, too
1002 * (reduce noise and power consumption) */
1003 if (!enable)
1004 snd_azf3328_codec_setfmt_lowpower(
1005 chip,
1006 chip->audio_stream[stream_type].portbase
1007 + IDX_IO_PLAY_SOUNDFORMAT
1008 );
1009 }
1010 chip->audio_stream[stream_type].running = enable;
1011}
1012
833static void 1013static void
834snd_azf3328_setdmaa(struct snd_azf3328 *chip, 1014snd_azf3328_setdmaa(struct snd_azf3328 *chip,
835 long unsigned int addr, 1015 long unsigned int addr,
836 unsigned int count, 1016 unsigned int count,
837 unsigned int size, 1017 unsigned int size,
838 int do_recording) 1018 enum snd_azf3328_stream_index stream_type
1019)
839{ 1020{
840 unsigned long flags, portbase;
841 unsigned int is_running;
842
843 snd_azf3328_dbgcallenter(); 1021 snd_azf3328_dbgcallenter();
844 if (do_recording) { 1022 if (!chip->audio_stream[stream_type].running) {
845 /* access capture registers, i.e. skip playback reg section */ 1023 /* AZF3328 uses a two buffer pointer DMA playback approach */
846 portbase = chip->codec_port + 0x20;
847 is_running = chip->is_recording;
848 } else {
849 /* access the playback register section */
850 portbase = chip->codec_port + 0x00;
851 is_running = chip->is_playing;
852 }
853 1024
854 /* AZF3328 uses a two buffer pointer DMA playback approach */ 1025 unsigned long flags, portbase, addr_area2;
855 if (!is_running) { 1026
856 unsigned long addr_area2; 1027 /* width 32bit (prevent overflow): */
857 unsigned long count_areas, count_tmp; /* width 32bit -- overflow!! */ 1028 unsigned long count_areas, count_tmp;
1029
1030 portbase = chip->audio_stream[stream_type].portbase;
858 count_areas = size/2; 1031 count_areas = size/2;
859 addr_area2 = addr+count_areas; 1032 addr_area2 = addr+count_areas;
860 count_areas--; /* max. index */ 1033 count_areas--; /* max. index */
@@ -884,11 +1057,11 @@ snd_azf3328_playback_prepare(struct snd_pcm_substream *substream)
884 1057
885 snd_azf3328_dbgcallenter(); 1058 snd_azf3328_dbgcallenter();
886#if 0 1059#if 0
887 snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, 1060 snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
888 runtime->rate, 1061 runtime->rate,
889 snd_pcm_format_width(runtime->format), 1062 snd_pcm_format_width(runtime->format),
890 runtime->channels); 1063 runtime->channels);
891 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 0); 1064 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_PLAYBACK);
892#endif 1065#endif
893 snd_azf3328_dbgcallleave(); 1066 snd_azf3328_dbgcallleave();
894 return 0; 1067 return 0;
@@ -906,11 +1079,11 @@ snd_azf3328_capture_prepare(struct snd_pcm_substream *substream)
906 1079
907 snd_azf3328_dbgcallenter(); 1080 snd_azf3328_dbgcallenter();
908#if 0 1081#if 0
909 snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, 1082 snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
910 runtime->rate, 1083 runtime->rate,
911 snd_pcm_format_width(runtime->format), 1084 snd_pcm_format_width(runtime->format),
912 runtime->channels); 1085 runtime->channels);
913 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 1); 1086 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_CAPTURE);
914#endif 1087#endif
915 snd_azf3328_dbgcallleave(); 1088 snd_azf3328_dbgcallleave();
916 return 0; 1089 return 0;
@@ -923,6 +1096,7 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
923 struct snd_pcm_runtime *runtime = substream->runtime; 1096 struct snd_pcm_runtime *runtime = substream->runtime;
924 int result = 0; 1097 int result = 0;
925 unsigned int status1; 1098 unsigned int status1;
1099 int previously_muted;
926 1100
927 snd_azf3328_dbgcalls("snd_azf3328_playback_trigger cmd %d\n", cmd); 1101 snd_azf3328_dbgcalls("snd_azf3328_playback_trigger cmd %d\n", cmd);
928 1102
@@ -930,20 +1104,23 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
930 case SNDRV_PCM_TRIGGER_START: 1104 case SNDRV_PCM_TRIGGER_START:
931 snd_azf3328_dbgplay("START PLAYBACK\n"); 1105 snd_azf3328_dbgplay("START PLAYBACK\n");
932 1106
933 /* mute WaveOut */ 1107 /* mute WaveOut (avoid clicking during setup) */
934 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1); 1108 previously_muted =
1109 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
935 1110
936 snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, 1111 snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
937 runtime->rate, 1112 runtime->rate,
938 snd_pcm_format_width(runtime->format), 1113 snd_pcm_format_width(runtime->format),
939 runtime->channels); 1114 runtime->channels);
940 1115
941 spin_lock(&chip->reg_lock); 1116 spin_lock(&chip->reg_lock);
942 /* stop playback */ 1117 /* first, remember current value: */
943 status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS); 1118 status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
1119
1120 /* stop playback */
944 status1 &= ~DMA_RESUME; 1121 status1 &= ~DMA_RESUME;
945 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1); 1122 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
946 1123
947 /* FIXME: clear interrupts or what??? */ 1124 /* FIXME: clear interrupts or what??? */
948 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_IRQTYPE, 0xffff); 1125 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_IRQTYPE, 0xffff);
949 spin_unlock(&chip->reg_lock); 1126 spin_unlock(&chip->reg_lock);
@@ -951,7 +1128,7 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
951 snd_azf3328_setdmaa(chip, runtime->dma_addr, 1128 snd_azf3328_setdmaa(chip, runtime->dma_addr,
952 snd_pcm_lib_period_bytes(substream), 1129 snd_pcm_lib_period_bytes(substream),
953 snd_pcm_lib_buffer_bytes(substream), 1130 snd_pcm_lib_buffer_bytes(substream),
954 0); 1131 AZF_PLAYBACK);
955 1132
956 spin_lock(&chip->reg_lock); 1133 spin_lock(&chip->reg_lock);
957#ifdef WIN9X 1134#ifdef WIN9X
@@ -978,30 +1155,35 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
978 DMA_SOMETHING_ELSE); 1155 DMA_SOMETHING_ELSE);
979#endif 1156#endif
980 spin_unlock(&chip->reg_lock); 1157 spin_unlock(&chip->reg_lock);
1158 snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 1);
981 1159
982 /* now unmute WaveOut */ 1160 /* now unmute WaveOut */
983 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0); 1161 if (!previously_muted)
1162 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
984 1163
985 chip->is_playing = 1;
986 snd_azf3328_dbgplay("STARTED PLAYBACK\n"); 1164 snd_azf3328_dbgplay("STARTED PLAYBACK\n");
987 break; 1165 break;
988 case SNDRV_PCM_TRIGGER_RESUME: 1166 case SNDRV_PCM_TRIGGER_RESUME:
989 snd_azf3328_dbgplay("RESUME PLAYBACK\n"); 1167 snd_azf3328_dbgplay("RESUME PLAYBACK\n");
990 /* resume playback if we were active */ 1168 /* resume playback if we were active */
991 if (chip->is_playing) 1169 spin_lock(&chip->reg_lock);
1170 if (chip->audio_stream[AZF_PLAYBACK].running)
992 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, 1171 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
993 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) | DMA_RESUME); 1172 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) | DMA_RESUME);
1173 spin_unlock(&chip->reg_lock);
994 break; 1174 break;
995 case SNDRV_PCM_TRIGGER_STOP: 1175 case SNDRV_PCM_TRIGGER_STOP:
996 snd_azf3328_dbgplay("STOP PLAYBACK\n"); 1176 snd_azf3328_dbgplay("STOP PLAYBACK\n");
997 1177
998 /* mute WaveOut */ 1178 /* mute WaveOut (avoid clicking during setup) */
999 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1); 1179 previously_muted =
1180 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
1000 1181
1001 spin_lock(&chip->reg_lock); 1182 spin_lock(&chip->reg_lock);
1002 /* stop playback */ 1183 /* first, remember current value: */
1003 status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS); 1184 status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
1004 1185
1186 /* stop playback */
1005 status1 &= ~DMA_RESUME; 1187 status1 &= ~DMA_RESUME;
1006 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1); 1188 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1007 1189
@@ -1013,10 +1195,12 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
1013 status1 &= ~DMA_PLAY_SOMETHING1; 1195 status1 &= ~DMA_PLAY_SOMETHING1;
1014 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1); 1196 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
1015 spin_unlock(&chip->reg_lock); 1197 spin_unlock(&chip->reg_lock);
1016 1198 snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0);
1199
1017 /* now unmute WaveOut */ 1200 /* now unmute WaveOut */
1018 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0); 1201 if (!previously_muted)
1019 chip->is_playing = 0; 1202 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
1203
1020 snd_azf3328_dbgplay("STOPPED PLAYBACK\n"); 1204 snd_azf3328_dbgplay("STOPPED PLAYBACK\n");
1021 break; 1205 break;
1022 case SNDRV_PCM_TRIGGER_SUSPEND: 1206 case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -1035,7 +1219,7 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
1035 printk(KERN_ERR "FIXME: unknown trigger mode!\n"); 1219 printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1036 return -EINVAL; 1220 return -EINVAL;
1037 } 1221 }
1038 1222
1039 snd_azf3328_dbgcallleave(); 1223 snd_azf3328_dbgcallleave();
1040 return result; 1224 return result;
1041} 1225}
@@ -1057,17 +1241,19 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1057 1241
1058 snd_azf3328_dbgplay("START CAPTURE\n"); 1242 snd_azf3328_dbgplay("START CAPTURE\n");
1059 1243
1060 snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, 1244 snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
1061 runtime->rate, 1245 runtime->rate,
1062 snd_pcm_format_width(runtime->format), 1246 snd_pcm_format_width(runtime->format),
1063 runtime->channels); 1247 runtime->channels);
1064 1248
1065 spin_lock(&chip->reg_lock); 1249 spin_lock(&chip->reg_lock);
1066 /* stop recording */ 1250 /* first, remember current value: */
1067 status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS); 1251 status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
1252
1253 /* stop recording */
1068 status1 &= ~DMA_RESUME; 1254 status1 &= ~DMA_RESUME;
1069 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1); 1255 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1070 1256
1071 /* FIXME: clear interrupts or what??? */ 1257 /* FIXME: clear interrupts or what??? */
1072 snd_azf3328_codec_outw(chip, IDX_IO_REC_IRQTYPE, 0xffff); 1258 snd_azf3328_codec_outw(chip, IDX_IO_REC_IRQTYPE, 0xffff);
1073 spin_unlock(&chip->reg_lock); 1259 spin_unlock(&chip->reg_lock);
@@ -1075,7 +1261,7 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1075 snd_azf3328_setdmaa(chip, runtime->dma_addr, 1261 snd_azf3328_setdmaa(chip, runtime->dma_addr,
1076 snd_pcm_lib_period_bytes(substream), 1262 snd_pcm_lib_period_bytes(substream),
1077 snd_pcm_lib_buffer_bytes(substream), 1263 snd_pcm_lib_buffer_bytes(substream),
1078 1); 1264 AZF_CAPTURE);
1079 1265
1080 spin_lock(&chip->reg_lock); 1266 spin_lock(&chip->reg_lock);
1081#ifdef WIN9X 1267#ifdef WIN9X
@@ -1102,24 +1288,27 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1102 DMA_SOMETHING_ELSE); 1288 DMA_SOMETHING_ELSE);
1103#endif 1289#endif
1104 spin_unlock(&chip->reg_lock); 1290 spin_unlock(&chip->reg_lock);
1291 snd_azf3328_codec_activity(chip, AZF_CAPTURE, 1);
1105 1292
1106 chip->is_recording = 1;
1107 snd_azf3328_dbgplay("STARTED CAPTURE\n"); 1293 snd_azf3328_dbgplay("STARTED CAPTURE\n");
1108 break; 1294 break;
1109 case SNDRV_PCM_TRIGGER_RESUME: 1295 case SNDRV_PCM_TRIGGER_RESUME:
1110 snd_azf3328_dbgplay("RESUME CAPTURE\n"); 1296 snd_azf3328_dbgplay("RESUME CAPTURE\n");
1111 /* resume recording if we were active */ 1297 /* resume recording if we were active */
1112 if (chip->is_recording) 1298 spin_lock(&chip->reg_lock);
1299 if (chip->audio_stream[AZF_CAPTURE].running)
1113 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, 1300 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1114 snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) | DMA_RESUME); 1301 snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) | DMA_RESUME);
1302 spin_unlock(&chip->reg_lock);
1115 break; 1303 break;
1116 case SNDRV_PCM_TRIGGER_STOP: 1304 case SNDRV_PCM_TRIGGER_STOP:
1117 snd_azf3328_dbgplay("STOP CAPTURE\n"); 1305 snd_azf3328_dbgplay("STOP CAPTURE\n");
1118 1306
1119 spin_lock(&chip->reg_lock); 1307 spin_lock(&chip->reg_lock);
1120 /* stop recording */ 1308 /* first, remember current value: */
1121 status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS); 1309 status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
1122 1310
1311 /* stop recording */
1123 status1 &= ~DMA_RESUME; 1312 status1 &= ~DMA_RESUME;
1124 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1); 1313 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1125 1314
@@ -1129,8 +1318,8 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1129 status1 &= ~DMA_PLAY_SOMETHING1; 1318 status1 &= ~DMA_PLAY_SOMETHING1;
1130 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1); 1319 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1131 spin_unlock(&chip->reg_lock); 1320 spin_unlock(&chip->reg_lock);
1132 1321 snd_azf3328_codec_activity(chip, AZF_CAPTURE, 0);
1133 chip->is_recording = 0; 1322
1134 snd_azf3328_dbgplay("STOPPED CAPTURE\n"); 1323 snd_azf3328_dbgplay("STOPPED CAPTURE\n");
1135 break; 1324 break;
1136 case SNDRV_PCM_TRIGGER_SUSPEND: 1325 case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -1149,7 +1338,7 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1149 printk(KERN_ERR "FIXME: unknown trigger mode!\n"); 1338 printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1150 return -EINVAL; 1339 return -EINVAL;
1151 } 1340 }
1152 1341
1153 snd_azf3328_dbgcallleave(); 1342 snd_azf3328_dbgcallleave();
1154 return result; 1343 return result;
1155} 1344}
@@ -1162,11 +1351,11 @@ snd_azf3328_playback_pointer(struct snd_pcm_substream *substream)
1162 snd_pcm_uframes_t frmres; 1351 snd_pcm_uframes_t frmres;
1163 1352
1164#ifdef QUERY_HARDWARE 1353#ifdef QUERY_HARDWARE
1165 bufptr = inl(chip->codec_port+IDX_IO_PLAY_DMA_START_1); 1354 bufptr = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_START_1);
1166#else 1355#else
1167 bufptr = substream->runtime->dma_addr; 1356 bufptr = substream->runtime->dma_addr;
1168#endif 1357#endif
1169 result = inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS); 1358 result = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_CURRPOS);
1170 1359
1171 /* calculate offset */ 1360 /* calculate offset */
1172 result -= bufptr; 1361 result -= bufptr;
@@ -1183,11 +1372,11 @@ snd_azf3328_capture_pointer(struct snd_pcm_substream *substream)
1183 snd_pcm_uframes_t frmres; 1372 snd_pcm_uframes_t frmres;
1184 1373
1185#ifdef QUERY_HARDWARE 1374#ifdef QUERY_HARDWARE
1186 bufptr = inl(chip->codec_port+IDX_IO_REC_DMA_START_1); 1375 bufptr = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_START_1);
1187#else 1376#else
1188 bufptr = substream->runtime->dma_addr; 1377 bufptr = substream->runtime->dma_addr;
1189#endif 1378#endif
1190 result = inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS); 1379 result = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_CURRPOS);
1191 1380
1192 /* calculate offset */ 1381 /* calculate offset */
1193 result -= bufptr; 1382 result -= bufptr;
@@ -1196,27 +1385,241 @@ snd_azf3328_capture_pointer(struct snd_pcm_substream *substream)
1196 return frmres; 1385 return frmres;
1197} 1386}
1198 1387
1388/******************************************************************/
1389
1390#ifdef SUPPORT_GAMEPORT
1391static inline void
1392snd_azf3328_gameport_irq_enable(struct snd_azf3328 *chip, int enable)
1393{
1394 snd_azf3328_io_reg_setb(
1395 chip->game_io+IDX_GAME_HWCONFIG,
1396 GAME_HWCFG_IRQ_ENABLE,
1397 enable
1398 );
1399}
1400
1401static inline void
1402snd_azf3328_gameport_legacy_address_enable(struct snd_azf3328 *chip, int enable)
1403{
1404 snd_azf3328_io_reg_setb(
1405 chip->game_io+IDX_GAME_HWCONFIG,
1406 GAME_HWCFG_LEGACY_ADDRESS_ENABLE,
1407 enable
1408 );
1409}
1410
1411static inline void
1412snd_azf3328_gameport_axis_circuit_enable(struct snd_azf3328 *chip, int enable)
1413{
1414 snd_azf3328_codec_reg_6AH_update(
1415 chip, IO_6A_SOMETHING2_GAMEPORT, enable
1416 );
1417}
1418
1419static inline void
1420snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1421{
1422 /*
1423 * skeleton handler only
1424 * (we do not want axis reading in interrupt handler - too much load!)
1425 */
1426 snd_azf3328_dbggame("gameport irq\n");
1427
1428 /* this should ACK the gameport IRQ properly, hopefully. */
1429 snd_azf3328_game_inw(chip, IDX_GAME_AXIS_VALUE);
1430}
1431
1432static int
1433snd_azf3328_gameport_open(struct gameport *gameport, int mode)
1434{
1435 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1436 int res;
1437
1438 snd_azf3328_dbggame("gameport_open, mode %d\n", mode);
1439 switch (mode) {
1440 case GAMEPORT_MODE_COOKED:
1441 case GAMEPORT_MODE_RAW:
1442 res = 0;
1443 break;
1444 default:
1445 res = -1;
1446 break;
1447 }
1448
1449 snd_azf3328_gameport_axis_circuit_enable(chip, (res == 0));
1450
1451 return res;
1452}
1453
1454static void
1455snd_azf3328_gameport_close(struct gameport *gameport)
1456{
1457 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1458
1459 snd_azf3328_dbggame("gameport_close\n");
1460 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1461}
1462
1463static int
1464snd_azf3328_gameport_cooked_read(struct gameport *gameport,
1465 int *axes,
1466 int *buttons
1467)
1468{
1469 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1470 int i;
1471 u8 val;
1472 unsigned long flags;
1473
1474 snd_assert(chip, return 0);
1475
1476 spin_lock_irqsave(&chip->reg_lock, flags);
1477 val = snd_azf3328_game_inb(chip, IDX_GAME_LEGACY_COMPATIBLE);
1478 *buttons = (~(val) >> 4) & 0xf;
1479
1480 /* ok, this one is a bit dirty: cooked_read is being polled by a timer,
1481 * thus we're atomic and cannot actively wait in here
1482 * (which would be useful for us since it probably would be better
1483 * to trigger a measurement in here, then wait a short amount of
1484 * time until it's finished, then read values of _this_ measurement).
1485 *
1486 * Thus we simply resort to reading values if they're available already
1487 * and trigger the next measurement.
1488 */
1489
1490 val = snd_azf3328_game_inb(chip, IDX_GAME_AXES_CONFIG);
1491 if (val & GAME_AXES_SAMPLING_READY) {
1492 for (i = 0; i < 4; ++i) {
1493 /* configure the axis to read */
1494 val = (i << 4) | 0x0f;
1495 snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1496
1497 chip->axes[i] = snd_azf3328_game_inw(
1498 chip, IDX_GAME_AXIS_VALUE
1499 );
1500 }
1501 }
1502
1503 /* trigger next axes sampling, to be evaluated the next time we
1504 * enter this function */
1505
1506 /* for some very, very strange reason we cannot enable
1507 * Measurement Ready monitoring for all axes here,
1508 * at least not when only one joystick connected */
1509 val = 0x03; /* we're able to monitor axes 1 and 2 only */
1510 snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1511
1512 snd_azf3328_game_outw(chip, IDX_GAME_AXIS_VALUE, 0xffff);
1513 spin_unlock_irqrestore(&chip->reg_lock, flags);
1514
1515 for (i = 0; i < 4; i++) {
1516 axes[i] = chip->axes[i];
1517 if (axes[i] == 0xffff)
1518 axes[i] = -1;
1519 }
1520
1521 snd_azf3328_dbggame("cooked_read: axes %d %d %d %d buttons %d\n",
1522 axes[0], axes[1], axes[2], axes[3], *buttons
1523 );
1524
1525 return 0;
1526}
1527
1528static int __devinit
1529snd_azf3328_gameport(struct snd_azf3328 *chip, int dev)
1530{
1531 struct gameport *gp;
1532
1533 chip->gameport = gp = gameport_allocate_port();
1534 if (!gp) {
1535 printk(KERN_ERR "azt3328: cannot alloc memory for gameport\n");
1536 return -ENOMEM;
1537 }
1538
1539 gameport_set_name(gp, "AZF3328 Gameport");
1540 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1541 gameport_set_dev_parent(gp, &chip->pci->dev);
1542 gp->io = chip->game_io;
1543 gameport_set_port_data(gp, chip);
1544
1545 gp->open = snd_azf3328_gameport_open;
1546 gp->close = snd_azf3328_gameport_close;
1547 gp->fuzz = 16; /* seems ok */
1548 gp->cooked_read = snd_azf3328_gameport_cooked_read;
1549
1550 /* DISABLE legacy address: we don't need it! */
1551 snd_azf3328_gameport_legacy_address_enable(chip, 0);
1552
1553 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1554
1555 gameport_register_port(chip->gameport);
1556
1557 return 0;
1558}
1559
1560static void
1561snd_azf3328_gameport_free(struct snd_azf3328 *chip)
1562{
1563 if (chip->gameport) {
1564 gameport_unregister_port(chip->gameport);
1565 chip->gameport = NULL;
1566 }
1567 snd_azf3328_gameport_irq_enable(chip, 0);
1568}
1569#else
1570static inline int
1571snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) { return -ENOSYS; }
1572static inline void
1573snd_azf3328_gameport_free(struct snd_azf3328 *chip) { }
1574static inline void
1575snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1576{
1577 printk(KERN_WARNING "huh, game port IRQ occurred!?\n");
1578}
1579#endif /* SUPPORT_GAMEPORT */
1580
1581/******************************************************************/
1582
1583static inline void
1584snd_azf3328_irq_log_unknown_type(u8 which)
1585{
1586 snd_azf3328_dbgplay(
1587 "azt3328: unknown IRQ type (%x) occurred, please report!\n",
1588 which
1589 );
1590}
1591
1199static irqreturn_t 1592static irqreturn_t
1200snd_azf3328_interrupt(int irq, void *dev_id) 1593snd_azf3328_interrupt(int irq, void *dev_id)
1201{ 1594{
1202 struct snd_azf3328 *chip = dev_id; 1595 struct snd_azf3328 *chip = dev_id;
1203 u8 status, which; 1596 u8 status, which;
1597#if DEBUG_PLAY_REC
1204 static unsigned long irq_count; 1598 static unsigned long irq_count;
1599#endif
1205 1600
1206 status = snd_azf3328_codec_inb(chip, IDX_IO_IRQSTATUS); 1601 status = snd_azf3328_codec_inb(chip, IDX_IO_IRQSTATUS);
1207 1602
1208 /* fast path out, to ease interrupt sharing */ 1603 /* fast path out, to ease interrupt sharing */
1209 if (!(status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_MPU401|IRQ_TIMER))) 1604 if (!(status &
1605 (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_GAMEPORT|IRQ_MPU401|IRQ_TIMER)
1606 ))
1210 return IRQ_NONE; /* must be interrupt for another device */ 1607 return IRQ_NONE; /* must be interrupt for another device */
1211 1608
1212 snd_azf3328_dbgplay("Interrupt %ld!\nIDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQTYPE %04x, IDX_IO_IRQSTATUS %04x\n", 1609 snd_azf3328_dbgplay(
1213 irq_count, 1610 "irq_count %ld! IDX_IO_PLAY_FLAGS %04x, "
1214 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS), 1611 "IDX_IO_PLAY_IRQTYPE %04x, IDX_IO_IRQSTATUS %04x\n",
1215 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE), 1612 irq_count++ /* debug-only */,
1216 status); 1613 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS),
1217 1614 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE),
1615 status
1616 );
1617
1218 if (status & IRQ_TIMER) { 1618 if (status & IRQ_TIMER) {
1219 /* snd_azf3328_dbgplay("timer %ld\n", inl(chip->codec_port+IDX_IO_TIMER_VALUE) & TIMER_VALUE_MASK); */ 1619 /* snd_azf3328_dbgplay("timer %ld\n",
1620 snd_azf3328_codec_inl(chip, IDX_IO_TIMER_VALUE)
1621 & TIMER_VALUE_MASK
1622 ); */
1220 if (chip->timer) 1623 if (chip->timer)
1221 snd_timer_interrupt(chip->timer, chip->timer->sticks); 1624 snd_timer_interrupt(chip->timer, chip->timer->sticks);
1222 /* ACK timer */ 1625 /* ACK timer */
@@ -1232,15 +1635,20 @@ snd_azf3328_interrupt(int irq, void *dev_id)
1232 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which); 1635 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which);
1233 spin_unlock(&chip->reg_lock); 1636 spin_unlock(&chip->reg_lock);
1234 1637
1235 if (chip->pcm && chip->playback_substream) { 1638 if (chip->pcm && chip->audio_stream[AZF_PLAYBACK].substream) {
1236 snd_pcm_period_elapsed(chip->playback_substream); 1639 snd_pcm_period_elapsed(
1640 chip->audio_stream[AZF_PLAYBACK].substream
1641 );
1237 snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n", 1642 snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n",
1238 which, 1643 which,
1239 inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS)); 1644 snd_azf3328_codec_inl(
1645 chip, IDX_IO_PLAY_DMA_CURRPOS
1646 )
1647 );
1240 } else 1648 } else
1241 snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n"); 1649 printk(KERN_WARNING "azt3328: irq handler problem!\n");
1242 if (which & IRQ_PLAY_SOMETHING) 1650 if (which & IRQ_PLAY_SOMETHING)
1243 snd_azf3328_dbgplay("azt3328: unknown play IRQ type occurred, please report!\n"); 1651 snd_azf3328_irq_log_unknown_type(which);
1244 } 1652 }
1245 if (status & IRQ_RECORDING) { 1653 if (status & IRQ_RECORDING) {
1246 spin_lock(&chip->reg_lock); 1654 spin_lock(&chip->reg_lock);
@@ -1249,16 +1657,23 @@ snd_azf3328_interrupt(int irq, void *dev_id)
1249 snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which); 1657 snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which);
1250 spin_unlock(&chip->reg_lock); 1658 spin_unlock(&chip->reg_lock);
1251 1659
1252 if (chip->pcm && chip->capture_substream) { 1660 if (chip->pcm && chip->audio_stream[AZF_CAPTURE].substream) {
1253 snd_pcm_period_elapsed(chip->capture_substream); 1661 snd_pcm_period_elapsed(
1662 chip->audio_stream[AZF_CAPTURE].substream
1663 );
1254 snd_azf3328_dbgplay("REC period done (#%x), @ %x\n", 1664 snd_azf3328_dbgplay("REC period done (#%x), @ %x\n",
1255 which, 1665 which,
1256 inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS)); 1666 snd_azf3328_codec_inl(
1667 chip, IDX_IO_REC_DMA_CURRPOS
1668 )
1669 );
1257 } else 1670 } else
1258 snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n"); 1671 printk(KERN_WARNING "azt3328: irq handler problem!\n");
1259 if (which & IRQ_REC_SOMETHING) 1672 if (which & IRQ_REC_SOMETHING)
1260 snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n"); 1673 snd_azf3328_irq_log_unknown_type(which);
1261 } 1674 }
1675 if (status & IRQ_GAMEPORT)
1676 snd_azf3328_gameport_interrupt(chip);
1262 /* MPU401 has less critical IRQ requirements 1677 /* MPU401 has less critical IRQ requirements
1263 * than timer and playback/recording, right? */ 1678 * than timer and playback/recording, right? */
1264 if (status & IRQ_MPU401) { 1679 if (status & IRQ_MPU401) {
@@ -1268,7 +1683,6 @@ snd_azf3328_interrupt(int irq, void *dev_id)
1268 * If so, then I don't know how... */ 1683 * If so, then I don't know how... */
1269 snd_azf3328_dbgplay("azt3328: MPU401 IRQ\n"); 1684 snd_azf3328_dbgplay("azt3328: MPU401 IRQ\n");
1270 } 1685 }
1271 irq_count++;
1272 return IRQ_HANDLED; 1686 return IRQ_HANDLED;
1273} 1687}
1274 1688
@@ -1287,8 +1701,8 @@ static const struct snd_pcm_hardware snd_azf3328_playback =
1287 .rates = SNDRV_PCM_RATE_5512 | 1701 .rates = SNDRV_PCM_RATE_5512 |
1288 SNDRV_PCM_RATE_8000_48000 | 1702 SNDRV_PCM_RATE_8000_48000 |
1289 SNDRV_PCM_RATE_KNOT, 1703 SNDRV_PCM_RATE_KNOT,
1290 .rate_min = 4000, 1704 .rate_min = AZF_FREQ_4000,
1291 .rate_max = 66200, 1705 .rate_max = AZF_FREQ_66200,
1292 .channels_min = 1, 1706 .channels_min = 1,
1293 .channels_max = 2, 1707 .channels_max = 2,
1294 .buffer_bytes_max = 65536, 1708 .buffer_bytes_max = 65536,
@@ -1315,8 +1729,8 @@ static const struct snd_pcm_hardware snd_azf3328_capture =
1315 .rates = SNDRV_PCM_RATE_5512 | 1729 .rates = SNDRV_PCM_RATE_5512 |
1316 SNDRV_PCM_RATE_8000_48000 | 1730 SNDRV_PCM_RATE_8000_48000 |
1317 SNDRV_PCM_RATE_KNOT, 1731 SNDRV_PCM_RATE_KNOT,
1318 .rate_min = 4000, 1732 .rate_min = AZF_FREQ_4000,
1319 .rate_max = 66200, 1733 .rate_max = AZF_FREQ_66200,
1320 .channels_min = 1, 1734 .channels_min = 1,
1321 .channels_max = 2, 1735 .channels_max = 2,
1322 .buffer_bytes_max = 65536, 1736 .buffer_bytes_max = 65536,
@@ -1329,10 +1743,24 @@ static const struct snd_pcm_hardware snd_azf3328_capture =
1329 1743
1330 1744
1331static unsigned int snd_azf3328_fixed_rates[] = { 1745static unsigned int snd_azf3328_fixed_rates[] = {
1332 4000, 4800, 5512, 6620, 8000, 9600, 11025, 13240, 16000, 22050, 32000, 1746 AZF_FREQ_4000,
1333 44100, 48000, 66200 }; 1747 AZF_FREQ_4800,
1748 AZF_FREQ_5512,
1749 AZF_FREQ_6620,
1750 AZF_FREQ_8000,
1751 AZF_FREQ_9600,
1752 AZF_FREQ_11025,
1753 AZF_FREQ_13240,
1754 AZF_FREQ_16000,
1755 AZF_FREQ_22050,
1756 AZF_FREQ_32000,
1757 AZF_FREQ_44100,
1758 AZF_FREQ_48000,
1759 AZF_FREQ_66200
1760};
1761
1334static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = { 1762static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = {
1335 .count = ARRAY_SIZE(snd_azf3328_fixed_rates), 1763 .count = ARRAY_SIZE(snd_azf3328_fixed_rates),
1336 .list = snd_azf3328_fixed_rates, 1764 .list = snd_azf3328_fixed_rates,
1337 .mask = 0, 1765 .mask = 0,
1338}; 1766};
@@ -1346,7 +1774,7 @@ snd_azf3328_playback_open(struct snd_pcm_substream *substream)
1346 struct snd_pcm_runtime *runtime = substream->runtime; 1774 struct snd_pcm_runtime *runtime = substream->runtime;
1347 1775
1348 snd_azf3328_dbgcallenter(); 1776 snd_azf3328_dbgcallenter();
1349 chip->playback_substream = substream; 1777 chip->audio_stream[AZF_PLAYBACK].substream = substream;
1350 runtime->hw = snd_azf3328_playback; 1778 runtime->hw = snd_azf3328_playback;
1351 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 1779 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1352 &snd_azf3328_hw_constraints_rates); 1780 &snd_azf3328_hw_constraints_rates);
@@ -1361,7 +1789,7 @@ snd_azf3328_capture_open(struct snd_pcm_substream *substream)
1361 struct snd_pcm_runtime *runtime = substream->runtime; 1789 struct snd_pcm_runtime *runtime = substream->runtime;
1362 1790
1363 snd_azf3328_dbgcallenter(); 1791 snd_azf3328_dbgcallenter();
1364 chip->capture_substream = substream; 1792 chip->audio_stream[AZF_CAPTURE].substream = substream;
1365 runtime->hw = snd_azf3328_capture; 1793 runtime->hw = snd_azf3328_capture;
1366 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 1794 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1367 &snd_azf3328_hw_constraints_rates); 1795 &snd_azf3328_hw_constraints_rates);
@@ -1375,7 +1803,7 @@ snd_azf3328_playback_close(struct snd_pcm_substream *substream)
1375 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1803 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1376 1804
1377 snd_azf3328_dbgcallenter(); 1805 snd_azf3328_dbgcallenter();
1378 chip->playback_substream = NULL; 1806 chip->audio_stream[AZF_PLAYBACK].substream = NULL;
1379 snd_azf3328_dbgcallleave(); 1807 snd_azf3328_dbgcallleave();
1380 return 0; 1808 return 0;
1381} 1809}
@@ -1386,7 +1814,7 @@ snd_azf3328_capture_close(struct snd_pcm_substream *substream)
1386 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1814 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1387 1815
1388 snd_azf3328_dbgcallenter(); 1816 snd_azf3328_dbgcallenter();
1389 chip->capture_substream = NULL; 1817 chip->audio_stream[AZF_CAPTURE].substream = NULL;
1390 snd_azf3328_dbgcallleave(); 1818 snd_azf3328_dbgcallleave();
1391 return 0; 1819 return 0;
1392} 1820}
@@ -1441,102 +1869,8 @@ snd_azf3328_pcm(struct snd_azf3328 *chip, int device)
1441 1869
1442/******************************************************************/ 1870/******************************************************************/
1443 1871
1444#ifdef SUPPORT_JOYSTICK 1872/*** NOTE: the physical timer resolution actually is 1024000 ticks per second
1445static int __devinit 1873 *** (probably derived from main crystal via a divider of 24),
1446snd_azf3328_config_joystick(struct snd_azf3328 *chip, int dev)
1447{
1448 struct gameport *gp;
1449 struct resource *r;
1450
1451 if (!joystick[dev])
1452 return -ENODEV;
1453
1454 if (!(r = request_region(0x200, 8, "AZF3328 gameport"))) {
1455 printk(KERN_WARNING "azt3328: cannot reserve joystick ports\n");
1456 return -EBUSY;
1457 }
1458
1459 chip->gameport = gp = gameport_allocate_port();
1460 if (!gp) {
1461 printk(KERN_ERR "azt3328: cannot allocate memory for gameport\n");
1462 release_and_free_resource(r);
1463 return -ENOMEM;
1464 }
1465
1466 gameport_set_name(gp, "AZF3328 Gameport");
1467 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1468 gameport_set_dev_parent(gp, &chip->pci->dev);
1469 gp->io = 0x200;
1470 gameport_set_port_data(gp, r);
1471
1472 snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
1473 snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) | LEGACY_JOY);
1474
1475 gameport_register_port(chip->gameport);
1476
1477 return 0;
1478}
1479
1480static void
1481snd_azf3328_free_joystick(struct snd_azf3328 *chip)
1482{
1483 if (chip->gameport) {
1484 struct resource *r = gameport_get_port_data(chip->gameport);
1485
1486 gameport_unregister_port(chip->gameport);
1487 chip->gameport = NULL;
1488 /* disable gameport */
1489 snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
1490 snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
1491 release_and_free_resource(r);
1492 }
1493}
1494#else
1495static inline int
1496snd_azf3328_config_joystick(struct snd_azf3328 *chip, int dev) { return -ENOSYS; }
1497static inline void
1498snd_azf3328_free_joystick(struct snd_azf3328 *chip) { }
1499#endif
1500
1501/******************************************************************/
1502
1503static int
1504snd_azf3328_free(struct snd_azf3328 *chip)
1505{
1506 if (chip->irq < 0)
1507 goto __end_hw;
1508
1509 /* reset (close) mixer */
1510 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1); /* first mute master volume */
1511 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
1512
1513 /* interrupt setup - mask everything (FIXME!) */
1514 /* well, at least we know how to disable the timer IRQ */
1515 snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00);
1516
1517 if (chip->irq >= 0)
1518 synchronize_irq(chip->irq);
1519__end_hw:
1520 snd_azf3328_free_joystick(chip);
1521 if (chip->irq >= 0)
1522 free_irq(chip->irq, chip);
1523 pci_release_regions(chip->pci);
1524 pci_disable_device(chip->pci);
1525
1526 kfree(chip);
1527 return 0;
1528}
1529
1530static int
1531snd_azf3328_dev_free(struct snd_device *device)
1532{
1533 struct snd_azf3328 *chip = device->device_data;
1534 return snd_azf3328_free(chip);
1535}
1536
1537/******************************************************************/
1538
1539/*** NOTE: the physical timer resolution actually is 1024000 ticks per second,
1540 *** but announcing those attributes to user-space would make programs 1874 *** but announcing those attributes to user-space would make programs
1541 *** configure the timer to a 1 tick value, resulting in an absolutely fatal 1875 *** configure the timer to a 1 tick value, resulting in an absolutely fatal
1542 *** timer IRQ storm. 1876 *** timer IRQ storm.
@@ -1564,7 +1898,7 @@ snd_azf3328_timer_start(struct snd_timer *timer)
1564 delay = 49; /* minimum time is 49 ticks */ 1898 delay = 49; /* minimum time is 49 ticks */
1565 } 1899 }
1566 snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay); 1900 snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay);
1567 delay |= TIMER_ENABLE_COUNTDOWN | TIMER_ENABLE_IRQ; 1901 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
1568 spin_lock_irqsave(&chip->reg_lock, flags); 1902 spin_lock_irqsave(&chip->reg_lock, flags);
1569 snd_azf3328_codec_outl(chip, IDX_IO_TIMER_VALUE, delay); 1903 snd_azf3328_codec_outl(chip, IDX_IO_TIMER_VALUE, delay);
1570 spin_unlock_irqrestore(&chip->reg_lock, flags); 1904 spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -1582,7 +1916,7 @@ snd_azf3328_timer_stop(struct snd_timer *timer)
1582 chip = snd_timer_chip(timer); 1916 chip = snd_timer_chip(timer);
1583 spin_lock_irqsave(&chip->reg_lock, flags); 1917 spin_lock_irqsave(&chip->reg_lock, flags);
1584 /* disable timer countdown and interrupt */ 1918 /* disable timer countdown and interrupt */
1585 /* FIXME: should we write TIMER_ACK_IRQ here? */ 1919 /* FIXME: should we write TIMER_IRQ_ACK here? */
1586 snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0); 1920 snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0);
1587 spin_unlock_irqrestore(&chip->reg_lock, flags); 1921 spin_unlock_irqrestore(&chip->reg_lock, flags);
1588 snd_azf3328_dbgcallleave(); 1922 snd_azf3328_dbgcallleave();
@@ -1626,9 +1960,10 @@ snd_azf3328_timer(struct snd_azf3328 *chip, int device)
1626 1960
1627 snd_azf3328_timer_hw.resolution *= seqtimer_scaling; 1961 snd_azf3328_timer_hw.resolution *= seqtimer_scaling;
1628 snd_azf3328_timer_hw.ticks /= seqtimer_scaling; 1962 snd_azf3328_timer_hw.ticks /= seqtimer_scaling;
1629 if ((err = snd_timer_new(chip->card, "AZF3328", &tid, &timer)) < 0) { 1963
1964 err = snd_timer_new(chip->card, "AZF3328", &tid, &timer);
1965 if (err < 0)
1630 goto out; 1966 goto out;
1631 }
1632 1967
1633 strcpy(timer->name, "AZF3328 timer"); 1968 strcpy(timer->name, "AZF3328 timer");
1634 timer->private_data = chip; 1969 timer->private_data = chip;
@@ -1636,6 +1971,8 @@ snd_azf3328_timer(struct snd_azf3328 *chip, int device)
1636 1971
1637 chip->timer = timer; 1972 chip->timer = timer;
1638 1973
1974 snd_azf3328_timer_stop(timer);
1975
1639 err = 0; 1976 err = 0;
1640 1977
1641out: 1978out:
@@ -1645,10 +1982,44 @@ out:
1645 1982
1646/******************************************************************/ 1983/******************************************************************/
1647 1984
1985static int
1986snd_azf3328_free(struct snd_azf3328 *chip)
1987{
1988 if (chip->irq < 0)
1989 goto __end_hw;
1990
1991 /* reset (close) mixer:
1992 * first mute master volume, then reset
1993 */
1994 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
1995 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
1996
1997 snd_azf3328_timer_stop(chip->timer);
1998 snd_azf3328_gameport_free(chip);
1999
2000 if (chip->irq >= 0)
2001 synchronize_irq(chip->irq);
2002__end_hw:
2003 if (chip->irq >= 0)
2004 free_irq(chip->irq, chip);
2005 pci_release_regions(chip->pci);
2006 pci_disable_device(chip->pci);
2007
2008 kfree(chip);
2009 return 0;
2010}
2011
2012static int
2013snd_azf3328_dev_free(struct snd_device *device)
2014{
2015 struct snd_azf3328 *chip = device->device_data;
2016 return snd_azf3328_free(chip);
2017}
2018
1648#if 0 2019#if 0
1649/* check whether a bit can be modified */ 2020/* check whether a bit can be modified */
1650static void 2021static void
1651snd_azf3328_test_bit(unsigned int reg, int bit) 2022snd_azf3328_test_bit(unsigned unsigned reg, int bit)
1652{ 2023{
1653 unsigned char val, valoff, valon; 2024 unsigned char val, valoff, valon;
1654 2025
@@ -1659,42 +2030,74 @@ snd_azf3328_test_bit(unsigned int reg, int bit)
1659 2030
1660 outb(val|(1 << bit), reg); 2031 outb(val|(1 << bit), reg);
1661 valon = inb(reg); 2032 valon = inb(reg);
1662 2033
1663 outb(val, reg); 2034 outb(val, reg);
1664 2035
1665 printk(KERN_ERR "reg %04x bit %d: %02x %02x %02x\n", reg, bit, val, valoff, valon); 2036 printk(KERN_ERR "reg %04x bit %d: %02x %02x %02x\n",
2037 reg, bit, val, valoff, valon
2038 );
1666} 2039}
1667#endif 2040#endif
1668 2041
1669#if DEBUG_MISC 2042static inline void
1670static void
1671snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) 2043snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
1672{ 2044{
2045#if DEBUG_MISC
1673 u16 tmp; 2046 u16 tmp;
1674 2047
1675 snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq); 2048 snd_azf3328_dbgmisc(
1676 2049 "codec_io 0x%lx, game_io 0x%lx, mpu_io 0x%lx, "
1677 snd_azf3328_dbgmisc("io2 %02x %02x %02x %02x %02x %02x\n", snd_azf3328_io2_inb(chip, 0), snd_azf3328_io2_inb(chip, 1), snd_azf3328_io2_inb(chip, 2), snd_azf3328_io2_inb(chip, 3), snd_azf3328_io2_inb(chip, 4), snd_azf3328_io2_inb(chip, 5)); 2050 "opl3_io 0x%lx, mixer_io 0x%lx, irq %d\n",
1678 2051 chip->codec_io, chip->game_io, chip->mpu_io,
1679 for (tmp=0; tmp <= 0x01; tmp += 1) 2052 chip->opl3_io, chip->mixer_io, chip->irq
1680 snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp)); 2053 );
2054
2055 snd_azf3328_dbgmisc("game %02x %02x %02x %02x %02x %02x\n",
2056 snd_azf3328_game_inb(chip, 0),
2057 snd_azf3328_game_inb(chip, 1),
2058 snd_azf3328_game_inb(chip, 2),
2059 snd_azf3328_game_inb(chip, 3),
2060 snd_azf3328_game_inb(chip, 4),
2061 snd_azf3328_game_inb(chip, 5)
2062 );
2063
2064 for (tmp = 0; tmp < 0x07; tmp += 1)
2065 snd_azf3328_dbgmisc("mpu_io 0x%04x\n", inb(chip->mpu_io + tmp));
2066
2067 for (tmp = 0; tmp <= 0x07; tmp += 1)
2068 snd_azf3328_dbgmisc("0x%02x: game200 0x%04x, game208 0x%04x\n",
2069 tmp, inb(0x200 + tmp), inb(0x208 + tmp));
2070
2071 for (tmp = 0; tmp <= 0x01; tmp += 1)
2072 snd_azf3328_dbgmisc(
2073 "0x%02x: mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, "
2074 "mpu330 0x%04x opl388 0x%04x opl38c 0x%04x\n",
2075 tmp,
2076 inb(0x300 + tmp),
2077 inb(0x310 + tmp),
2078 inb(0x320 + tmp),
2079 inb(0x330 + tmp),
2080 inb(0x388 + tmp),
2081 inb(0x38c + tmp)
2082 );
1681 2083
1682 for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2) 2084 for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2)
1683 snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inw(chip, tmp)); 2085 snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n",
2086 tmp, snd_azf3328_codec_inw(chip, tmp)
2087 );
1684 2088
1685 for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2) 2089 for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)
1686 snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n", tmp, snd_azf3328_mixer_inw(chip, tmp)); 2090 snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n",
2091 tmp, snd_azf3328_mixer_inw(chip, tmp)
2092 );
2093#endif /* DEBUG_MISC */
1687} 2094}
1688#else
1689static inline void
1690snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) {}
1691#endif
1692 2095
1693static int __devinit 2096static int __devinit
1694snd_azf3328_create(struct snd_card *card, 2097snd_azf3328_create(struct snd_card *card,
1695 struct pci_dev *pci, 2098 struct pci_dev *pci,
1696 unsigned long device_type, 2099 unsigned long device_type,
1697 struct snd_azf3328 ** rchip) 2100 struct snd_azf3328 **rchip)
1698{ 2101{
1699 struct snd_azf3328 *chip; 2102 struct snd_azf3328 *chip;
1700 int err; 2103 int err;
@@ -1705,7 +2108,8 @@ snd_azf3328_create(struct snd_card *card,
1705 2108
1706 *rchip = NULL; 2109 *rchip = NULL;
1707 2110
1708 if ((err = pci_enable_device(pci)) < 0) 2111 err = pci_enable_device(pci);
2112 if (err < 0)
1709 return err; 2113 return err;
1710 2114
1711 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 2115 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -1721,20 +2125,25 @@ snd_azf3328_create(struct snd_card *card,
1721 /* check if we can restrict PCI DMA transfers to 24 bits */ 2125 /* check if we can restrict PCI DMA transfers to 24 bits */
1722 if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 || 2126 if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 ||
1723 pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) { 2127 pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) {
1724 snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n"); 2128 snd_printk(KERN_ERR "architecture does not support "
2129 "24bit PCI busmaster DMA\n"
2130 );
1725 err = -ENXIO; 2131 err = -ENXIO;
1726 goto out_err; 2132 goto out_err;
1727 } 2133 }
1728 2134
1729 if ((err = pci_request_regions(pci, "Aztech AZF3328")) < 0) { 2135 err = pci_request_regions(pci, "Aztech AZF3328");
2136 if (err < 0)
1730 goto out_err; 2137 goto out_err;
1731 }
1732 2138
1733 chip->codec_port = pci_resource_start(pci, 0); 2139 chip->codec_io = pci_resource_start(pci, 0);
1734 chip->io2_port = pci_resource_start(pci, 1); 2140 chip->game_io = pci_resource_start(pci, 1);
1735 chip->mpu_port = pci_resource_start(pci, 2); 2141 chip->mpu_io = pci_resource_start(pci, 2);
1736 chip->synth_port = pci_resource_start(pci, 3); 2142 chip->opl3_io = pci_resource_start(pci, 3);
1737 chip->mixer_port = pci_resource_start(pci, 4); 2143 chip->mixer_io = pci_resource_start(pci, 4);
2144
2145 chip->audio_stream[AZF_PLAYBACK].portbase = chip->codec_io + 0x00;
2146 chip->audio_stream[AZF_CAPTURE].portbase = chip->codec_io + 0x20;
1738 2147
1739 if (request_irq(pci->irq, snd_azf3328_interrupt, 2148 if (request_irq(pci->irq, snd_azf3328_interrupt,
1740 IRQF_SHARED, card->shortname, chip)) { 2149 IRQF_SHARED, card->shortname, chip)) {
@@ -1747,29 +2156,29 @@ snd_azf3328_create(struct snd_card *card,
1747 synchronize_irq(chip->irq); 2156 synchronize_irq(chip->irq);
1748 2157
1749 snd_azf3328_debug_show_ports(chip); 2158 snd_azf3328_debug_show_ports(chip);
1750 2159
1751 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 2160 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
2161 if (err < 0)
1752 goto out_err; 2162 goto out_err;
1753 }
1754 2163
1755 /* create mixer interface & switches */ 2164 /* create mixer interface & switches */
1756 if ((err = snd_azf3328_mixer_new(chip)) < 0) 2165 err = snd_azf3328_mixer_new(chip);
2166 if (err < 0)
1757 goto out_err; 2167 goto out_err;
1758 2168
1759#if 0 2169 /* shutdown codecs to save power */
1760 /* set very low bitrate to reduce noise and power consumption? */ 2170 /* have snd_azf3328_codec_activity() act properly */
1761 snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, 5512, 8, 1); 2171 chip->audio_stream[AZF_PLAYBACK].running = 1;
1762#endif 2172 snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0);
1763 2173
1764 /* standard chip init stuff */ 2174 /* standard chip init stuff */
1765 /* default IRQ init value */ 2175 /* default IRQ init value */
1766 tmp = DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE; 2176 tmp = DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;
1767 2177
1768 spin_lock_irq(&chip->reg_lock); 2178 spin_lock_irq(&chip->reg_lock);
1769 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_FLAGS, tmp); 2179 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_FLAGS, tmp);
1770 snd_azf3328_codec_outb(chip, IDX_IO_REC_FLAGS, tmp); 2180 snd_azf3328_codec_outb(chip, IDX_IO_REC_FLAGS, tmp);
1771 snd_azf3328_codec_outb(chip, IDX_IO_SOMETHING_FLAGS, tmp); 2181 snd_azf3328_codec_outb(chip, IDX_IO_SOMETHING_FLAGS, tmp);
1772 snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00); /* disable timer */
1773 spin_unlock_irq(&chip->reg_lock); 2182 spin_unlock_irq(&chip->reg_lock);
1774 2183
1775 snd_card_set_dev(card, &pci->dev); 2184 snd_card_set_dev(card, &pci->dev);
@@ -1805,52 +2214,61 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
1805 return -ENOENT; 2214 return -ENOENT;
1806 } 2215 }
1807 2216
1808 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0 ); 2217 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1809 if (card == NULL) 2218 if (card == NULL)
1810 return -ENOMEM; 2219 return -ENOMEM;
1811 2220
1812 strcpy(card->driver, "AZF3328"); 2221 strcpy(card->driver, "AZF3328");
1813 strcpy(card->shortname, "Aztech AZF3328 (PCI168)"); 2222 strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
1814 2223
1815 if ((err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip)) < 0) { 2224 err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip);
2225 if (err < 0)
1816 goto out_err; 2226 goto out_err;
1817 }
1818 2227
1819 card->private_data = chip; 2228 card->private_data = chip;
1820 2229
1821 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401, 2230 err = snd_mpu401_uart_new(
1822 chip->mpu_port, MPU401_INFO_INTEGRATED, 2231 card, 0, MPU401_HW_MPU401, chip->mpu_io, MPU401_INFO_INTEGRATED,
1823 pci->irq, 0, &chip->rmidi)) < 0) { 2232 pci->irq, 0, &chip->rmidi
1824 snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port); 2233 );
2234 if (err < 0) {
2235 snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n",
2236 chip->mpu_io
2237 );
1825 goto out_err; 2238 goto out_err;
1826 } 2239 }
1827 2240
1828 if ((err = snd_azf3328_timer(chip, 0)) < 0) { 2241 err = snd_azf3328_timer(chip, 0);
2242 if (err < 0)
1829 goto out_err; 2243 goto out_err;
1830 }
1831 2244
1832 if ((err = snd_azf3328_pcm(chip, 0)) < 0) { 2245 err = snd_azf3328_pcm(chip, 0);
2246 if (err < 0)
1833 goto out_err; 2247 goto out_err;
1834 }
1835 2248
1836 if (snd_opl3_create(card, chip->synth_port, chip->synth_port+2, 2249 if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2,
1837 OPL3_HW_AUTO, 1, &opl3) < 0) { 2250 OPL3_HW_AUTO, 1, &opl3) < 0) {
1838 snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n", 2251 snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
1839 chip->synth_port, chip->synth_port+2 ); 2252 chip->opl3_io, chip->opl3_io+2
2253 );
1840 } else { 2254 } else {
1841 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { 2255 /* need to use IDs 1, 2 since ID 0 is snd_azf3328_timer above */
2256 err = snd_opl3_timer_new(opl3, 1, 2);
2257 if (err < 0)
2258 goto out_err;
2259 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
2260 if (err < 0)
1842 goto out_err; 2261 goto out_err;
1843 }
1844 } 2262 }
1845 2263
1846 opl3->private_data = chip; 2264 opl3->private_data = chip;
1847 2265
1848 sprintf(card->longname, "%s at 0x%lx, irq %i", 2266 sprintf(card->longname, "%s at 0x%lx, irq %i",
1849 card->shortname, chip->codec_port, chip->irq); 2267 card->shortname, chip->codec_io, chip->irq);
1850 2268
1851 if ((err = snd_card_register(card)) < 0) { 2269 err = snd_card_register(card);
2270 if (err < 0)
1852 goto out_err; 2271 goto out_err;
1853 }
1854 2272
1855#ifdef MODULE 2273#ifdef MODULE
1856 printk( 2274 printk(
@@ -1861,19 +2279,18 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
1861 1024000 / seqtimer_scaling, seqtimer_scaling); 2279 1024000 / seqtimer_scaling, seqtimer_scaling);
1862#endif 2280#endif
1863 2281
1864 if (snd_azf3328_config_joystick(chip, dev) < 0) 2282 snd_azf3328_gameport(chip, dev);
1865 snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
1866 snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
1867 2283
1868 pci_set_drvdata(pci, card); 2284 pci_set_drvdata(pci, card);
1869 dev++; 2285 dev++;
1870 2286
1871 err = 0; 2287 err = 0;
1872 goto out; 2288 goto out;
1873 2289
1874out_err: 2290out_err:
2291 snd_printk(KERN_ERR "azf3328: something failed, exiting\n");
1875 snd_card_free(card); 2292 snd_card_free(card);
1876 2293
1877out: 2294out:
1878 snd_azf3328_dbgcallleave(); 2295 snd_azf3328_dbgcallleave();
1879 return err; 2296 return err;
@@ -1894,27 +2311,31 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
1894{ 2311{
1895 struct snd_card *card = pci_get_drvdata(pci); 2312 struct snd_card *card = pci_get_drvdata(pci);
1896 struct snd_azf3328 *chip = card->private_data; 2313 struct snd_azf3328 *chip = card->private_data;
1897 int reg; 2314 unsigned reg;
1898 2315
1899 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2316 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1900 2317
1901 snd_pcm_suspend_all(chip->pcm); 2318 snd_pcm_suspend_all(chip->pcm);
1902 2319
1903 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; reg++) 2320 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg)
1904 chip->saved_regs_mixer[reg] = inw(chip->mixer_port + reg * 2); 2321 chip->saved_regs_mixer[reg] = inw(chip->mixer_io + reg * 2);
1905 2322
1906 /* make sure to disable master volume etc. to prevent looping sound */ 2323 /* make sure to disable master volume etc. to prevent looping sound */
1907 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1); 2324 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
1908 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1); 2325 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
1909 2326
1910 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; reg++) 2327 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg)
1911 chip->saved_regs_codec[reg] = inw(chip->codec_port + reg * 2); 2328 chip->saved_regs_codec[reg] = inw(chip->codec_io + reg * 2);
1912 for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++) 2329
1913 chip->saved_regs_io2[reg] = inw(chip->io2_port + reg * 2); 2330 /* manually store the one currently relevant write-only reg, too */
1914 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; reg++) 2331 chip->saved_regs_codec[IDX_IO_6AH / 2] = chip->shadow_reg_codec_6AH;
1915 chip->saved_regs_mpu[reg] = inw(chip->mpu_port + reg * 2); 2332
1916 for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++) 2333 for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg)
1917 chip->saved_regs_synth[reg] = inw(chip->synth_port + reg * 2); 2334 chip->saved_regs_game[reg] = inw(chip->game_io + reg * 2);
2335 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg)
2336 chip->saved_regs_mpu[reg] = inw(chip->mpu_io + reg * 2);
2337 for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg)
2338 chip->saved_regs_opl3[reg] = inw(chip->opl3_io + reg * 2);
1918 2339
1919 pci_disable_device(pci); 2340 pci_disable_device(pci);
1920 pci_save_state(pci); 2341 pci_save_state(pci);
@@ -1927,7 +2348,7 @@ snd_azf3328_resume(struct pci_dev *pci)
1927{ 2348{
1928 struct snd_card *card = pci_get_drvdata(pci); 2349 struct snd_card *card = pci_get_drvdata(pci);
1929 struct snd_azf3328 *chip = card->private_data; 2350 struct snd_azf3328 *chip = card->private_data;
1930 int reg; 2351 unsigned reg;
1931 2352
1932 pci_set_power_state(pci, PCI_D0); 2353 pci_set_power_state(pci, PCI_D0);
1933 pci_restore_state(pci); 2354 pci_restore_state(pci);
@@ -1939,23 +2360,21 @@ snd_azf3328_resume(struct pci_dev *pci)
1939 } 2360 }
1940 pci_set_master(pci); 2361 pci_set_master(pci);
1941 2362
1942 for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++) 2363 for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg)
1943 outw(chip->saved_regs_io2[reg], chip->io2_port + reg * 2); 2364 outw(chip->saved_regs_game[reg], chip->game_io + reg * 2);
1944 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; reg++) 2365 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg)
1945 outw(chip->saved_regs_mpu[reg], chip->mpu_port + reg * 2); 2366 outw(chip->saved_regs_mpu[reg], chip->mpu_io + reg * 2);
1946 for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++) 2367 for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg)
1947 outw(chip->saved_regs_synth[reg], chip->synth_port + reg * 2); 2368 outw(chip->saved_regs_opl3[reg], chip->opl3_io + reg * 2);
1948 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; reg++) 2369 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg)
1949 outw(chip->saved_regs_mixer[reg], chip->mixer_port + reg * 2); 2370 outw(chip->saved_regs_mixer[reg], chip->mixer_io + reg * 2);
1950 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; reg++) 2371 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg)
1951 outw(chip->saved_regs_codec[reg], chip->codec_port + reg * 2); 2372 outw(chip->saved_regs_codec[reg], chip->codec_io + reg * 2);
1952 2373
1953 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2374 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1954 return 0; 2375 return 0;
1955} 2376}
1956#endif 2377#endif /* CONFIG_PM */
1957
1958
1959 2378
1960 2379
1961static struct pci_driver driver = { 2380static struct pci_driver driver = {
diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h
index 679fa992e2bc..7e3e8942d073 100644
--- a/sound/pci/azt3328.h
+++ b/sound/pci/azt3328.h
@@ -1,7 +1,8 @@
1#ifndef __SOUND_AZT3328_H 1#ifndef __SOUND_AZT3328_H
2#define __SOUND_AZT3328_H 2#define __SOUND_AZT3328_H
3 3
4/* "PU" == "power-up value", as tested on PCI168 PCI rev. 10 */ 4/* "PU" == "power-up value", as tested on PCI168 PCI rev. 10
5 * "WRITE_ONLY" == register does not indicate actual bit values */
5 6
6/*** main I/O area port indices ***/ 7/*** main I/O area port indices ***/
7/* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */ 8/* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */
@@ -54,7 +55,10 @@
54 #define SOUNDFORMAT_XTAL1 0x00 55 #define SOUNDFORMAT_XTAL1 0x00
55 #define SOUNDFORMAT_XTAL2 0x01 56 #define SOUNDFORMAT_XTAL2 0x01
56 /* all _SUSPECTED_ values are not used by Windows drivers, so we don't 57 /* all _SUSPECTED_ values are not used by Windows drivers, so we don't
57 * have any hard facts, only rough measurements */ 58 * have any hard facts, only rough measurements.
59 * All we know is that the crystal used on the board has 24.576MHz,
60 * like many soundcards (which results in the frequencies below when
61 * using certain divider values selected by the values below) */
58 #define SOUNDFORMAT_FREQ_SUSPECTED_4000 0x0c | SOUNDFORMAT_XTAL1 62 #define SOUNDFORMAT_FREQ_SUSPECTED_4000 0x0c | SOUNDFORMAT_XTAL1
59 #define SOUNDFORMAT_FREQ_SUSPECTED_4800 0x0a | SOUNDFORMAT_XTAL1 63 #define SOUNDFORMAT_FREQ_SUSPECTED_4800 0x0a | SOUNDFORMAT_XTAL1
60 #define SOUNDFORMAT_FREQ_5510 0x0c | SOUNDFORMAT_XTAL2 64 #define SOUNDFORMAT_FREQ_5510 0x0c | SOUNDFORMAT_XTAL2
@@ -72,6 +76,26 @@
72 #define SOUNDFORMAT_FLAG_16BIT 0x0010 76 #define SOUNDFORMAT_FLAG_16BIT 0x0010
73 #define SOUNDFORMAT_FLAG_2CHANNELS 0x0020 77 #define SOUNDFORMAT_FLAG_2CHANNELS 0x0020
74 78
79/* define frequency helpers, for maximum value safety */
80enum azf_freq_t {
81#define AZF_FREQ(rate) AZF_FREQ_##rate = rate
82 AZF_FREQ(4000),
83 AZF_FREQ(4800),
84 AZF_FREQ(5512),
85 AZF_FREQ(6620),
86 AZF_FREQ(8000),
87 AZF_FREQ(9600),
88 AZF_FREQ(11025),
89 AZF_FREQ(13240),
90 AZF_FREQ(16000),
91 AZF_FREQ(22050),
92 AZF_FREQ(32000),
93 AZF_FREQ(44100),
94 AZF_FREQ(48000),
95 AZF_FREQ(66200),
96#undef AZF_FREQ
97} AZF_FREQUENCIES;
98
75/** recording area (see also: playback bit flag definitions) **/ 99/** recording area (see also: playback bit flag definitions) **/
76#define IDX_IO_REC_FLAGS 0x20 /* ??, PU:0x0000 */ 100#define IDX_IO_REC_FLAGS 0x20 /* ??, PU:0x0000 */
77#define IDX_IO_REC_IRQTYPE 0x22 /* ??, PU:0x0000 */ 101#define IDX_IO_REC_IRQTYPE 0x22 /* ??, PU:0x0000 */
@@ -97,40 +121,171 @@
97 121
98/** DirectX timer, main interrupt area (FIXME: and something else?) **/ 122/** DirectX timer, main interrupt area (FIXME: and something else?) **/
99#define IDX_IO_TIMER_VALUE 0x60 /* found this timer area by pure luck :-) */ 123#define IDX_IO_TIMER_VALUE 0x60 /* found this timer area by pure luck :-) */
100 #define TIMER_VALUE_MASK 0x000fffffUL /* timer countdown value; triggers IRQ when timer is finished */ 124 /* timer countdown value; triggers IRQ when timer is finished */
101 #define TIMER_ENABLE_COUNTDOWN 0x01000000UL /* activate the timer countdown */ 125 #define TIMER_VALUE_MASK 0x000fffffUL
102 #define TIMER_ENABLE_IRQ 0x02000000UL /* trigger timer IRQ on zero transition */ 126 /* activate timer countdown */
103 #define TIMER_ACK_IRQ 0x04000000UL /* being set in IRQ handler in case port 0x00 (hmm, not port 0x64!?!?) had 0x0020 set upon IRQ handler */ 127 #define TIMER_COUNTDOWN_ENABLE 0x01000000UL
128 /* trigger timer IRQ on zero transition */
129 #define TIMER_IRQ_ENABLE 0x02000000UL
130 /* being set in IRQ handler in case port 0x00 (hmm, not port 0x64!?!?)
131 * had 0x0020 set upon IRQ handler */
132 #define TIMER_IRQ_ACK 0x04000000UL
104#define IDX_IO_IRQSTATUS 0x64 133#define IDX_IO_IRQSTATUS 0x64
105 #define IRQ_PLAYBACK 0x0001 134 /* some IRQ bit in here might also be used to signal a power-management timer
106 #define IRQ_RECORDING 0x0002 135 * timeout, to request shutdown of the chip (e.g. AD1815JS has such a thing).
107 #define IRQ_MPU401 0x0010 136 * Some OPL3 hardware (e.g. in LM4560) has some special timer hardware which
108 #define IRQ_TIMER 0x0020 /* DirectX timer */ 137 * can trigger an OPL3 timer IRQ, so maybe there's such a thing as well... */
109 #define IRQ_UNKNOWN1 0x0040 /* probably unused, or possibly I2S port? or gameport IRQ? */ 138
110 #define IRQ_UNKNOWN2 0x0080 /* probably unused, or possibly I2S port? or gameport IRQ? */ 139 #define IRQ_PLAYBACK 0x0001
140 #define IRQ_RECORDING 0x0002
141 #define IRQ_UNKNOWN1 0x0004 /* most probably I2S port */
142 #define IRQ_GAMEPORT 0x0008 /* Interrupt of Digital(ly) Enhanced Game Port */
143 #define IRQ_MPU401 0x0010
144 #define IRQ_TIMER 0x0020 /* DirectX timer */
145 #define IRQ_UNKNOWN2 0x0040 /* probably unused, or possibly I2S port? */
146 #define IRQ_UNKNOWN3 0x0080 /* probably unused, or possibly I2S port? */
111#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */ 147#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */
112#define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */ 148 /* this is set to e.g. 0x3ff or 0x300, and writable;
113#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated (FIXME: correct??); actually inhibits PCM playback!!! maybe power management?? */ 149 * maybe some buffer limit, but I couldn't find out more, PU:0x00ff: */
114 #define IO_6A_PAUSE_PLAYBACK 0x0200 /* bit 9; sure, this pauses playback, but what the heck is this really about?? */ 150#define IDX_IO_SOME_VALUE 0x68
115#define IDX_IO_6CH 0x6C 151 #define IO_68_RANDOM_TOGGLE1 0x0100 /* toggles randomly */
116#define IDX_IO_6EH 0x6E /* writing 0xffff returns 0x83fe */ 152 #define IO_68_RANDOM_TOGGLE2 0x0200 /* toggles randomly */
117/* further I/O indices not saved/restored, so probably not used */ 153 /* umm, nope, behaviour of these bits changes depending on what we wrote
154 * to 0x6b!!
155 * And they change upon playback/stop, too:
156 * Writing a value to 0x68 will display this exact value during playback,
157 * too but when stopped it can fall back to a rather different
158 * seemingly random value). Hmm, possibly this is a register which
159 * has a remote shadow which needs proper device supply which only exists
160 * in case playback is active? Or is this driver-induced?
161 */
162
163/* this WORD can be set to have bits 0x0028 activated (FIXME: correct??);
164 * actually inhibits PCM playback!!! maybe power management??: */
165#define IDX_IO_6AH 0x6A /* WRITE_ONLY! */
166 /* bit 5: enabling this will activate permanent counting of bytes 2/3
167 * at gameport I/O (0xb402/3) (equal values each) and cause
168 * gameport legacy I/O at 0x0200 to be _DISABLED_!
169 * Is this Digital Enhanced Game Port Enable??? Or maybe it's Testmode
170 * for Enhanced Digital Gameport (see 4D Wave DX card): */
171 #define IO_6A_SOMETHING1_GAMEPORT 0x0020
172 /* bit 8; sure, this _pauses_ playback (later resumes at same spot!),
173 * but what the heck is this really about??: */
174 #define IO_6A_PAUSE_PLAYBACK_BIT8 0x0100
175 /* bit 9; sure, this _pauses_ playback (later resumes at same spot!),
176 * but what the heck is this really about??: */
177 #define IO_6A_PAUSE_PLAYBACK_BIT9 0x0200
178 /* BIT8 and BIT9 are _NOT_ able to affect OPL3 MIDI playback,
179 * thus it suggests influence on PCM only!!
180 * However OTOH there seems to be no bit anywhere around here
181 * which is able to disable OPL3... */
182 /* bit 10: enabling this actually changes values at legacy gameport
183 * I/O address (0x200); is this enabling of the Digital Enhanced Game Port???
184 * Or maybe this simply switches off the NE558 circuit, since enabling this
185 * still lets us evaluate button states, but not axis states */
186 #define IO_6A_SOMETHING2_GAMEPORT 0x0400
187 /* writing 0x0300: causes quite some crackling during
188 * PC activity such as switching windows (PCI traffic??
189 * --> FIFO/timing settings???) */
190 /* writing 0x0100 plus/or 0x0200 inhibits playback */
191 /* since the Windows .INF file has Flag_Enable_JoyStick and
192 * Flag_Enable_SB_DOS_Emulation directly together, it stands to reason
193 * that some other bit in this same register might be responsible
194 * for SB DOS Emulation activation (note that the file did NOT define
195 * a switch for OPL3!) */
196#define IDX_IO_6CH 0x6C /* unknown; fully read-writable */
197#define IDX_IO_6EH 0x6E
198 /* writing 0xffff returns 0x83fe (or 0x03fe only).
199 * writing 0x83 (and only 0x83!!) to 0x6f will cause 0x6c to switch
200 * from 0000 to ffff. */
118 201
202/* further I/O indices not saved/restored and not readable after writing,
203 * so probably not used */
119 204
120/*** I/O 2 area port indices ***/ 205
206/*** Gameport area port indices ***/
121/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */ 207/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */
122#define AZF_IO_SIZE_IO2 0x08 208#define AZF_IO_SIZE_GAME 0x08
123#define AZF_IO_SIZE_IO2_PM 0x06 209#define AZF_IO_SIZE_GAME_PM 0x06
210
211enum {
212 AZF_GAME_LEGACY_IO_PORT = 0x200
213} AZF_GAME_CONFIGS;
214
215#define IDX_GAME_LEGACY_COMPATIBLE 0x00
216 /* in some operation mode, writing anything to this port
217 * triggers an interrupt:
218 * yup, that's in case IDX_GAME_01H has one of the
219 * axis measurement bits enabled
220 * (and of course one needs to have GAME_HWCFG_IRQ_ENABLE, too) */
221
222#define IDX_GAME_AXES_CONFIG 0x01
223 /* NOTE: layout of this register awfully similar (read: "identical??")
224 * to AD1815JS.pdf (p.29) */
225
226 /* enables axis 1 (X axis) measurement: */
227 #define GAME_AXES_ENABLE_1 0x01
228 /* enables axis 2 (Y axis) measurement: */
229 #define GAME_AXES_ENABLE_2 0x02
230 /* enables axis 3 (X axis) measurement: */
231 #define GAME_AXES_ENABLE_3 0x04
232 /* enables axis 4 (Y axis) measurement: */
233 #define GAME_AXES_ENABLE_4 0x08
234 /* selects the current axis to read the measured value of
235 * (at IDX_GAME_AXIS_VALUE):
236 * 00 = axis 1, 01 = axis 2, 10 = axis 3, 11 = axis 4: */
237 #define GAME_AXES_READ_MASK 0x30
238 /* enable to have the latch continuously accept ADC values
239 * (and continuously cause interrupts in case interrupts are enabled);
240 * AD1815JS.pdf says it's ~16ms interval there: */
241 #define GAME_AXES_LATCH_ENABLE 0x40
242 /* joystick data (measured axes) ready for reading: */
243 #define GAME_AXES_SAMPLING_READY 0x80
244
245 /* NOTE: other card specs (SiS960 and others!) state that the
246 * game position latches should be frozen when reading and be freed
247 * (== reset?) after reading!!!
248 * Freezing most likely means disabling 0x40 (GAME_AXES_LATCH_ENABLE),
249 * but how to free the value? */
250 /* An internet search for "gameport latch ADC" should provide some insight
251 * into how to program such a gameport system. */
252
253 /* writing 0xf0 to 01H once reset both counters to 0, in some special mode!?
254 * yup, in case 6AH 0x20 is not enabled
255 * (and 0x40 is sufficient, 0xf0 is not needed) */
256
257#define IDX_GAME_AXIS_VALUE 0x02
258 /* R: value of currently configured axis (word value!);
259 * W: trigger axis measurement */
260
261#define IDX_GAME_HWCONFIG 0x04
262 /* note: bits 4 to 7 are never set (== 0) when reading!
263 * --> reserved bits? */
264 /* enables IRQ notification upon axes measurement ready: */
265 #define GAME_HWCFG_IRQ_ENABLE 0x01
266 /* these bits choose a different frequency for the
267 * internal ADC counter increment.
268 * hmm, seems to be a combo of bits:
269 * 00 --> standard frequency
270 * 10 --> 1/2
271 * 01 --> 1/20
272 * 11 --> 1/200: */
273 #define GAME_HWCFG_ADC_COUNTER_FREQ_MASK 0x06
124 274
125#define IDX_IO2_LEGACY_ADDR 0x04 275 /* enable gameport legacy I/O address (0x200)
126 #define LEGACY_SOMETHING 0x01 /* OPL3?? */ 276 * I was unable to locate any configurability for a different address: */
127 #define LEGACY_JOY 0x08 277 #define GAME_HWCFG_LEGACY_ADDRESS_ENABLE 0x08
128 278
279/*** MPU401 ***/
129#define AZF_IO_SIZE_MPU 0x04 280#define AZF_IO_SIZE_MPU 0x04
130#define AZF_IO_SIZE_MPU_PM 0x04 281#define AZF_IO_SIZE_MPU_PM 0x04
131 282
132#define AZF_IO_SIZE_SYNTH 0x08 283/*** OPL3 synth ***/
133#define AZF_IO_SIZE_SYNTH_PM 0x06 284#define AZF_IO_SIZE_OPL3 0x08
285#define AZF_IO_SIZE_OPL3_PM 0x06
286/* hmm, given that a standard OPL3 has 4 registers only,
287 * there might be some enhanced functionality lurking at the end
288 * (especially since register 0x04 has a "non-empty" value 0xfe) */
134 289
135/*** mixer I/O area port indices ***/ 290/*** mixer I/O area port indices ***/
136/* (only 0x22 of 0x40 bytes saved/restored by Windows driver) 291/* (only 0x22 of 0x40 bytes saved/restored by Windows driver)
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index ecbe79b67e43..2f8b28add276 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -249,6 +249,11 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
249 .name = "MSI K8N Diamond MB [SB0438]", 249 .name = "MSI K8N Diamond MB [SB0438]",
250 .gpio_type = 2, 250 .gpio_type = 2,
251 .i2c_adc = 1 } , 251 .i2c_adc = 1 } ,
252 /* Another MSI K8N Diamond MB, which has apprently a different SSID */
253 { .serial = 0x10091102,
254 .name = "MSI K8N Diamond MB",
255 .gpio_type = 2,
256 .i2c_adc = 1 } ,
252 /* Shuttle XPC SD31P which has an onboard Creative Labs 257 /* Shuttle XPC SD31P which has an onboard Creative Labs
253 * Sound Blaster Live! 24-bit EAX 258 * Sound Blaster Live! 24-bit EAX
254 * high-definition 7.1 audio processor". 259 * high-definition 7.1 audio processor".
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 548c9cc81af5..2f283ea6ad9a 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -1528,6 +1528,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1528 .ca0151_chip = 1, 1528 .ca0151_chip = 1,
1529 .spk71 = 1, 1529 .spk71 = 1,
1530 .spdif_bug = 1, 1530 .spdif_bug = 1,
1531 .invert_shared_spdif = 1, /* digital/analog switch swapped */
1531 .adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */ 1532 .adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */
1532 .ac97_chip = 1} , 1533 .ac97_chip = 1} ,
1533 {.vendor = 0x1102, .device = 0x0004, .revision = 0x04, 1534 {.vendor = 0x1102, .device = 0x0004, .revision = 0x04,
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index fd221209abcb..f34bbfb705f5 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -1578,6 +1578,10 @@ static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol,
1578 ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0; 1578 ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
1579 else 1579 else
1580 ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0; 1580 ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
1581 if (emu->card_capabilities->invert_shared_spdif)
1582 ucontrol->value.integer.value[0] =
1583 !ucontrol->value.integer.value[0];
1584
1581 return 0; 1585 return 0;
1582} 1586}
1583 1587
@@ -1586,15 +1590,18 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
1586{ 1590{
1587 unsigned long flags; 1591 unsigned long flags;
1588 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); 1592 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1589 unsigned int reg, val; 1593 unsigned int reg, val, sw;
1590 int change = 0; 1594 int change = 0;
1591 1595
1596 sw = ucontrol->value.integer.value[0];
1597 if (emu->card_capabilities->invert_shared_spdif)
1598 sw = !sw;
1592 spin_lock_irqsave(&emu->reg_lock, flags); 1599 spin_lock_irqsave(&emu->reg_lock, flags);
1593 if ( emu->card_capabilities->i2c_adc) { 1600 if ( emu->card_capabilities->i2c_adc) {
1594 /* Do nothing for Audigy 2 ZS Notebook */ 1601 /* Do nothing for Audigy 2 ZS Notebook */
1595 } else if (emu->audigy) { 1602 } else if (emu->audigy) {
1596 reg = inl(emu->port + A_IOCFG); 1603 reg = inl(emu->port + A_IOCFG);
1597 val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0; 1604 val = sw ? A_IOCFG_GPOUT0 : 0;
1598 change = (reg & A_IOCFG_GPOUT0) != val; 1605 change = (reg & A_IOCFG_GPOUT0) != val;
1599 if (change) { 1606 if (change) {
1600 reg &= ~A_IOCFG_GPOUT0; 1607 reg &= ~A_IOCFG_GPOUT0;
@@ -1603,7 +1610,7 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
1603 } 1610 }
1604 } 1611 }
1605 reg = inl(emu->port + HCFG); 1612 reg = inl(emu->port + HCFG);
1606 val = ucontrol->value.integer.value[0] ? HCFG_GPOUT0 : 0; 1613 val = sw ? HCFG_GPOUT0 : 0;
1607 change |= (reg & HCFG_GPOUT0) != val; 1614 change |= (reg & HCFG_GPOUT0) != val;
1608 if (change) { 1615 if (change) {
1609 reg &= ~HCFG_GPOUT0; 1616 reg &= ~HCFG_GPOUT0;
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 916c1dbcd53c..7d379f5131fb 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -437,43 +437,49 @@ static void get_single_page_range(struct snd_util_memhdr *hdr,
437 *last_page_ret = last_page; 437 *last_page_ret = last_page;
438} 438}
439 439
440/* release allocated pages */
441static void __synth_free_pages(struct snd_emu10k1 *emu, int first_page,
442 int last_page)
443{
444 int page;
445
446 for (page = first_page; page <= last_page; page++) {
447 free_page((unsigned long)emu->page_ptr_table[page]);
448 emu->page_addr_table[page] = 0;
449 emu->page_ptr_table[page] = NULL;
450 }
451}
452
440/* 453/*
441 * allocate kernel pages 454 * allocate kernel pages
442 */ 455 */
443static int synth_alloc_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) 456static int synth_alloc_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
444{ 457{
445 int page, first_page, last_page; 458 int page, first_page, last_page;
446 struct snd_dma_buffer dmab;
447 459
448 emu10k1_memblk_init(blk); 460 emu10k1_memblk_init(blk);
449 get_single_page_range(emu->memhdr, blk, &first_page, &last_page); 461 get_single_page_range(emu->memhdr, blk, &first_page, &last_page);
450 /* allocate kernel pages */ 462 /* allocate kernel pages */
451 for (page = first_page; page <= last_page; page++) { 463 for (page = first_page; page <= last_page; page++) {
452 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 464 /* first try to allocate from <4GB zone */
453 PAGE_SIZE, &dmab) < 0) 465 struct page *p = alloc_page(GFP_KERNEL | GFP_DMA32 |
454 goto __fail; 466 __GFP_NOWARN);
455 if (! is_valid_page(emu, dmab.addr)) { 467 if (!p || (page_to_pfn(p) & ~(emu->dma_mask >> PAGE_SHIFT))) {
456 snd_dma_free_pages(&dmab); 468 if (p)
457 goto __fail; 469 __free_page(p);
470 /* try to allocate from <16MB zone */
471 p = alloc_page(GFP_ATOMIC | GFP_DMA |
472 __GFP_NORETRY | /* no OOM-killer */
473 __GFP_NOWARN);
474 }
475 if (!p) {
476 __synth_free_pages(emu, first_page, page - 1);
477 return -ENOMEM;
458 } 478 }
459 emu->page_addr_table[page] = dmab.addr; 479 emu->page_addr_table[page] = page_to_phys(p);
460 emu->page_ptr_table[page] = dmab.area; 480 emu->page_ptr_table[page] = page_address(p);
461 } 481 }
462 return 0; 482 return 0;
463
464__fail:
465 /* release allocated pages */
466 last_page = page - 1;
467 for (page = first_page; page <= last_page; page++) {
468 dmab.area = emu->page_ptr_table[page];
469 dmab.addr = emu->page_addr_table[page];
470 dmab.bytes = PAGE_SIZE;
471 snd_dma_free_pages(&dmab);
472 emu->page_addr_table[page] = 0;
473 emu->page_ptr_table[page] = NULL;
474 }
475
476 return -ENOMEM;
477} 483}
478 484
479/* 485/*
@@ -481,23 +487,10 @@ __fail:
481 */ 487 */
482static int synth_free_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) 488static int synth_free_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
483{ 489{
484 int page, first_page, last_page; 490 int first_page, last_page;
485 struct snd_dma_buffer dmab;
486 491
487 get_single_page_range(emu->memhdr, blk, &first_page, &last_page); 492 get_single_page_range(emu->memhdr, blk, &first_page, &last_page);
488 dmab.dev.type = SNDRV_DMA_TYPE_DEV; 493 __synth_free_pages(emu, first_page, last_page);
489 dmab.dev.dev = snd_dma_pci_data(emu->pci);
490 for (page = first_page; page <= last_page; page++) {
491 if (emu->page_ptr_table[page] == NULL)
492 continue;
493 dmab.area = emu->page_ptr_table[page];
494 dmab.addr = emu->page_addr_table[page];
495 dmab.bytes = PAGE_SIZE;
496 snd_dma_free_pages(&dmab);
497 emu->page_addr_table[page] = 0;
498 emu->page_ptr_table[page] = NULL;
499 }
500
501 return 0; 494 return 0;
502} 495}
503 496
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index a6be6e3e8716..d2e1093f8e97 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2335,7 +2335,7 @@ int snd_hda_check_board_config(struct hda_codec *codec,
2335 if (!tbl) 2335 if (!tbl)
2336 return -1; 2336 return -1;
2337 if (tbl->value >= 0 && tbl->value < num_configs) { 2337 if (tbl->value >= 0 && tbl->value < num_configs) {
2338#ifdef CONFIG_SND_DEBUG_DETECT 2338#ifdef CONFIG_SND_DEBUG_VERBOSE
2339 char tmp[10]; 2339 char tmp[10];
2340 const char *model = NULL; 2340 const char *model = NULL;
2341 if (models) 2341 if (models)
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index dcd390b2bbaa..efc682888b31 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -78,7 +78,7 @@ enum {
78#define AC_VERB_GET_BEEP_CONTROL 0x0f0a 78#define AC_VERB_GET_BEEP_CONTROL 0x0f0a
79#define AC_VERB_GET_EAPD_BTLENABLE 0x0f0c 79#define AC_VERB_GET_EAPD_BTLENABLE 0x0f0c
80#define AC_VERB_GET_DIGI_CONVERT_1 0x0f0d 80#define AC_VERB_GET_DIGI_CONVERT_1 0x0f0d
81#define AC_VERB_GET_DIGI_CONVERT_2 0x0f0e 81#define AC_VERB_GET_DIGI_CONVERT_2 0x0f0e /* unused */
82#define AC_VERB_GET_VOLUME_KNOB_CONTROL 0x0f0f 82#define AC_VERB_GET_VOLUME_KNOB_CONTROL 0x0f0f
83/* f10-f1a: GPIO */ 83/* f10-f1a: GPIO */
84#define AC_VERB_GET_GPIO_DATA 0x0f15 84#define AC_VERB_GET_GPIO_DATA 0x0f15
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 2177d9af5334..6e18a422d993 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -88,7 +88,7 @@ static int hda_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file,
88 88
89static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file) 89static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file)
90{ 90{
91#ifndef CONFIG_SND_DEBUG_DETECT 91#ifndef CONFIG_SND_DEBUG_VERBOSE
92 if (!capable(CAP_SYS_RAWIO)) 92 if (!capable(CAP_SYS_RAWIO))
93 return -EACCES; 93 return -EACCES;
94#endif 94#endif
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index b3a618eb42cd..16715a68ba5e 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -55,6 +55,7 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
55static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 55static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
56static char *model[SNDRV_CARDS]; 56static char *model[SNDRV_CARDS];
57static int position_fix[SNDRV_CARDS]; 57static int position_fix[SNDRV_CARDS];
58static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
58static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; 59static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
59static int single_cmd; 60static int single_cmd;
60static int enable_msi; 61static int enable_msi;
@@ -69,7 +70,9 @@ module_param_array(model, charp, NULL, 0444);
69MODULE_PARM_DESC(model, "Use the given board model."); 70MODULE_PARM_DESC(model, "Use the given board model.");
70module_param_array(position_fix, int, NULL, 0444); 71module_param_array(position_fix, int, NULL, 0444);
71MODULE_PARM_DESC(position_fix, "Fix DMA pointer " 72MODULE_PARM_DESC(position_fix, "Fix DMA pointer "
72 "(0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); 73 "(0 = auto, 1 = none, 2 = POSBUF).");
74module_param_array(bdl_pos_adj, int, NULL, 0644);
75MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
73module_param_array(probe_mask, int, NULL, 0444); 76module_param_array(probe_mask, int, NULL, 0444);
74MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); 77MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
75module_param(single_cmd, bool, 0444); 78module_param(single_cmd, bool, 0444);
@@ -197,6 +200,10 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
197#define ATIHDMI_NUM_CAPTURE 0 200#define ATIHDMI_NUM_CAPTURE 0
198#define ATIHDMI_NUM_PLAYBACK 1 201#define ATIHDMI_NUM_PLAYBACK 1
199 202
203/* TERA has 4 playback and 3 capture */
204#define TERA_NUM_CAPTURE 3
205#define TERA_NUM_PLAYBACK 4
206
200/* this number is statically defined for simplicity */ 207/* this number is statically defined for simplicity */
201#define MAX_AZX_DEV 16 208#define MAX_AZX_DEV 16
202 209
@@ -259,9 +266,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
259/* position fix mode */ 266/* position fix mode */
260enum { 267enum {
261 POS_FIX_AUTO, 268 POS_FIX_AUTO,
262 POS_FIX_NONE, 269 POS_FIX_LPIB,
263 POS_FIX_POSBUF, 270 POS_FIX_POSBUF,
264 POS_FIX_FIFO,
265}; 271};
266 272
267/* Defines for ATI HD Audio support in SB450 south bridge */ 273/* Defines for ATI HD Audio support in SB450 south bridge */
@@ -285,6 +291,7 @@ struct azx_dev {
285 u32 *posbuf; /* position buffer pointer */ 291 u32 *posbuf; /* position buffer pointer */
286 292
287 unsigned int bufsize; /* size of the play buffer in bytes */ 293 unsigned int bufsize; /* size of the play buffer in bytes */
294 unsigned int period_bytes; /* size of the period in bytes */
288 unsigned int frags; /* number for period in the play buffer */ 295 unsigned int frags; /* number for period in the play buffer */
289 unsigned int fifo_size; /* FIFO size */ 296 unsigned int fifo_size; /* FIFO size */
290 297
@@ -301,11 +308,11 @@ struct azx_dev {
301 */ 308 */
302 unsigned char stream_tag; /* assigned stream */ 309 unsigned char stream_tag; /* assigned stream */
303 unsigned char index; /* stream index */ 310 unsigned char index; /* stream index */
304 /* for sanity check of position buffer */
305 unsigned int period_intr;
306 311
307 unsigned int opened :1; 312 unsigned int opened :1;
308 unsigned int running :1; 313 unsigned int running :1;
314 unsigned int irq_pending :1;
315 unsigned int irq_ignore :1;
309}; 316};
310 317
311/* CORB/RIRB */ 318/* CORB/RIRB */
@@ -323,6 +330,7 @@ struct azx_rb {
323struct azx { 330struct azx {
324 struct snd_card *card; 331 struct snd_card *card;
325 struct pci_dev *pci; 332 struct pci_dev *pci;
333 int dev_index;
326 334
327 /* chip type specific */ 335 /* chip type specific */
328 int driver_type; 336 int driver_type;
@@ -366,9 +374,13 @@ struct azx {
366 unsigned int single_cmd :1; 374 unsigned int single_cmd :1;
367 unsigned int polling_mode :1; 375 unsigned int polling_mode :1;
368 unsigned int msi :1; 376 unsigned int msi :1;
377 unsigned int irq_pending_warned :1;
369 378
370 /* for debugging */ 379 /* for debugging */
371 unsigned int last_cmd; /* last issued command (to sync) */ 380 unsigned int last_cmd; /* last issued command (to sync) */
381
382 /* for pending irqs */
383 struct work_struct irq_pending_work;
372}; 384};
373 385
374/* driver types */ 386/* driver types */
@@ -381,6 +393,7 @@ enum {
381 AZX_DRIVER_SIS, 393 AZX_DRIVER_SIS,
382 AZX_DRIVER_ULI, 394 AZX_DRIVER_ULI,
383 AZX_DRIVER_NVIDIA, 395 AZX_DRIVER_NVIDIA,
396 AZX_DRIVER_TERA,
384}; 397};
385 398
386static char *driver_short_names[] __devinitdata = { 399static char *driver_short_names[] __devinitdata = {
@@ -392,6 +405,7 @@ static char *driver_short_names[] __devinitdata = {
392 [AZX_DRIVER_SIS] = "HDA SIS966", 405 [AZX_DRIVER_SIS] = "HDA SIS966",
393 [AZX_DRIVER_ULI] = "HDA ULI M5461", 406 [AZX_DRIVER_ULI] = "HDA ULI M5461",
394 [AZX_DRIVER_NVIDIA] = "HDA NVidia", 407 [AZX_DRIVER_NVIDIA] = "HDA NVidia",
408 [AZX_DRIVER_TERA] = "HDA Teradici",
395}; 409};
396 410
397/* 411/*
@@ -426,11 +440,6 @@ static char *driver_short_names[] __devinitdata = {
426/* for pcm support */ 440/* for pcm support */
427#define get_azx_dev(substream) (substream->runtime->private_data) 441#define get_azx_dev(substream) (substream->runtime->private_data)
428 442
429/* Get the upper 32bit of the given dma_addr_t
430 * Compiler should optimize and eliminate the code if dma_addr_t is 32bit
431 */
432#define upper_32bit(addr) (sizeof(addr) > 4 ? (u32)((addr) >> 32) : (u32)0)
433
434static int azx_acquire_irq(struct azx *chip, int do_disconnect); 443static int azx_acquire_irq(struct azx *chip, int do_disconnect);
435 444
436/* 445/*
@@ -461,7 +470,7 @@ static void azx_init_cmd_io(struct azx *chip)
461 chip->corb.addr = chip->rb.addr; 470 chip->corb.addr = chip->rb.addr;
462 chip->corb.buf = (u32 *)chip->rb.area; 471 chip->corb.buf = (u32 *)chip->rb.area;
463 azx_writel(chip, CORBLBASE, (u32)chip->corb.addr); 472 azx_writel(chip, CORBLBASE, (u32)chip->corb.addr);
464 azx_writel(chip, CORBUBASE, upper_32bit(chip->corb.addr)); 473 azx_writel(chip, CORBUBASE, upper_32_bits(chip->corb.addr));
465 474
466 /* set the corb size to 256 entries (ULI requires explicitly) */ 475 /* set the corb size to 256 entries (ULI requires explicitly) */
467 azx_writeb(chip, CORBSIZE, 0x02); 476 azx_writeb(chip, CORBSIZE, 0x02);
@@ -476,7 +485,7 @@ static void azx_init_cmd_io(struct azx *chip)
476 chip->rirb.addr = chip->rb.addr + 2048; 485 chip->rirb.addr = chip->rb.addr + 2048;
477 chip->rirb.buf = (u32 *)(chip->rb.area + 2048); 486 chip->rirb.buf = (u32 *)(chip->rb.area + 2048);
478 azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr); 487 azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr);
479 azx_writel(chip, RIRBUBASE, upper_32bit(chip->rirb.addr)); 488 azx_writel(chip, RIRBUBASE, upper_32_bits(chip->rirb.addr));
480 489
481 /* set the rirb size to 256 entries (ULI requires explicitly) */ 490 /* set the rirb size to 256 entries (ULI requires explicitly) */
482 azx_writeb(chip, RIRBSIZE, 0x02); 491 azx_writeb(chip, RIRBSIZE, 0x02);
@@ -847,7 +856,7 @@ static void azx_init_chip(struct azx *chip)
847 856
848 /* program the position buffer */ 857 /* program the position buffer */
849 azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); 858 azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
850 azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr)); 859 azx_writel(chip, DPUBASE, upper_32_bits(chip->posbuf.addr));
851 860
852 chip->initialized = 1; 861 chip->initialized = 1;
853} 862}
@@ -908,6 +917,8 @@ static void azx_init_pci(struct azx *chip)
908} 917}
909 918
910 919
920static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);
921
911/* 922/*
912 * interrupt handler 923 * interrupt handler
913 */ 924 */
@@ -930,11 +941,23 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
930 azx_dev = &chip->azx_dev[i]; 941 azx_dev = &chip->azx_dev[i];
931 if (status & azx_dev->sd_int_sta_mask) { 942 if (status & azx_dev->sd_int_sta_mask) {
932 azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); 943 azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
933 if (azx_dev->substream && azx_dev->running) { 944 if (!azx_dev->substream || !azx_dev->running)
934 azx_dev->period_intr++; 945 continue;
946 /* ignore the first dummy IRQ (due to pos_adj) */
947 if (azx_dev->irq_ignore) {
948 azx_dev->irq_ignore = 0;
949 continue;
950 }
951 /* check whether this IRQ is really acceptable */
952 if (azx_position_ok(chip, azx_dev)) {
953 azx_dev->irq_pending = 0;
935 spin_unlock(&chip->reg_lock); 954 spin_unlock(&chip->reg_lock);
936 snd_pcm_period_elapsed(azx_dev->substream); 955 snd_pcm_period_elapsed(azx_dev->substream);
937 spin_lock(&chip->reg_lock); 956 spin_lock(&chip->reg_lock);
957 } else {
958 /* bogus IRQ, process it later */
959 azx_dev->irq_pending = 1;
960 schedule_work(&chip->irq_pending_work);
938 } 961 }
939 } 962 }
940 } 963 }
@@ -959,59 +982,107 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
959 982
960 983
961/* 984/*
985 * set up a BDL entry
986 */
987static int setup_bdle(struct snd_pcm_substream *substream,
988 struct azx_dev *azx_dev, u32 **bdlp,
989 int ofs, int size, int with_ioc)
990{
991 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
992 u32 *bdl = *bdlp;
993
994 while (size > 0) {
995 dma_addr_t addr;
996 int chunk;
997
998 if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES)
999 return -EINVAL;
1000
1001 addr = snd_pcm_sgbuf_get_addr(sgbuf, ofs);
1002 /* program the address field of the BDL entry */
1003 bdl[0] = cpu_to_le32((u32)addr);
1004 bdl[1] = cpu_to_le32(upper_32_bits(addr));
1005 /* program the size field of the BDL entry */
1006 chunk = PAGE_SIZE - (ofs % PAGE_SIZE);
1007 if (size < chunk)
1008 chunk = size;
1009 bdl[2] = cpu_to_le32(chunk);
1010 /* program the IOC to enable interrupt
1011 * only when the whole fragment is processed
1012 */
1013 size -= chunk;
1014 bdl[3] = (size || !with_ioc) ? 0 : cpu_to_le32(0x01);
1015 bdl += 4;
1016 azx_dev->frags++;
1017 ofs += chunk;
1018 }
1019 *bdlp = bdl;
1020 return ofs;
1021}
1022
1023/*
962 * set up BDL entries 1024 * set up BDL entries
963 */ 1025 */
964static int azx_setup_periods(struct snd_pcm_substream *substream, 1026static int azx_setup_periods(struct azx *chip,
1027 struct snd_pcm_substream *substream,
965 struct azx_dev *azx_dev) 1028 struct azx_dev *azx_dev)
966{ 1029{
967 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
968 u32 *bdl; 1030 u32 *bdl;
969 int i, ofs, periods, period_bytes; 1031 int i, ofs, periods, period_bytes;
1032 int pos_adj;
970 1033
971 /* reset BDL address */ 1034 /* reset BDL address */
972 azx_sd_writel(azx_dev, SD_BDLPL, 0); 1035 azx_sd_writel(azx_dev, SD_BDLPL, 0);
973 azx_sd_writel(azx_dev, SD_BDLPU, 0); 1036 azx_sd_writel(azx_dev, SD_BDLPU, 0);
974 1037
975 period_bytes = snd_pcm_lib_period_bytes(substream); 1038 period_bytes = snd_pcm_lib_period_bytes(substream);
1039 azx_dev->period_bytes = period_bytes;
976 periods = azx_dev->bufsize / period_bytes; 1040 periods = azx_dev->bufsize / period_bytes;
977 1041
978 /* program the initial BDL entries */ 1042 /* program the initial BDL entries */
979 bdl = (u32 *)azx_dev->bdl.area; 1043 bdl = (u32 *)azx_dev->bdl.area;
980 ofs = 0; 1044 ofs = 0;
981 azx_dev->frags = 0; 1045 azx_dev->frags = 0;
982 for (i = 0; i < periods; i++) { 1046 azx_dev->irq_ignore = 0;
983 int size, rest; 1047 pos_adj = bdl_pos_adj[chip->dev_index];
984 if (i >= AZX_MAX_BDL_ENTRIES) { 1048 if (pos_adj > 0) {
985 snd_printk(KERN_ERR "Too many BDL entries: " 1049 struct snd_pcm_runtime *runtime = substream->runtime;
986 "buffer=%d, period=%d\n", 1050 pos_adj = (pos_adj * runtime->rate + 47999) / 48000;
987 azx_dev->bufsize, period_bytes); 1051 if (!pos_adj)
988 /* reset */ 1052 pos_adj = 1;
989 azx_sd_writel(azx_dev, SD_BDLPL, 0); 1053 pos_adj = frames_to_bytes(runtime, pos_adj);
990 azx_sd_writel(azx_dev, SD_BDLPU, 0); 1054 if (pos_adj >= period_bytes) {
991 return -EINVAL; 1055 snd_printk(KERN_WARNING "Too big adjustment %d\n",
1056 bdl_pos_adj[chip->dev_index]);
1057 pos_adj = 0;
1058 } else {
1059 ofs = setup_bdle(substream, azx_dev,
1060 &bdl, ofs, pos_adj, 1);
1061 if (ofs < 0)
1062 goto error;
1063 azx_dev->irq_ignore = 1;
992 } 1064 }
993 rest = period_bytes; 1065 } else
994 do { 1066 pos_adj = 0;
995 dma_addr_t addr = snd_pcm_sgbuf_get_addr(sgbuf, ofs); 1067 for (i = 0; i < periods; i++) {
996 /* program the address field of the BDL entry */ 1068 if (i == periods - 1 && pos_adj)
997 bdl[0] = cpu_to_le32((u32)addr); 1069 ofs = setup_bdle(substream, azx_dev, &bdl, ofs,
998 bdl[1] = cpu_to_le32(upper_32bit(addr)); 1070 period_bytes - pos_adj, 0);
999 /* program the size field of the BDL entry */ 1071 else
1000 size = PAGE_SIZE - (ofs % PAGE_SIZE); 1072 ofs = setup_bdle(substream, azx_dev, &bdl, ofs,
1001 if (rest < size) 1073 period_bytes, 1);
1002 size = rest; 1074 if (ofs < 0)
1003 bdl[2] = cpu_to_le32(size); 1075 goto error;
1004 /* program the IOC to enable interrupt
1005 * only when the whole fragment is processed
1006 */
1007 rest -= size;
1008 bdl[3] = rest ? 0 : cpu_to_le32(0x01);
1009 bdl += 4;
1010 azx_dev->frags++;
1011 ofs += size;
1012 } while (rest > 0);
1013 } 1076 }
1014 return 0; 1077 return 0;
1078
1079 error:
1080 snd_printk(KERN_ERR "Too many BDL entries: buffer=%d, period=%d\n",
1081 azx_dev->bufsize, period_bytes);
1082 /* reset */
1083 azx_sd_writel(azx_dev, SD_BDLPL, 0);
1084 azx_sd_writel(azx_dev, SD_BDLPU, 0);
1085 return -EINVAL;
1015} 1086}
1016 1087
1017/* 1088/*
@@ -1062,7 +1133,7 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
1062 /* lower BDL address */ 1133 /* lower BDL address */
1063 azx_sd_writel(azx_dev, SD_BDLPL, (u32)azx_dev->bdl.addr); 1134 azx_sd_writel(azx_dev, SD_BDLPL, (u32)azx_dev->bdl.addr);
1064 /* upper BDL address */ 1135 /* upper BDL address */
1065 azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl.addr)); 1136 azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr));
1066 1137
1067 /* enable the position buffer */ 1138 /* enable the position buffer */
1068 if (chip->position_fix == POS_FIX_POSBUF || 1139 if (chip->position_fix == POS_FIX_POSBUF ||
@@ -1085,7 +1156,7 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
1085 */ 1156 */
1086 1157
1087static unsigned int azx_max_codecs[] __devinitdata = { 1158static unsigned int azx_max_codecs[] __devinitdata = {
1088 [AZX_DRIVER_ICH] = 3, 1159 [AZX_DRIVER_ICH] = 4, /* Some ICH9 boards use SD3 */
1089 [AZX_DRIVER_SCH] = 3, 1160 [AZX_DRIVER_SCH] = 3,
1090 [AZX_DRIVER_ATI] = 4, 1161 [AZX_DRIVER_ATI] = 4,
1091 [AZX_DRIVER_ATIHDMI] = 4, 1162 [AZX_DRIVER_ATIHDMI] = 4,
@@ -1093,6 +1164,7 @@ static unsigned int azx_max_codecs[] __devinitdata = {
1093 [AZX_DRIVER_SIS] = 3, /* FIXME: correct? */ 1164 [AZX_DRIVER_SIS] = 3, /* FIXME: correct? */
1094 [AZX_DRIVER_ULI] = 3, /* FIXME: correct? */ 1165 [AZX_DRIVER_ULI] = 3, /* FIXME: correct? */
1095 [AZX_DRIVER_NVIDIA] = 3, /* FIXME: correct? */ 1166 [AZX_DRIVER_NVIDIA] = 3, /* FIXME: correct? */
1167 [AZX_DRIVER_TERA] = 1,
1096}; 1168};
1097 1169
1098static int __devinit azx_codec_create(struct azx *chip, const char *model, 1170static int __devinit azx_codec_create(struct azx *chip, const char *model,
@@ -1316,7 +1388,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
1316 1388
1317 snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n", 1389 snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
1318 azx_dev->bufsize, azx_dev->format_val); 1390 azx_dev->bufsize, azx_dev->format_val);
1319 if (azx_setup_periods(substream, azx_dev) < 0) 1391 if (azx_setup_periods(chip, substream, azx_dev) < 0)
1320 return -EINVAL; 1392 return -EINVAL;
1321 azx_setup_controller(chip, azx_dev); 1393 azx_setup_controller(chip, azx_dev);
1322 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1394 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -1421,35 +1493,113 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1421 return 0; 1493 return 0;
1422} 1494}
1423 1495
1424static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) 1496static unsigned int azx_get_position(struct azx *chip,
1497 struct azx_dev *azx_dev)
1425{ 1498{
1426 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
1427 struct azx *chip = apcm->chip;
1428 struct azx_dev *azx_dev = get_azx_dev(substream);
1429 unsigned int pos; 1499 unsigned int pos;
1430 1500
1431 if (chip->position_fix == POS_FIX_POSBUF || 1501 if (chip->position_fix == POS_FIX_POSBUF ||
1432 chip->position_fix == POS_FIX_AUTO) { 1502 chip->position_fix == POS_FIX_AUTO) {
1433 /* use the position buffer */ 1503 /* use the position buffer */
1434 pos = le32_to_cpu(*azx_dev->posbuf); 1504 pos = le32_to_cpu(*azx_dev->posbuf);
1435 if (chip->position_fix == POS_FIX_AUTO &&
1436 azx_dev->period_intr == 1 && !pos) {
1437 printk(KERN_WARNING
1438 "hda-intel: Invalid position buffer, "
1439 "using LPIB read method instead.\n");
1440 chip->position_fix = POS_FIX_NONE;
1441 goto read_lpib;
1442 }
1443 } else { 1505 } else {
1444 read_lpib:
1445 /* read LPIB */ 1506 /* read LPIB */
1446 pos = azx_sd_readl(azx_dev, SD_LPIB); 1507 pos = azx_sd_readl(azx_dev, SD_LPIB);
1447 if (chip->position_fix == POS_FIX_FIFO)
1448 pos += azx_dev->fifo_size;
1449 } 1508 }
1450 if (pos >= azx_dev->bufsize) 1509 if (pos >= azx_dev->bufsize)
1451 pos = 0; 1510 pos = 0;
1452 return bytes_to_frames(substream->runtime, pos); 1511 return pos;
1512}
1513
1514static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
1515{
1516 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
1517 struct azx *chip = apcm->chip;
1518 struct azx_dev *azx_dev = get_azx_dev(substream);
1519 return bytes_to_frames(substream->runtime,
1520 azx_get_position(chip, azx_dev));
1521}
1522
1523/*
1524 * Check whether the current DMA position is acceptable for updating
1525 * periods. Returns non-zero if it's OK.
1526 *
1527 * Many HD-audio controllers appear pretty inaccurate about
1528 * the update-IRQ timing. The IRQ is issued before actually the
1529 * data is processed. So, we need to process it afterwords in a
1530 * workqueue.
1531 */
1532static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
1533{
1534 unsigned int pos;
1535
1536 pos = azx_get_position(chip, azx_dev);
1537 if (chip->position_fix == POS_FIX_AUTO) {
1538 if (!pos) {
1539 printk(KERN_WARNING
1540 "hda-intel: Invalid position buffer, "
1541 "using LPIB read method instead.\n");
1542 chip->position_fix = POS_FIX_LPIB;
1543 pos = azx_get_position(chip, azx_dev);
1544 } else
1545 chip->position_fix = POS_FIX_POSBUF;
1546 }
1547
1548 if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
1549 return 0; /* NG - it's below the period boundary */
1550 return 1; /* OK, it's fine */
1551}
1552
1553/*
1554 * The work for pending PCM period updates.
1555 */
1556static void azx_irq_pending_work(struct work_struct *work)
1557{
1558 struct azx *chip = container_of(work, struct azx, irq_pending_work);
1559 int i, pending;
1560
1561 if (!chip->irq_pending_warned) {
1562 printk(KERN_WARNING
1563 "hda-intel: IRQ timing workaround is activated "
1564 "for card #%d. Suggest a bigger bdl_pos_adj.\n",
1565 chip->card->number);
1566 chip->irq_pending_warned = 1;
1567 }
1568
1569 for (;;) {
1570 pending = 0;
1571 spin_lock_irq(&chip->reg_lock);
1572 for (i = 0; i < chip->num_streams; i++) {
1573 struct azx_dev *azx_dev = &chip->azx_dev[i];
1574 if (!azx_dev->irq_pending ||
1575 !azx_dev->substream ||
1576 !azx_dev->running)
1577 continue;
1578 if (azx_position_ok(chip, azx_dev)) {
1579 azx_dev->irq_pending = 0;
1580 spin_unlock(&chip->reg_lock);
1581 snd_pcm_period_elapsed(azx_dev->substream);
1582 spin_lock(&chip->reg_lock);
1583 } else
1584 pending++;
1585 }
1586 spin_unlock_irq(&chip->reg_lock);
1587 if (!pending)
1588 return;
1589 cond_resched();
1590 }
1591}
1592
1593/* clear irq_pending flags and assure no on-going workq */
1594static void azx_clear_irq_pending(struct azx *chip)
1595{
1596 int i;
1597
1598 spin_lock_irq(&chip->reg_lock);
1599 for (i = 0; i < chip->num_streams; i++)
1600 chip->azx_dev[i].irq_pending = 0;
1601 spin_unlock_irq(&chip->reg_lock);
1602 flush_scheduled_work();
1453} 1603}
1454 1604
1455static struct snd_pcm_ops azx_pcm_ops = { 1605static struct snd_pcm_ops azx_pcm_ops = {
@@ -1676,6 +1826,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
1676 int i; 1826 int i;
1677 1827
1678 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 1828 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1829 azx_clear_irq_pending(chip);
1679 for (i = 0; i < AZX_MAX_PCMS; i++) 1830 for (i = 0; i < AZX_MAX_PCMS; i++)
1680 snd_pcm_suspend_all(chip->pcm[i]); 1831 snd_pcm_suspend_all(chip->pcm[i]);
1681 if (chip->initialized) 1832 if (chip->initialized)
@@ -1732,6 +1883,7 @@ static int azx_free(struct azx *chip)
1732 int i; 1883 int i;
1733 1884
1734 if (chip->initialized) { 1885 if (chip->initialized) {
1886 azx_clear_irq_pending(chip);
1735 for (i = 0; i < chip->num_streams; i++) 1887 for (i = 0; i < chip->num_streams; i++)
1736 azx_stream_stop(chip, &chip->azx_dev[i]); 1888 azx_stream_stop(chip, &chip->azx_dev[i]);
1737 azx_stop_chip(chip); 1889 azx_stop_chip(chip);
@@ -1770,9 +1922,9 @@ static int azx_dev_free(struct snd_device *device)
1770 * white/black-listing for position_fix 1922 * white/black-listing for position_fix
1771 */ 1923 */
1772static struct snd_pci_quirk position_fix_list[] __devinitdata = { 1924static struct snd_pci_quirk position_fix_list[] __devinitdata = {
1773 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE), 1925 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
1774 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_NONE), 1926 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
1775 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_NONE), 1927 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
1776 {} 1928 {}
1777}; 1929};
1778 1930
@@ -1857,12 +2009,25 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
1857 chip->irq = -1; 2009 chip->irq = -1;
1858 chip->driver_type = driver_type; 2010 chip->driver_type = driver_type;
1859 chip->msi = enable_msi; 2011 chip->msi = enable_msi;
2012 chip->dev_index = dev;
2013 INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
1860 2014
1861 chip->position_fix = check_position_fix(chip, position_fix[dev]); 2015 chip->position_fix = check_position_fix(chip, position_fix[dev]);
1862 check_probe_mask(chip, dev); 2016 check_probe_mask(chip, dev);
1863 2017
1864 chip->single_cmd = single_cmd; 2018 chip->single_cmd = single_cmd;
1865 2019
2020 if (bdl_pos_adj[dev] < 0) {
2021 switch (chip->driver_type) {
2022 case AZX_DRIVER_ICH:
2023 bdl_pos_adj[dev] = 1;
2024 break;
2025 default:
2026 bdl_pos_adj[dev] = 32;
2027 break;
2028 }
2029 }
2030
1866#if BITS_PER_LONG != 64 2031#if BITS_PER_LONG != 64
1867 /* Fix up base address on ULI M5461 */ 2032 /* Fix up base address on ULI M5461 */
1868 if (chip->driver_type == AZX_DRIVER_ULI) { 2033 if (chip->driver_type == AZX_DRIVER_ULI) {
@@ -2089,6 +2254,7 @@ static struct pci_device_id azx_ids[] = {
2089 { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH }, 2254 { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH },
2090 { PCI_DEVICE(0x8086, 0x269a), .driver_data = AZX_DRIVER_ICH }, 2255 { PCI_DEVICE(0x8086, 0x269a), .driver_data = AZX_DRIVER_ICH },
2091 { PCI_DEVICE(0x8086, 0x284b), .driver_data = AZX_DRIVER_ICH }, 2256 { PCI_DEVICE(0x8086, 0x284b), .driver_data = AZX_DRIVER_ICH },
2257 { PCI_DEVICE(0x8086, 0x2911), .driver_data = AZX_DRIVER_ICH },
2092 { PCI_DEVICE(0x8086, 0x293e), .driver_data = AZX_DRIVER_ICH }, 2258 { PCI_DEVICE(0x8086, 0x293e), .driver_data = AZX_DRIVER_ICH },
2093 { PCI_DEVICE(0x8086, 0x293f), .driver_data = AZX_DRIVER_ICH }, 2259 { PCI_DEVICE(0x8086, 0x293f), .driver_data = AZX_DRIVER_ICH },
2094 { PCI_DEVICE(0x8086, 0x3a3e), .driver_data = AZX_DRIVER_ICH }, 2260 { PCI_DEVICE(0x8086, 0x3a3e), .driver_data = AZX_DRIVER_ICH },
@@ -2141,6 +2307,8 @@ static struct pci_device_id azx_ids[] = {
2141 { PCI_DEVICE(0x10de, 0x0bd5), .driver_data = AZX_DRIVER_NVIDIA }, 2307 { PCI_DEVICE(0x10de, 0x0bd5), .driver_data = AZX_DRIVER_NVIDIA },
2142 { PCI_DEVICE(0x10de, 0x0bd6), .driver_data = AZX_DRIVER_NVIDIA }, 2308 { PCI_DEVICE(0x10de, 0x0bd6), .driver_data = AZX_DRIVER_NVIDIA },
2143 { PCI_DEVICE(0x10de, 0x0bd7), .driver_data = AZX_DRIVER_NVIDIA }, 2309 { PCI_DEVICE(0x10de, 0x0bd7), .driver_data = AZX_DRIVER_NVIDIA },
2310 /* Teradici */
2311 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
2144 { 0, } 2312 { 0, }
2145}; 2313};
2146MODULE_DEVICE_TABLE(pci, azx_ids); 2314MODULE_DEVICE_TABLE(pci, azx_ids);
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 5633f77f8f3b..1e5aff5c48d1 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -366,8 +366,6 @@ static void print_digital_conv(struct snd_info_buffer *buffer,
366{ 366{
367 unsigned int digi1 = snd_hda_codec_read(codec, nid, 0, 367 unsigned int digi1 = snd_hda_codec_read(codec, nid, 0,
368 AC_VERB_GET_DIGI_CONVERT_1, 0); 368 AC_VERB_GET_DIGI_CONVERT_1, 0);
369 unsigned int digi2 = snd_hda_codec_read(codec, nid, 0,
370 AC_VERB_GET_DIGI_CONVERT_2, 0);
371 snd_iprintf(buffer, " Digital:"); 369 snd_iprintf(buffer, " Digital:");
372 if (digi1 & AC_DIG1_ENABLE) 370 if (digi1 & AC_DIG1_ENABLE)
373 snd_iprintf(buffer, " Enabled"); 371 snd_iprintf(buffer, " Enabled");
@@ -386,7 +384,8 @@ static void print_digital_conv(struct snd_info_buffer *buffer,
386 if (digi1 & AC_DIG1_LEVEL) 384 if (digi1 & AC_DIG1_LEVEL)
387 snd_iprintf(buffer, " GenLevel"); 385 snd_iprintf(buffer, " GenLevel");
388 snd_iprintf(buffer, "\n"); 386 snd_iprintf(buffer, "\n");
389 snd_iprintf(buffer, " Digital category: 0x%x\n", digi2 & AC_DIG2_CC); 387 snd_iprintf(buffer, " Digital category: 0x%x\n",
388 (digi1 >> 8) & AC_DIG2_CC);
390} 389}
391 390
392static const char *get_pwr_state(u32 state) 391static const char *get_pwr_state(u32 state)
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index a99e86d74278..e8003d99f0bf 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -23,7 +23,6 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/mutex.h>
27 26
28#include <sound/core.h> 27#include <sound/core.h>
29#include "hda_codec.h" 28#include "hda_codec.h"
@@ -64,7 +63,6 @@ struct ad198x_spec {
64 /* PCM information */ 63 /* PCM information */
65 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 64 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
66 65
67 struct mutex amp_mutex; /* PCM volume/mute control mutex */
68 unsigned int spdif_route; 66 unsigned int spdif_route;
69 67
70 /* dynamic controls, init_verbs and input_mux */ 68 /* dynamic controls, init_verbs and input_mux */
@@ -1618,6 +1616,7 @@ static const char *ad1981_models[AD1981_MODELS] = {
1618 1616
1619static struct snd_pci_quirk ad1981_cfg_tbl[] = { 1617static struct snd_pci_quirk ad1981_cfg_tbl[] = {
1620 SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), 1618 SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
1619 SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
1621 /* All HP models */ 1620 /* All HP models */
1622 SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP), 1621 SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP),
1623 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA), 1622 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
@@ -2623,7 +2622,7 @@ static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2623{ 2622{
2624 struct ad198x_spec *spec = codec->spec; 2623 struct ad198x_spec *spec = codec->spec;
2625 hda_nid_t nid; 2624 hda_nid_t nid;
2626 int idx, err; 2625 int i, idx, err;
2627 char name[32]; 2626 char name[32];
2628 2627
2629 if (! pin) 2628 if (! pin)
@@ -2631,16 +2630,26 @@ static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2631 2630
2632 idx = ad1988_pin_idx(pin); 2631 idx = ad1988_pin_idx(pin);
2633 nid = ad1988_idx_to_dac(codec, idx); 2632 nid = ad1988_idx_to_dac(codec, idx);
2634 /* specify the DAC as the extra output */ 2633 /* check whether the corresponding DAC was already taken */
2635 if (! spec->multiout.hp_nid) 2634 for (i = 0; i < spec->autocfg.line_outs; i++) {
2636 spec->multiout.hp_nid = nid; 2635 hda_nid_t pin = spec->autocfg.line_out_pins[i];
2637 else 2636 hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin));
2638 spec->multiout.extra_out_nid[0] = nid; 2637 if (dac == nid)
2639 /* control HP volume/switch on the output mixer amp */ 2638 break;
2640 sprintf(name, "%s Playback Volume", pfx); 2639 }
2641 if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name, 2640 if (i >= spec->autocfg.line_outs) {
2642 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) 2641 /* specify the DAC as the extra output */
2643 return err; 2642 if (!spec->multiout.hp_nid)
2643 spec->multiout.hp_nid = nid;
2644 else
2645 spec->multiout.extra_out_nid[0] = nid;
2646 /* control HP volume/switch on the output mixer amp */
2647 sprintf(name, "%s Playback Volume", pfx);
2648 err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2649 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
2650 if (err < 0)
2651 return err;
2652 }
2644 nid = ad1988_mixer_nids[idx]; 2653 nid = ad1988_mixer_nids[idx];
2645 sprintf(name, "%s Playback Switch", pfx); 2654 sprintf(name, "%s Playback Switch", pfx);
2646 if ((err = add_control(spec, AD_CTL_BIND_MUTE, name, 2655 if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
@@ -3177,7 +3186,6 @@ static int patch_ad1884(struct hda_codec *codec)
3177 if (spec == NULL) 3186 if (spec == NULL)
3178 return -ENOMEM; 3187 return -ENOMEM;
3179 3188
3180 mutex_init(&spec->amp_mutex);
3181 codec->spec = spec; 3189 codec->spec = spec;
3182 3190
3183 spec->multiout.max_channels = 2; 3191 spec->multiout.max_channels = 2;
@@ -3847,7 +3855,6 @@ static int patch_ad1884a(struct hda_codec *codec)
3847 if (spec == NULL) 3855 if (spec == NULL)
3848 return -ENOMEM; 3856 return -ENOMEM;
3849 3857
3850 mutex_init(&spec->amp_mutex);
3851 codec->spec = spec; 3858 codec->spec = spec;
3852 3859
3853 spec->multiout.max_channels = 2; 3860 spec->multiout.max_channels = 2;
@@ -4152,7 +4159,6 @@ static int patch_ad1882(struct hda_codec *codec)
4152 if (spec == NULL) 4159 if (spec == NULL)
4153 return -ENOMEM; 4160 return -ENOMEM;
4154 4161
4155 mutex_init(&spec->amp_mutex);
4156 codec->spec = spec; 4162 codec->spec = spec;
4157 4163
4158 spec->multiout.max_channels = 6; 4164 spec->multiout.max_channels = 6;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 36fd85260035..7c1eb23f0cec 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -82,7 +82,6 @@ struct conexant_spec {
82 /* PCM information */ 82 /* PCM information */
83 struct hda_pcm pcm_rec[2]; /* used in build_pcms() */ 83 struct hda_pcm pcm_rec[2]; /* used in build_pcms() */
84 84
85 struct mutex amp_mutex; /* PCM volume/mute control mutex */
86 unsigned int spdif_route; 85 unsigned int spdif_route;
87 86
88 /* dynamic controls, init_verbs and input_mux */ 87 /* dynamic controls, init_verbs and input_mux */
@@ -687,7 +686,7 @@ static struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
687 686
688static struct hda_verb cxt5045_init_verbs[] = { 687static struct hda_verb cxt5045_init_verbs[] = {
689 /* Line in, Mic */ 688 /* Line in, Mic */
690 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 689 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
691 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 690 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
692 /* HP, Amp */ 691 /* HP, Amp */
693 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 692 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -907,10 +906,12 @@ static struct snd_pci_quirk cxt5045_cfg_tbl[] = {
907 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV9533EG", CXT5045_LAPTOP_HPSENSE), 906 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV9533EG", CXT5045_LAPTOP_HPSENSE),
908 SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530), 907 SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
909 SND_PCI_QUIRK(0x103c, 0x30d9, "HP Spartan", CXT5045_LAPTOP_HPSENSE), 908 SND_PCI_QUIRK(0x103c, 0x30d9, "HP Spartan", CXT5045_LAPTOP_HPSENSE),
909 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
910 SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ), 910 SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
911 SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE), 911 SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
912 SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE), 912 SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE),
913 SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505", CXT5045_LAPTOP_HPSENSE), 913 SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505",
914 CXT5045_LAPTOP_HPMICSENSE),
914 SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE), 915 SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE),
915 SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE), 916 SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE),
916 SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE), 917 SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE),
@@ -928,7 +929,6 @@ static int patch_cxt5045(struct hda_codec *codec)
928 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 929 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
929 if (!spec) 930 if (!spec)
930 return -ENOMEM; 931 return -ENOMEM;
931 mutex_init(&spec->amp_mutex);
932 codec->spec = spec; 932 codec->spec = spec;
933 933
934 spec->multiout.max_channels = 2; 934 spec->multiout.max_channels = 2;
@@ -963,6 +963,7 @@ static int patch_cxt5045(struct hda_codec *codec)
963 codec->patch_ops.init = cxt5045_init; 963 codec->patch_ops.init = cxt5045_init;
964 break; 964 break;
965 case CXT5045_LAPTOP_MICSENSE: 965 case CXT5045_LAPTOP_MICSENSE:
966 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
966 spec->input_mux = &cxt5045_capture_source; 967 spec->input_mux = &cxt5045_capture_source;
967 spec->num_init_verbs = 2; 968 spec->num_init_verbs = 2;
968 spec->init_verbs[1] = cxt5045_mic_sense_init_verbs; 969 spec->init_verbs[1] = cxt5045_mic_sense_init_verbs;
@@ -1007,15 +1008,19 @@ static int patch_cxt5045(struct hda_codec *codec)
1007#endif 1008#endif
1008 } 1009 }
1009 1010
1010 /* 1011 switch (codec->subsystem_id >> 16) {
1011 * Fix max PCM level to 0 dB 1012 case 0x103c:
1012 * (originall it has 0x2b steps with 0dB offset 0x14) 1013 /* HP laptop has a really bad sound over 0dB on NID 0x17.
1013 */ 1014 * Fix max PCM level to 0 dB
1014 snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, 1015 * (originall it has 0x2b steps with 0dB offset 0x14)
1015 (0x14 << AC_AMPCAP_OFFSET_SHIFT) | 1016 */
1016 (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) | 1017 snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
1017 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | 1018 (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
1018 (1 << AC_AMPCAP_MUTE_SHIFT)); 1019 (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1020 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1021 (1 << AC_AMPCAP_MUTE_SHIFT));
1022 break;
1023 }
1019 1024
1020 return 0; 1025 return 0;
1021} 1026}
@@ -1477,7 +1482,6 @@ static int patch_cxt5047(struct hda_codec *codec)
1477 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1482 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1478 if (!spec) 1483 if (!spec)
1479 return -ENOMEM; 1484 return -ENOMEM;
1480 mutex_init(&spec->amp_mutex);
1481 codec->spec = spec; 1485 codec->spec = spec;
1482 1486
1483 spec->multiout.max_channels = 2; 1487 spec->multiout.max_channels = 2;
@@ -1736,7 +1740,6 @@ static int patch_cxt5051(struct hda_codec *codec)
1736 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1740 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1737 if (!spec) 1741 if (!spec)
1738 return -ENOMEM; 1742 return -ENOMEM;
1739 mutex_init(&spec->amp_mutex);
1740 codec->spec = spec; 1743 codec->spec = spec;
1741 1744
1742 codec->patch_ops = conexant_patch_ops; 1745 codec->patch_ops = conexant_patch_ops;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index b0a2a262ece2..2807bc840d26 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -163,6 +163,10 @@ enum {
163 ALC662_LENOVO_101E, 163 ALC662_LENOVO_101E,
164 ALC662_ASUS_EEEPC_P701, 164 ALC662_ASUS_EEEPC_P701,
165 ALC662_ASUS_EEEPC_EP20, 165 ALC662_ASUS_EEEPC_EP20,
166 ALC663_ASUS_M51VA,
167 ALC663_ASUS_G71V,
168 ALC663_ASUS_H13,
169 ALC663_ASUS_G50V,
166 ALC662_AUTO, 170 ALC662_AUTO,
167 ALC662_MODEL_LAST, 171 ALC662_MODEL_LAST,
168}; 172};
@@ -205,6 +209,7 @@ enum {
205 ALC883_MITAC, 209 ALC883_MITAC,
206 ALC883_CLEVO_M720, 210 ALC883_CLEVO_M720,
207 ALC883_FUJITSU_PI2515, 211 ALC883_FUJITSU_PI2515,
212 ALC883_3ST_6ch_INTEL,
208 ALC883_AUTO, 213 ALC883_AUTO,
209 ALC883_MODEL_LAST, 214 ALC883_MODEL_LAST,
210}; 215};
@@ -280,6 +285,10 @@ struct alc_spec {
280#ifdef CONFIG_SND_HDA_POWER_SAVE 285#ifdef CONFIG_SND_HDA_POWER_SAVE
281 struct hda_loopback_check loopback; 286 struct hda_loopback_check loopback;
282#endif 287#endif
288
289 /* for PLL fix */
290 hda_nid_t pll_nid;
291 unsigned int pll_coef_idx, pll_coef_bit;
283}; 292};
284 293
285/* 294/*
@@ -747,6 +756,38 @@ static struct hda_verb alc_gpio3_init_verbs[] = {
747 { } 756 { }
748}; 757};
749 758
759/*
760 * Fix hardware PLL issue
761 * On some codecs, the analog PLL gating control must be off while
762 * the default value is 1.
763 */
764static void alc_fix_pll(struct hda_codec *codec)
765{
766 struct alc_spec *spec = codec->spec;
767 unsigned int val;
768
769 if (!spec->pll_nid)
770 return;
771 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
772 spec->pll_coef_idx);
773 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
774 AC_VERB_GET_PROC_COEF, 0);
775 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
776 spec->pll_coef_idx);
777 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
778 val & ~(1 << spec->pll_coef_bit));
779}
780
781static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
782 unsigned int coef_idx, unsigned int coef_bit)
783{
784 struct alc_spec *spec = codec->spec;
785 spec->pll_nid = nid;
786 spec->pll_coef_idx = coef_idx;
787 spec->pll_coef_bit = coef_bit;
788 alc_fix_pll(codec);
789}
790
750static void alc_sku_automute(struct hda_codec *codec) 791static void alc_sku_automute(struct hda_codec *codec)
751{ 792{
752 struct alc_spec *spec = codec->spec; 793 struct alc_spec *spec = codec->spec;
@@ -776,6 +817,24 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
776 alc_sku_automute(codec); 817 alc_sku_automute(codec);
777} 818}
778 819
820/* additional initialization for ALC888 variants */
821static void alc888_coef_init(struct hda_codec *codec)
822{
823 unsigned int tmp;
824
825 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
826 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
827 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
828 if ((tmp & 0xf0) == 2)
829 /* alc888S-VC */
830 snd_hda_codec_read(codec, 0x20, 0,
831 AC_VERB_SET_PROC_COEF, 0x830);
832 else
833 /* alc888-VB */
834 snd_hda_codec_read(codec, 0x20, 0,
835 AC_VERB_SET_PROC_COEF, 0x3030);
836}
837
779/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 838/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
780 * 31 ~ 16 : Manufacture ID 839 * 31 ~ 16 : Manufacture ID
781 * 15 ~ 8 : SKU ID 840 * 15 ~ 8 : SKU ID
@@ -851,8 +910,10 @@ do_sku:
851 case 0x10ec0267: 910 case 0x10ec0267:
852 case 0x10ec0268: 911 case 0x10ec0268:
853 case 0x10ec0269: 912 case 0x10ec0269:
913 case 0x10ec0660:
914 case 0x10ec0662:
915 case 0x10ec0663:
854 case 0x10ec0862: 916 case 0x10ec0862:
855 case 0x10ec0662:
856 case 0x10ec0889: 917 case 0x10ec0889:
857 snd_hda_codec_write(codec, 0x14, 0, 918 snd_hda_codec_write(codec, 0x14, 0,
858 AC_VERB_SET_EAPD_BTLENABLE, 2); 919 AC_VERB_SET_EAPD_BTLENABLE, 2);
@@ -877,7 +938,6 @@ do_sku:
877 case 0x10ec0882: 938 case 0x10ec0882:
878 case 0x10ec0883: 939 case 0x10ec0883:
879 case 0x10ec0885: 940 case 0x10ec0885:
880 case 0x10ec0888:
881 case 0x10ec0889: 941 case 0x10ec0889:
882 snd_hda_codec_write(codec, 0x20, 0, 942 snd_hda_codec_write(codec, 0x20, 0,
883 AC_VERB_SET_COEF_INDEX, 7); 943 AC_VERB_SET_COEF_INDEX, 7);
@@ -889,6 +949,9 @@ do_sku:
889 AC_VERB_SET_PROC_COEF, 949 AC_VERB_SET_PROC_COEF,
890 tmp | 0x2010); 950 tmp | 0x2010);
891 break; 951 break;
952 case 0x10ec0888:
953 alc888_coef_init(codec);
954 break;
892 case 0x10ec0267: 955 case 0x10ec0267:
893 case 0x10ec0268: 956 case 0x10ec0268:
894 snd_hda_codec_write(codec, 0x20, 0, 957 snd_hda_codec_write(codec, 0x20, 0,
@@ -2373,6 +2436,8 @@ static int alc_init(struct hda_codec *codec)
2373 struct alc_spec *spec = codec->spec; 2436 struct alc_spec *spec = codec->spec;
2374 unsigned int i; 2437 unsigned int i;
2375 2438
2439 alc_fix_pll(codec);
2440
2376 for (i = 0; i < spec->num_init_verbs; i++) 2441 for (i = 0; i < spec->num_init_verbs; i++)
2377 snd_hda_sequence_write(codec, spec->init_verbs[i]); 2442 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2378 2443
@@ -3009,6 +3074,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
3009 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), 3074 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3010 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 3075 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3011 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 3076 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3077 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3012 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), 3078 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3013 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 3079 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3014 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 3080 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
@@ -5101,7 +5167,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = {
5101 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 5167 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5102 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), 5168 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5103 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 5169 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5104 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP), 5170 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5105 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013), 5171 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
5106 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), 5172 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5107 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), 5173 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
@@ -6127,6 +6193,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
6127 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), 6193 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6128 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), 6194 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6129 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), 6195 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6196 SND_PCI_QUIRK(0x106b, 0x00a0, "Apple iMac 24''", ALC885_IMAC24),
6130 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), 6197 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6131 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 6198 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6132 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), 6199 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
@@ -6353,7 +6420,9 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec)
6353 continue; 6420 continue;
6354 vref = PIN_IN; 6421 vref = PIN_IN;
6355 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) { 6422 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6356 if (snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP) & 6423 unsigned int pincap;
6424 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6425 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6357 AC_PINCAP_VREF_80) 6426 AC_PINCAP_VREF_80)
6358 vref = PIN_VREF80; 6427 vref = PIN_VREF80;
6359 } 6428 }
@@ -6450,8 +6519,9 @@ static int patch_alc882(struct hda_codec *codec)
6450 case 0x106b1000: /* iMac 24 */ 6519 case 0x106b1000: /* iMac 24 */
6451 board_config = ALC885_IMAC24; 6520 board_config = ALC885_IMAC24;
6452 break; 6521 break;
6453 case 0x106b00a1: /* Macbook */ 6522 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6454 case 0x106b2c00: /* Macbook Pro rev3 */ 6523 case 0x106b2c00: /* Macbook Pro rev3 */
6524 case 0x106b3600: /* Macbook 3.1 */
6455 board_config = ALC885_MBP3; 6525 board_config = ALC885_MBP3;
6456 break; 6526 break;
6457 default: 6527 default:
@@ -6485,14 +6555,20 @@ static int patch_alc882(struct hda_codec *codec)
6485 if (board_config != ALC882_AUTO) 6555 if (board_config != ALC882_AUTO)
6486 setup_preset(spec, &alc882_presets[board_config]); 6556 setup_preset(spec, &alc882_presets[board_config]);
6487 6557
6488 spec->stream_name_analog = "ALC882 Analog"; 6558 if (codec->vendor_id == 0x10ec0885) {
6559 spec->stream_name_analog = "ALC885 Analog";
6560 spec->stream_name_digital = "ALC885 Digital";
6561 } else {
6562 spec->stream_name_analog = "ALC882 Analog";
6563 spec->stream_name_digital = "ALC882 Digital";
6564 }
6565
6489 spec->stream_analog_playback = &alc882_pcm_analog_playback; 6566 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6490 spec->stream_analog_capture = &alc882_pcm_analog_capture; 6567 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6491 /* FIXME: setup DAC5 */ 6568 /* FIXME: setup DAC5 */
6492 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ 6569 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6493 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 6570 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6494 6571
6495 spec->stream_name_digital = "ALC882 Digital";
6496 spec->stream_digital_playback = &alc882_pcm_digital_playback; 6572 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6497 spec->stream_digital_capture = &alc882_pcm_digital_capture; 6573 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6498 6574
@@ -6569,6 +6645,16 @@ static struct hda_input_mux alc883_capture_source = {
6569 }, 6645 },
6570}; 6646};
6571 6647
6648static struct hda_input_mux alc883_3stack_6ch_intel = {
6649 .num_items = 4,
6650 .items = {
6651 { "Mic", 0x1 },
6652 { "Front Mic", 0x0 },
6653 { "Line", 0x2 },
6654 { "CD", 0x4 },
6655 },
6656};
6657
6572static struct hda_input_mux alc883_lenovo_101e_capture_source = { 6658static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6573 .num_items = 2, 6659 .num_items = 2,
6574 .items = { 6660 .items = {
@@ -6650,6 +6736,48 @@ static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6650}; 6736};
6651 6737
6652/* 6738/*
6739 * 2ch mode
6740 */
6741static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6742 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6743 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6744 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6745 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6746 { } /* end */
6747};
6748
6749/*
6750 * 4ch mode
6751 */
6752static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6753 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6754 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6755 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6756 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6757 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6758 { } /* end */
6759};
6760
6761/*
6762 * 6ch mode
6763 */
6764static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6765 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6766 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6767 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6768 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6769 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6770 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6771 { } /* end */
6772};
6773
6774static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6775 { 2, alc883_3ST_ch2_intel_init },
6776 { 4, alc883_3ST_ch4_intel_init },
6777 { 6, alc883_3ST_ch6_intel_init },
6778};
6779
6780/*
6653 * 6ch mode 6781 * 6ch mode
6654 */ 6782 */
6655static struct hda_verb alc883_sixstack_ch6_init[] = { 6783static struct hda_verb alc883_sixstack_ch6_init[] = {
@@ -6881,15 +7009,54 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6881 { } /* end */ 7009 { } /* end */
6882}; 7010};
6883 7011
7012static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7013 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7014 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7015 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7016 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7017 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7018 HDA_OUTPUT),
7019 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7020 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7021 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7022 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7023 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7024 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7025 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7026 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7027 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7028 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7029 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7030 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7031 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7032 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7033 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7034 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7035 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7036 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7037 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7038 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7039 {
7040 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7041 /* .name = "Capture Source", */
7042 .name = "Input Source",
7043 .count = 2,
7044 .info = alc883_mux_enum_info,
7045 .get = alc883_mux_enum_get,
7046 .put = alc883_mux_enum_put,
7047 },
7048 { } /* end */
7049};
7050
6884static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 7051static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6885 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7052 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6886 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7053 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6887 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7054 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6888 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7055 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6889 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7056 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6890 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7057 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6891 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT), 7058 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6892 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 7059 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6893 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7060 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6894 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7061 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6895 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7062 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
@@ -7729,6 +7896,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
7729 [ALC883_MITAC] = "mitac", 7896 [ALC883_MITAC] = "mitac",
7730 [ALC883_CLEVO_M720] = "clevo-m720", 7897 [ALC883_CLEVO_M720] = "clevo-m720",
7731 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", 7898 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
7899 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
7732 [ALC883_AUTO] = "auto", 7900 [ALC883_AUTO] = "auto",
7733}; 7901};
7734 7902
@@ -7786,6 +7954,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
7786 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), 7954 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7787 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), 7955 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
7788 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 7956 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
7957 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
7958 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
7789 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), 7959 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
7790 {} 7960 {}
7791}; 7961};
@@ -7824,6 +7994,18 @@ static struct alc_config_preset alc883_presets[] = {
7824 .need_dac_fix = 1, 7994 .need_dac_fix = 1,
7825 .input_mux = &alc883_capture_source, 7995 .input_mux = &alc883_capture_source,
7826 }, 7996 },
7997 [ALC883_3ST_6ch_INTEL] = {
7998 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
7999 .init_verbs = { alc883_init_verbs },
8000 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8001 .dac_nids = alc883_dac_nids,
8002 .dig_out_nid = ALC883_DIGOUT_NID,
8003 .dig_in_nid = ALC883_DIGIN_NID,
8004 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8005 .channel_mode = alc883_3ST_6ch_intel_modes,
8006 .need_dac_fix = 1,
8007 .input_mux = &alc883_3stack_6ch_intel,
8008 },
7827 [ALC883_6ST_DIG] = { 8009 [ALC883_6ST_DIG] = {
7828 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 8010 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7829 .init_verbs = { alc883_init_verbs }, 8011 .init_verbs = { alc883_init_verbs },
@@ -8145,6 +8327,8 @@ static int patch_alc883(struct hda_codec *codec)
8145 8327
8146 codec->spec = spec; 8328 codec->spec = spec;
8147 8329
8330 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8331
8148 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, 8332 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8149 alc883_models, 8333 alc883_models,
8150 alc883_cfg_tbl); 8334 alc883_cfg_tbl);
@@ -8171,12 +8355,25 @@ static int patch_alc883(struct hda_codec *codec)
8171 if (board_config != ALC883_AUTO) 8355 if (board_config != ALC883_AUTO)
8172 setup_preset(spec, &alc883_presets[board_config]); 8356 setup_preset(spec, &alc883_presets[board_config]);
8173 8357
8174 spec->stream_name_analog = "ALC883 Analog"; 8358 switch (codec->vendor_id) {
8359 case 0x10ec0888:
8360 spec->stream_name_analog = "ALC888 Analog";
8361 spec->stream_name_digital = "ALC888 Digital";
8362 break;
8363 case 0x10ec0889:
8364 spec->stream_name_analog = "ALC889 Analog";
8365 spec->stream_name_digital = "ALC889 Digital";
8366 break;
8367 default:
8368 spec->stream_name_analog = "ALC883 Analog";
8369 spec->stream_name_digital = "ALC883 Digital";
8370 break;
8371 }
8372
8175 spec->stream_analog_playback = &alc883_pcm_analog_playback; 8373 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8176 spec->stream_analog_capture = &alc883_pcm_analog_capture; 8374 spec->stream_analog_capture = &alc883_pcm_analog_capture;
8177 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture; 8375 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8178 8376
8179 spec->stream_name_digital = "ALC883 Digital";
8180 spec->stream_digital_playback = &alc883_pcm_digital_playback; 8377 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8181 spec->stream_digital_capture = &alc883_pcm_digital_capture; 8378 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8182 8379
@@ -8189,6 +8386,9 @@ static int patch_alc883(struct hda_codec *codec)
8189 codec->patch_ops = alc_patch_ops; 8386 codec->patch_ops = alc_patch_ops;
8190 if (board_config == ALC883_AUTO) 8387 if (board_config == ALC883_AUTO)
8191 spec->init_hook = alc883_auto_init; 8388 spec->init_hook = alc883_auto_init;
8389 else if (codec->vendor_id == 0x10ec0888)
8390 spec->init_hook = alc888_coef_init;
8391
8192#ifdef CONFIG_SND_HDA_POWER_SAVE 8392#ifdef CONFIG_SND_HDA_POWER_SAVE
8193 if (!spec->loopback.amplist) 8393 if (!spec->loopback.amplist)
8194 spec->loopback.amplist = alc883_loopbacks; 8394 spec->loopback.amplist = alc883_loopbacks;
@@ -9522,6 +9722,8 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
9522 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 9722 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9523 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), 9723 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9524 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), 9724 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
9725 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9726 ALC262_SONY_ASSAMD),
9525 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 9727 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
9526 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), 9728 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
9527 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), 9729 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
@@ -9729,6 +9931,8 @@ static int patch_alc262(struct hda_codec *codec)
9729 } 9931 }
9730#endif 9932#endif
9731 9933
9934 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9935
9732 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 9936 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9733 alc262_models, 9937 alc262_models,
9734 alc262_cfg_tbl); 9938 alc262_cfg_tbl);
@@ -10674,12 +10878,18 @@ static int patch_alc268(struct hda_codec *codec)
10674 if (board_config != ALC268_AUTO) 10878 if (board_config != ALC268_AUTO)
10675 setup_preset(spec, &alc268_presets[board_config]); 10879 setup_preset(spec, &alc268_presets[board_config]);
10676 10880
10677 spec->stream_name_analog = "ALC268 Analog"; 10881 if (codec->vendor_id == 0x10ec0267) {
10882 spec->stream_name_analog = "ALC267 Analog";
10883 spec->stream_name_digital = "ALC267 Digital";
10884 } else {
10885 spec->stream_name_analog = "ALC268 Analog";
10886 spec->stream_name_digital = "ALC268 Digital";
10887 }
10888
10678 spec->stream_analog_playback = &alc268_pcm_analog_playback; 10889 spec->stream_analog_playback = &alc268_pcm_analog_playback;
10679 spec->stream_analog_capture = &alc268_pcm_analog_capture; 10890 spec->stream_analog_capture = &alc268_pcm_analog_capture;
10680 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; 10891 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
10681 10892
10682 spec->stream_name_digital = "ALC268 Digital";
10683 spec->stream_digital_playback = &alc268_pcm_digital_playback; 10893 spec->stream_digital_playback = &alc268_pcm_digital_playback;
10684 10894
10685 if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) 10895 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
@@ -11033,6 +11243,8 @@ static int patch_alc269(struct hda_codec *codec)
11033 11243
11034 codec->spec = spec; 11244 codec->spec = spec;
11035 11245
11246 alc_fix_pll_init(codec, 0x20, 0x04, 15);
11247
11036 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 11248 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
11037 alc269_models, 11249 alc269_models,
11038 alc269_cfg_tbl); 11250 alc269_cfg_tbl);
@@ -12631,6 +12843,12 @@ static struct hda_verb alc861vd_eapd_verbs[] = {
12631 { } 12843 { }
12632}; 12844};
12633 12845
12846static struct hda_verb alc660vd_eapd_verbs[] = {
12847 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12848 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12849 { }
12850};
12851
12634static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 12852static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
12635 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12853 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12636 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12854 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -12786,6 +13004,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
12786 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), 13004 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
12787 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), 13005 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
12788 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), 13006 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
13007 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
12789 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), 13008 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
12790 {} 13009 {}
12791}; 13010};
@@ -13168,11 +13387,19 @@ static int patch_alc861vd(struct hda_codec *codec)
13168 if (board_config != ALC861VD_AUTO) 13387 if (board_config != ALC861VD_AUTO)
13169 setup_preset(spec, &alc861vd_presets[board_config]); 13388 setup_preset(spec, &alc861vd_presets[board_config]);
13170 13389
13171 spec->stream_name_analog = "ALC861VD Analog"; 13390 if (codec->vendor_id == 0x10ec0660) {
13391 spec->stream_name_analog = "ALC660-VD Analog";
13392 spec->stream_name_digital = "ALC660-VD Digital";
13393 /* always turn on EAPD */
13394 spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs;
13395 } else {
13396 spec->stream_name_analog = "ALC861VD Analog";
13397 spec->stream_name_digital = "ALC861VD Digital";
13398 }
13399
13172 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 13400 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
13173 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 13401 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
13174 13402
13175 spec->stream_name_digital = "ALC861VD Digital";
13176 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 13403 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
13177 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 13404 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
13178 13405
@@ -13251,6 +13478,23 @@ static struct hda_input_mux alc662_eeepc_capture_source = {
13251 }, 13478 },
13252}; 13479};
13253 13480
13481static struct hda_input_mux alc663_capture_source = {
13482 .num_items = 3,
13483 .items = {
13484 { "Mic", 0x0 },
13485 { "Front Mic", 0x1 },
13486 { "Line", 0x2 },
13487 },
13488};
13489
13490static struct hda_input_mux alc663_m51va_capture_source = {
13491 .num_items = 2,
13492 .items = {
13493 { "Ext-Mic", 0x0 },
13494 { "D-Mic", 0x9 },
13495 },
13496};
13497
13254#define alc662_mux_enum_info alc_mux_enum_info 13498#define alc662_mux_enum_info alc_mux_enum_info
13255#define alc662_mux_enum_get alc_mux_enum_get 13499#define alc662_mux_enum_get alc_mux_enum_get
13256#define alc662_mux_enum_put alc882_mux_enum_put 13500#define alc662_mux_enum_put alc882_mux_enum_put
@@ -13431,6 +13675,44 @@ static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
13431 { } /* end */ 13675 { } /* end */
13432}; 13676};
13433 13677
13678static struct snd_kcontrol_new alc663_m51va_mixer[] = {
13679 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13680 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13681 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13682 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13683 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13684 HDA_CODEC_MUTE("DMic Playback Switch", 0x23, 0x9, HDA_INPUT),
13685 { } /* end */
13686};
13687
13688static struct snd_kcontrol_new alc663_g71v_mixer[] = {
13689 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13690 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13691 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13692 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13693 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13694
13695 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13696 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13697 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13698 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13699 { } /* end */
13700};
13701
13702static struct snd_kcontrol_new alc663_g50v_mixer[] = {
13703 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13704 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13705 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13706
13707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13709 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13710 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13711 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13712 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13713 { } /* end */
13714};
13715
13434static struct snd_kcontrol_new alc662_chmode_mixer[] = { 13716static struct snd_kcontrol_new alc662_chmode_mixer[] = {
13435 { 13717 {
13436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13718 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -13501,6 +13783,11 @@ static struct hda_verb alc662_init_verbs[] = {
13501 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13783 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13502 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13784 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13503 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 13785 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13786
13787 /* always trun on EAPD */
13788 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13789 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13790
13504 { } 13791 { }
13505}; 13792};
13506 13793
@@ -13571,6 +13858,43 @@ static struct hda_verb alc662_auto_init_verbs[] = {
13571 { } 13858 { }
13572}; 13859};
13573 13860
13861static struct hda_verb alc663_m51va_init_verbs[] = {
13862 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13863 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13864 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
13865
13866 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
13867
13868 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13869 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13870 {}
13871};
13872
13873static struct hda_verb alc663_g71v_init_verbs[] = {
13874 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13875 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
13876 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
13877
13878 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13879 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13880 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
13881
13882 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
13883 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
13884 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
13885 {}
13886};
13887
13888static struct hda_verb alc663_g50v_init_verbs[] = {
13889 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13890 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13891 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
13892
13893 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13894 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13895 {}
13896};
13897
13574/* capture mixer elements */ 13898/* capture mixer elements */
13575static struct snd_kcontrol_new alc662_capture_mixer[] = { 13899static struct snd_kcontrol_new alc662_capture_mixer[] = {
13576 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 13900 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
@@ -13692,6 +14016,125 @@ static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
13692 alc662_eeepc_ep20_automute(codec); 14016 alc662_eeepc_ep20_automute(codec);
13693} 14017}
13694 14018
14019static void alc663_m51va_speaker_automute(struct hda_codec *codec)
14020{
14021 unsigned int present;
14022 unsigned char bits;
14023
14024 present = snd_hda_codec_read(codec, 0x21, 0,
14025 AC_VERB_GET_PIN_SENSE, 0)
14026 & AC_PINSENSE_PRESENCE;
14027 bits = present ? HDA_AMP_MUTE : 0;
14028 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14029 HDA_AMP_MUTE, bits);
14030}
14031
14032static void alc663_m51va_mic_automute(struct hda_codec *codec)
14033{
14034 unsigned int present;
14035
14036 present = snd_hda_codec_read(codec, 0x18, 0,
14037 AC_VERB_GET_PIN_SENSE, 0)
14038 & AC_PINSENSE_PRESENCE;
14039 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14040 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14041 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14042 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14043 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14044 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
14045 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14046 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
14047}
14048
14049static void alc663_m51va_unsol_event(struct hda_codec *codec,
14050 unsigned int res)
14051{
14052 switch (res >> 26) {
14053 case ALC880_HP_EVENT:
14054 alc663_m51va_speaker_automute(codec);
14055 break;
14056 case ALC880_MIC_EVENT:
14057 alc663_m51va_mic_automute(codec);
14058 break;
14059 }
14060}
14061
14062static void alc663_m51va_inithook(struct hda_codec *codec)
14063{
14064 alc663_m51va_speaker_automute(codec);
14065 alc663_m51va_mic_automute(codec);
14066}
14067
14068static void alc663_g71v_hp_automute(struct hda_codec *codec)
14069{
14070 unsigned int present;
14071 unsigned char bits;
14072
14073 present = snd_hda_codec_read(codec, 0x21, 0,
14074 AC_VERB_GET_PIN_SENSE, 0)
14075 & AC_PINSENSE_PRESENCE;
14076 bits = present ? HDA_AMP_MUTE : 0;
14077 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14078 HDA_AMP_MUTE, bits);
14079 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14080 HDA_AMP_MUTE, bits);
14081}
14082
14083static void alc663_g71v_front_automute(struct hda_codec *codec)
14084{
14085 unsigned int present;
14086 unsigned char bits;
14087
14088 present = snd_hda_codec_read(codec, 0x15, 0,
14089 AC_VERB_GET_PIN_SENSE, 0)
14090 & AC_PINSENSE_PRESENCE;
14091 bits = present ? HDA_AMP_MUTE : 0;
14092 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14093 HDA_AMP_MUTE, bits);
14094}
14095
14096static void alc663_g71v_unsol_event(struct hda_codec *codec,
14097 unsigned int res)
14098{
14099 switch (res >> 26) {
14100 case ALC880_HP_EVENT:
14101 alc663_g71v_hp_automute(codec);
14102 break;
14103 case ALC880_FRONT_EVENT:
14104 alc663_g71v_front_automute(codec);
14105 break;
14106 case ALC880_MIC_EVENT:
14107 alc662_eeepc_mic_automute(codec);
14108 break;
14109 }
14110}
14111
14112static void alc663_g71v_inithook(struct hda_codec *codec)
14113{
14114 alc663_g71v_front_automute(codec);
14115 alc663_g71v_hp_automute(codec);
14116 alc662_eeepc_mic_automute(codec);
14117}
14118
14119static void alc663_g50v_unsol_event(struct hda_codec *codec,
14120 unsigned int res)
14121{
14122 switch (res >> 26) {
14123 case ALC880_HP_EVENT:
14124 alc663_m51va_speaker_automute(codec);
14125 break;
14126 case ALC880_MIC_EVENT:
14127 alc662_eeepc_mic_automute(codec);
14128 break;
14129 }
14130}
14131
14132static void alc663_g50v_inithook(struct hda_codec *codec)
14133{
14134 alc663_m51va_speaker_automute(codec);
14135 alc662_eeepc_mic_automute(codec);
14136}
14137
13695#ifdef CONFIG_SND_HDA_POWER_SAVE 14138#ifdef CONFIG_SND_HDA_POWER_SAVE
13696#define alc662_loopbacks alc880_loopbacks 14139#define alc662_loopbacks alc880_loopbacks
13697#endif 14140#endif
@@ -13714,14 +14157,24 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
13714 [ALC662_LENOVO_101E] = "lenovo-101e", 14157 [ALC662_LENOVO_101E] = "lenovo-101e",
13715 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", 14158 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
13716 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", 14159 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
14160 [ALC663_ASUS_M51VA] = "m51va",
14161 [ALC663_ASUS_G71V] = "g71v",
14162 [ALC663_ASUS_H13] = "h13",
14163 [ALC663_ASUS_G50V] = "g50v",
13717 [ALC662_AUTO] = "auto", 14164 [ALC662_AUTO] = "auto",
13718}; 14165};
13719 14166
13720static struct snd_pci_quirk alc662_cfg_tbl[] = { 14167static struct snd_pci_quirk alc662_cfg_tbl[] = {
14168 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS G71V", ALC663_ASUS_G71V),
14169 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
14170 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V),
13721 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), 14171 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
13722 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), 14172 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
13723 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), 14173 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
13724 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 14174 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
14175 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
14176 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
14177 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
13725 {} 14178 {}
13726}; 14179};
13727 14180
@@ -13809,7 +14262,53 @@ static struct alc_config_preset alc662_presets[] = {
13809 .unsol_event = alc662_eeepc_ep20_unsol_event, 14262 .unsol_event = alc662_eeepc_ep20_unsol_event,
13810 .init_hook = alc662_eeepc_ep20_inithook, 14263 .init_hook = alc662_eeepc_ep20_inithook,
13811 }, 14264 },
13812 14265 [ALC663_ASUS_M51VA] = {
14266 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
14267 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
14268 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14269 .dac_nids = alc662_dac_nids,
14270 .dig_out_nid = ALC662_DIGOUT_NID,
14271 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14272 .channel_mode = alc662_3ST_2ch_modes,
14273 .input_mux = &alc663_m51va_capture_source,
14274 .unsol_event = alc663_m51va_unsol_event,
14275 .init_hook = alc663_m51va_inithook,
14276 },
14277 [ALC663_ASUS_G71V] = {
14278 .mixers = { alc663_g71v_mixer, alc662_capture_mixer},
14279 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
14280 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14281 .dac_nids = alc662_dac_nids,
14282 .dig_out_nid = ALC662_DIGOUT_NID,
14283 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14284 .channel_mode = alc662_3ST_2ch_modes,
14285 .input_mux = &alc662_eeepc_capture_source,
14286 .unsol_event = alc663_g71v_unsol_event,
14287 .init_hook = alc663_g71v_inithook,
14288 },
14289 [ALC663_ASUS_H13] = {
14290 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
14291 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
14292 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14293 .dac_nids = alc662_dac_nids,
14294 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14295 .channel_mode = alc662_3ST_2ch_modes,
14296 .input_mux = &alc663_m51va_capture_source,
14297 .unsol_event = alc663_m51va_unsol_event,
14298 .init_hook = alc663_m51va_inithook,
14299 },
14300 [ALC663_ASUS_G50V] = {
14301 .mixers = { alc663_g50v_mixer, alc662_capture_mixer},
14302 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
14303 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14304 .dac_nids = alc662_dac_nids,
14305 .dig_out_nid = ALC662_DIGOUT_NID,
14306 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
14307 .channel_mode = alc662_3ST_6ch_modes,
14308 .input_mux = &alc663_capture_source,
14309 .unsol_event = alc663_g50v_unsol_event,
14310 .init_hook = alc663_g50v_inithook,
14311 },
13813}; 14312};
13814 14313
13815 14314
@@ -14082,6 +14581,8 @@ static int patch_alc662(struct hda_codec *codec)
14082 14581
14083 codec->spec = spec; 14582 codec->spec = spec;
14084 14583
14584 alc_fix_pll_init(codec, 0x20, 0x04, 15);
14585
14085 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 14586 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
14086 alc662_models, 14587 alc662_models,
14087 alc662_cfg_tbl); 14588 alc662_cfg_tbl);
@@ -14108,11 +14609,17 @@ static int patch_alc662(struct hda_codec *codec)
14108 if (board_config != ALC662_AUTO) 14609 if (board_config != ALC662_AUTO)
14109 setup_preset(spec, &alc662_presets[board_config]); 14610 setup_preset(spec, &alc662_presets[board_config]);
14110 14611
14111 spec->stream_name_analog = "ALC662 Analog"; 14612 if (codec->vendor_id == 0x10ec0663) {
14613 spec->stream_name_analog = "ALC663 Analog";
14614 spec->stream_name_digital = "ALC663 Digital";
14615 } else {
14616 spec->stream_name_analog = "ALC662 Analog";
14617 spec->stream_name_digital = "ALC662 Digital";
14618 }
14619
14112 spec->stream_analog_playback = &alc662_pcm_analog_playback; 14620 spec->stream_analog_playback = &alc662_pcm_analog_playback;
14113 spec->stream_analog_capture = &alc662_pcm_analog_capture; 14621 spec->stream_analog_capture = &alc662_pcm_analog_capture;
14114 14622
14115 spec->stream_name_digital = "ALC662 Digital";
14116 spec->stream_digital_playback = &alc662_pcm_digital_playback; 14623 spec->stream_digital_playback = &alc662_pcm_digital_playback;
14117 spec->stream_digital_capture = &alc662_pcm_digital_capture; 14624 spec->stream_digital_capture = &alc662_pcm_digital_capture;
14118 14625
@@ -14151,6 +14658,7 @@ struct hda_codec_preset snd_hda_preset_realtek[] = {
14151 .patch = patch_alc883 }, 14658 .patch = patch_alc883 },
14152 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 14659 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
14153 .patch = patch_alc662 }, 14660 .patch = patch_alc662 },
14661 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
14154 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 14662 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
14155 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 14663 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
14156 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, 14664 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index a4f44a00bae8..08cb77f51880 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -636,21 +636,28 @@ static struct hda_verb stac92hd71bxx_core_init[] = {
636 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 636 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
637}; 637};
638 638
639#define HD_DISABLE_PORTF 3
639static struct hda_verb stac92hd71bxx_analog_core_init[] = { 640static struct hda_verb stac92hd71bxx_analog_core_init[] = {
641 /* start of config #1 */
642
643 /* connect port 0f to audio mixer */
644 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
645 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */
646 /* unmute right and left channels for node 0x0f */
647 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
648 /* start of config #2 */
649
640 /* set master volume and direct control */ 650 /* set master volume and direct control */
641 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 651 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
642 /* connect headphone jack to dac1 */ 652 /* connect headphone jack to dac1 */
643 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, 653 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
644 /* connect ports 0d and 0f to audio mixer */ 654 /* connect port 0d to audio mixer */
645 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x2}, 655 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x2},
646 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
647 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */
648 /* unmute dac0 input in audio mixer */ 656 /* unmute dac0 input in audio mixer */
649 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, 657 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
650 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ 658 /* unmute right and left channels for nodes 0x0a, 0xd */
651 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 659 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
652 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 660 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
653 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
654 {} 661 {}
655}; 662};
656 663
@@ -818,6 +825,9 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
818 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), 825 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
819 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT), 826 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT),
820 827
828 HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT),
829 HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT),
830
821 HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT), 831 HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT),
822 HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT), 832 HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT),
823 { } /* end */ 833 { } /* end */
@@ -1317,13 +1327,13 @@ static unsigned int ref92hd71bxx_pin_configs[10] = {
1317 0x90a000f0, 0x01452050, 1327 0x90a000f0, 0x01452050,
1318}; 1328};
1319 1329
1320static unsigned int dell_m4_1_pin_configs[13] = { 1330static unsigned int dell_m4_1_pin_configs[10] = {
1321 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, 1331 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110,
1322 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, 1332 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0,
1323 0x40f000f0, 0x4f0000f0, 1333 0x40f000f0, 0x4f0000f0,
1324}; 1334};
1325 1335
1326static unsigned int dell_m4_2_pin_configs[13] = { 1336static unsigned int dell_m4_2_pin_configs[10] = {
1327 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, 1337 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
1328 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, 1338 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0,
1329 0x40f000f0, 0x044413b0, 1339 0x40f000f0, 0x044413b0,
@@ -1754,12 +1764,8 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = {
1754 "unknown Dell", STAC_9205_DELL_M42), 1764 "unknown Dell", STAC_9205_DELL_M42),
1755 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8, 1765 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
1756 "Dell Precision", STAC_9205_DELL_M43), 1766 "Dell Precision", STAC_9205_DELL_M43),
1757 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
1758 "Dell Precision", STAC_9205_DELL_M43),
1759 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9, 1767 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
1760 "Dell Precision", STAC_9205_DELL_M43), 1768 "Dell Precision", STAC_9205_DELL_M43),
1761 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
1762 "Dell Precision", STAC_9205_DELL_M43),
1763 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa, 1769 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
1764 "Dell Precision", STAC_9205_DELL_M43), 1770 "Dell Precision", STAC_9205_DELL_M43),
1765 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc, 1771 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
@@ -1770,18 +1776,14 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = {
1770 "Dell Precision", STAC_9205_DELL_M43), 1776 "Dell Precision", STAC_9205_DELL_M43),
1771 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff, 1777 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
1772 "Dell Precision M4300", STAC_9205_DELL_M43), 1778 "Dell Precision M4300", STAC_9205_DELL_M43),
1773 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
1774 "Dell Precision", STAC_9205_DELL_M43),
1775 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
1776 "Dell Inspiron", STAC_9205_DELL_M44),
1777 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
1778 "Dell Inspiron", STAC_9205_DELL_M44),
1779 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
1780 "Dell Inspiron", STAC_9205_DELL_M44),
1781 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
1782 "Dell Inspiron", STAC_9205_DELL_M44),
1783 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204, 1779 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
1784 "unknown Dell", STAC_9205_DELL_M42), 1780 "unknown Dell", STAC_9205_DELL_M42),
1781 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
1782 "Dell Precision", STAC_9205_DELL_M43),
1783 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
1784 "Dell Precision", STAC_9205_DELL_M43),
1785 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
1786 "Dell Precision", STAC_9205_DELL_M43),
1785 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f, 1787 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
1786 "Dell Inspiron", STAC_9205_DELL_M44), 1788 "Dell Inspiron", STAC_9205_DELL_M44),
1787 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, 1789 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
@@ -3103,13 +3105,16 @@ static int stac92xx_init(struct hda_codec *codec)
3103 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3105 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3104 int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i], 3106 int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i],
3105 0, AC_VERB_GET_CONFIG_DEFAULT, 0); 3107 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
3108 def_conf = get_defcfg_connect(def_conf);
3106 /* outputs are only ports capable of power management 3109 /* outputs are only ports capable of power management
3107 * any attempts on powering down a input port cause the 3110 * any attempts on powering down a input port cause the
3108 * referenced VREF to act quirky. 3111 * referenced VREF to act quirky.
3109 */ 3112 */
3110 if (pinctl & AC_PINCTL_IN_EN) 3113 if (pinctl & AC_PINCTL_IN_EN)
3111 continue; 3114 continue;
3112 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) 3115 /* skip any ports that don't have jacks since presence
3116 * detection is useless */
3117 if (def_conf && def_conf != AC_JACK_PORT_FIXED)
3113 continue; 3118 continue;
3114 enable_pin_detect(codec, spec->pwr_nids[i], event | i); 3119 enable_pin_detect(codec, spec->pwr_nids[i], event | i);
3115 codec->patch_ops.unsol_event(codec, (event | i) << 26); 3120 codec->patch_ops.unsol_event(codec, (event | i) << 26);
@@ -3614,6 +3619,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
3614 3619
3615 codec->spec = spec; 3620 codec->spec = spec;
3616 spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids); 3621 spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids);
3622 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
3617 spec->pin_nids = stac92hd71bxx_pin_nids; 3623 spec->pin_nids = stac92hd71bxx_pin_nids;
3618 spec->board_config = snd_hda_check_board_config(codec, 3624 spec->board_config = snd_hda_check_board_config(codec,
3619 STAC_92HD71BXX_MODELS, 3625 STAC_92HD71BXX_MODELS,
@@ -3642,6 +3648,19 @@ again:
3642 spec->mixer = stac92hd71bxx_mixer; 3648 spec->mixer = stac92hd71bxx_mixer;
3643 spec->init = stac92hd71bxx_core_init; 3649 spec->init = stac92hd71bxx_core_init;
3644 break; 3650 break;
3651 case 0x111d7608: /* 5 Port with Analog Mixer */
3652 /* no output amps */
3653 spec->num_pwrs = 0;
3654 spec->mixer = stac92hd71bxx_analog_mixer;
3655
3656 /* disable VSW */
3657 spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF];
3658 stac92xx_set_config_reg(codec, 0xf, 0x40f000f0);
3659 break;
3660 case 0x111d7603: /* 6 Port with Analog Mixer */
3661 /* no output amps */
3662 spec->num_pwrs = 0;
3663 /* fallthru */
3645 default: 3664 default:
3646 spec->mixer = stac92hd71bxx_analog_mixer; 3665 spec->mixer = stac92hd71bxx_analog_mixer;
3647 spec->init = stac92hd71bxx_analog_core_init; 3666 spec->init = stac92hd71bxx_analog_core_init;
@@ -3653,22 +3672,19 @@ again:
3653 /* GPIO0 High = EAPD */ 3672 /* GPIO0 High = EAPD */
3654 spec->gpio_mask = 0x01; 3673 spec->gpio_mask = 0x01;
3655 spec->gpio_dir = 0x01; 3674 spec->gpio_dir = 0x01;
3656 spec->gpio_mask = 0x01;
3657 spec->gpio_data = 0x01; 3675 spec->gpio_data = 0x01;
3658 3676
3659 spec->mux_nids = stac92hd71bxx_mux_nids; 3677 spec->mux_nids = stac92hd71bxx_mux_nids;
3660 spec->adc_nids = stac92hd71bxx_adc_nids; 3678 spec->adc_nids = stac92hd71bxx_adc_nids;
3661 spec->dmic_nids = stac92hd71bxx_dmic_nids; 3679 spec->dmic_nids = stac92hd71bxx_dmic_nids;
3662 spec->dmux_nids = stac92hd71bxx_dmux_nids; 3680 spec->dmux_nids = stac92hd71bxx_dmux_nids;
3681 spec->pwr_nids = stac92hd71bxx_pwr_nids;
3663 3682
3664 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); 3683 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
3665 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); 3684 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
3666 spec->num_dmics = STAC92HD71BXX_NUM_DMICS; 3685 spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
3667 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); 3686 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
3668 3687
3669 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
3670 spec->pwr_nids = stac92hd71bxx_pwr_nids;
3671
3672 spec->multiout.num_dacs = 1; 3688 spec->multiout.num_dacs = 1;
3673 spec->multiout.hp_nid = 0x11; 3689 spec->multiout.hp_nid = 0x11;
3674 spec->multiout.dac_nids = stac92hd71bxx_dac_nids; 3690 spec->multiout.dac_nids = stac92hd71bxx_dac_nids;
@@ -4306,10 +4322,11 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
4306 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 }, 4322 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
4307 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, 4323 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
4308 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, 4324 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
4325 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
4326 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
4309 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, 4327 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
4310 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, 4328 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
4311 { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx }, 4329 { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx },
4312 { .id = 0x111d7608, .name = "92HD71BXX", .patch = patch_stac92hd71bxx },
4313 { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, 4330 { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
4314 { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, 4331 { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
4315 { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx }, 4332 { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
diff --git a/sound/pci/ice1712/envy24ht.h b/sound/pci/ice1712/envy24ht.h
index 43b9e3e858be..a0c5e009bb4a 100644
--- a/sound/pci/ice1712/envy24ht.h
+++ b/sound/pci/ice1712/envy24ht.h
@@ -93,9 +93,13 @@ enum {
93#define VT1724_REG_MPU_TXFIFO 0x0a /*byte ro. number of bytes in TX fifo*/ 93#define VT1724_REG_MPU_TXFIFO 0x0a /*byte ro. number of bytes in TX fifo*/
94#define VT1724_REG_MPU_RXFIFO 0x0b /*byte ro. number of bytes in RX fifo*/ 94#define VT1724_REG_MPU_RXFIFO 0x0b /*byte ro. number of bytes in RX fifo*/
95 95
96//are these 2 the wrong way around? they don't seem to be used yet anyway 96#define VT1724_REG_MPU_DATA 0x0c /* byte */
97#define VT1724_REG_MPU_CTRL 0x0c /* byte */ 97#define VT1724_REG_MPU_CTRL 0x0d /* byte */
98#define VT1724_REG_MPU_DATA 0x0d /* byte */ 98#define VT1724_MPU_UART 0x01
99#define VT1724_MPU_TX_EMPTY 0x02
100#define VT1724_MPU_TX_FULL 0x04
101#define VT1724_MPU_RX_EMPTY 0x08
102#define VT1724_MPU_RX_FULL 0x10
99 103
100#define VT1724_REG_MPU_FIFO_WM 0x0e /*byte set the high/low watermarks for RX/TX fifos*/ 104#define VT1724_REG_MPU_FIFO_WM 0x0e /*byte set the high/low watermarks for RX/TX fifos*/
101#define VT1724_MPU_RX_FIFO 0x20 //1=rx fifo watermark 0=tx fifo watermark 105#define VT1724_MPU_RX_FIFO 0x20 //1=rx fifo watermark 0=tx fifo watermark
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index 3208901c740e..762fbd7a7507 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -333,6 +333,8 @@ struct snd_ice1712 {
333 unsigned int has_spdif: 1; /* VT1720/4 - has SPDIF I/O */ 333 unsigned int has_spdif: 1; /* VT1720/4 - has SPDIF I/O */
334 unsigned int force_pdma4: 1; /* VT1720/4 - PDMA4 as non-spdif */ 334 unsigned int force_pdma4: 1; /* VT1720/4 - PDMA4 as non-spdif */
335 unsigned int force_rdma1: 1; /* VT1720/4 - RDMA1 as non-spdif */ 335 unsigned int force_rdma1: 1; /* VT1720/4 - RDMA1 as non-spdif */
336 unsigned int midi_output: 1; /* VT1720/4: MIDI output triggered */
337 unsigned int midi_input: 1; /* VT1720/4: MIDI input triggered */
336 unsigned int num_total_dacs; /* total DACs */ 338 unsigned int num_total_dacs; /* total DACs */
337 unsigned int num_total_adcs; /* total ADCs */ 339 unsigned int num_total_adcs; /* total ADCs */
338 unsigned int cur_rate; /* current rate */ 340 unsigned int cur_rate; /* current rate */
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 67350901772c..e596d777d9dd 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -32,7 +32,7 @@
32#include <linux/mutex.h> 32#include <linux/mutex.h>
33#include <sound/core.h> 33#include <sound/core.h>
34#include <sound/info.h> 34#include <sound/info.h>
35#include <sound/mpu401.h> 35#include <sound/rawmidi.h>
36#include <sound/initval.h> 36#include <sound/initval.h>
37 37
38#include <sound/asoundef.h> 38#include <sound/asoundef.h>
@@ -223,30 +223,153 @@ static unsigned int snd_vt1724_get_gpio_data(struct snd_ice1712 *ice)
223} 223}
224 224
225/* 225/*
226 * MPU401 accessor 226 * MIDI
227 */ 227 */
228static unsigned char snd_vt1724_mpu401_read(struct snd_mpu401 *mpu, 228
229 unsigned long addr) 229static void vt1724_midi_clear_rx(struct snd_ice1712 *ice)
230{
231 unsigned int count;
232
233 for (count = inb(ICEREG1724(ice, MPU_RXFIFO)); count > 0; --count)
234 inb(ICEREG1724(ice, MPU_DATA));
235}
236
237static inline struct snd_rawmidi_substream *
238get_rawmidi_substream(struct snd_ice1712 *ice, unsigned int stream)
230{ 239{
231 /* fix status bits to the standard position */ 240 return list_first_entry(&ice->rmidi[0]->streams[stream].substreams,
232 /* only RX_EMPTY and TX_FULL are checked */ 241 struct snd_rawmidi_substream, list);
233 if (addr == MPU401C(mpu)) 242}
234 return (inb(addr) & 0x0c) << 4; 243
244static void vt1724_midi_write(struct snd_ice1712 *ice)
245{
246 struct snd_rawmidi_substream *s;
247 int count, i;
248 u8 buffer[32];
249
250 s = get_rawmidi_substream(ice, SNDRV_RAWMIDI_STREAM_OUTPUT);
251 count = 31 - inb(ICEREG1724(ice, MPU_TXFIFO));
252 if (count > 0) {
253 count = snd_rawmidi_transmit(s, buffer, count);
254 for (i = 0; i < count; ++i)
255 outb(buffer[i], ICEREG1724(ice, MPU_DATA));
256 }
257}
258
259static void vt1724_midi_read(struct snd_ice1712 *ice)
260{
261 struct snd_rawmidi_substream *s;
262 int count, i;
263 u8 buffer[32];
264
265 s = get_rawmidi_substream(ice, SNDRV_RAWMIDI_STREAM_INPUT);
266 count = inb(ICEREG1724(ice, MPU_RXFIFO));
267 if (count > 0) {
268 count = min(count, 32);
269 for (i = 0; i < count; ++i)
270 buffer[i] = inb(ICEREG1724(ice, MPU_DATA));
271 snd_rawmidi_receive(s, buffer, count);
272 }
273}
274
275static void vt1724_enable_midi_irq(struct snd_rawmidi_substream *substream,
276 u8 flag, int enable)
277{
278 struct snd_ice1712 *ice = substream->rmidi->private_data;
279 u8 mask;
280
281 spin_lock_irq(&ice->reg_lock);
282 mask = inb(ICEREG1724(ice, IRQMASK));
283 if (enable)
284 mask &= ~flag;
235 else 285 else
236 return inb(addr); 286 mask |= flag;
287 outb(mask, ICEREG1724(ice, IRQMASK));
288 spin_unlock_irq(&ice->reg_lock);
237} 289}
238 290
239static void snd_vt1724_mpu401_write(struct snd_mpu401 *mpu, 291static int vt1724_midi_output_open(struct snd_rawmidi_substream *s)
240 unsigned char data, unsigned long addr)
241{ 292{
242 if (addr == MPU401C(mpu)) { 293 vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_TX, 1);
243 if (data == MPU401_ENTER_UART) 294 return 0;
244 outb(0x01, addr); 295}
245 /* what else? */ 296
246 } else 297static int vt1724_midi_output_close(struct snd_rawmidi_substream *s)
247 outb(data, addr); 298{
299 vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_TX, 0);
300 return 0;
248} 301}
249 302
303static void vt1724_midi_output_trigger(struct snd_rawmidi_substream *s, int up)
304{
305 struct snd_ice1712 *ice = s->rmidi->private_data;
306 unsigned long flags;
307
308 spin_lock_irqsave(&ice->reg_lock, flags);
309 if (up) {
310 ice->midi_output = 1;
311 vt1724_midi_write(ice);
312 } else {
313 ice->midi_output = 0;
314 }
315 spin_unlock_irqrestore(&ice->reg_lock, flags);
316}
317
318static void vt1724_midi_output_drain(struct snd_rawmidi_substream *s)
319{
320 struct snd_ice1712 *ice = s->rmidi->private_data;
321 unsigned long timeout;
322
323 /* 32 bytes should be transmitted in less than about 12 ms */
324 timeout = jiffies + msecs_to_jiffies(15);
325 do {
326 if (inb(ICEREG1724(ice, MPU_CTRL)) & VT1724_MPU_TX_EMPTY)
327 break;
328 schedule_timeout_uninterruptible(1);
329 } while (time_after(timeout, jiffies));
330}
331
332static struct snd_rawmidi_ops vt1724_midi_output_ops = {
333 .open = vt1724_midi_output_open,
334 .close = vt1724_midi_output_close,
335 .trigger = vt1724_midi_output_trigger,
336 .drain = vt1724_midi_output_drain,
337};
338
339static int vt1724_midi_input_open(struct snd_rawmidi_substream *s)
340{
341 vt1724_midi_clear_rx(s->rmidi->private_data);
342 vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_RX, 1);
343 return 0;
344}
345
346static int vt1724_midi_input_close(struct snd_rawmidi_substream *s)
347{
348 vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_RX, 0);
349 return 0;
350}
351
352static void vt1724_midi_input_trigger(struct snd_rawmidi_substream *s, int up)
353{
354 struct snd_ice1712 *ice = s->rmidi->private_data;
355 unsigned long flags;
356
357 spin_lock_irqsave(&ice->reg_lock, flags);
358 if (up) {
359 ice->midi_input = 1;
360 vt1724_midi_read(ice);
361 } else {
362 ice->midi_input = 0;
363 }
364 spin_unlock_irqrestore(&ice->reg_lock, flags);
365}
366
367static struct snd_rawmidi_ops vt1724_midi_input_ops = {
368 .open = vt1724_midi_input_open,
369 .close = vt1724_midi_input_close,
370 .trigger = vt1724_midi_input_trigger,
371};
372
250 373
251/* 374/*
252 * Interrupt handler 375 * Interrupt handler
@@ -278,13 +401,10 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
278#endif 401#endif
279 handled = 1; 402 handled = 1;
280 if (status & VT1724_IRQ_MPU_TX) { 403 if (status & VT1724_IRQ_MPU_TX) {
281 if (ice->rmidi[0]) 404 spin_lock(&ice->reg_lock);
282 snd_mpu401_uart_interrupt_tx(irq, 405 if (ice->midi_output)
283 ice->rmidi[0]->private_data); 406 vt1724_midi_write(ice);
284 else /* disable TX to be sure */ 407 spin_unlock(&ice->reg_lock);
285 outb(inb(ICEREG1724(ice, IRQMASK)) |
286 VT1724_IRQ_MPU_TX,
287 ICEREG1724(ice, IRQMASK));
288 /* Due to mysterical reasons, MPU_TX is always 408 /* Due to mysterical reasons, MPU_TX is always
289 * generated (and can't be cleared) when a PCM 409 * generated (and can't be cleared) when a PCM
290 * playback is going. So let's ignore at the 410 * playback is going. So let's ignore at the
@@ -293,13 +413,12 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
293 status_mask &= ~VT1724_IRQ_MPU_TX; 413 status_mask &= ~VT1724_IRQ_MPU_TX;
294 } 414 }
295 if (status & VT1724_IRQ_MPU_RX) { 415 if (status & VT1724_IRQ_MPU_RX) {
296 if (ice->rmidi[0]) 416 spin_lock(&ice->reg_lock);
297 snd_mpu401_uart_interrupt(irq, 417 if (ice->midi_input)
298 ice->rmidi[0]->private_data); 418 vt1724_midi_read(ice);
299 else /* disable RX to be sure */ 419 else
300 outb(inb(ICEREG1724(ice, IRQMASK)) | 420 vt1724_midi_clear_rx(ice);
301 VT1724_IRQ_MPU_RX, 421 spin_unlock(&ice->reg_lock);
302 ICEREG1724(ice, IRQMASK));
303 } 422 }
304 /* ack MPU irq */ 423 /* ack MPU irq */
305 outb(status, ICEREG1724(ice, IRQSTAT)); 424 outb(status, ICEREG1724(ice, IRQSTAT));
@@ -2425,28 +2544,30 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
2425 2544
2426 if (! c->no_mpu401) { 2545 if (! c->no_mpu401) {
2427 if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) { 2546 if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) {
2428 struct snd_mpu401 *mpu; 2547 struct snd_rawmidi *rmidi;
2429 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, 2548
2430 ICEREG1724(ice, MPU_CTRL), 2549 err = snd_rawmidi_new(card, "MIDI", 0, 1, 1, &rmidi);
2431 (MPU401_INFO_INTEGRATED | 2550 if (err < 0) {
2432 MPU401_INFO_NO_ACK |
2433 MPU401_INFO_TX_IRQ),
2434 ice->irq, 0,
2435 &ice->rmidi[0])) < 0) {
2436 snd_card_free(card); 2551 snd_card_free(card);
2437 return err; 2552 return err;
2438 } 2553 }
2439 mpu = ice->rmidi[0]->private_data; 2554 ice->rmidi[0] = rmidi;
2440 mpu->read = snd_vt1724_mpu401_read; 2555 rmidi->private_data = ice;
2441 mpu->write = snd_vt1724_mpu401_write; 2556 strcpy(rmidi->name, "ICE1724 MIDI");
2442 /* unmask MPU RX/TX irqs */ 2557 rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
2443 outb(inb(ICEREG1724(ice, IRQMASK)) & 2558 SNDRV_RAWMIDI_INFO_INPUT |
2444 ~(VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX), 2559 SNDRV_RAWMIDI_INFO_DUPLEX;
2445 ICEREG1724(ice, IRQMASK)); 2560 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
2561 &vt1724_midi_output_ops);
2562 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
2563 &vt1724_midi_input_ops);
2564
2446 /* set watermarks */ 2565 /* set watermarks */
2447 outb(VT1724_MPU_RX_FIFO | 0x1, 2566 outb(VT1724_MPU_RX_FIFO | 0x1,
2448 ICEREG1724(ice, MPU_FIFO_WM)); 2567 ICEREG1724(ice, MPU_FIFO_WM));
2449 outb(0x1, ICEREG1724(ice, MPU_FIFO_WM)); 2568 outb(0x1, ICEREG1724(ice, MPU_FIFO_WM));
2569 /* set UART mode */
2570 outb(VT1724_MPU_UART, ICEREG1724(ice, MPU_CTRL));
2450 } 2571 }
2451 } 2572 }
2452 2573
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index a536c59fbea1..f4788dee05c3 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -2427,6 +2427,29 @@ snd_m3_amp_enable(struct snd_m3 *chip, int enable)
2427 outw(0xffff, io + GPIO_MASK); 2427 outw(0xffff, io + GPIO_MASK);
2428} 2428}
2429 2429
2430static void
2431snd_m3_hv_init(struct snd_m3 *chip)
2432{
2433 unsigned long io = chip->iobase;
2434 u16 val = GPI_VOL_DOWN | GPI_VOL_UP;
2435
2436 if (!chip->is_omnibook)
2437 return;
2438
2439 /*
2440 * Volume buttons on some HP OmniBook laptops
2441 * require some GPIO magic to work correctly.
2442 */
2443 outw(0xffff, io + GPIO_MASK);
2444 outw(0x0000, io + GPIO_DATA);
2445
2446 outw(~val, io + GPIO_MASK);
2447 outw(inw(io + GPIO_DIRECTION) & ~val, io + GPIO_DIRECTION);
2448 outw(val, io + GPIO_MASK);
2449
2450 outw(0xffff, io + GPIO_MASK);
2451}
2452
2430static int 2453static int
2431snd_m3_chip_init(struct snd_m3 *chip) 2454snd_m3_chip_init(struct snd_m3 *chip)
2432{ 2455{
@@ -2442,21 +2465,6 @@ snd_m3_chip_init(struct snd_m3 *chip)
2442 DISABLE_LEGACY); 2465 DISABLE_LEGACY);
2443 pci_write_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, w); 2466 pci_write_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, w);
2444 2467
2445 if (chip->is_omnibook) {
2446 /*
2447 * Volume buttons on some HP OmniBook laptops don't work
2448 * correctly. This makes them work for the most part.
2449 *
2450 * Volume up and down buttons on the laptop side work.
2451 * Fn+cursor_up (volme up) works.
2452 * Fn+cursor_down (volume down) doesn't work.
2453 * Fn+F7 (mute) works acts as volume up.
2454 */
2455 outw(~(GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_MASK);
2456 outw(inw(io + GPIO_DIRECTION) & ~(GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_DIRECTION);
2457 outw((GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_DATA);
2458 outw(0xffff, io + GPIO_MASK);
2459 }
2460 pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n); 2468 pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
2461 n &= ~(HV_CTRL_ENABLE | REDUCED_DEBOUNCE | HV_BUTTON_FROM_GD); 2469 n &= ~(HV_CTRL_ENABLE | REDUCED_DEBOUNCE | HV_BUTTON_FROM_GD);
2462 n |= chip->hv_config; 2470 n |= chip->hv_config;
@@ -2642,6 +2650,8 @@ static int m3_resume(struct pci_dev *pci)
2642 snd_m3_enable_ints(chip); 2650 snd_m3_enable_ints(chip);
2643 snd_m3_amp_enable(chip, 1); 2651 snd_m3_amp_enable(chip, 1);
2644 2652
2653 snd_m3_hv_init(chip);
2654
2645 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2655 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2646 return 0; 2656 return 0;
2647} 2657}
@@ -2781,6 +2791,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2781 2791
2782 snd_m3_amp_enable(chip, 1); 2792 snd_m3_amp_enable(chip, 1);
2783 2793
2794 snd_m3_hv_init(chip);
2795
2784 tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip); 2796 tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
2785 2797
2786 if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED, 2798 if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED,
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 7efb838d18a6..06d13e717114 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -1302,8 +1302,8 @@ snd_nm256_mixer(struct nm256 *chip)
1302 .read = snd_nm256_ac97_read, 1302 .read = snd_nm256_ac97_read,
1303 }; 1303 };
1304 1304
1305 chip->ac97_regs = kcalloc(sizeof(short), 1305 chip->ac97_regs = kcalloc(ARRAY_SIZE(nm256_ac97_init_val),
1306 ARRAY_SIZE(nm256_ac97_init_val), GFP_KERNEL); 1306 sizeof(short), GFP_KERNEL);
1307 if (! chip->ac97_regs) 1307 if (! chip->ac97_regs)
1308 return -ENOMEM; 1308 return -ENOMEM;
1309 1309
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
index 090dd4354a28..7442460583dd 100644
--- a/sound/pci/oxygen/hifier.c
+++ b/sound/pci/oxygen/hifier.c
@@ -28,7 +28,7 @@
28 28
29MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 29MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
30MODULE_DESCRIPTION("TempoTec HiFier driver"); 30MODULE_DESCRIPTION("TempoTec HiFier driver");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL v2");
32 32
33static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 33static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
34static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 34static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
@@ -62,16 +62,28 @@ static void ak4396_write(struct oxygen *chip, u8 reg, u8 value)
62 AK4396_WRITE | (reg << 8) | value); 62 AK4396_WRITE | (reg << 8) | value);
63} 63}
64 64
65static void hifier_init(struct oxygen *chip) 65static void update_ak4396_volume(struct oxygen *chip)
66{
67 ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
68 ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
69}
70
71static void hifier_registers_init(struct oxygen *chip)
66{ 72{
67 struct hifier_data *data = chip->model_data; 73 struct hifier_data *data = chip->model_data;
68 74
69 data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
70 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); 75 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
71 ak4396_write(chip, AK4396_CONTROL_2, data->ak4396_ctl2); 76 ak4396_write(chip, AK4396_CONTROL_2, data->ak4396_ctl2);
72 ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM); 77 ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM);
73 ak4396_write(chip, AK4396_LCH_ATT, 0); 78 update_ak4396_volume(chip);
74 ak4396_write(chip, AK4396_RCH_ATT, 0); 79}
80
81static void hifier_init(struct oxygen *chip)
82{
83 struct hifier_data *data = chip->model_data;
84
85 data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
86 hifier_registers_init(chip);
75 87
76 snd_component_add(chip->card, "AK4396"); 88 snd_component_add(chip->card, "AK4396");
77 snd_component_add(chip->card, "CS5340"); 89 snd_component_add(chip->card, "CS5340");
@@ -100,12 +112,6 @@ static void set_ak4396_params(struct oxygen *chip,
100 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); 112 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
101} 113}
102 114
103static void update_ak4396_volume(struct oxygen *chip)
104{
105 ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
106 ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
107}
108
109static void update_ak4396_mute(struct oxygen *chip) 115static void update_ak4396_mute(struct oxygen *chip)
110{ 116{
111 struct hifier_data *data = chip->model_data; 117 struct hifier_data *data = chip->model_data;
@@ -140,6 +146,7 @@ static const struct oxygen_model model_hifier = {
140 .init = hifier_init, 146 .init = hifier_init,
141 .control_filter = hifier_control_filter, 147 .control_filter = hifier_control_filter,
142 .cleanup = hifier_cleanup, 148 .cleanup = hifier_cleanup,
149 .resume = hifier_registers_init,
143 .set_dac_params = set_ak4396_params, 150 .set_dac_params = set_ak4396_params,
144 .set_adc_params = set_cs5340_params, 151 .set_adc_params = set_cs5340_params,
145 .update_dac_volume = update_ak4396_volume, 152 .update_dac_volume = update_ak4396_volume,
@@ -180,6 +187,10 @@ static struct pci_driver hifier_driver = {
180 .id_table = hifier_ids, 187 .id_table = hifier_ids,
181 .probe = hifier_probe, 188 .probe = hifier_probe,
182 .remove = __devexit_p(oxygen_pci_remove), 189 .remove = __devexit_p(oxygen_pci_remove),
190#ifdef CONFIG_PM
191 .suspend = oxygen_pci_suspend,
192 .resume = oxygen_pci_resume,
193#endif
183}; 194};
184 195
185static int __init alsa_card_hifier_init(void) 196static int __init alsa_card_hifier_init(void)
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 63f185c1ed1e..7c8ae31eb468 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -43,7 +43,7 @@
43 43
44MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 44MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
45MODULE_DESCRIPTION("C-Media CMI8788 driver"); 45MODULE_DESCRIPTION("C-Media CMI8788 driver");
46MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL v2");
47MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8788}}"); 47MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8788}}");
48 48
49static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 49static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
@@ -80,6 +80,7 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids);
80 80
81struct generic_data { 81struct generic_data {
82 u8 ak4396_ctl2; 82 u8 ak4396_ctl2;
83 u16 saved_wm8785_registers[2];
83}; 84};
84 85
85static void ak4396_write(struct oxygen *chip, unsigned int codec, 86static void ak4396_write(struct oxygen *chip, unsigned int codec,
@@ -99,20 +100,35 @@ static void ak4396_write(struct oxygen *chip, unsigned int codec,
99 100
100static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value) 101static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value)
101{ 102{
103 struct generic_data *data = chip->model_data;
104
102 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | 105 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
103 OXYGEN_SPI_DATA_LENGTH_2 | 106 OXYGEN_SPI_DATA_LENGTH_2 |
104 OXYGEN_SPI_CLOCK_160 | 107 OXYGEN_SPI_CLOCK_160 |
105 (3 << OXYGEN_SPI_CODEC_SHIFT) | 108 (3 << OXYGEN_SPI_CODEC_SHIFT) |
106 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 109 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
107 (reg << 9) | value); 110 (reg << 9) | value);
111 if (reg < ARRAY_SIZE(data->saved_wm8785_registers))
112 data->saved_wm8785_registers[reg] = value;
108} 113}
109 114
110static void ak4396_init(struct oxygen *chip) 115static void update_ak4396_volume(struct oxygen *chip)
116{
117 unsigned int i;
118
119 for (i = 0; i < 4; ++i) {
120 ak4396_write(chip, i,
121 AK4396_LCH_ATT, chip->dac_volume[i * 2]);
122 ak4396_write(chip, i,
123 AK4396_RCH_ATT, chip->dac_volume[i * 2 + 1]);
124 }
125}
126
127static void ak4396_registers_init(struct oxygen *chip)
111{ 128{
112 struct generic_data *data = chip->model_data; 129 struct generic_data *data = chip->model_data;
113 unsigned int i; 130 unsigned int i;
114 131
115 data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
116 for (i = 0; i < 4; ++i) { 132 for (i = 0; i < 4; ++i) {
117 ak4396_write(chip, i, 133 ak4396_write(chip, i,
118 AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); 134 AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
@@ -120,9 +136,16 @@ static void ak4396_init(struct oxygen *chip)
120 AK4396_CONTROL_2, data->ak4396_ctl2); 136 AK4396_CONTROL_2, data->ak4396_ctl2);
121 ak4396_write(chip, i, 137 ak4396_write(chip, i,
122 AK4396_CONTROL_3, AK4396_PCM); 138 AK4396_CONTROL_3, AK4396_PCM);
123 ak4396_write(chip, i, AK4396_LCH_ATT, 0);
124 ak4396_write(chip, i, AK4396_RCH_ATT, 0);
125 } 139 }
140 update_ak4396_volume(chip);
141}
142
143static void ak4396_init(struct oxygen *chip)
144{
145 struct generic_data *data = chip->model_data;
146
147 data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
148 ak4396_registers_init(chip);
126 snd_component_add(chip->card, "AK4396"); 149 snd_component_add(chip->card, "AK4396");
127} 150}
128 151
@@ -133,12 +156,23 @@ static void ak5385_init(struct oxygen *chip)
133 snd_component_add(chip->card, "AK5385"); 156 snd_component_add(chip->card, "AK5385");
134} 157}
135 158
136static void wm8785_init(struct oxygen *chip) 159static void wm8785_registers_init(struct oxygen *chip)
137{ 160{
161 struct generic_data *data = chip->model_data;
162
138 wm8785_write(chip, WM8785_R7, 0); 163 wm8785_write(chip, WM8785_R7, 0);
139 wm8785_write(chip, WM8785_R0, WM8785_MCR_SLAVE | 164 wm8785_write(chip, WM8785_R0, data->saved_wm8785_registers[0]);
140 WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST); 165 wm8785_write(chip, WM8785_R1, data->saved_wm8785_registers[1]);
141 wm8785_write(chip, WM8785_R1, WM8785_WL_24); 166}
167
168static void wm8785_init(struct oxygen *chip)
169{
170 struct generic_data *data = chip->model_data;
171
172 data->saved_wm8785_registers[0] = WM8785_MCR_SLAVE |
173 WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST;
174 data->saved_wm8785_registers[1] = WM8785_WL_24;
175 wm8785_registers_init(chip);
142 snd_component_add(chip->card, "WM8785"); 176 snd_component_add(chip->card, "WM8785");
143} 177}
144 178
@@ -158,6 +192,12 @@ static void generic_cleanup(struct oxygen *chip)
158{ 192{
159} 193}
160 194
195static void generic_resume(struct oxygen *chip)
196{
197 ak4396_registers_init(chip);
198 wm8785_registers_init(chip);
199}
200
161static void set_ak4396_params(struct oxygen *chip, 201static void set_ak4396_params(struct oxygen *chip,
162 struct snd_pcm_hw_params *params) 202 struct snd_pcm_hw_params *params)
163{ 203{
@@ -183,18 +223,6 @@ static void set_ak4396_params(struct oxygen *chip,
183 } 223 }
184} 224}
185 225
186static void update_ak4396_volume(struct oxygen *chip)
187{
188 unsigned int i;
189
190 for (i = 0; i < 4; ++i) {
191 ak4396_write(chip, i,
192 AK4396_LCH_ATT, chip->dac_volume[i * 2]);
193 ak4396_write(chip, i,
194 AK4396_RCH_ATT, chip->dac_volume[i * 2 + 1]);
195 }
196}
197
198static void update_ak4396_mute(struct oxygen *chip) 226static void update_ak4396_mute(struct oxygen *chip)
199{ 227{
200 struct generic_data *data = chip->model_data; 228 struct generic_data *data = chip->model_data;
@@ -256,6 +284,7 @@ static const struct oxygen_model model_generic = {
256 .owner = THIS_MODULE, 284 .owner = THIS_MODULE,
257 .init = generic_init, 285 .init = generic_init,
258 .cleanup = generic_cleanup, 286 .cleanup = generic_cleanup,
287 .resume = generic_resume,
259 .set_dac_params = set_ak4396_params, 288 .set_dac_params = set_ak4396_params,
260 .set_adc_params = set_wm8785_params, 289 .set_adc_params = set_wm8785_params,
261 .update_dac_volume = update_ak4396_volume, 290 .update_dac_volume = update_ak4396_volume,
@@ -283,6 +312,7 @@ static const struct oxygen_model model_meridian = {
283 .owner = THIS_MODULE, 312 .owner = THIS_MODULE,
284 .init = meridian_init, 313 .init = meridian_init,
285 .cleanup = generic_cleanup, 314 .cleanup = generic_cleanup,
315 .resume = ak4396_registers_init,
286 .set_dac_params = set_ak4396_params, 316 .set_dac_params = set_ak4396_params,
287 .set_adc_params = set_ak5385_params, 317 .set_adc_params = set_ak5385_params,
288 .update_dac_volume = update_ak4396_volume, 318 .update_dac_volume = update_ak4396_volume,
@@ -331,6 +361,10 @@ static struct pci_driver oxygen_driver = {
331 .id_table = oxygen_ids, 361 .id_table = oxygen_ids,
332 .probe = generic_oxygen_probe, 362 .probe = generic_oxygen_probe,
333 .remove = __devexit_p(oxygen_pci_remove), 363 .remove = __devexit_p(oxygen_pci_remove),
364#ifdef CONFIG_PM
365 .suspend = oxygen_pci_suspend,
366 .resume = oxygen_pci_resume,
367#endif
334}; 368};
335 369
336static int __init alsa_card_oxygen_init(void) 370static int __init alsa_card_oxygen_init(void)
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index a71c6e059260..74a644880074 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -16,6 +16,8 @@
16#define PCM_AC97 5 16#define PCM_AC97 5
17#define PCM_COUNT 6 17#define PCM_COUNT 6
18 18
19#define OXYGEN_IO_SIZE 0x100
20
19/* model-specific configuration of outputs/inputs */ 21/* model-specific configuration of outputs/inputs */
20#define PLAYBACK_0_TO_I2S 0x001 22#define PLAYBACK_0_TO_I2S 0x001
21#define PLAYBACK_1_TO_SPDIF 0x004 23#define PLAYBACK_1_TO_SPDIF 0x004
@@ -78,6 +80,12 @@ struct oxygen {
78 struct work_struct spdif_input_bits_work; 80 struct work_struct spdif_input_bits_work;
79 struct work_struct gpio_work; 81 struct work_struct gpio_work;
80 wait_queue_head_t ac97_waitqueue; 82 wait_queue_head_t ac97_waitqueue;
83 union {
84 u8 _8[OXYGEN_IO_SIZE];
85 __le16 _16[OXYGEN_IO_SIZE / 2];
86 __le32 _32[OXYGEN_IO_SIZE / 4];
87 } saved_registers;
88 u16 saved_ac97_registers[2][0x40];
81}; 89};
82 90
83struct oxygen_model { 91struct oxygen_model {
@@ -89,6 +97,8 @@ struct oxygen_model {
89 int (*control_filter)(struct snd_kcontrol_new *template); 97 int (*control_filter)(struct snd_kcontrol_new *template);
90 int (*mixer_init)(struct oxygen *chip); 98 int (*mixer_init)(struct oxygen *chip);
91 void (*cleanup)(struct oxygen *chip); 99 void (*cleanup)(struct oxygen *chip);
100 void (*suspend)(struct oxygen *chip);
101 void (*resume)(struct oxygen *chip);
92 void (*pcm_hardware_filter)(unsigned int channel, 102 void (*pcm_hardware_filter)(unsigned int channel,
93 struct snd_pcm_hardware *hardware); 103 struct snd_pcm_hardware *hardware);
94 void (*set_dac_params)(struct oxygen *chip, 104 void (*set_dac_params)(struct oxygen *chip,
@@ -117,6 +127,10 @@ struct oxygen_model {
117int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, 127int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
118 const struct oxygen_model *model); 128 const struct oxygen_model *model);
119void oxygen_pci_remove(struct pci_dev *pci); 129void oxygen_pci_remove(struct pci_dev *pci);
130#ifdef CONFIG_PM
131int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state);
132int oxygen_pci_resume(struct pci_dev *pci);
133#endif
120 134
121/* oxygen_mixer.c */ 135/* oxygen_mixer.c */
122 136
diff --git a/sound/pci/oxygen/oxygen_io.c b/sound/pci/oxygen/oxygen_io.c
index 5569606ee87f..83f135f80df4 100644
--- a/sound/pci/oxygen/oxygen_io.c
+++ b/sound/pci/oxygen/oxygen_io.c
@@ -44,18 +44,21 @@ EXPORT_SYMBOL(oxygen_read32);
44void oxygen_write8(struct oxygen *chip, unsigned int reg, u8 value) 44void oxygen_write8(struct oxygen *chip, unsigned int reg, u8 value)
45{ 45{
46 outb(value, chip->addr + reg); 46 outb(value, chip->addr + reg);
47 chip->saved_registers._8[reg] = value;
47} 48}
48EXPORT_SYMBOL(oxygen_write8); 49EXPORT_SYMBOL(oxygen_write8);
49 50
50void oxygen_write16(struct oxygen *chip, unsigned int reg, u16 value) 51void oxygen_write16(struct oxygen *chip, unsigned int reg, u16 value)
51{ 52{
52 outw(value, chip->addr + reg); 53 outw(value, chip->addr + reg);
54 chip->saved_registers._16[reg / 2] = cpu_to_le16(value);
53} 55}
54EXPORT_SYMBOL(oxygen_write16); 56EXPORT_SYMBOL(oxygen_write16);
55 57
56void oxygen_write32(struct oxygen *chip, unsigned int reg, u32 value) 58void oxygen_write32(struct oxygen *chip, unsigned int reg, u32 value)
57{ 59{
58 outl(value, chip->addr + reg); 60 outl(value, chip->addr + reg);
61 chip->saved_registers._32[reg / 4] = cpu_to_le32(value);
59} 62}
60EXPORT_SYMBOL(oxygen_write32); 63EXPORT_SYMBOL(oxygen_write32);
61 64
@@ -63,7 +66,10 @@ void oxygen_write8_masked(struct oxygen *chip, unsigned int reg,
63 u8 value, u8 mask) 66 u8 value, u8 mask)
64{ 67{
65 u8 tmp = inb(chip->addr + reg); 68 u8 tmp = inb(chip->addr + reg);
66 outb((tmp & ~mask) | (value & mask), chip->addr + reg); 69 tmp &= ~mask;
70 tmp |= value & mask;
71 outb(tmp, chip->addr + reg);
72 chip->saved_registers._8[reg] = tmp;
67} 73}
68EXPORT_SYMBOL(oxygen_write8_masked); 74EXPORT_SYMBOL(oxygen_write8_masked);
69 75
@@ -71,7 +77,10 @@ void oxygen_write16_masked(struct oxygen *chip, unsigned int reg,
71 u16 value, u16 mask) 77 u16 value, u16 mask)
72{ 78{
73 u16 tmp = inw(chip->addr + reg); 79 u16 tmp = inw(chip->addr + reg);
74 outw((tmp & ~mask) | (value & mask), chip->addr + reg); 80 tmp &= ~mask;
81 tmp |= value & mask;
82 outw(tmp, chip->addr + reg);
83 chip->saved_registers._16[reg / 2] = cpu_to_le16(tmp);
75} 84}
76EXPORT_SYMBOL(oxygen_write16_masked); 85EXPORT_SYMBOL(oxygen_write16_masked);
77 86
@@ -79,7 +88,10 @@ void oxygen_write32_masked(struct oxygen *chip, unsigned int reg,
79 u32 value, u32 mask) 88 u32 value, u32 mask)
80{ 89{
81 u32 tmp = inl(chip->addr + reg); 90 u32 tmp = inl(chip->addr + reg);
82 outl((tmp & ~mask) | (value & mask), chip->addr + reg); 91 tmp &= ~mask;
92 tmp |= value & mask;
93 outl(tmp, chip->addr + reg);
94 chip->saved_registers._32[reg / 4] = cpu_to_le32(tmp);
83} 95}
84EXPORT_SYMBOL(oxygen_write32_masked); 96EXPORT_SYMBOL(oxygen_write32_masked);
85 97
@@ -128,8 +140,10 @@ void oxygen_write_ac97(struct oxygen *chip, unsigned int codec,
128 oxygen_write32(chip, OXYGEN_AC97_REGS, reg); 140 oxygen_write32(chip, OXYGEN_AC97_REGS, reg);
129 /* require two "completed" writes, just to be sure */ 141 /* require two "completed" writes, just to be sure */
130 if (oxygen_ac97_wait(chip, OXYGEN_AC97_INT_WRITE_DONE) >= 0 && 142 if (oxygen_ac97_wait(chip, OXYGEN_AC97_INT_WRITE_DONE) >= 0 &&
131 ++succeeded >= 2) 143 ++succeeded >= 2) {
144 chip->saved_ac97_registers[codec][index / 2] = data;
132 return; 145 return;
146 }
133 } 147 }
134 snd_printk(KERN_ERR "AC'97 write timeout\n"); 148 snd_printk(KERN_ERR "AC'97 write timeout\n");
135} 149}
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 897697d43506..22f37851045e 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -32,7 +32,7 @@
32 32
33MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 33MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
34MODULE_DESCRIPTION("C-Media CMI8788 helper library"); 34MODULE_DESCRIPTION("C-Media CMI8788 helper library");
35MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL v2");
36 36
37 37
38static irqreturn_t oxygen_interrupt(int dummy, void *dev_id) 38static irqreturn_t oxygen_interrupt(int dummy, void *dev_id)
@@ -173,7 +173,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
173 int i, j; 173 int i, j;
174 174
175 snd_iprintf(buffer, "CMI8788\n\n"); 175 snd_iprintf(buffer, "CMI8788\n\n");
176 for (i = 0; i < 0x100; i += 0x10) { 176 for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) {
177 snd_iprintf(buffer, "%02x:", i); 177 snd_iprintf(buffer, "%02x:", i);
178 for (j = 0; j < 0x10; ++j) 178 for (j = 0; j < 0x10; ++j)
179 snd_iprintf(buffer, " %02x", oxygen_read8(chip, i + j)); 179 snd_iprintf(buffer, " %02x", oxygen_read8(chip, i + j));
@@ -314,6 +314,10 @@ static void oxygen_init(struct oxygen *chip)
314 OXYGEN_SPDIF_LOCK_MASK | 314 OXYGEN_SPDIF_LOCK_MASK |
315 OXYGEN_SPDIF_RATE_MASK); 315 OXYGEN_SPDIF_RATE_MASK);
316 oxygen_write32(chip, OXYGEN_SPDIF_OUTPUT_BITS, chip->spdif_bits); 316 oxygen_write32(chip, OXYGEN_SPDIF_OUTPUT_BITS, chip->spdif_bits);
317 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
318 OXYGEN_2WIRE_LENGTH_8 |
319 OXYGEN_2WIRE_INTERRUPT_MASK |
320 OXYGEN_2WIRE_SPEED_STANDARD);
317 oxygen_clear_bits8(chip, OXYGEN_MPU401_CONTROL, OXYGEN_MPU401_LOOPBACK); 321 oxygen_clear_bits8(chip, OXYGEN_MPU401_CONTROL, OXYGEN_MPU401_LOOPBACK);
318 oxygen_write8(chip, OXYGEN_GPI_INTERRUPT_MASK, 0); 322 oxygen_write8(chip, OXYGEN_GPI_INTERRUPT_MASK, 0);
319 oxygen_write16(chip, OXYGEN_GPIO_INTERRUPT_MASK, 0); 323 oxygen_write16(chip, OXYGEN_GPIO_INTERRUPT_MASK, 0);
@@ -455,7 +459,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
455 } 459 }
456 460
457 if (!(pci_resource_flags(pci, 0) & IORESOURCE_IO) || 461 if (!(pci_resource_flags(pci, 0) & IORESOURCE_IO) ||
458 pci_resource_len(pci, 0) < 0x100) { 462 pci_resource_len(pci, 0) < OXYGEN_IO_SIZE) {
459 snd_printk(KERN_ERR "invalid PCI I/O range\n"); 463 snd_printk(KERN_ERR "invalid PCI I/O range\n");
460 err = -ENXIO; 464 err = -ENXIO;
461 goto err_pci_regions; 465 goto err_pci_regions;
@@ -534,3 +538,99 @@ void oxygen_pci_remove(struct pci_dev *pci)
534 pci_set_drvdata(pci, NULL); 538 pci_set_drvdata(pci, NULL);
535} 539}
536EXPORT_SYMBOL(oxygen_pci_remove); 540EXPORT_SYMBOL(oxygen_pci_remove);
541
542#ifdef CONFIG_PM
543int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state)
544{
545 struct snd_card *card = pci_get_drvdata(pci);
546 struct oxygen *chip = card->private_data;
547 unsigned int i, saved_interrupt_mask;
548
549 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
550
551 for (i = 0; i < PCM_COUNT; ++i)
552 if (chip->streams[i])
553 snd_pcm_suspend(chip->streams[i]);
554
555 if (chip->model->suspend)
556 chip->model->suspend(chip);
557
558 spin_lock_irq(&chip->reg_lock);
559 saved_interrupt_mask = chip->interrupt_mask;
560 chip->interrupt_mask = 0;
561 oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
562 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
563 spin_unlock_irq(&chip->reg_lock);
564
565 synchronize_irq(chip->irq);
566 flush_scheduled_work();
567 chip->interrupt_mask = saved_interrupt_mask;
568
569 pci_disable_device(pci);
570 pci_save_state(pci);
571 pci_set_power_state(pci, pci_choose_state(pci, state));
572 return 0;
573}
574EXPORT_SYMBOL(oxygen_pci_suspend);
575
576static const u32 registers_to_restore[OXYGEN_IO_SIZE / 32] = {
577 0xffffffff, 0x00ff077f, 0x00011d08, 0x007f00ff,
578 0x00300000, 0x00000fe4, 0x0ff7001f, 0x00000000
579};
580static const u32 ac97_registers_to_restore[2][0x40 / 32] = {
581 { 0x18284fa2, 0x03060000 },
582 { 0x00007fa6, 0x00200000 }
583};
584
585static inline int is_bit_set(const u32 *bitmap, unsigned int bit)
586{
587 return bitmap[bit / 32] & (1 << (bit & 31));
588}
589
590static void oxygen_restore_ac97(struct oxygen *chip, unsigned int codec)
591{
592 unsigned int i;
593
594 oxygen_write_ac97(chip, codec, AC97_RESET, 0);
595 msleep(1);
596 for (i = 1; i < 0x40; ++i)
597 if (is_bit_set(ac97_registers_to_restore[codec], i))
598 oxygen_write_ac97(chip, codec, i * 2,
599 chip->saved_ac97_registers[codec][i]);
600}
601
602int oxygen_pci_resume(struct pci_dev *pci)
603{
604 struct snd_card *card = pci_get_drvdata(pci);
605 struct oxygen *chip = card->private_data;
606 unsigned int i;
607
608 pci_set_power_state(pci, PCI_D0);
609 pci_restore_state(pci);
610 if (pci_enable_device(pci) < 0) {
611 snd_printk(KERN_ERR "cannot reenable device");
612 snd_card_disconnect(card);
613 return -EIO;
614 }
615 pci_set_master(pci);
616
617 oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
618 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
619 for (i = 0; i < OXYGEN_IO_SIZE; ++i)
620 if (is_bit_set(registers_to_restore, i))
621 oxygen_write8(chip, i, chip->saved_registers._8[i]);
622 if (chip->has_ac97_0)
623 oxygen_restore_ac97(chip, 0);
624 if (chip->has_ac97_1)
625 oxygen_restore_ac97(chip, 1);
626
627 if (chip->model->resume)
628 chip->model->resume(chip);
629
630 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
631
632 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
633 return 0;
634}
635EXPORT_SYMBOL(oxygen_pci_resume);
636#endif /* CONFIG_PM */
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index b17c405e069d..c4ad65a3406f 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -24,6 +24,16 @@
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include "oxygen.h" 25#include "oxygen.h"
26 26
27/* most DMA channels have a 16-bit counter for 32-bit words */
28#define BUFFER_BYTES_MAX ((1 << 16) * 4)
29/* the multichannel DMA channel has a 24-bit counter */
30#define BUFFER_BYTES_MAX_MULTICH ((1 << 24) * 4)
31
32#define PERIOD_BYTES_MIN 64
33
34#define DEFAULT_BUFFER_BYTES (BUFFER_BYTES_MAX / 2)
35#define DEFAULT_BUFFER_BYTES_MULTICH (1024 * 1024)
36
27static const struct snd_pcm_hardware oxygen_stereo_hardware = { 37static const struct snd_pcm_hardware oxygen_stereo_hardware = {
28 .info = SNDRV_PCM_INFO_MMAP | 38 .info = SNDRV_PCM_INFO_MMAP |
29 SNDRV_PCM_INFO_MMAP_VALID | 39 SNDRV_PCM_INFO_MMAP_VALID |
@@ -44,11 +54,11 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = {
44 .rate_max = 192000, 54 .rate_max = 192000,
45 .channels_min = 2, 55 .channels_min = 2,
46 .channels_max = 2, 56 .channels_max = 2,
47 .buffer_bytes_max = 256 * 1024, 57 .buffer_bytes_max = BUFFER_BYTES_MAX,
48 .period_bytes_min = 128, 58 .period_bytes_min = PERIOD_BYTES_MIN,
49 .period_bytes_max = 128 * 1024, 59 .period_bytes_max = BUFFER_BYTES_MAX / 2,
50 .periods_min = 2, 60 .periods_min = 2,
51 .periods_max = 2048, 61 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
52}; 62};
53static const struct snd_pcm_hardware oxygen_multichannel_hardware = { 63static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
54 .info = SNDRV_PCM_INFO_MMAP | 64 .info = SNDRV_PCM_INFO_MMAP |
@@ -70,11 +80,11 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
70 .rate_max = 192000, 80 .rate_max = 192000,
71 .channels_min = 2, 81 .channels_min = 2,
72 .channels_max = 8, 82 .channels_max = 8,
73 .buffer_bytes_max = 2048 * 1024, 83 .buffer_bytes_max = BUFFER_BYTES_MAX_MULTICH,
74 .period_bytes_min = 128, 84 .period_bytes_min = PERIOD_BYTES_MIN,
75 .period_bytes_max = 256 * 1024, 85 .period_bytes_max = BUFFER_BYTES_MAX_MULTICH / 2,
76 .periods_min = 2, 86 .periods_min = 2,
77 .periods_max = 16384, 87 .periods_max = BUFFER_BYTES_MAX_MULTICH / PERIOD_BYTES_MIN,
78}; 88};
79static const struct snd_pcm_hardware oxygen_ac97_hardware = { 89static const struct snd_pcm_hardware oxygen_ac97_hardware = {
80 .info = SNDRV_PCM_INFO_MMAP | 90 .info = SNDRV_PCM_INFO_MMAP |
@@ -88,11 +98,11 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = {
88 .rate_max = 48000, 98 .rate_max = 48000,
89 .channels_min = 2, 99 .channels_min = 2,
90 .channels_max = 2, 100 .channels_max = 2,
91 .buffer_bytes_max = 256 * 1024, 101 .buffer_bytes_max = BUFFER_BYTES_MAX,
92 .period_bytes_min = 128, 102 .period_bytes_min = PERIOD_BYTES_MIN,
93 .period_bytes_max = 128 * 1024, 103 .period_bytes_max = BUFFER_BYTES_MAX / 2,
94 .periods_min = 2, 104 .periods_min = 2,
95 .periods_max = 2048, 105 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
96}; 106};
97 107
98static const struct snd_pcm_hardware *const oxygen_hardware[PCM_COUNT] = { 108static const struct snd_pcm_hardware *const oxygen_hardware[PCM_COUNT] = {
@@ -155,6 +165,12 @@ static int oxygen_open(struct snd_pcm_substream *substream,
155 if (err < 0) 165 if (err < 0)
156 return err; 166 return err;
157 } 167 }
168 if (channel == PCM_MULTICH) {
169 err = snd_pcm_hw_constraint_minmax
170 (runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 0, 8192000);
171 if (err < 0)
172 return err;
173 }
158 snd_pcm_set_sync(substream); 174 snd_pcm_set_sync(substream);
159 chip->streams[channel] = substream; 175 chip->streams[channel] = substream;
160 176
@@ -517,6 +533,7 @@ static int oxygen_trigger(struct snd_pcm_substream *substream, int cmd)
517 switch (cmd) { 533 switch (cmd) {
518 case SNDRV_PCM_TRIGGER_STOP: 534 case SNDRV_PCM_TRIGGER_STOP:
519 case SNDRV_PCM_TRIGGER_START: 535 case SNDRV_PCM_TRIGGER_START:
536 case SNDRV_PCM_TRIGGER_SUSPEND:
520 pausing = 0; 537 pausing = 0;
521 break; 538 break;
522 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 539 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
@@ -663,12 +680,14 @@ int oxygen_pcm_init(struct oxygen *chip)
663 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream, 680 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
664 SNDRV_DMA_TYPE_DEV, 681 SNDRV_DMA_TYPE_DEV,
665 snd_dma_pci_data(chip->pci), 682 snd_dma_pci_data(chip->pci),
666 512 * 1024, 2048 * 1024); 683 DEFAULT_BUFFER_BYTES_MULTICH,
684 BUFFER_BYTES_MAX_MULTICH);
667 if (ins) 685 if (ins)
668 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream, 686 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
669 SNDRV_DMA_TYPE_DEV, 687 SNDRV_DMA_TYPE_DEV,
670 snd_dma_pci_data(chip->pci), 688 snd_dma_pci_data(chip->pci),
671 128 * 1024, 256 * 1024); 689 DEFAULT_BUFFER_BYTES,
690 BUFFER_BYTES_MAX);
672 } 691 }
673 692
674 outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_1_TO_SPDIF); 693 outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_1_TO_SPDIF);
@@ -688,7 +707,8 @@ int oxygen_pcm_init(struct oxygen *chip)
688 strcpy(pcm->name, "Digital"); 707 strcpy(pcm->name, "Digital");
689 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 708 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
690 snd_dma_pci_data(chip->pci), 709 snd_dma_pci_data(chip->pci),
691 128 * 1024, 256 * 1024); 710 DEFAULT_BUFFER_BYTES,
711 BUFFER_BYTES_MAX);
692 } 712 }
693 713
694 if (chip->has_ac97_1) { 714 if (chip->has_ac97_1) {
@@ -718,7 +738,8 @@ int oxygen_pcm_init(struct oxygen *chip)
718 strcpy(pcm->name, outs ? "Front Panel" : "Analog 2"); 738 strcpy(pcm->name, outs ? "Front Panel" : "Analog 2");
719 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 739 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
720 snd_dma_pci_data(chip->pci), 740 snd_dma_pci_data(chip->pci),
721 128 * 1024, 256 * 1024); 741 DEFAULT_BUFFER_BYTES,
742 BUFFER_BYTES_MAX);
722 } 743 }
723 return 0; 744 return 0;
724} 745}
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 7f84fa5deca2..9a2c16bf94e0 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -79,7 +79,7 @@
79 79
80MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 80MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
81MODULE_DESCRIPTION("Asus AVx00 driver"); 81MODULE_DESCRIPTION("Asus AVx00 driver");
82MODULE_LICENSE("GPL"); 82MODULE_LICENSE("GPL v2");
83MODULE_SUPPORTED_DEVICE("{{Asus,AV100},{Asus,AV200}}"); 83MODULE_SUPPORTED_DEVICE("{{Asus,AV100},{Asus,AV200}}");
84 84
85static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 85static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
@@ -132,6 +132,9 @@ struct xonar_data {
132 u8 ext_power_int_reg; 132 u8 ext_power_int_reg;
133 u8 ext_power_bit; 133 u8 ext_power_bit;
134 u8 has_power; 134 u8 has_power;
135 u8 pcm1796_oversampling;
136 u8 cs4398_fm;
137 u8 cs4362a_fm;
135}; 138};
136 139
137static void pcm1796_write(struct oxygen *chip, unsigned int codec, 140static void pcm1796_write(struct oxygen *chip, unsigned int codec,
@@ -159,6 +162,14 @@ static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value)
159 oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value); 162 oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value);
160} 163}
161 164
165static void xonar_enable_output(struct oxygen *chip)
166{
167 struct xonar_data *data = chip->model_data;
168
169 msleep(data->anti_pop_delay);
170 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
171}
172
162static void xonar_common_init(struct oxygen *chip) 173static void xonar_common_init(struct oxygen *chip)
163{ 174{
164 struct xonar_data *data = chip->model_data; 175 struct xonar_data *data = chip->model_data;
@@ -170,32 +181,59 @@ static void xonar_common_init(struct oxygen *chip)
170 data->has_power = !!(oxygen_read8(chip, data->ext_power_reg) 181 data->has_power = !!(oxygen_read8(chip, data->ext_power_reg)
171 & data->ext_power_bit); 182 & data->ext_power_bit);
172 } 183 }
173 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CS53x1_M_MASK); 184 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
185 GPIO_CS53x1_M_MASK | data->output_enable_bit);
174 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 186 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
175 GPIO_CS53x1_M_SINGLE, GPIO_CS53x1_M_MASK); 187 GPIO_CS53x1_M_SINGLE, GPIO_CS53x1_M_MASK);
176 oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC); 188 oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
177 msleep(data->anti_pop_delay); 189 xonar_enable_output(chip);
178 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, data->output_enable_bit);
179 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
180} 190}
181 191
182static void xonar_d2_init(struct oxygen *chip) 192static void update_pcm1796_volume(struct oxygen *chip)
183{ 193{
184 struct xonar_data *data = chip->model_data;
185 unsigned int i; 194 unsigned int i;
186 195
187 data->anti_pop_delay = 300; 196 for (i = 0; i < 4; ++i) {
188 data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE; 197 pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]);
198 pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]);
199 }
200}
201
202static void update_pcm1796_mute(struct oxygen *chip)
203{
204 unsigned int i;
205 u8 value;
206
207 value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD;
208 if (chip->dac_mute)
209 value |= PCM1796_MUTE;
210 for (i = 0; i < 4; ++i)
211 pcm1796_write(chip, i, 18, value);
212}
213
214static void pcm1796_init(struct oxygen *chip)
215{
216 struct xonar_data *data = chip->model_data;
217 unsigned int i;
189 218
190 for (i = 0; i < 4; ++i) { 219 for (i = 0; i < 4; ++i) {
191 pcm1796_write(chip, i, 18, PCM1796_MUTE | PCM1796_DMF_DISABLED |
192 PCM1796_FMT_24_LJUST | PCM1796_ATLD);
193 pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1); 220 pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1);
194 pcm1796_write(chip, i, 20, PCM1796_OS_64); 221 pcm1796_write(chip, i, 20, data->pcm1796_oversampling);
195 pcm1796_write(chip, i, 21, 0); 222 pcm1796_write(chip, i, 21, 0);
196 pcm1796_write(chip, i, 16, 0x0f); /* set ATL/ATR after ATLD */
197 pcm1796_write(chip, i, 17, 0x0f);
198 } 223 }
224 update_pcm1796_mute(chip); /* set ATLD before ATL/ATR */
225 update_pcm1796_volume(chip);
226}
227
228static void xonar_d2_init(struct oxygen *chip)
229{
230 struct xonar_data *data = chip->model_data;
231
232 data->anti_pop_delay = 300;
233 data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE;
234 data->pcm1796_oversampling = PCM1796_OS_64;
235
236 pcm1796_init(chip);
199 237
200 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2_ALT); 238 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2_ALT);
201 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D2_ALT); 239 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D2_ALT);
@@ -217,31 +255,47 @@ static void xonar_d2x_init(struct oxygen *chip)
217 xonar_d2_init(chip); 255 xonar_d2_init(chip);
218} 256}
219 257
220static void xonar_dx_init(struct oxygen *chip) 258static void update_cs4362a_volumes(struct oxygen *chip)
221{ 259{
222 struct xonar_data *data = chip->model_data; 260 u8 mute;
223 261
224 data->anti_pop_delay = 800; 262 mute = chip->dac_mute ? CS4362A_MUTE : 0;
225 data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE; 263 cs4362a_write(chip, 7, (127 - chip->dac_volume[2]) | mute);
226 data->ext_power_reg = OXYGEN_GPI_DATA; 264 cs4362a_write(chip, 8, (127 - chip->dac_volume[3]) | mute);
227 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; 265 cs4362a_write(chip, 10, (127 - chip->dac_volume[4]) | mute);
228 data->ext_power_bit = GPI_DX_EXT_POWER; 266 cs4362a_write(chip, 11, (127 - chip->dac_volume[5]) | mute);
267 cs4362a_write(chip, 13, (127 - chip->dac_volume[6]) | mute);
268 cs4362a_write(chip, 14, (127 - chip->dac_volume[7]) | mute);
269}
229 270
230 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, 271static void update_cs43xx_volume(struct oxygen *chip)
231 OXYGEN_2WIRE_LENGTH_8 | 272{
232 OXYGEN_2WIRE_INTERRUPT_MASK | 273 cs4398_write(chip, 5, (127 - chip->dac_volume[0]) * 2);
233 OXYGEN_2WIRE_SPEED_FAST); 274 cs4398_write(chip, 6, (127 - chip->dac_volume[1]) * 2);
275 update_cs4362a_volumes(chip);
276}
277
278static void update_cs43xx_mute(struct oxygen *chip)
279{
280 u8 reg;
281
282 reg = CS4398_MUTEP_LOW | CS4398_PAMUTE;
283 if (chip->dac_mute)
284 reg |= CS4398_MUTE_B | CS4398_MUTE_A;
285 cs4398_write(chip, 4, reg);
286 update_cs4362a_volumes(chip);
287}
288
289static void cs43xx_init(struct oxygen *chip)
290{
291 struct xonar_data *data = chip->model_data;
234 292
235 /* set CPEN (control port mode) and power down */ 293 /* set CPEN (control port mode) and power down */
236 cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN); 294 cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN);
237 cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN); 295 cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
238 /* configure */ 296 /* configure */
239 cs4398_write(chip, 2, CS4398_FM_SINGLE | 297 cs4398_write(chip, 2, data->cs4398_fm);
240 CS4398_DEM_NONE | CS4398_DIF_LJUST);
241 cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L); 298 cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L);
242 cs4398_write(chip, 4, CS4398_MUTEP_LOW | CS4398_PAMUTE);
243 cs4398_write(chip, 5, 0xfe);
244 cs4398_write(chip, 6, 0xfe);
245 cs4398_write(chip, 7, CS4398_RMP_DN | CS4398_RMP_UP | 299 cs4398_write(chip, 7, CS4398_RMP_DN | CS4398_RMP_UP |
246 CS4398_ZERO_CROSS | CS4398_SOFT_RAMP); 300 CS4398_ZERO_CROSS | CS4398_SOFT_RAMP);
247 cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST); 301 cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST);
@@ -249,21 +303,35 @@ static void xonar_dx_init(struct oxygen *chip)
249 CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP); 303 CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP);
250 cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE); 304 cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE);
251 cs4362a_write(chip, 0x05, 0); 305 cs4362a_write(chip, 0x05, 0);
252 cs4362a_write(chip, 0x06, CS4362A_FM_SINGLE | 306 cs4362a_write(chip, 0x06, data->cs4362a_fm);
253 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L); 307 cs4362a_write(chip, 0x09, data->cs4362a_fm);
254 cs4362a_write(chip, 0x07, 0x7f | CS4362A_MUTE); 308 cs4362a_write(chip, 0x0c, data->cs4362a_fm);
255 cs4362a_write(chip, 0x08, 0x7f | CS4362A_MUTE); 309 update_cs43xx_volume(chip);
256 cs4362a_write(chip, 0x09, CS4362A_FM_SINGLE | 310 update_cs43xx_mute(chip);
257 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L);
258 cs4362a_write(chip, 0x0a, 0x7f | CS4362A_MUTE);
259 cs4362a_write(chip, 0x0b, 0x7f | CS4362A_MUTE);
260 cs4362a_write(chip, 0x0c, CS4362A_FM_SINGLE |
261 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L);
262 cs4362a_write(chip, 0x0d, 0x7f | CS4362A_MUTE);
263 cs4362a_write(chip, 0x0e, 0x7f | CS4362A_MUTE);
264 /* clear power down */ 311 /* clear power down */
265 cs4398_write(chip, 8, CS4398_CPEN); 312 cs4398_write(chip, 8, CS4398_CPEN);
266 cs4362a_write(chip, 0x01, CS4362A_CPEN); 313 cs4362a_write(chip, 0x01, CS4362A_CPEN);
314}
315
316static void xonar_dx_init(struct oxygen *chip)
317{
318 struct xonar_data *data = chip->model_data;
319
320 data->anti_pop_delay = 800;
321 data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
322 data->ext_power_reg = OXYGEN_GPI_DATA;
323 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
324 data->ext_power_bit = GPI_DX_EXT_POWER;
325 data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
326 data->cs4362a_fm = CS4362A_FM_SINGLE |
327 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
328
329 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
330 OXYGEN_2WIRE_LENGTH_8 |
331 OXYGEN_2WIRE_INTERRUPT_MASK |
332 OXYGEN_2WIRE_SPEED_FAST);
333
334 cs43xx_init(chip);
267 335
268 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 336 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
269 GPIO_DX_FRONT_PANEL | GPIO_DX_INPUT_ROUTE); 337 GPIO_DX_FRONT_PANEL | GPIO_DX_INPUT_ROUTE);
@@ -291,37 +359,28 @@ static void xonar_dx_cleanup(struct oxygen *chip)
291 oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC); 359 oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
292} 360}
293 361
294static void set_pcm1796_params(struct oxygen *chip, 362static void xonar_d2_resume(struct oxygen *chip)
295 struct snd_pcm_hw_params *params)
296{ 363{
297 unsigned int i; 364 pcm1796_init(chip);
298 u8 value; 365 xonar_enable_output(chip);
299
300 value = params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64;
301 for (i = 0; i < 4; ++i)
302 pcm1796_write(chip, i, 20, value);
303} 366}
304 367
305static void update_pcm1796_volume(struct oxygen *chip) 368static void xonar_dx_resume(struct oxygen *chip)
306{ 369{
307 unsigned int i; 370 cs43xx_init(chip);
308 371 xonar_enable_output(chip);
309 for (i = 0; i < 4; ++i) {
310 pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]);
311 pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]);
312 }
313} 372}
314 373
315static void update_pcm1796_mute(struct oxygen *chip) 374static void set_pcm1796_params(struct oxygen *chip,
375 struct snd_pcm_hw_params *params)
316{ 376{
377 struct xonar_data *data = chip->model_data;
317 unsigned int i; 378 unsigned int i;
318 u8 value;
319 379
320 value = PCM1796_FMT_24_LJUST | PCM1796_ATLD; 380 data->pcm1796_oversampling =
321 if (chip->dac_mute) 381 params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64;
322 value |= PCM1796_MUTE;
323 for (i = 0; i < 4; ++i) 382 for (i = 0; i < 4; ++i)
324 pcm1796_write(chip, i, 18, value); 383 pcm1796_write(chip, i, 20, data->pcm1796_oversampling);
325} 384}
326 385
327static void set_cs53x1_params(struct oxygen *chip, 386static void set_cs53x1_params(struct oxygen *chip,
@@ -342,55 +401,24 @@ static void set_cs53x1_params(struct oxygen *chip,
342static void set_cs43xx_params(struct oxygen *chip, 401static void set_cs43xx_params(struct oxygen *chip,
343 struct snd_pcm_hw_params *params) 402 struct snd_pcm_hw_params *params)
344{ 403{
345 u8 fm_cs4398, fm_cs4362a; 404 struct xonar_data *data = chip->model_data;
346 405
347 fm_cs4398 = CS4398_DEM_NONE | CS4398_DIF_LJUST; 406 data->cs4398_fm = CS4398_DEM_NONE | CS4398_DIF_LJUST;
348 fm_cs4362a = CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; 407 data->cs4362a_fm = CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
349 if (params_rate(params) <= 50000) { 408 if (params_rate(params) <= 50000) {
350 fm_cs4398 |= CS4398_FM_SINGLE; 409 data->cs4398_fm |= CS4398_FM_SINGLE;
351 fm_cs4362a |= CS4362A_FM_SINGLE; 410 data->cs4362a_fm |= CS4362A_FM_SINGLE;
352 } else if (params_rate(params) <= 100000) { 411 } else if (params_rate(params) <= 100000) {
353 fm_cs4398 |= CS4398_FM_DOUBLE; 412 data->cs4398_fm |= CS4398_FM_DOUBLE;
354 fm_cs4362a |= CS4362A_FM_DOUBLE; 413 data->cs4362a_fm |= CS4362A_FM_DOUBLE;
355 } else { 414 } else {
356 fm_cs4398 |= CS4398_FM_QUAD; 415 data->cs4398_fm |= CS4398_FM_QUAD;
357 fm_cs4362a |= CS4362A_FM_QUAD; 416 data->cs4362a_fm |= CS4362A_FM_QUAD;
358 } 417 }
359 cs4398_write(chip, 2, fm_cs4398); 418 cs4398_write(chip, 2, data->cs4398_fm);
360 cs4362a_write(chip, 0x06, fm_cs4362a); 419 cs4362a_write(chip, 0x06, data->cs4362a_fm);
361 cs4362a_write(chip, 0x09, fm_cs4362a); 420 cs4362a_write(chip, 0x09, data->cs4362a_fm);
362 cs4362a_write(chip, 0x0c, fm_cs4362a); 421 cs4362a_write(chip, 0x0c, data->cs4362a_fm);
363}
364
365static void update_cs4362a_volumes(struct oxygen *chip)
366{
367 u8 mute;
368
369 mute = chip->dac_mute ? CS4362A_MUTE : 0;
370 cs4362a_write(chip, 7, (127 - chip->dac_volume[2]) | mute);
371 cs4362a_write(chip, 8, (127 - chip->dac_volume[3]) | mute);
372 cs4362a_write(chip, 10, (127 - chip->dac_volume[4]) | mute);
373 cs4362a_write(chip, 11, (127 - chip->dac_volume[5]) | mute);
374 cs4362a_write(chip, 13, (127 - chip->dac_volume[6]) | mute);
375 cs4362a_write(chip, 14, (127 - chip->dac_volume[7]) | mute);
376}
377
378static void update_cs43xx_volume(struct oxygen *chip)
379{
380 cs4398_write(chip, 5, (127 - chip->dac_volume[0]) * 2);
381 cs4398_write(chip, 6, (127 - chip->dac_volume[1]) * 2);
382 update_cs4362a_volumes(chip);
383}
384
385static void update_cs43xx_mute(struct oxygen *chip)
386{
387 u8 reg;
388
389 reg = CS4398_MUTEP_LOW | CS4398_PAMUTE;
390 if (chip->dac_mute)
391 reg |= CS4398_MUTE_B | CS4398_MUTE_A;
392 cs4398_write(chip, 4, reg);
393 update_cs4362a_volumes(chip);
394} 422}
395 423
396static void xonar_gpio_changed(struct oxygen *chip) 424static void xonar_gpio_changed(struct oxygen *chip)
@@ -535,6 +563,8 @@ static const struct oxygen_model xonar_models[] = {
535 .control_filter = xonar_d2_control_filter, 563 .control_filter = xonar_d2_control_filter,
536 .mixer_init = xonar_mixer_init, 564 .mixer_init = xonar_mixer_init,
537 .cleanup = xonar_cleanup, 565 .cleanup = xonar_cleanup,
566 .suspend = xonar_cleanup,
567 .resume = xonar_d2_resume,
538 .set_dac_params = set_pcm1796_params, 568 .set_dac_params = set_pcm1796_params,
539 .set_adc_params = set_cs53x1_params, 569 .set_adc_params = set_cs53x1_params,
540 .update_dac_volume = update_pcm1796_volume, 570 .update_dac_volume = update_pcm1796_volume,
@@ -563,6 +593,8 @@ static const struct oxygen_model xonar_models[] = {
563 .control_filter = xonar_d2_control_filter, 593 .control_filter = xonar_d2_control_filter,
564 .mixer_init = xonar_mixer_init, 594 .mixer_init = xonar_mixer_init,
565 .cleanup = xonar_cleanup, 595 .cleanup = xonar_cleanup,
596 .suspend = xonar_cleanup,
597 .resume = xonar_d2_resume,
566 .set_dac_params = set_pcm1796_params, 598 .set_dac_params = set_pcm1796_params,
567 .set_adc_params = set_cs53x1_params, 599 .set_adc_params = set_cs53x1_params,
568 .update_dac_volume = update_pcm1796_volume, 600 .update_dac_volume = update_pcm1796_volume,
@@ -592,6 +624,8 @@ static const struct oxygen_model xonar_models[] = {
592 .control_filter = xonar_dx_control_filter, 624 .control_filter = xonar_dx_control_filter,
593 .mixer_init = xonar_dx_mixer_init, 625 .mixer_init = xonar_dx_mixer_init,
594 .cleanup = xonar_dx_cleanup, 626 .cleanup = xonar_dx_cleanup,
627 .suspend = xonar_dx_cleanup,
628 .resume = xonar_dx_resume,
595 .set_dac_params = set_cs43xx_params, 629 .set_dac_params = set_cs43xx_params,
596 .set_adc_params = set_cs53x1_params, 630 .set_adc_params = set_cs53x1_params,
597 .update_dac_volume = update_cs43xx_volume, 631 .update_dac_volume = update_cs43xx_volume,
@@ -636,6 +670,10 @@ static struct pci_driver xonar_driver = {
636 .id_table = xonar_ids, 670 .id_table = xonar_ids,
637 .probe = xonar_probe, 671 .probe = xonar_probe,
638 .remove = __devexit_p(oxygen_pci_remove), 672 .remove = __devexit_p(oxygen_pci_remove),
673#ifdef CONFIG_PM
674 .suspend = oxygen_pci_suspend,
675 .resume = oxygen_pci_resume,
676#endif
639}; 677};
640 678
641static int __init alsa_card_xonar_init(void) 679static int __init alsa_card_xonar_init(void)
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 7fdcdc8c6b64..2c7e25336795 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -516,7 +516,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
516 int capture_mask = 0; 516 int capture_mask = 0;
517 int playback_mask = 0; 517 int playback_mask = 0;
518 518
519#ifdef CONFIG_SND_DEBUG_DETECT 519#ifdef CONFIG_SND_DEBUG_VERBOSE
520 struct timeval my_tv1, my_tv2; 520 struct timeval my_tv1, my_tv2;
521 do_gettimeofday(&my_tv1); 521 do_gettimeofday(&my_tv1);
522#endif 522#endif
@@ -623,7 +623,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
623 623
624 mutex_unlock(&mgr->setup_mutex); 624 mutex_unlock(&mgr->setup_mutex);
625 625
626#ifdef CONFIG_SND_DEBUG_DETECT 626#ifdef CONFIG_SND_DEBUG_VERBOSE
627 do_gettimeofday(&my_tv2); 627 do_gettimeofday(&my_tv2);
628 snd_printdd("***TRIGGER TASKLET*** TIME = %ld (err = %x)\n", 628 snd_printdd("***TRIGGER TASKLET*** TIME = %ld (err = %x)\n",
629 (long)(my_tv2.tv_usec - my_tv1.tv_usec), err); 629 (long)(my_tv2.tv_usec - my_tv1.tv_usec), err);
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c
index 78aa81feaa4a..abe5c59b72df 100644
--- a/sound/pci/pcxhr/pcxhr_core.c
+++ b/sound/pci/pcxhr/pcxhr_core.c
@@ -473,7 +473,7 @@ static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = {
473[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED }, 473[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED },
474}; 474};
475 475
476#ifdef CONFIG_SND_DEBUG_DETECT 476#ifdef CONFIG_SND_DEBUG_VERBOSE
477static char* cmd_names[] = { 477static char* cmd_names[] = {
478[CMD_VERSION] = "CMD_VERSION", 478[CMD_VERSION] = "CMD_VERSION",
479[CMD_SUPPORTED] = "CMD_SUPPORTED", 479[CMD_SUPPORTED] = "CMD_SUPPORTED",
@@ -549,7 +549,7 @@ static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
549 } 549 }
550 } 550 }
551 } 551 }
552#ifdef CONFIG_SND_DEBUG_DETECT 552#ifdef CONFIG_SND_DEBUG_VERBOSE
553 if (rmh->cmd_idx < CMD_LAST_INDEX) 553 if (rmh->cmd_idx < CMD_LAST_INDEX)
554 snd_printdd(" stat[%d]=%x\n", i, data); 554 snd_printdd(" stat[%d]=%x\n", i, data);
555#endif 555#endif
@@ -597,7 +597,7 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
597 data |= 0x008000; /* MASK_MORE_THAN_1_WORD_COMMAND */ 597 data |= 0x008000; /* MASK_MORE_THAN_1_WORD_COMMAND */
598 else 598 else
599 data &= 0xff7fff; /* MASK_1_WORD_COMMAND */ 599 data &= 0xff7fff; /* MASK_1_WORD_COMMAND */
600#ifdef CONFIG_SND_DEBUG_DETECT 600#ifdef CONFIG_SND_DEBUG_VERBOSE
601 if (rmh->cmd_idx < CMD_LAST_INDEX) 601 if (rmh->cmd_idx < CMD_LAST_INDEX)
602 snd_printdd("MSG cmd[0]=%x (%s)\n", data, cmd_names[rmh->cmd_idx]); 602 snd_printdd("MSG cmd[0]=%x (%s)\n", data, cmd_names[rmh->cmd_idx]);
603#endif 603#endif
@@ -624,7 +624,7 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
624 for (i=1; i < rmh->cmd_len; i++) { 624 for (i=1; i < rmh->cmd_len; i++) {
625 /* send other words */ 625 /* send other words */
626 data = rmh->cmd[i]; 626 data = rmh->cmd[i];
627#ifdef CONFIG_SND_DEBUG_DETECT 627#ifdef CONFIG_SND_DEBUG_VERBOSE
628 if (rmh->cmd_idx < CMD_LAST_INDEX) 628 if (rmh->cmd_idx < CMD_LAST_INDEX)
629 snd_printdd(" cmd[%d]=%x\n", i, data); 629 snd_printdd(" cmd[%d]=%x\n", i, data);
630#endif 630#endif
@@ -847,7 +847,7 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_m
847 int state, i, err; 847 int state, i, err;
848 int audio_mask; 848 int audio_mask;
849 849
850#ifdef CONFIG_SND_DEBUG_DETECT 850#ifdef CONFIG_SND_DEBUG_VERBOSE
851 struct timeval my_tv1, my_tv2; 851 struct timeval my_tv1, my_tv2;
852 do_gettimeofday(&my_tv1); 852 do_gettimeofday(&my_tv1);
853#endif 853#endif
@@ -894,7 +894,7 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_m
894 if (err) 894 if (err)
895 return err; 895 return err;
896 } 896 }
897#ifdef CONFIG_SND_DEBUG_DETECT 897#ifdef CONFIG_SND_DEBUG_VERBOSE
898 do_gettimeofday(&my_tv2); 898 do_gettimeofday(&my_tv2);
899 snd_printdd("***SET PIPE STATE*** TIME = %ld (err = %x)\n", 899 snd_printdd("***SET PIPE STATE*** TIME = %ld (err = %x)\n",
900 (long)(my_tv2.tv_usec - my_tv1.tv_usec), err); 900 (long)(my_tv2.tv_usec - my_tv1.tv_usec), err);
@@ -951,7 +951,7 @@ static int pcxhr_handle_async_err(struct pcxhr_mgr *mgr, u32 err,
951 enum pcxhr_async_err_src err_src, int pipe, 951 enum pcxhr_async_err_src err_src, int pipe,
952 int is_capture) 952 int is_capture)
953{ 953{
954#ifdef CONFIG_SND_DEBUG_DETECT 954#ifdef CONFIG_SND_DEBUG_VERBOSE
955 static char* err_src_name[] = { 955 static char* err_src_name[] = {
956 [PCXHR_ERR_PIPE] = "Pipe", 956 [PCXHR_ERR_PIPE] = "Pipe",
957 [PCXHR_ERR_STREAM] = "Stream", 957 [PCXHR_ERR_STREAM] = "Stream",
@@ -1169,7 +1169,7 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1169 mgr->dsp_time_last, dsp_time_new); 1169 mgr->dsp_time_last, dsp_time_new);
1170 mgr->dsp_time_err++; 1170 mgr->dsp_time_err++;
1171 } 1171 }
1172#ifdef CONFIG_SND_DEBUG_DETECT 1172#ifdef CONFIG_SND_DEBUG_VERBOSE
1173 if (dsp_time_diff == 0) 1173 if (dsp_time_diff == 0)
1174 snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n", dsp_time_new); 1174 snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n", dsp_time_new);
1175 else if (dsp_time_diff >= (2*PCXHR_GRANULARITY)) 1175 else if (dsp_time_diff >= (2*PCXHR_GRANULARITY))
@@ -1208,7 +1208,7 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1208 mgr->src_it_dsp = reg; 1208 mgr->src_it_dsp = reg;
1209 tasklet_hi_schedule(&mgr->msg_taskq); 1209 tasklet_hi_schedule(&mgr->msg_taskq);
1210 } 1210 }
1211#ifdef CONFIG_SND_DEBUG_DETECT 1211#ifdef CONFIG_SND_DEBUG_VERBOSE
1212 if (reg & PCXHR_FATAL_DSP_ERR) 1212 if (reg & PCXHR_FATAL_DSP_ERR)
1213 snd_printdd("FATAL DSP ERROR : %x\n", reg); 1213 snd_printdd("FATAL DSP ERROR : %x\n", reg);
1214#endif 1214#endif
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index bbcee2c09ae4..a69b4206c69e 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -1590,7 +1590,10 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream,
1590 if (spdif_flag) { 1590 if (spdif_flag) {
1591 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 1591 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
1592 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS)); 1592 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
1593 outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); 1593 val = trident->spdif_pcm_ctrl;
1594 if (!go)
1595 val &= ~(0x28);
1596 outb(val, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
1594 } else { 1597 } else {
1595 outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS)); 1598 outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS));
1596 val = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) | SPDIF_EN; 1599 val = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) | SPDIF_EN;
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index df9b487fa17e..3fd7f1b29b0f 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -310,181 +310,3 @@ int snd_trident_free_pages(struct snd_trident *trident,
310 mutex_unlock(&hdr->block_mutex); 310 mutex_unlock(&hdr->block_mutex);
311 return 0; 311 return 0;
312} 312}
313
314
315/*----------------------------------------------------------------
316 * memory allocation using multiple pages (for synth)
317 *----------------------------------------------------------------
318 * Unlike the DMA allocation above, non-contiguous pages are
319 * assigned to TLB.
320 *----------------------------------------------------------------*/
321
322/*
323 */
324static int synth_alloc_pages(struct snd_trident *hw, struct snd_util_memblk *blk);
325static int synth_free_pages(struct snd_trident *hw, struct snd_util_memblk *blk);
326
327/*
328 * allocate a synth sample area
329 */
330struct snd_util_memblk *
331snd_trident_synth_alloc(struct snd_trident *hw, unsigned int size)
332{
333 struct snd_util_memblk *blk;
334 struct snd_util_memhdr *hdr = hw->tlb.memhdr;
335
336 mutex_lock(&hdr->block_mutex);
337 blk = __snd_util_mem_alloc(hdr, size);
338 if (blk == NULL) {
339 mutex_unlock(&hdr->block_mutex);
340 return NULL;
341 }
342 if (synth_alloc_pages(hw, blk)) {
343 __snd_util_mem_free(hdr, blk);
344 mutex_unlock(&hdr->block_mutex);
345 return NULL;
346 }
347 mutex_unlock(&hdr->block_mutex);
348 return blk;
349}
350
351EXPORT_SYMBOL(snd_trident_synth_alloc);
352
353/*
354 * free a synth sample area
355 */
356int
357snd_trident_synth_free(struct snd_trident *hw, struct snd_util_memblk *blk)
358{
359 struct snd_util_memhdr *hdr = hw->tlb.memhdr;
360
361 mutex_lock(&hdr->block_mutex);
362 synth_free_pages(hw, blk);
363 __snd_util_mem_free(hdr, blk);
364 mutex_unlock(&hdr->block_mutex);
365 return 0;
366}
367
368EXPORT_SYMBOL(snd_trident_synth_free);
369
370/*
371 * reset TLB entry and free kernel page
372 */
373static void clear_tlb(struct snd_trident *trident, int page)
374{
375 void *ptr = page_to_ptr(trident, page);
376 dma_addr_t addr = page_to_addr(trident, page);
377 set_silent_tlb(trident, page);
378 if (ptr) {
379 struct snd_dma_buffer dmab;
380 dmab.dev.type = SNDRV_DMA_TYPE_DEV;
381 dmab.dev.dev = snd_dma_pci_data(trident->pci);
382 dmab.area = ptr;
383 dmab.addr = addr;
384 dmab.bytes = ALIGN_PAGE_SIZE;
385 snd_dma_free_pages(&dmab);
386 }
387}
388
389/* check new allocation range */
390static void get_single_page_range(struct snd_util_memhdr *hdr,
391 struct snd_util_memblk *blk,
392 int *first_page_ret, int *last_page_ret)
393{
394 struct list_head *p;
395 struct snd_util_memblk *q;
396 int first_page, last_page;
397 first_page = firstpg(blk);
398 if ((p = blk->list.prev) != &hdr->block) {
399 q = list_entry(p, struct snd_util_memblk, list);
400 if (lastpg(q) == first_page)
401 first_page++; /* first page was already allocated */
402 }
403 last_page = lastpg(blk);
404 if ((p = blk->list.next) != &hdr->block) {
405 q = list_entry(p, struct snd_util_memblk, list);
406 if (firstpg(q) == last_page)
407 last_page--; /* last page was already allocated */
408 }
409 *first_page_ret = first_page;
410 *last_page_ret = last_page;
411}
412
413/*
414 * allocate kernel pages and assign them to TLB
415 */
416static int synth_alloc_pages(struct snd_trident *hw, struct snd_util_memblk *blk)
417{
418 int page, first_page, last_page;
419 struct snd_dma_buffer dmab;
420
421 firstpg(blk) = get_aligned_page(blk->offset);
422 lastpg(blk) = get_aligned_page(blk->offset + blk->size - 1);
423 get_single_page_range(hw->tlb.memhdr, blk, &first_page, &last_page);
424
425 /* allocate a kernel page for each Trident page -
426 * fortunately Trident page size and kernel PAGE_SIZE is identical!
427 */
428 for (page = first_page; page <= last_page; page++) {
429 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(hw->pci),
430 ALIGN_PAGE_SIZE, &dmab) < 0)
431 goto __fail;
432 if (! is_valid_page(dmab.addr)) {
433 snd_dma_free_pages(&dmab);
434 goto __fail;
435 }
436 set_tlb_bus(hw, page, (unsigned long)dmab.area, dmab.addr);
437 }
438 return 0;
439
440__fail:
441 /* release allocated pages */
442 last_page = page - 1;
443 for (page = first_page; page <= last_page; page++)
444 clear_tlb(hw, page);
445
446 return -ENOMEM;
447}
448
449/*
450 * free pages
451 */
452static int synth_free_pages(struct snd_trident *trident, struct snd_util_memblk *blk)
453{
454 int page, first_page, last_page;
455
456 get_single_page_range(trident->tlb.memhdr, blk, &first_page, &last_page);
457 for (page = first_page; page <= last_page; page++)
458 clear_tlb(trident, page);
459
460 return 0;
461}
462
463/*
464 * copy_from_user(blk + offset, data, size)
465 */
466int snd_trident_synth_copy_from_user(struct snd_trident *trident,
467 struct snd_util_memblk *blk,
468 int offset, const char __user *data, int size)
469{
470 int page, nextofs, end_offset, temp, temp1;
471
472 offset += blk->offset;
473 end_offset = offset + size;
474 page = get_aligned_page(offset) + 1;
475 do {
476 nextofs = aligned_page_offset(page);
477 temp = nextofs - offset;
478 temp1 = end_offset - offset;
479 if (temp1 < temp)
480 temp = temp1;
481 if (copy_from_user(offset_ptr(trident, offset), data, temp))
482 return -EFAULT;
483 offset = nextofs;
484 data += temp;
485 page++;
486 } while (offset < end_offset);
487 return 0;
488}
489
490EXPORT_SYMBOL(snd_trident_synth_copy_from_user);
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index b585cc3e4c47..6781be9e3078 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1757,6 +1757,12 @@ static struct ac97_quirk ac97_quirks[] = {
1757 .type = AC97_TUNE_HP_ONLY 1757 .type = AC97_TUNE_HP_ONLY
1758 }, 1758 },
1759 { 1759 {
1760 .subvendor = 0x1019,
1761 .subdevice = 0x1841,
1762 .name = "ECS K7VTA3",
1763 .type = AC97_TUNE_HP_ONLY
1764 },
1765 {
1760 .subvendor = 0x1849, 1766 .subvendor = 0x1849,
1761 .subdevice = 0x3059, 1767 .subdevice = 0x3059,
1762 .name = "ASRock K7VM2", 1768 .name = "ASRock K7VM2",
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 29b3056c5109..7129df5f315b 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -2205,6 +2205,7 @@ static int __devinit snd_ymfpci_memalloc(struct snd_ymfpci *chip)
2205 for (reg = 0x80; reg < 0xc0; reg += 4) 2205 for (reg = 0x80; reg < 0xc0; reg += 4)
2206 snd_ymfpci_writel(chip, reg, 0); 2206 snd_ymfpci_writel(chip, reg, 0);
2207 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff); 2207 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff);
2208 snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0x3fff3fff);
2208 snd_ymfpci_writel(chip, YDSXGR_ZVOUTVOL, 0x3fff3fff); 2209 snd_ymfpci_writel(chip, YDSXGR_ZVOUTVOL, 0x3fff3fff);
2209 snd_ymfpci_writel(chip, YDSXGR_SPDIFOUTVOL, 0x3fff3fff); 2210 snd_ymfpci_writel(chip, YDSXGR_SPDIFOUTVOL, 0x3fff3fff);
2210 snd_ymfpci_writel(chip, YDSXGR_NATIVEADCINVOL, 0x3fff3fff); 2211 snd_ymfpci_writel(chip, YDSXGR_NATIVEADCINVOL, 0x3fff3fff);
@@ -2324,6 +2325,7 @@ int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state)
2324 chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]); 2325 chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]);
2325 chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE); 2326 chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE);
2326 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); 2327 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
2328 snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);
2327 snd_ymfpci_disable_dsp(chip); 2329 snd_ymfpci_disable_dsp(chip);
2328 pci_disable_device(pci); 2330 pci_disable_device(pci);
2329 pci_save_state(pci); 2331 pci_save_state(pci);
diff --git a/sound/pcmcia/Kconfig b/sound/pcmcia/Kconfig
index c9fa1a2bc58b..7fbb190adf6d 100644
--- a/sound/pcmcia/Kconfig
+++ b/sound/pcmcia/Kconfig
@@ -1,11 +1,16 @@
1# ALSA PCMCIA drivers 1# ALSA PCMCIA drivers
2 2
3menu "PCMCIA devices" 3menuconfig SND_PCMCIA
4 depends on SND!=n && PCMCIA 4 bool "PCMCIA sound devices"
5 depends on PCMCIA
6 default y
7 help
8 Support for sound devices connected via the PCMCIA bus.
9
10if SND_PCMCIA && PCMCIA
5 11
6config SND_VXPOCKET 12config SND_VXPOCKET
7 tristate "Digigram VXpocket" 13 tristate "Digigram VXpocket"
8 depends on SND && PCMCIA
9 select SND_VX_LIB 14 select SND_VX_LIB
10 help 15 help
11 Say Y here to include support for Digigram VXpocket and 16 Say Y here to include support for Digigram VXpocket and
@@ -16,7 +21,6 @@ config SND_VXPOCKET
16 21
17config SND_PDAUDIOCF 22config SND_PDAUDIOCF
18 tristate "Sound Core PDAudioCF" 23 tristate "Sound Core PDAudioCF"
19 depends on SND && PCMCIA
20 select SND_PCM 24 select SND_PCM
21 help 25 help
22 Say Y here to include support for Sound Core PDAudioCF 26 Say Y here to include support for Sound Core PDAudioCF
@@ -25,4 +29,5 @@ config SND_PDAUDIOCF
25 To compile this driver as a module, choose M here: the module 29 To compile this driver as a module, choose M here: the module
26 will be called snd-pdaudiocf. 30 will be called snd-pdaudiocf.
27 31
28endmenu 32endif # SND_PCMCIA
33
diff --git a/sound/pcmcia/vx/vxp_ops.c b/sound/pcmcia/vx/vxp_ops.c
index 157b0b539f39..99bf2a65a6f5 100644
--- a/sound/pcmcia/vx/vxp_ops.c
+++ b/sound/pcmcia/vx/vxp_ops.c
@@ -151,7 +151,7 @@ static int vxp_load_xilinx_binary(struct vx_core *_chip, const struct firmware *
151 unsigned int i; 151 unsigned int i;
152 int c; 152 int c;
153 int regCSUER, regRUER; 153 int regCSUER, regRUER;
154 unsigned char *image; 154 const unsigned char *image;
155 unsigned char data; 155 unsigned char data;
156 156
157 /* Switch to programmation mode */ 157 /* Switch to programmation mode */
diff --git a/sound/ppc/Kconfig b/sound/ppc/Kconfig
index cacb0b136883..777de2b17178 100644
--- a/sound/ppc/Kconfig
+++ b/sound/ppc/Kconfig
@@ -1,17 +1,17 @@
1# ALSA PowerMac drivers 1# ALSA PowerMac drivers
2 2
3menu "ALSA PowerMac devices" 3menuconfig SND_PPC
4 depends on SND!=n && PPC 4 bool "PowerPC sound devices"
5 5 depends on PPC64 || PPC32
6comment "ALSA PowerMac requires I2C" 6 default y
7 depends on SND && I2C=n 7 help
8 Support for sound devices specific to PowerPC architectures.
8 9
9comment "ALSA PowerMac requires INPUT" 10if SND_PPC
10 depends on SND && INPUT=n
11 11
12config SND_POWERMAC 12config SND_POWERMAC
13 tristate "PowerMac (AWACS, DACA, Burgundy, Tumbler, Keywest)" 13 tristate "PowerMac (AWACS, DACA, Burgundy, Tumbler, Keywest)"
14 depends on SND && I2C && INPUT && PPC_PMAC 14 depends on I2C && INPUT && PPC_PMAC
15 select SND_PCM 15 select SND_PCM
16 help 16 help
17 Say Y here to include support for the integrated sound device. 17 Say Y here to include support for the integrated sound device.
@@ -32,14 +32,9 @@ config SND_POWERMAC_AUTO_DRC
32 Note that you can turn on/off DRC manually even without this 32 Note that you can turn on/off DRC manually even without this
33 option. 33 option.
34 34
35endmenu
36
37menu "ALSA PowerPC devices"
38 depends on SND!=n && ( PPC64 || PPC32 )
39
40config SND_PS3 35config SND_PS3
41 tristate "PS3 Audio support" 36 tristate "PS3 Audio support"
42 depends on SND && PS3_PS3AV 37 depends on PS3_PS3AV
43 select SND_PCM 38 select SND_PCM
44 default m 39 default m
45 help 40 help
@@ -52,4 +47,5 @@ config SND_PS3_DEFAULT_START_DELAY
52 int "Startup delay time in ms" 47 int "Startup delay time in ms"
53 depends on SND_PS3 48 depends on SND_PS3
54 default "2000" 49 default "2000"
55endmenu 50
51endif # SND_PPC
diff --git a/sound/ppc/daca.c b/sound/ppc/daca.c
index ca9452901a50..8a5b29031933 100644
--- a/sound/ppc/daca.c
+++ b/sound/ppc/daca.c
@@ -249,9 +249,7 @@ int __init snd_pmac_daca_init(struct snd_pmac *chip)
249 int i, err; 249 int i, err;
250 struct pmac_daca *mix; 250 struct pmac_daca *mix;
251 251
252#ifdef CONFIG_KMOD
253 request_module("i2c-powermac"); 252 request_module("i2c-powermac");
254#endif /* CONFIG_KMOD */
255 253
256 mix = kzalloc(sizeof(*mix), GFP_KERNEL); 254 mix = kzalloc(sizeof(*mix), GFP_KERNEL);
257 if (! mix) 255 if (! mix)
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 3f8d7164cef9..009df8dd37a8 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -1350,9 +1350,7 @@ int __init snd_pmac_tumbler_init(struct snd_pmac *chip)
1350 struct device_node *tas_node, *np; 1350 struct device_node *tas_node, *np;
1351 char *chipname; 1351 char *chipname;
1352 1352
1353#ifdef CONFIG_KMOD
1354 request_module("i2c-powermac"); 1353 request_module("i2c-powermac");
1355#endif /* CONFIG_KMOD */
1356 1354
1357 mix = kzalloc(sizeof(*mix), GFP_KERNEL); 1355 mix = kzalloc(sizeof(*mix), GFP_KERNEL);
1358 if (! mix) 1356 if (! mix)
diff --git a/sound/sh/Kconfig b/sound/sh/Kconfig
index b7e08ef22a94..cfc143985802 100644
--- a/sound/sh/Kconfig
+++ b/sound/sh/Kconfig
@@ -1,14 +1,22 @@
1# ALSA SH drivers 1# ALSA SH drivers
2 2
3menu "SUPERH devices" 3menuconfig SND_SUPERH
4 depends on SND!=n && SUPERH 4 bool "SUPERH sound devices"
5 depends on SUPERH
6 default y
7 help
8 Support for sound devices specific to SUPERH architectures.
9 Drivers that are implemented on ASoC can be found in
10 "ALSA for SoC audio support" section.
11
12if SND_SUPERH
5 13
6config SND_AICA 14config SND_AICA
7 tristate "Dreamcast Yamaha AICA sound" 15 tristate "Dreamcast Yamaha AICA sound"
8 depends on SH_DREAMCAST && SND 16 depends on SH_DREAMCAST
9 select SND_PCM 17 select SND_PCM
10 help 18 help
11 ALSA Sound driver for the SEGA Dreamcast console. 19 ALSA Sound driver for the SEGA Dreamcast console.
12 20
13endmenu 21endif # SND_SUPERH
14 22
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 18f28ac4bfe8..f743530add8f 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -2,15 +2,8 @@
2# SoC audio configuration 2# SoC audio configuration
3# 3#
4 4
5menu "System on Chip audio support" 5menuconfig SND_SOC
6 depends on SND!=n
7
8config SND_SOC_AC97_BUS
9 bool
10
11config SND_SOC
12 tristate "ALSA for SoC audio support" 6 tristate "ALSA for SoC audio support"
13 depends on SND
14 select SND_PCM 7 select SND_PCM
15 ---help--- 8 ---help---
16 9
@@ -23,8 +16,15 @@ config SND_SOC
23 This ASoC audio support can also be built as a module. If so, the module 16 This ASoC audio support can also be built as a module. If so, the module
24 will be called snd-soc-core. 17 will be called snd-soc-core.
25 18
19if SND_SOC
20
21config SND_SOC_AC97_BUS
22 bool
23
26# All the supported Soc's 24# All the supported Soc's
25source "sound/soc/at32/Kconfig"
27source "sound/soc/at91/Kconfig" 26source "sound/soc/at91/Kconfig"
27source "sound/soc/au1x/Kconfig"
28source "sound/soc/pxa/Kconfig" 28source "sound/soc/pxa/Kconfig"
29source "sound/soc/s3c24xx/Kconfig" 29source "sound/soc/s3c24xx/Kconfig"
30source "sound/soc/sh/Kconfig" 30source "sound/soc/sh/Kconfig"
@@ -35,4 +35,5 @@ source "sound/soc/omap/Kconfig"
35# Supported codecs 35# Supported codecs
36source "sound/soc/codecs/Kconfig" 36source "sound/soc/codecs/Kconfig"
37 37
38endmenu 38endif # SND_SOC
39
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 782db2127108..933a66d30804 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,4 +1,5 @@
1snd-soc-core-objs := soc-core.o soc-dapm.o 1snd-soc-core-objs := soc-core.o soc-dapm.o
2 2
3obj-$(CONFIG_SND_SOC) += snd-soc-core.o 3obj-$(CONFIG_SND_SOC) += snd-soc-core.o
4obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ s3c24xx/ sh/ fsl/ davinci/ omap/ 4obj-$(CONFIG_SND_SOC) += codecs/ at32/ at91/ pxa/ s3c24xx/ sh/ fsl/ davinci/
5obj-$(CONFIG_SND_SOC) += omap/ au1x/
diff --git a/sound/soc/at32/Kconfig b/sound/soc/at32/Kconfig
new file mode 100644
index 000000000000..b0765e86c085
--- /dev/null
+++ b/sound/soc/at32/Kconfig
@@ -0,0 +1,34 @@
1config SND_AT32_SOC
2 tristate "SoC Audio for the Atmel AT32 System-on-a-Chip"
3 depends on AVR32 && SND_SOC
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the AT32 SSC interface. You will also need to
7 to select the audio interfaces to support below.
8
9
10config SND_AT32_SOC_SSC
11 tristate
12
13
14
15config SND_AT32_SOC_PLAYPAQ
16 tristate "SoC Audio support for PlayPaq with WM8510"
17 depends on SND_AT32_SOC && BOARD_PLAYPAQ
18 select SND_AT32_SOC_SSC
19 select SND_SOC_WM8510
20 help
21 Say Y or M here if you want to add support for SoC audio
22 on the LRS PlayPaq.
23
24
25
26config SND_AT32_SOC_PLAYPAQ_SLAVE
27 bool "Run CODEC on PlayPaq in slave mode"
28 depends on SND_AT32_SOC_PLAYPAQ
29 default n
30 help
31 Say Y if you want to run with the AT32 SSC generating the BCLK
32 and FRAME signals on the PlayPaq. Unless you want to play
33 with the AT32 as the SSC master, you probably want to say N here,
34 as this will give you better sound quality.
diff --git a/sound/soc/at32/Makefile b/sound/soc/at32/Makefile
new file mode 100644
index 000000000000..c03e55ececeb
--- /dev/null
+++ b/sound/soc/at32/Makefile
@@ -0,0 +1,11 @@
1# AT32 Platform Support
2snd-soc-at32-objs := at32-pcm.o
3snd-soc-at32-ssc-objs := at32-ssc.o
4
5obj-$(CONFIG_SND_AT32_SOC) += snd-soc-at32.o
6obj-$(CONFIG_SND_AT32_SOC_SSC) += snd-soc-at32-ssc.o
7
8# AT32 Machine Support
9snd-soc-playpaq-objs := playpaq_wm8510.o
10
11obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o
diff --git a/sound/soc/at32/at32-pcm.c b/sound/soc/at32/at32-pcm.c
new file mode 100644
index 000000000000..435f1daf177c
--- /dev/null
+++ b/sound/soc/at32/at32-pcm.c
@@ -0,0 +1,491 @@
1/* sound/soc/at32/at32-pcm.c
2 * ASoC PCM interface for Atmel AT32 SoC
3 *
4 * Copyright (C) 2008 Long Range Systems
5 * Geoffrey Wossum <gwossum@acm.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Note that this is basically a port of the sound/soc/at91-pcm.c to
12 * the AVR32 kernel. Thanks to Frank Mandarino for that code.
13 */
14
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19#include <linux/dma-mapping.h>
20#include <linux/atmel_pdc.h>
21
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26
27#include "at32-pcm.h"
28
29
30
31/*--------------------------------------------------------------------------*\
32 * Hardware definition
33\*--------------------------------------------------------------------------*/
34/* TODO: These values were taken from the AT91 platform driver, check
35 * them against real values for AT32
36 */
37static const struct snd_pcm_hardware at32_pcm_hardware = {
38 .info = (SNDRV_PCM_INFO_MMAP |
39 SNDRV_PCM_INFO_MMAP_VALID |
40 SNDRV_PCM_INFO_INTERLEAVED |
41 SNDRV_PCM_INFO_BLOCK_TRANSFER |
42 SNDRV_PCM_INFO_PAUSE),
43
44 .formats = SNDRV_PCM_FMTBIT_S16,
45 .period_bytes_min = 32,
46 .period_bytes_max = 8192, /* 512 frames * 16 bytes / frame */
47 .periods_min = 2,
48 .periods_max = 1024,
49 .buffer_bytes_max = 32 * 1024,
50};
51
52
53
54/*--------------------------------------------------------------------------*\
55 * Data types
56\*--------------------------------------------------------------------------*/
57struct at32_runtime_data {
58 struct at32_pcm_dma_params *params;
59 dma_addr_t dma_buffer; /* physical address of DMA buffer */
60 dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */
61 size_t period_size;
62
63 dma_addr_t period_ptr; /* physical address of next period */
64 int periods; /* period index of period_ptr */
65
66 /* Save PDC registers (for power management) */
67 u32 pdc_xpr_save;
68 u32 pdc_xcr_save;
69 u32 pdc_xnpr_save;
70 u32 pdc_xncr_save;
71};
72
73
74
75/*--------------------------------------------------------------------------*\
76 * Helper functions
77\*--------------------------------------------------------------------------*/
78static int at32_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
79{
80 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
81 struct snd_dma_buffer *dmabuf = &substream->dma_buffer;
82 size_t size = at32_pcm_hardware.buffer_bytes_max;
83
84 dmabuf->dev.type = SNDRV_DMA_TYPE_DEV;
85 dmabuf->dev.dev = pcm->card->dev;
86 dmabuf->private_data = NULL;
87 dmabuf->area = dma_alloc_coherent(pcm->card->dev, size,
88 &dmabuf->addr, GFP_KERNEL);
89 pr_debug("at32_pcm: preallocate_dma_buffer: "
90 "area=%p, addr=%p, size=%ld\n",
91 (void *)dmabuf->area, (void *)dmabuf->addr, size);
92
93 if (!dmabuf->area)
94 return -ENOMEM;
95
96 dmabuf->bytes = size;
97 return 0;
98}
99
100
101
102/*--------------------------------------------------------------------------*\
103 * ISR
104\*--------------------------------------------------------------------------*/
105static void at32_pcm_dma_irq(u32 ssc_sr, struct snd_pcm_substream *substream)
106{
107 struct snd_pcm_runtime *rtd = substream->runtime;
108 struct at32_runtime_data *prtd = rtd->private_data;
109 struct at32_pcm_dma_params *params = prtd->params;
110 static int count;
111
112 count++;
113 if (ssc_sr & params->mask->ssc_endbuf) {
114 pr_warning("at32-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n",
115 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
116 "underrun" : "overrun", params->name, ssc_sr, count);
117
118 /* re-start the PDC */
119 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
120 params->mask->pdc_disable);
121 prtd->period_ptr += prtd->period_size;
122 if (prtd->period_ptr >= prtd->dma_buffer_end)
123 prtd->period_ptr = prtd->dma_buffer;
124
125
126 ssc_writex(params->ssc->regs, params->pdc->xpr,
127 prtd->period_ptr);
128 ssc_writex(params->ssc->regs, params->pdc->xcr,
129 prtd->period_size / params->pdc_xfer_size);
130 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
131 params->mask->pdc_enable);
132 }
133
134
135 if (ssc_sr & params->mask->ssc_endx) {
136 /* Load the PDC next pointer and counter registers */
137 prtd->period_ptr += prtd->period_size;
138 if (prtd->period_ptr >= prtd->dma_buffer_end)
139 prtd->period_ptr = prtd->dma_buffer;
140 ssc_writex(params->ssc->regs, params->pdc->xnpr,
141 prtd->period_ptr);
142 ssc_writex(params->ssc->regs, params->pdc->xncr,
143 prtd->period_size / params->pdc_xfer_size);
144 }
145
146
147 snd_pcm_period_elapsed(substream);
148}
149
150
151
152/*--------------------------------------------------------------------------*\
153 * PCM operations
154\*--------------------------------------------------------------------------*/
155static int at32_pcm_hw_params(struct snd_pcm_substream *substream,
156 struct snd_pcm_hw_params *params)
157{
158 struct snd_pcm_runtime *runtime = substream->runtime;
159 struct at32_runtime_data *prtd = runtime->private_data;
160 struct snd_soc_pcm_runtime *rtd = substream->private_data;
161
162 /* this may get called several times by oss emulation
163 * with different params
164 */
165 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
166 runtime->dma_bytes = params_buffer_bytes(params);
167
168 prtd->params = rtd->dai->cpu_dai->dma_data;
169 prtd->params->dma_intr_handler = at32_pcm_dma_irq;
170
171 prtd->dma_buffer = runtime->dma_addr;
172 prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
173 prtd->period_size = params_period_bytes(params);
174
175 pr_debug("hw_params: DMA for %s initialized "
176 "(dma_bytes=%ld, period_size=%ld)\n",
177 prtd->params->name, runtime->dma_bytes, prtd->period_size);
178
179 return 0;
180}
181
182
183
184static int at32_pcm_hw_free(struct snd_pcm_substream *substream)
185{
186 struct at32_runtime_data *prtd = substream->runtime->private_data;
187 struct at32_pcm_dma_params *params = prtd->params;
188
189 if (params != NULL) {
190 ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
191 params->mask->pdc_disable);
192 prtd->params->dma_intr_handler = NULL;
193 }
194
195 return 0;
196}
197
198
199
200static int at32_pcm_prepare(struct snd_pcm_substream *substream)
201{
202 struct at32_runtime_data *prtd = substream->runtime->private_data;
203 struct at32_pcm_dma_params *params = prtd->params;
204
205 ssc_writex(params->ssc->regs, SSC_IDR,
206 params->mask->ssc_endx | params->mask->ssc_endbuf);
207 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
208 params->mask->pdc_disable);
209
210 return 0;
211}
212
213
214static int at32_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
215{
216 struct snd_pcm_runtime *rtd = substream->runtime;
217 struct at32_runtime_data *prtd = rtd->private_data;
218 struct at32_pcm_dma_params *params = prtd->params;
219 int ret = 0;
220
221 pr_debug("at32_pcm_trigger: buffer_size = %ld, "
222 "dma_area = %p, dma_bytes = %ld\n",
223 rtd->buffer_size, rtd->dma_area, rtd->dma_bytes);
224
225 switch (cmd) {
226 case SNDRV_PCM_TRIGGER_START:
227 prtd->period_ptr = prtd->dma_buffer;
228
229 ssc_writex(params->ssc->regs, params->pdc->xpr,
230 prtd->period_ptr);
231 ssc_writex(params->ssc->regs, params->pdc->xcr,
232 prtd->period_size / params->pdc_xfer_size);
233
234 prtd->period_ptr += prtd->period_size;
235 ssc_writex(params->ssc->regs, params->pdc->xnpr,
236 prtd->period_ptr);
237 ssc_writex(params->ssc->regs, params->pdc->xncr,
238 prtd->period_size / params->pdc_xfer_size);
239
240 pr_debug("trigger: period_ptr=%lx, xpr=%x, "
241 "xcr=%d, xnpr=%x, xncr=%d\n",
242 (unsigned long)prtd->period_ptr,
243 ssc_readx(params->ssc->regs, params->pdc->xpr),
244 ssc_readx(params->ssc->regs, params->pdc->xcr),
245 ssc_readx(params->ssc->regs, params->pdc->xnpr),
246 ssc_readx(params->ssc->regs, params->pdc->xncr));
247
248 ssc_writex(params->ssc->regs, SSC_IER,
249 params->mask->ssc_endx | params->mask->ssc_endbuf);
250 ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
251 params->mask->pdc_enable);
252
253 pr_debug("sr=%x, imr=%x\n",
254 ssc_readx(params->ssc->regs, SSC_SR),
255 ssc_readx(params->ssc->regs, SSC_IER));
256 break; /* SNDRV_PCM_TRIGGER_START */
257
258
259
260 case SNDRV_PCM_TRIGGER_STOP:
261 case SNDRV_PCM_TRIGGER_SUSPEND:
262 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
263 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
264 params->mask->pdc_disable);
265 break;
266
267
268 case SNDRV_PCM_TRIGGER_RESUME:
269 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
270 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
271 params->mask->pdc_enable);
272 break;
273
274 default:
275 ret = -EINVAL;
276 }
277
278 return ret;
279}
280
281
282
283static snd_pcm_uframes_t at32_pcm_pointer(struct snd_pcm_substream *substream)
284{
285 struct snd_pcm_runtime *runtime = substream->runtime;
286 struct at32_runtime_data *prtd = runtime->private_data;
287 struct at32_pcm_dma_params *params = prtd->params;
288 dma_addr_t ptr;
289 snd_pcm_uframes_t x;
290
291 ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr);
292 x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
293
294 if (x == runtime->buffer_size)
295 x = 0;
296
297 return x;
298}
299
300
301
302static int at32_pcm_open(struct snd_pcm_substream *substream)
303{
304 struct snd_pcm_runtime *runtime = substream->runtime;
305 struct at32_runtime_data *prtd;
306 int ret = 0;
307
308 snd_soc_set_runtime_hwparams(substream, &at32_pcm_hardware);
309
310 /* ensure that buffer size is a multiple of period size */
311 ret = snd_pcm_hw_constraint_integer(runtime,
312 SNDRV_PCM_HW_PARAM_PERIODS);
313 if (ret < 0)
314 goto out;
315
316 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
317 if (prtd == NULL) {
318 ret = -ENOMEM;
319 goto out;
320 }
321 runtime->private_data = prtd;
322
323
324out:
325 return ret;
326}
327
328
329
330static int at32_pcm_close(struct snd_pcm_substream *substream)
331{
332 struct at32_runtime_data *prtd = substream->runtime->private_data;
333
334 kfree(prtd);
335 return 0;
336}
337
338
339static int at32_pcm_mmap(struct snd_pcm_substream *substream,
340 struct vm_area_struct *vma)
341{
342 return remap_pfn_range(vma, vma->vm_start,
343 substream->dma_buffer.addr >> PAGE_SHIFT,
344 vma->vm_end - vma->vm_start, vma->vm_page_prot);
345}
346
347
348
349static struct snd_pcm_ops at32_pcm_ops = {
350 .open = at32_pcm_open,
351 .close = at32_pcm_close,
352 .ioctl = snd_pcm_lib_ioctl,
353 .hw_params = at32_pcm_hw_params,
354 .hw_free = at32_pcm_hw_free,
355 .prepare = at32_pcm_prepare,
356 .trigger = at32_pcm_trigger,
357 .pointer = at32_pcm_pointer,
358 .mmap = at32_pcm_mmap,
359};
360
361
362
363/*--------------------------------------------------------------------------*\
364 * ASoC platform driver
365\*--------------------------------------------------------------------------*/
366static u64 at32_pcm_dmamask = 0xffffffff;
367
368static int at32_pcm_new(struct snd_card *card,
369 struct snd_soc_dai *dai,
370 struct snd_pcm *pcm)
371{
372 int ret = 0;
373
374 if (!card->dev->dma_mask)
375 card->dev->dma_mask = &at32_pcm_dmamask;
376 if (!card->dev->coherent_dma_mask)
377 card->dev->coherent_dma_mask = 0xffffffff;
378
379 if (dai->playback.channels_min) {
380 ret = at32_pcm_preallocate_dma_buffer(
381 pcm, SNDRV_PCM_STREAM_PLAYBACK);
382 if (ret)
383 goto out;
384 }
385
386 if (dai->capture.channels_min) {
387 pr_debug("at32-pcm: Allocating PCM capture DMA buffer\n");
388 ret = at32_pcm_preallocate_dma_buffer(
389 pcm, SNDRV_PCM_STREAM_CAPTURE);
390 if (ret)
391 goto out;
392 }
393
394
395out:
396 return ret;
397}
398
399
400
401static void at32_pcm_free_dma_buffers(struct snd_pcm *pcm)
402{
403 struct snd_pcm_substream *substream;
404 struct snd_dma_buffer *buf;
405 int stream;
406
407 for (stream = 0; stream < 2; stream++) {
408 substream = pcm->streams[stream].substream;
409 if (substream == NULL)
410 continue;
411
412 buf = &substream->dma_buffer;
413 if (!buf->area)
414 continue;
415 dma_free_coherent(pcm->card->dev, buf->bytes,
416 buf->area, buf->addr);
417 buf->area = NULL;
418 }
419}
420
421
422
423#ifdef CONFIG_PM
424static int at32_pcm_suspend(struct platform_device *pdev,
425 struct snd_soc_dai *dai)
426{
427 struct snd_pcm_runtime *runtime = dai->runtime;
428 struct at32_runtime_data *prtd;
429 struct at32_pcm_dma_params *params;
430
431 if (runtime == NULL)
432 return 0;
433 prtd = runtime->private_data;
434 params = prtd->params;
435
436 /* Disable the PDC and save the PDC registers */
437 ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable);
438
439 prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
440 prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
441 prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr);
442 prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr);
443
444 return 0;
445}
446
447
448
449static int at32_pcm_resume(struct platform_device *pdev,
450 struct snd_soc_dai *dai)
451{
452 struct snd_pcm_runtime *runtime = dai->runtime;
453 struct at32_runtime_data *prtd;
454 struct at32_pcm_dma_params *params;
455
456 if (runtime == NULL)
457 return 0;
458 prtd = runtime->private_data;
459 params = prtd->params;
460
461 /* Restore the PDC registers and enable the PDC */
462 ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save);
463 ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save);
464 ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
465 ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
466
467 ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable);
468 return 0;
469}
470#else /* CONFIG_PM */
471# define at32_pcm_suspend NULL
472# define at32_pcm_resume NULL
473#endif /* CONFIG_PM */
474
475
476
477struct snd_soc_platform at32_soc_platform = {
478 .name = "at32-audio",
479 .pcm_ops = &at32_pcm_ops,
480 .pcm_new = at32_pcm_new,
481 .pcm_free = at32_pcm_free_dma_buffers,
482 .suspend = at32_pcm_suspend,
483 .resume = at32_pcm_resume,
484};
485EXPORT_SYMBOL_GPL(at32_soc_platform);
486
487
488
489MODULE_AUTHOR("Geoffrey Wossum <gwossum@acm.org>");
490MODULE_DESCRIPTION("Atmel AT32 PCM module");
491MODULE_LICENSE("GPL");
diff --git a/sound/soc/at32/at32-pcm.h b/sound/soc/at32/at32-pcm.h
new file mode 100644
index 000000000000..2a52430417da
--- /dev/null
+++ b/sound/soc/at32/at32-pcm.h
@@ -0,0 +1,79 @@
1/* sound/soc/at32/at32-pcm.h
2 * ASoC PCM interface for Atmel AT32 SoC
3 *
4 * Copyright (C) 2008 Long Range Systems
5 * Geoffrey Wossum <gwossum@acm.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __SOUND_SOC_AT32_AT32_PCM_H
13#define __SOUND_SOC_AT32_AT32_PCM_H __FILE__
14
15#include <linux/atmel-ssc.h>
16
17
18/*
19 * Registers and status bits that are required by the PCM driver
20 * TODO: Is ptcr really used?
21 */
22struct at32_pdc_regs {
23 u32 xpr; /* PDC RX/TX pointer */
24 u32 xcr; /* PDC RX/TX counter */
25 u32 xnpr; /* PDC next RX/TX pointer */
26 u32 xncr; /* PDC next RX/TX counter */
27 u32 ptcr; /* PDC transfer control */
28};
29
30
31
32/*
33 * SSC mask info
34 */
35struct at32_ssc_mask {
36 u32 ssc_enable; /* SSC RX/TX enable */
37 u32 ssc_disable; /* SSC RX/TX disable */
38 u32 ssc_endx; /* SSC ENDTX or ENDRX */
39 u32 ssc_endbuf; /* SSC TXBUFF or RXBUFF */
40 u32 pdc_enable; /* PDC RX/TX enable */
41 u32 pdc_disable; /* PDC RX/TX disable */
42};
43
44
45
46/*
47 * This structure, shared between the PCM driver and the interface,
48 * contains all information required by the PCM driver to perform the
49 * PDC DMA operation. All fields except dma_intr_handler() are initialized
50 * by the interface. The dms_intr_handler() pointer is set by the PCM
51 * driver and called by the interface SSC interrupt handler if it is
52 * non-NULL.
53 */
54struct at32_pcm_dma_params {
55 char *name; /* stream identifier */
56 int pdc_xfer_size; /* PDC counter increment in bytes */
57 struct ssc_device *ssc; /* SSC device for stream */
58 struct at32_pdc_regs *pdc; /* PDC register info */
59 struct at32_ssc_mask *mask; /* SSC mask info */
60 struct snd_pcm_substream *substream;
61 void (*dma_intr_handler) (u32, struct snd_pcm_substream *);
62};
63
64
65
66/*
67 * The AT32 ASoC platform driver
68 */
69extern struct snd_soc_platform at32_soc_platform;
70
71
72
73/*
74 * SSC register access (since ssc_writel() / ssc_readl() require literal name)
75 */
76#define ssc_readx(base, reg) (__raw_readl((base) + (reg)))
77#define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg))
78
79#endif /* __SOUND_SOC_AT32_AT32_PCM_H */
diff --git a/sound/soc/at32/at32-ssc.c b/sound/soc/at32/at32-ssc.c
new file mode 100644
index 000000000000..4ef6492c902e
--- /dev/null
+++ b/sound/soc/at32/at32-ssc.c
@@ -0,0 +1,849 @@
1/* sound/soc/at32/at32-ssc.c
2 * ASoC platform driver for AT32 using SSC as DAI
3 *
4 * Copyright (C) 2008 Long Range Systems
5 * Geoffrey Wossum <gwossum@acm.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Note that this is basically a port of the sound/soc/at91-ssc.c to
12 * the AVR32 kernel. Thanks to Frank Mandarino for that code.
13 */
14
15/* #define DEBUG */
16
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/interrupt.h>
20#include <linux/device.h>
21#include <linux/delay.h>
22#include <linux/clk.h>
23#include <linux/io.h>
24#include <linux/atmel_pdc.h>
25#include <linux/atmel-ssc.h>
26
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/initval.h>
31#include <sound/soc.h>
32
33#include "at32-pcm.h"
34#include "at32-ssc.h"
35
36
37
38/*-------------------------------------------------------------------------*\
39 * Constants
40\*-------------------------------------------------------------------------*/
41#define NUM_SSC_DEVICES 3
42
43/*
44 * SSC direction masks
45 */
46#define SSC_DIR_MASK_UNUSED 0
47#define SSC_DIR_MASK_PLAYBACK 1
48#define SSC_DIR_MASK_CAPTURE 2
49
50/*
51 * SSC register values that Atmel left out of <linux/atmel-ssc.h>. These
52 * are expected to be used with SSC_BF
53 */
54/* START bit field values */
55#define SSC_START_CONTINUOUS 0
56#define SSC_START_TX_RX 1
57#define SSC_START_LOW_RF 2
58#define SSC_START_HIGH_RF 3
59#define SSC_START_FALLING_RF 4
60#define SSC_START_RISING_RF 5
61#define SSC_START_LEVEL_RF 6
62#define SSC_START_EDGE_RF 7
63#define SSS_START_COMPARE_0 8
64
65/* CKI bit field values */
66#define SSC_CKI_FALLING 0
67#define SSC_CKI_RISING 1
68
69/* CKO bit field values */
70#define SSC_CKO_NONE 0
71#define SSC_CKO_CONTINUOUS 1
72#define SSC_CKO_TRANSFER 2
73
74/* CKS bit field values */
75#define SSC_CKS_DIV 0
76#define SSC_CKS_CLOCK 1
77#define SSC_CKS_PIN 2
78
79/* FSEDGE bit field values */
80#define SSC_FSEDGE_POSITIVE 0
81#define SSC_FSEDGE_NEGATIVE 1
82
83/* FSOS bit field values */
84#define SSC_FSOS_NONE 0
85#define SSC_FSOS_NEGATIVE 1
86#define SSC_FSOS_POSITIVE 2
87#define SSC_FSOS_LOW 3
88#define SSC_FSOS_HIGH 4
89#define SSC_FSOS_TOGGLE 5
90
91#define START_DELAY 1
92
93
94
95/*-------------------------------------------------------------------------*\
96 * Module data
97\*-------------------------------------------------------------------------*/
98/*
99 * SSC PDC registered required by the PCM DMA engine
100 */
101static struct at32_pdc_regs pdc_tx_reg = {
102 .xpr = SSC_PDC_TPR,
103 .xcr = SSC_PDC_TCR,
104 .xnpr = SSC_PDC_TNPR,
105 .xncr = SSC_PDC_TNCR,
106};
107
108
109
110static struct at32_pdc_regs pdc_rx_reg = {
111 .xpr = SSC_PDC_RPR,
112 .xcr = SSC_PDC_RCR,
113 .xnpr = SSC_PDC_RNPR,
114 .xncr = SSC_PDC_RNCR,
115};
116
117
118
119/*
120 * SSC and PDC status bits for transmit and receive
121 */
122static struct at32_ssc_mask ssc_tx_mask = {
123 .ssc_enable = SSC_BIT(CR_TXEN),
124 .ssc_disable = SSC_BIT(CR_TXDIS),
125 .ssc_endx = SSC_BIT(SR_ENDTX),
126 .ssc_endbuf = SSC_BIT(SR_TXBUFE),
127 .pdc_enable = SSC_BIT(PDC_PTCR_TXTEN),
128 .pdc_disable = SSC_BIT(PDC_PTCR_TXTDIS),
129};
130
131
132
133static struct at32_ssc_mask ssc_rx_mask = {
134 .ssc_enable = SSC_BIT(CR_RXEN),
135 .ssc_disable = SSC_BIT(CR_RXDIS),
136 .ssc_endx = SSC_BIT(SR_ENDRX),
137 .ssc_endbuf = SSC_BIT(SR_RXBUFF),
138 .pdc_enable = SSC_BIT(PDC_PTCR_RXTEN),
139 .pdc_disable = SSC_BIT(PDC_PTCR_RXTDIS),
140};
141
142
143
144/*
145 * DMA parameters for each SSC
146 */
147static struct at32_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
148 {
149 {
150 .name = "SSC0 PCM out",
151 .pdc = &pdc_tx_reg,
152 .mask = &ssc_tx_mask,
153 },
154 {
155 .name = "SSC0 PCM in",
156 .pdc = &pdc_rx_reg,
157 .mask = &ssc_rx_mask,
158 },
159 },
160 {
161 {
162 .name = "SSC1 PCM out",
163 .pdc = &pdc_tx_reg,
164 .mask = &ssc_tx_mask,
165 },
166 {
167 .name = "SSC1 PCM in",
168 .pdc = &pdc_rx_reg,
169 .mask = &ssc_rx_mask,
170 },
171 },
172 {
173 {
174 .name = "SSC2 PCM out",
175 .pdc = &pdc_tx_reg,
176 .mask = &ssc_tx_mask,
177 },
178 {
179 .name = "SSC2 PCM in",
180 .pdc = &pdc_rx_reg,
181 .mask = &ssc_rx_mask,
182 },
183 },
184};
185
186
187
188static struct at32_ssc_info ssc_info[NUM_SSC_DEVICES] = {
189 {
190 .name = "ssc0",
191 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
192 .dir_mask = SSC_DIR_MASK_UNUSED,
193 .initialized = 0,
194 },
195 {
196 .name = "ssc1",
197 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
198 .dir_mask = SSC_DIR_MASK_UNUSED,
199 .initialized = 0,
200 },
201 {
202 .name = "ssc2",
203 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
204 .dir_mask = SSC_DIR_MASK_UNUSED,
205 .initialized = 0,
206 },
207};
208
209
210
211
212/*-------------------------------------------------------------------------*\
213 * ISR
214\*-------------------------------------------------------------------------*/
215/*
216 * SSC interrupt handler. Passes PDC interrupts to the DMA interrupt
217 * handler in the PCM driver.
218 */
219static irqreturn_t at32_ssc_interrupt(int irq, void *dev_id)
220{
221 struct at32_ssc_info *ssc_p = dev_id;
222 struct at32_pcm_dma_params *dma_params;
223 u32 ssc_sr;
224 u32 ssc_substream_mask;
225 int i;
226
227 ssc_sr = (ssc_readl(ssc_p->ssc->regs, SR) &
228 ssc_readl(ssc_p->ssc->regs, IMR));
229
230 /*
231 * Loop through substreams attached to this SSC. If a DMA-related
232 * interrupt occured on that substream, call the DMA interrupt
233 * handler function, if one has been registered in the dma_param
234 * structure by the PCM driver.
235 */
236 for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
237 dma_params = ssc_p->dma_params[i];
238
239 if ((dma_params != NULL) &&
240 (dma_params->dma_intr_handler != NULL)) {
241 ssc_substream_mask = (dma_params->mask->ssc_endx |
242 dma_params->mask->ssc_endbuf);
243 if (ssc_sr & ssc_substream_mask) {
244 dma_params->dma_intr_handler(ssc_sr,
245 dma_params->
246 substream);
247 }
248 }
249 }
250
251
252 return IRQ_HANDLED;
253}
254
255/*-------------------------------------------------------------------------*\
256 * DAI functions
257\*-------------------------------------------------------------------------*/
258/*
259 * Startup. Only that one substream allowed in each direction.
260 */
261static int at32_ssc_startup(struct snd_pcm_substream *substream)
262{
263 struct snd_soc_pcm_runtime *rtd = substream->private_data;
264 struct at32_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
265 int dir_mask;
266
267 dir_mask = ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
268 SSC_DIR_MASK_PLAYBACK : SSC_DIR_MASK_CAPTURE);
269
270 spin_lock_irq(&ssc_p->lock);
271 if (ssc_p->dir_mask & dir_mask) {
272 spin_unlock_irq(&ssc_p->lock);
273 return -EBUSY;
274 }
275 ssc_p->dir_mask |= dir_mask;
276 spin_unlock_irq(&ssc_p->lock);
277
278 return 0;
279}
280
281
282
283/*
284 * Shutdown. Clear DMA parameters and shutdown the SSC if there
285 * are no other substreams open.
286 */
287static void at32_ssc_shutdown(struct snd_pcm_substream *substream)
288{
289 struct snd_soc_pcm_runtime *rtd = substream->private_data;
290 struct at32_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
291 struct at32_pcm_dma_params *dma_params;
292 int dir_mask;
293
294 dma_params = ssc_p->dma_params[substream->stream];
295
296 if (dma_params != NULL) {
297 ssc_writel(dma_params->ssc->regs, CR,
298 dma_params->mask->ssc_disable);
299 pr_debug("%s disabled SSC_SR=0x%08x\n",
300 (substream->stream ? "receiver" : "transmit"),
301 ssc_readl(ssc_p->ssc->regs, SR));
302
303 dma_params->ssc = NULL;
304 dma_params->substream = NULL;
305 ssc_p->dma_params[substream->stream] = NULL;
306 }
307
308
309 dir_mask = 1 << substream->stream;
310 spin_lock_irq(&ssc_p->lock);
311 ssc_p->dir_mask &= ~dir_mask;
312 if (!ssc_p->dir_mask) {
313 /* Shutdown the SSC clock */
314 pr_debug("at32-ssc: Stopping user %d clock\n",
315 ssc_p->ssc->user);
316 clk_disable(ssc_p->ssc->clk);
317
318 if (ssc_p->initialized) {
319 free_irq(ssc_p->ssc->irq, ssc_p);
320 ssc_p->initialized = 0;
321 }
322
323 /* Reset the SSC */
324 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
325
326 /* clear the SSC dividers */
327 ssc_p->cmr_div = 0;
328 ssc_p->tcmr_period = 0;
329 ssc_p->rcmr_period = 0;
330 }
331 spin_unlock_irq(&ssc_p->lock);
332}
333
334
335
336/*
337 * Set the SSC system clock rate
338 */
339static int at32_ssc_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
340 int clk_id, unsigned int freq, int dir)
341{
342 /* TODO: What the heck do I do here? */
343 return 0;
344}
345
346
347
348/*
349 * Record DAI format for use by hw_params()
350 */
351static int at32_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
352 unsigned int fmt)
353{
354 struct at32_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
355
356 ssc_p->daifmt = fmt;
357 return 0;
358}
359
360
361
362/*
363 * Record SSC clock dividers for use in hw_params()
364 */
365static int at32_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
366 int div_id, int div)
367{
368 struct at32_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
369
370 switch (div_id) {
371 case AT32_SSC_CMR_DIV:
372 /*
373 * The same master clock divider is used for both
374 * transmit and receive, so if a value has already
375 * been set, it must match this value
376 */
377 if (ssc_p->cmr_div == 0)
378 ssc_p->cmr_div = div;
379 else if (div != ssc_p->cmr_div)
380 return -EBUSY;
381 break;
382
383 case AT32_SSC_TCMR_PERIOD:
384 ssc_p->tcmr_period = div;
385 break;
386
387 case AT32_SSC_RCMR_PERIOD:
388 ssc_p->rcmr_period = div;
389 break;
390
391 default:
392 return -EINVAL;
393 }
394
395 return 0;
396}
397
398
399
400/*
401 * Configure the SSC
402 */
403static int at32_ssc_hw_params(struct snd_pcm_substream *substream,
404 struct snd_pcm_hw_params *params)
405{
406 struct snd_soc_pcm_runtime *rtd = substream->private_data;
407 int id = rtd->dai->cpu_dai->id;
408 struct at32_ssc_info *ssc_p = &ssc_info[id];
409 struct at32_pcm_dma_params *dma_params;
410 int channels, bits;
411 u32 tfmr, rfmr, tcmr, rcmr;
412 int start_event;
413 int ret;
414
415
416 /*
417 * Currently, there is only one set of dma_params for each direction.
418 * If more are added, this code will have to be changed to select
419 * the proper set
420 */
421 dma_params = &ssc_dma_params[id][substream->stream];
422 dma_params->ssc = ssc_p->ssc;
423 dma_params->substream = substream;
424
425 ssc_p->dma_params[substream->stream] = dma_params;
426
427
428 /*
429 * The cpu_dai->dma_data field is only used to communicate the
430 * appropriate DMA parameters to the PCM driver's hw_params()
431 * function. It should not be used for other purposes as it
432 * is common to all substreams.
433 */
434 rtd->dai->cpu_dai->dma_data = dma_params;
435
436 channels = params_channels(params);
437
438
439 /*
440 * Determine sample size in bits and the PDC increment
441 */
442 switch (params_format(params)) {
443 case SNDRV_PCM_FORMAT_S8:
444 bits = 8;
445 dma_params->pdc_xfer_size = 1;
446 break;
447
448 case SNDRV_PCM_FORMAT_S16:
449 bits = 16;
450 dma_params->pdc_xfer_size = 2;
451 break;
452
453 case SNDRV_PCM_FORMAT_S24:
454 bits = 24;
455 dma_params->pdc_xfer_size = 4;
456 break;
457
458 case SNDRV_PCM_FORMAT_S32:
459 bits = 32;
460 dma_params->pdc_xfer_size = 4;
461 break;
462
463 default:
464 pr_warning("at32-ssc: Unsupported PCM format %d",
465 params_format(params));
466 return -EINVAL;
467 }
468 pr_debug("at32-ssc: bits = %d, pdc_xfer_size = %d, channels = %d\n",
469 bits, dma_params->pdc_xfer_size, channels);
470
471
472 /*
473 * The SSC only supports up to 16-bit samples in I2S format, due
474 * to the size of the Frame Mode Register FSLEN field.
475 */
476 if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S)
477 if (bits > 16) {
478 pr_warning("at32-ssc: "
479 "sample size %d is too large for I2S\n",
480 bits);
481 return -EINVAL;
482 }
483
484
485 /*
486 * Compute the SSC register settings
487 */
488 switch (ssc_p->daifmt & (SND_SOC_DAIFMT_FORMAT_MASK |
489 SND_SOC_DAIFMT_MASTER_MASK)) {
490 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
491 /*
492 * I2S format, SSC provides BCLK and LRS clocks.
493 *
494 * The SSC transmit and receive clocks are generated from the
495 * MCK divider, and the BCLK signal is output on the SSC TK line
496 */
497 pr_debug("at32-ssc: SSC mode is I2S BCLK / FRAME master\n");
498 rcmr = (SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) |
499 SSC_BF(RCMR_STTDLY, START_DELAY) |
500 SSC_BF(RCMR_START, SSC_START_FALLING_RF) |
501 SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
502 SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
503 SSC_BF(RCMR_CKS, SSC_CKS_DIV));
504
505 rfmr = (SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
506 SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE) |
507 SSC_BF(RFMR_FSLEN, bits - 1) |
508 SSC_BF(RFMR_DATNB, channels - 1) |
509 SSC_BIT(RFMR_MSBF) | SSC_BF(RFMR_DATLEN, bits - 1));
510
511 tcmr = (SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) |
512 SSC_BF(TCMR_STTDLY, START_DELAY) |
513 SSC_BF(TCMR_START, SSC_START_FALLING_RF) |
514 SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
515 SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS) |
516 SSC_BF(TCMR_CKS, SSC_CKS_DIV));
517
518 tfmr = (SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
519 SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE) |
520 SSC_BF(TFMR_FSLEN, bits - 1) |
521 SSC_BF(TFMR_DATNB, channels - 1) | SSC_BIT(TFMR_MSBF) |
522 SSC_BF(TFMR_DATLEN, bits - 1));
523 break;
524
525
526 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
527 /*
528 * I2S format, CODEC supplies BCLK and LRC clock.
529 *
530 * The SSC transmit clock is obtained from the BCLK signal
531 * on the TK line, and the SSC receive clock is generated from
532 * the transmit clock.
533 *
534 * For single channel data, one sample is transferred on the
535 * falling edge of the LRC clock. For two channel data, one
536 * sample is transferred on both edges of the LRC clock.
537 */
538 pr_debug("at32-ssc: SSC mode is I2S BCLK / FRAME slave\n");
539 start_event = ((channels == 1) ?
540 SSC_START_FALLING_RF : SSC_START_EDGE_RF);
541
542 rcmr = (SSC_BF(RCMR_STTDLY, START_DELAY) |
543 SSC_BF(RCMR_START, start_event) |
544 SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
545 SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
546 SSC_BF(RCMR_CKS, SSC_CKS_CLOCK));
547
548 rfmr = (SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
549 SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) |
550 SSC_BIT(RFMR_MSBF) | SSC_BF(RFMR_DATLEN, bits - 1));
551
552 tcmr = (SSC_BF(TCMR_STTDLY, START_DELAY) |
553 SSC_BF(TCMR_START, start_event) |
554 SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
555 SSC_BF(TCMR_CKO, SSC_CKO_NONE) |
556 SSC_BF(TCMR_CKS, SSC_CKS_PIN));
557
558 tfmr = (SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
559 SSC_BF(TFMR_FSOS, SSC_FSOS_NONE) |
560 SSC_BIT(TFMR_MSBF) | SSC_BF(TFMR_DATLEN, bits - 1));
561 break;
562
563
564 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
565 /*
566 * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
567 *
568 * The SSC transmit and receive clocks are generated from the
569 * MCK divider, and the BCLK signal is output on the SSC TK line
570 */
571 pr_debug("at32-ssc: SSC mode is DSP A BCLK / FRAME master\n");
572 rcmr = (SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) |
573 SSC_BF(RCMR_STTDLY, 1) |
574 SSC_BF(RCMR_START, SSC_START_RISING_RF) |
575 SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
576 SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
577 SSC_BF(RCMR_CKS, SSC_CKS_DIV));
578
579 rfmr = (SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
580 SSC_BF(RFMR_FSOS, SSC_FSOS_POSITIVE) |
581 SSC_BF(RFMR_DATNB, channels - 1) |
582 SSC_BIT(RFMR_MSBF) | SSC_BF(RFMR_DATLEN, bits - 1));
583
584 tcmr = (SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) |
585 SSC_BF(TCMR_STTDLY, 1) |
586 SSC_BF(TCMR_START, SSC_START_RISING_RF) |
587 SSC_BF(TCMR_CKI, SSC_CKI_RISING) |
588 SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS) |
589 SSC_BF(TCMR_CKS, SSC_CKS_DIV));
590
591 tfmr = (SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
592 SSC_BF(TFMR_FSOS, SSC_FSOS_POSITIVE) |
593 SSC_BF(TFMR_DATNB, channels - 1) |
594 SSC_BIT(TFMR_MSBF) | SSC_BF(TFMR_DATLEN, bits - 1));
595 break;
596
597
598 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
599 default:
600 pr_warning("at32-ssc: unsupported DAI format 0x%x\n",
601 ssc_p->daifmt);
602 return -EINVAL;
603 break;
604 }
605 pr_debug("at32-ssc: RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n",
606 rcmr, rfmr, tcmr, tfmr);
607
608
609 if (!ssc_p->initialized) {
610 /* enable peripheral clock */
611 pr_debug("at32-ssc: Starting clock\n");
612 clk_enable(ssc_p->ssc->clk);
613
614 /* Reset the SSC and its PDC registers */
615 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
616
617 ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0);
618 ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0);
619 ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0);
620 ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0);
621
622 ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0);
623 ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0);
624 ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0);
625 ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0);
626
627 ret = request_irq(ssc_p->ssc->irq, at32_ssc_interrupt, 0,
628 ssc_p->name, ssc_p);
629 if (ret < 0) {
630 pr_warning("at32-ssc: request irq failed (%d)\n", ret);
631 pr_debug("at32-ssc: Stopping clock\n");
632 clk_disable(ssc_p->ssc->clk);
633 return ret;
634 }
635
636 ssc_p->initialized = 1;
637 }
638
639 /* Set SSC clock mode register */
640 ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->cmr_div);
641
642 /* set receive clock mode and format */
643 ssc_writel(ssc_p->ssc->regs, RCMR, rcmr);
644 ssc_writel(ssc_p->ssc->regs, RFMR, rfmr);
645
646 /* set transmit clock mode and format */
647 ssc_writel(ssc_p->ssc->regs, TCMR, tcmr);
648 ssc_writel(ssc_p->ssc->regs, TFMR, tfmr);
649
650 pr_debug("at32-ssc: SSC initialized\n");
651 return 0;
652}
653
654
655
656static int at32_ssc_prepare(struct snd_pcm_substream *substream)
657{
658 struct snd_soc_pcm_runtime *rtd = substream->private_data;
659 struct at32_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
660 struct at32_pcm_dma_params *dma_params;
661
662 dma_params = ssc_p->dma_params[substream->stream];
663
664 ssc_writel(dma_params->ssc->regs, CR, dma_params->mask->ssc_enable);
665
666 return 0;
667}
668
669
670
671#ifdef CONFIG_PM
672static int at32_ssc_suspend(struct platform_device *pdev,
673 struct snd_soc_dai *cpu_dai)
674{
675 struct at32_ssc_info *ssc_p;
676
677 if (!cpu_dai->active)
678 return 0;
679
680 ssc_p = &ssc_info[cpu_dai->id];
681
682 /* Save the status register before disabling transmit and receive */
683 ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR);
684 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_TXDIS) | SSC_BIT(CR_RXDIS));
685
686 /* Save the current interrupt mask, then disable unmasked interrupts */
687 ssc_p->ssc_state.ssc_imr = ssc_readl(ssc_p->ssc->regs, IMR);
688 ssc_writel(ssc_p->ssc->regs, IDR, ssc_p->ssc_state.ssc_imr);
689
690 ssc_p->ssc_state.ssc_cmr = ssc_readl(ssc_p->ssc->regs, CMR);
691 ssc_p->ssc_state.ssc_rcmr = ssc_readl(ssc_p->ssc->regs, RCMR);
692 ssc_p->ssc_state.ssc_rfmr = ssc_readl(ssc_p->ssc->regs, RFMR);
693 ssc_p->ssc_state.ssc_tcmr = ssc_readl(ssc_p->ssc->regs, TCMR);
694 ssc_p->ssc_state.ssc_tfmr = ssc_readl(ssc_p->ssc->regs, TFMR);
695
696 return 0;
697}
698
699
700
701static int at32_ssc_resume(struct platform_device *pdev,
702 struct snd_soc_dai *cpu_dai)
703{
704 struct at32_ssc_info *ssc_p;
705 u32 cr;
706
707 if (!cpu_dai->active)
708 return 0;
709
710 ssc_p = &ssc_info[cpu_dai->id];
711
712 /* restore SSC register settings */
713 ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr);
714 ssc_writel(ssc_p->ssc->regs, TCMR, ssc_p->ssc_state.ssc_tcmr);
715 ssc_writel(ssc_p->ssc->regs, RFMR, ssc_p->ssc_state.ssc_rfmr);
716 ssc_writel(ssc_p->ssc->regs, RCMR, ssc_p->ssc_state.ssc_rcmr);
717 ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->ssc_state.ssc_cmr);
718
719 /* re-enable interrupts */
720 ssc_writel(ssc_p->ssc->regs, IER, ssc_p->ssc_state.ssc_imr);
721
722 /* Re-enable recieve and transmit as appropriate */
723 cr = 0;
724 cr |=
725 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_RXEN)) ? SSC_BIT(CR_RXEN) : 0;
726 cr |=
727 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_TXEN)) ? SSC_BIT(CR_TXEN) : 0;
728 ssc_writel(ssc_p->ssc->regs, CR, cr);
729
730 return 0;
731}
732#else /* CONFIG_PM */
733# define at32_ssc_suspend NULL
734# define at32_ssc_resume NULL
735#endif /* CONFIG_PM */
736
737
738#define AT32_SSC_RATES \
739 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
740 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
741 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
742
743
744#define AT32_SSC_FORMATS \
745 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16 | \
746 SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_S32)
747
748
749struct snd_soc_dai at32_ssc_dai[NUM_SSC_DEVICES] = {
750 {
751 .name = "at32-ssc0",
752 .id = 0,
753 .type = SND_SOC_DAI_PCM,
754 .suspend = at32_ssc_suspend,
755 .resume = at32_ssc_resume,
756 .playback = {
757 .channels_min = 1,
758 .channels_max = 2,
759 .rates = AT32_SSC_RATES,
760 .formats = AT32_SSC_FORMATS,
761 },
762 .capture = {
763 .channels_min = 1,
764 .channels_max = 2,
765 .rates = AT32_SSC_RATES,
766 .formats = AT32_SSC_FORMATS,
767 },
768 .ops = {
769 .startup = at32_ssc_startup,
770 .shutdown = at32_ssc_shutdown,
771 .prepare = at32_ssc_prepare,
772 .hw_params = at32_ssc_hw_params,
773 },
774 .dai_ops = {
775 .set_sysclk = at32_ssc_set_dai_sysclk,
776 .set_fmt = at32_ssc_set_dai_fmt,
777 .set_clkdiv = at32_ssc_set_dai_clkdiv,
778 },
779 .private_data = &ssc_info[0],
780 },
781 {
782 .name = "at32-ssc1",
783 .id = 1,
784 .type = SND_SOC_DAI_PCM,
785 .suspend = at32_ssc_suspend,
786 .resume = at32_ssc_resume,
787 .playback = {
788 .channels_min = 1,
789 .channels_max = 2,
790 .rates = AT32_SSC_RATES,
791 .formats = AT32_SSC_FORMATS,
792 },
793 .capture = {
794 .channels_min = 1,
795 .channels_max = 2,
796 .rates = AT32_SSC_RATES,
797 .formats = AT32_SSC_FORMATS,
798 },
799 .ops = {
800 .startup = at32_ssc_startup,
801 .shutdown = at32_ssc_shutdown,
802 .prepare = at32_ssc_prepare,
803 .hw_params = at32_ssc_hw_params,
804 },
805 .dai_ops = {
806 .set_sysclk = at32_ssc_set_dai_sysclk,
807 .set_fmt = at32_ssc_set_dai_fmt,
808 .set_clkdiv = at32_ssc_set_dai_clkdiv,
809 },
810 .private_data = &ssc_info[1],
811 },
812 {
813 .name = "at32-ssc2",
814 .id = 2,
815 .type = SND_SOC_DAI_PCM,
816 .suspend = at32_ssc_suspend,
817 .resume = at32_ssc_resume,
818 .playback = {
819 .channels_min = 1,
820 .channels_max = 2,
821 .rates = AT32_SSC_RATES,
822 .formats = AT32_SSC_FORMATS,
823 },
824 .capture = {
825 .channels_min = 1,
826 .channels_max = 2,
827 .rates = AT32_SSC_RATES,
828 .formats = AT32_SSC_FORMATS,
829 },
830 .ops = {
831 .startup = at32_ssc_startup,
832 .shutdown = at32_ssc_shutdown,
833 .prepare = at32_ssc_prepare,
834 .hw_params = at32_ssc_hw_params,
835 },
836 .dai_ops = {
837 .set_sysclk = at32_ssc_set_dai_sysclk,
838 .set_fmt = at32_ssc_set_dai_fmt,
839 .set_clkdiv = at32_ssc_set_dai_clkdiv,
840 },
841 .private_data = &ssc_info[2],
842 },
843};
844EXPORT_SYMBOL_GPL(at32_ssc_dai);
845
846
847MODULE_AUTHOR("Geoffrey Wossum <gwossum@acm.org>");
848MODULE_DESCRIPTION("AT32 SSC ASoC Interface");
849MODULE_LICENSE("GPL");
diff --git a/sound/soc/at32/at32-ssc.h b/sound/soc/at32/at32-ssc.h
new file mode 100644
index 000000000000..3c052dbbe460
--- /dev/null
+++ b/sound/soc/at32/at32-ssc.h
@@ -0,0 +1,59 @@
1/* sound/soc/at32/at32-ssc.h
2 * ASoC SSC interface for Atmel AT32 SoC
3 *
4 * Copyright (C) 2008 Long Range Systems
5 * Geoffrey Wossum <gwossum@acm.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __SOUND_SOC_AT32_AT32_SSC_H
13#define __SOUND_SOC_AT32_AT32_SSC_H __FILE__
14
15#include <linux/types.h>
16#include <linux/atmel-ssc.h>
17
18#include "at32-pcm.h"
19
20
21
22struct at32_ssc_state {
23 u32 ssc_cmr;
24 u32 ssc_rcmr;
25 u32 ssc_rfmr;
26 u32 ssc_tcmr;
27 u32 ssc_tfmr;
28 u32 ssc_sr;
29 u32 ssc_imr;
30};
31
32
33
34struct at32_ssc_info {
35 char *name;
36 struct ssc_device *ssc;
37 spinlock_t lock; /* lock for dir_mask */
38 unsigned short dir_mask; /* 0=unused, 1=playback, 2=capture */
39 unsigned short initialized; /* true if SSC has been initialized */
40 unsigned short daifmt;
41 unsigned short cmr_div;
42 unsigned short tcmr_period;
43 unsigned short rcmr_period;
44 struct at32_pcm_dma_params *dma_params[2];
45 struct at32_ssc_state ssc_state;
46};
47
48
49/* SSC divider ids */
50#define AT32_SSC_CMR_DIV 0 /* MCK divider for BCLK */
51#define AT32_SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */
52#define AT32_SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */
53
54
55extern struct snd_soc_dai at32_ssc_dai[];
56
57
58
59#endif /* __SOUND_SOC_AT32_AT32_SSC_H */
diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/at32/playpaq_wm8510.c
new file mode 100644
index 000000000000..fee5f8e58957
--- /dev/null
+++ b/sound/soc/at32/playpaq_wm8510.c
@@ -0,0 +1,522 @@
1/* sound/soc/at32/playpaq_wm8510.c
2 * ASoC machine driver for PlayPaq using WM8510 codec
3 *
4 * Copyright (C) 2008 Long Range Systems
5 * Geoffrey Wossum <gwossum@acm.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This code is largely inspired by sound/soc/at91/eti_b1_wm8731.c
12 *
13 * NOTE: If you don't have the AT32 enhanced portmux configured (which
14 * isn't currently in the mainline or Atmel patched kernel), you will
15 * need to set the MCLK pin (PA30) to peripheral A in your board initialization
16 * code. Something like:
17 * at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0);
18 *
19 */
20
21/* #define DEBUG */
22
23#include <linux/module.h>
24#include <linux/moduleparam.h>
25#include <linux/version.h>
26#include <linux/kernel.h>
27#include <linux/errno.h>
28#include <linux/clk.h>
29#include <linux/timer.h>
30#include <linux/interrupt.h>
31#include <linux/platform_device.h>
32
33#include <sound/core.h>
34#include <sound/pcm.h>
35#include <sound/pcm_params.h>
36#include <sound/soc.h>
37#include <sound/soc-dapm.h>
38
39#include <asm/arch/at32ap700x.h>
40#include <asm/arch/portmux.h>
41
42#include "../codecs/wm8510.h"
43#include "at32-pcm.h"
44#include "at32-ssc.h"
45
46
47/*-------------------------------------------------------------------------*\
48 * constants
49\*-------------------------------------------------------------------------*/
50#define MCLK_PIN GPIO_PIN_PA(30)
51#define MCLK_PERIPH GPIO_PERIPH_A
52
53
54/*-------------------------------------------------------------------------*\
55 * data types
56\*-------------------------------------------------------------------------*/
57/* SSC clocking data */
58struct ssc_clock_data {
59 /* CMR div */
60 unsigned int cmr_div;
61
62 /* Frame period (as needed by xCMR.PERIOD) */
63 unsigned int period;
64
65 /* The SSC clock rate these settings where calculated for */
66 unsigned long ssc_rate;
67};
68
69
70/*-------------------------------------------------------------------------*\
71 * module data
72\*-------------------------------------------------------------------------*/
73static struct clk *_gclk0;
74static struct clk *_pll0;
75
76#define CODEC_CLK (_gclk0)
77
78
79/*-------------------------------------------------------------------------*\
80 * Sound SOC operations
81\*-------------------------------------------------------------------------*/
82#if defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE
83static struct ssc_clock_data playpaq_wm8510_calc_ssc_clock(
84 struct snd_pcm_hw_params *params,
85 struct snd_soc_dai *cpu_dai)
86{
87 struct at32_ssc_info *ssc_p = cpu_dai->private_data;
88 struct ssc_device *ssc = ssc_p->ssc;
89 struct ssc_clock_data cd;
90 unsigned int rate, width_bits, channels;
91 unsigned int bitrate, ssc_div;
92 unsigned actual_rate;
93
94
95 /*
96 * Figure out required bitrate
97 */
98 rate = params_rate(params);
99 channels = params_channels(params);
100 width_bits = snd_pcm_format_physical_width(params_format(params));
101 bitrate = rate * width_bits * channels;
102
103
104 /*
105 * Figure out required SSC divider and period for required bitrate
106 */
107 cd.ssc_rate = clk_get_rate(ssc->clk);
108 ssc_div = cd.ssc_rate / bitrate;
109 cd.cmr_div = ssc_div / 2;
110 if (ssc_div & 1) {
111 /* round cmr_div up */
112 cd.cmr_div++;
113 }
114 cd.period = width_bits - 1;
115
116
117 /*
118 * Find actual rate, compare to requested rate
119 */
120 actual_rate = (cd.ssc_rate / (cd.cmr_div * 2)) / (2 * (cd.period + 1));
121 pr_debug("playpaq_wm8510: Request rate = %d, actual rate = %d\n",
122 rate, actual_rate);
123
124
125 return cd;
126}
127#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */
128
129
130
131static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream,
132 struct snd_pcm_hw_params *params)
133{
134 struct snd_soc_pcm_runtime *rtd = substream->private_data;
135 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
136 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
137 struct at32_ssc_info *ssc_p = cpu_dai->private_data;
138 struct ssc_device *ssc = ssc_p->ssc;
139 unsigned int pll_out = 0, bclk = 0, mclk_div = 0;
140 int ret;
141
142
143 /* Due to difficulties with getting the correct clocks from the AT32's
144 * PLL0, we're going to let the CODEC be in charge of all the clocks
145 */
146#if !defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE
147 const unsigned int fmt = (SND_SOC_DAIFMT_I2S |
148 SND_SOC_DAIFMT_NB_NF |
149 SND_SOC_DAIFMT_CBM_CFM);
150#else
151 struct ssc_clock_data cd;
152 const unsigned int fmt = (SND_SOC_DAIFMT_I2S |
153 SND_SOC_DAIFMT_NB_NF |
154 SND_SOC_DAIFMT_CBS_CFS);
155#endif
156
157 if (ssc == NULL) {
158 pr_warning("playpaq_wm8510_hw_params: ssc is NULL!\n");
159 return -EINVAL;
160 }
161
162
163 /*
164 * Figure out PLL and BCLK dividers for WM8510
165 */
166 switch (params_rate(params)) {
167 case 48000:
168 pll_out = 12288000;
169 mclk_div = WM8510_MCLKDIV_1;
170 bclk = WM8510_BCLKDIV_8;
171 break;
172
173 case 44100:
174 pll_out = 11289600;
175 mclk_div = WM8510_MCLKDIV_1;
176 bclk = WM8510_BCLKDIV_8;
177 break;
178
179 case 22050:
180 pll_out = 11289600;
181 mclk_div = WM8510_MCLKDIV_2;
182 bclk = WM8510_BCLKDIV_8;
183 break;
184
185 case 16000:
186 pll_out = 12288000;
187 mclk_div = WM8510_MCLKDIV_3;
188 bclk = WM8510_BCLKDIV_8;
189 break;
190
191 case 11025:
192 pll_out = 11289600;
193 mclk_div = WM8510_MCLKDIV_4;
194 bclk = WM8510_BCLKDIV_8;
195 break;
196
197 case 8000:
198 pll_out = 12288000;
199 mclk_div = WM8510_MCLKDIV_6;
200 bclk = WM8510_BCLKDIV_8;
201 break;
202
203 default:
204 pr_warning("playpaq_wm8510: Unsupported sample rate %d\n",
205 params_rate(params));
206 return -EINVAL;
207 }
208
209
210 /*
211 * set CPU and CODEC DAI configuration
212 */
213 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
214 if (ret < 0) {
215 pr_warning("playpaq_wm8510: "
216 "Failed to set CODEC DAI format (%d)\n",
217 ret);
218 return ret;
219 }
220 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
221 if (ret < 0) {
222 pr_warning("playpaq_wm8510: "
223 "Failed to set CPU DAI format (%d)\n",
224 ret);
225 return ret;
226 }
227
228
229 /*
230 * Set CPU clock configuration
231 */
232#if defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE
233 cd = playpaq_wm8510_calc_ssc_clock(params, cpu_dai);
234 pr_debug("playpaq_wm8510: cmr_div = %d, period = %d\n",
235 cd.cmr_div, cd.period);
236 ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_CMR_DIV, cd.cmr_div);
237 if (ret < 0) {
238 pr_warning("playpaq_wm8510: Failed to set CPU CMR_DIV (%d)\n",
239 ret);
240 return ret;
241 }
242 ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_TCMR_PERIOD,
243 cd.period);
244 if (ret < 0) {
245 pr_warning("playpaq_wm8510: "
246 "Failed to set CPU transmit period (%d)\n",
247 ret);
248 return ret;
249 }
250#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */
251
252
253 /*
254 * Set CODEC clock configuration
255 */
256 pr_debug("playpaq_wm8510: "
257 "pll_in = %ld, pll_out = %u, bclk = %x, mclk = %x\n",
258 clk_get_rate(CODEC_CLK), pll_out, bclk, mclk_div);
259
260
261#if !defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE
262 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_BCLKDIV, bclk);
263 if (ret < 0) {
264 pr_warning
265 ("playpaq_wm8510: Failed to set CODEC DAI BCLKDIV (%d)\n",
266 ret);
267 return ret;
268 }
269#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */
270
271
272 ret = snd_soc_dai_set_pll(codec_dai, 0,
273 clk_get_rate(CODEC_CLK), pll_out);
274 if (ret < 0) {
275 pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n",
276 ret);
277 return ret;
278 }
279
280
281 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_MCLKDIV, mclk_div);
282 if (ret < 0) {
283 pr_warning("playpaq_wm8510: Failed to set CODEC MCLKDIV (%d)\n",
284 ret);
285 return ret;
286 }
287
288
289 return 0;
290}
291
292
293
294static struct snd_soc_ops playpaq_wm8510_ops = {
295 .hw_params = playpaq_wm8510_hw_params,
296};
297
298
299
300static const struct snd_soc_dapm_widget playpaq_dapm_widgets[] = {
301 SND_SOC_DAPM_MIC("Int Mic", NULL),
302 SND_SOC_DAPM_SPK("Ext Spk", NULL),
303};
304
305
306
307static const char *intercon[][3] = {
308 /* speaker connected to SPKOUT */
309 {"Ext Spk", NULL, "SPKOUTP"},
310 {"Ext Spk", NULL, "SPKOUTN"},
311
312 {"Mic Bias", NULL, "Int Mic"},
313 {"MICN", NULL, "Mic Bias"},
314 {"MICP", NULL, "Mic Bias"},
315
316 /* Terminator */
317 {NULL, NULL, NULL},
318};
319
320
321
322static int playpaq_wm8510_init(struct snd_soc_codec *codec)
323{
324 int i;
325
326 /*
327 * Add DAPM widgets
328 */
329 for (i = 0; i < ARRAY_SIZE(playpaq_dapm_widgets); i++)
330 snd_soc_dapm_new_control(codec, &playpaq_dapm_widgets[i]);
331
332
333
334 /*
335 * Setup audio path interconnects
336 */
337 for (i = 0; intercon[i][0] != NULL; i++) {
338 snd_soc_dapm_connect_input(codec,
339 intercon[i][0],
340 intercon[i][1], intercon[i][2]);
341 }
342
343
344 /* always connected pins */
345 snd_soc_dapm_enable_pin(codec, "Int Mic");
346 snd_soc_dapm_enable_pin(codec, "Ext Spk");
347 snd_soc_dapm_sync(codec);
348
349
350
351 /* Make CSB show PLL rate */
352 snd_soc_dai_set_clkdiv(codec->dai, WM8510_OPCLKDIV,
353 WM8510_OPCLKDIV_1 | 4);
354
355 return 0;
356}
357
358
359
360static struct snd_soc_dai_link playpaq_wm8510_dai = {
361 .name = "WM8510",
362 .stream_name = "WM8510 PCM",
363 .cpu_dai = &at32_ssc_dai[0],
364 .codec_dai = &wm8510_dai,
365 .init = playpaq_wm8510_init,
366 .ops = &playpaq_wm8510_ops,
367};
368
369
370
371static struct snd_soc_machine snd_soc_machine_playpaq = {
372 .name = "LRS_PlayPaq_WM8510",
373 .dai_link = &playpaq_wm8510_dai,
374 .num_links = 1,
375};
376
377
378
379static struct wm8510_setup_data playpaq_wm8510_setup = {
380 .i2c_address = 0x1a,
381};
382
383
384
385static struct snd_soc_device playpaq_wm8510_snd_devdata = {
386 .machine = &snd_soc_machine_playpaq,
387 .platform = &at32_soc_platform,
388 .codec_dev = &soc_codec_dev_wm8510,
389 .codec_data = &playpaq_wm8510_setup,
390};
391
392static struct platform_device *playpaq_snd_device;
393
394
395static int __init playpaq_asoc_init(void)
396{
397 int ret = 0;
398 struct at32_ssc_info *ssc_p = playpaq_wm8510_dai.cpu_dai->private_data;
399 struct ssc_device *ssc = NULL;
400
401
402 /*
403 * Request SSC device
404 */
405 ssc = ssc_request(0);
406 if (IS_ERR(ssc)) {
407 ret = PTR_ERR(ssc);
408 ssc = NULL;
409 goto err_ssc;
410 }
411 ssc_p->ssc = ssc;
412
413
414 /*
415 * Configure MCLK for WM8510
416 */
417 _gclk0 = clk_get(NULL, "gclk0");
418 if (IS_ERR(_gclk0)) {
419 _gclk0 = NULL;
420 goto err_gclk0;
421 }
422 _pll0 = clk_get(NULL, "pll0");
423 if (IS_ERR(_pll0)) {
424 _pll0 = NULL;
425 goto err_pll0;
426 }
427 if (clk_set_parent(_gclk0, _pll0)) {
428 pr_warning("snd-soc-playpaq: "
429 "Failed to set PLL0 as parent for DAC clock\n");
430 goto err_set_clk;
431 }
432 clk_set_rate(CODEC_CLK, 12000000);
433 clk_enable(CODEC_CLK);
434
435#if defined CONFIG_AT32_ENHANCED_PORTMUX
436 at32_select_periph(MCLK_PIN, MCLK_PERIPH, 0);
437#endif
438
439
440 /*
441 * Create and register platform device
442 */
443 playpaq_snd_device = platform_device_alloc("soc-audio", 0);
444 if (playpaq_snd_device == NULL) {
445 ret = -ENOMEM;
446 goto err_device_alloc;
447 }
448
449 platform_set_drvdata(playpaq_snd_device, &playpaq_wm8510_snd_devdata);
450 playpaq_wm8510_snd_devdata.dev = &playpaq_snd_device->dev;
451
452 ret = platform_device_add(playpaq_snd_device);
453 if (ret) {
454 pr_warning("playpaq_wm8510: platform_device_add failed (%d)\n",
455 ret);
456 goto err_device_add;
457 }
458
459 return 0;
460
461
462err_device_add:
463 if (playpaq_snd_device != NULL) {
464 platform_device_put(playpaq_snd_device);
465 playpaq_snd_device = NULL;
466 }
467err_device_alloc:
468err_set_clk:
469 if (_pll0 != NULL) {
470 clk_put(_pll0);
471 _pll0 = NULL;
472 }
473err_pll0:
474 if (_gclk0 != NULL) {
475 clk_put(_gclk0);
476 _gclk0 = NULL;
477 }
478err_gclk0:
479 if (ssc != NULL) {
480 ssc_free(ssc);
481 ssc = NULL;
482 }
483err_ssc:
484 return ret;
485}
486
487
488static void __exit playpaq_asoc_exit(void)
489{
490 struct at32_ssc_info *ssc_p = playpaq_wm8510_dai.cpu_dai->private_data;
491 struct ssc_device *ssc;
492
493 if (ssc_p != NULL) {
494 ssc = ssc_p->ssc;
495 if (ssc != NULL)
496 ssc_free(ssc);
497 ssc_p->ssc = NULL;
498 }
499
500 if (_gclk0 != NULL) {
501 clk_put(_gclk0);
502 _gclk0 = NULL;
503 }
504 if (_pll0 != NULL) {
505 clk_put(_pll0);
506 _pll0 = NULL;
507 }
508
509#if defined CONFIG_AT32_ENHANCED_PORTMUX
510 at32_free_pin(MCLK_PIN);
511#endif
512
513 platform_device_unregister(playpaq_snd_device);
514 playpaq_snd_device = NULL;
515}
516
517module_init(playpaq_asoc_init);
518module_exit(playpaq_asoc_exit);
519
520MODULE_AUTHOR("Geoffrey Wossum <gwossum@acm.org>");
521MODULE_DESCRIPTION("ASoC machine driver for LRS PlayPaq");
522MODULE_LICENSE("GPL");
diff --git a/sound/soc/at91/Kconfig b/sound/soc/at91/Kconfig
index 5cb93fd3a407..905186502e00 100644
--- a/sound/soc/at91/Kconfig
+++ b/sound/soc/at91/Kconfig
@@ -1,6 +1,6 @@
1config SND_AT91_SOC 1config SND_AT91_SOC
2 tristate "SoC Audio for the Atmel AT91 System-on-Chip" 2 tristate "SoC Audio for the Atmel AT91 System-on-Chip"
3 depends on ARCH_AT91 && SND_SOC 3 depends on ARCH_AT91
4 help 4 help
5 Say Y or M if you want to add support for codecs attached to 5 Say Y or M if you want to add support for codecs attached to
6 the AT91 SSC interface. You will also need 6 the AT91 SSC interface. You will also need
diff --git a/sound/soc/at91/at91-pcm.c b/sound/soc/at91/at91-pcm.c
index ccac6bd2889c..d47492b2b6e5 100644
--- a/sound/soc/at91/at91-pcm.c
+++ b/sound/soc/at91/at91-pcm.c
@@ -318,7 +318,7 @@ static int at91_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
318static u64 at91_pcm_dmamask = 0xffffffff; 318static u64 at91_pcm_dmamask = 0xffffffff;
319 319
320static int at91_pcm_new(struct snd_card *card, 320static int at91_pcm_new(struct snd_card *card,
321 struct snd_soc_codec_dai *dai, struct snd_pcm *pcm) 321 struct snd_soc_dai *dai, struct snd_pcm *pcm)
322{ 322{
323 int ret = 0; 323 int ret = 0;
324 324
@@ -367,7 +367,7 @@ static void at91_pcm_free_dma_buffers(struct snd_pcm *pcm)
367 367
368#ifdef CONFIG_PM 368#ifdef CONFIG_PM
369static int at91_pcm_suspend(struct platform_device *pdev, 369static int at91_pcm_suspend(struct platform_device *pdev,
370 struct snd_soc_cpu_dai *dai) 370 struct snd_soc_dai *dai)
371{ 371{
372 struct snd_pcm_runtime *runtime = dai->runtime; 372 struct snd_pcm_runtime *runtime = dai->runtime;
373 struct at91_runtime_data *prtd; 373 struct at91_runtime_data *prtd;
@@ -392,7 +392,7 @@ static int at91_pcm_suspend(struct platform_device *pdev,
392} 392}
393 393
394static int at91_pcm_resume(struct platform_device *pdev, 394static int at91_pcm_resume(struct platform_device *pdev,
395 struct snd_soc_cpu_dai *dai) 395 struct snd_soc_dai *dai)
396{ 396{
397 struct snd_pcm_runtime *runtime = dai->runtime; 397 struct snd_pcm_runtime *runtime = dai->runtime;
398 struct at91_runtime_data *prtd; 398 struct at91_runtime_data *prtd;
diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c
index bc35d00a38f8..c3625b665c5a 100644
--- a/sound/soc/at91/at91-ssc.c
+++ b/sound/soc/at91/at91-ssc.c
@@ -281,7 +281,7 @@ static void at91_ssc_shutdown(struct snd_pcm_substream *substream)
281/* 281/*
282 * Record the SSC system clock rate. 282 * Record the SSC system clock rate.
283 */ 283 */
284static int at91_ssc_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, 284static int at91_ssc_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
285 int clk_id, unsigned int freq, int dir) 285 int clk_id, unsigned int freq, int dir)
286{ 286{
287 /* 287 /*
@@ -303,7 +303,7 @@ static int at91_ssc_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
303/* 303/*
304 * Record the DAI format for use in hw_params(). 304 * Record the DAI format for use in hw_params().
305 */ 305 */
306static int at91_ssc_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, 306static int at91_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
307 unsigned int fmt) 307 unsigned int fmt)
308{ 308{
309 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; 309 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
@@ -315,7 +315,7 @@ static int at91_ssc_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai,
315/* 315/*
316 * Record SSC clock dividers for use in hw_params(). 316 * Record SSC clock dividers for use in hw_params().
317 */ 317 */
318static int at91_ssc_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai, 318static int at91_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
319 int div_id, int div) 319 int div_id, int div)
320{ 320{
321 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; 321 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
@@ -634,7 +634,7 @@ static int at91_ssc_prepare(struct snd_pcm_substream *substream)
634 634
635#ifdef CONFIG_PM 635#ifdef CONFIG_PM
636static int at91_ssc_suspend(struct platform_device *pdev, 636static int at91_ssc_suspend(struct platform_device *pdev,
637 struct snd_soc_cpu_dai *cpu_dai) 637 struct snd_soc_dai *cpu_dai)
638{ 638{
639 struct at91_ssc_info *ssc_p; 639 struct at91_ssc_info *ssc_p;
640 640
@@ -662,7 +662,7 @@ static int at91_ssc_suspend(struct platform_device *pdev,
662} 662}
663 663
664static int at91_ssc_resume(struct platform_device *pdev, 664static int at91_ssc_resume(struct platform_device *pdev,
665 struct snd_soc_cpu_dai *cpu_dai) 665 struct snd_soc_dai *cpu_dai)
666{ 666{
667 struct at91_ssc_info *ssc_p; 667 struct at91_ssc_info *ssc_p;
668 668
@@ -700,7 +700,7 @@ static int at91_ssc_resume(struct platform_device *pdev,
700#define AT91_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ 700#define AT91_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
701 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 701 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
702 702
703struct snd_soc_cpu_dai at91_ssc_dai[NUM_SSC_DEVICES] = { 703struct snd_soc_dai at91_ssc_dai[NUM_SSC_DEVICES] = {
704 { .name = "at91-ssc0", 704 { .name = "at91-ssc0",
705 .id = 0, 705 .id = 0,
706 .type = SND_SOC_DAI_PCM, 706 .type = SND_SOC_DAI_PCM,
diff --git a/sound/soc/at91/at91-ssc.h b/sound/soc/at91/at91-ssc.h
index b188f973df9f..6b7bf382d06f 100644
--- a/sound/soc/at91/at91-ssc.h
+++ b/sound/soc/at91/at91-ssc.h
@@ -21,7 +21,7 @@
21#define AT91SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */ 21#define AT91SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */
22#define AT91SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */ 22#define AT91SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */
23 23
24extern struct snd_soc_cpu_dai at91_ssc_dai[]; 24extern struct snd_soc_dai at91_ssc_dai[];
25 25
26#endif /* _AT91_SSC_H */ 26#endif /* _AT91_SSC_H */
27 27
diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c
index 1347dcf3f80b..d532de954241 100644
--- a/sound/soc/at91/eti_b1_wm8731.c
+++ b/sound/soc/at91/eti_b1_wm8731.c
@@ -53,18 +53,18 @@ static struct clk *pllb_clk;
53static int eti_b1_startup(struct snd_pcm_substream *substream) 53static int eti_b1_startup(struct snd_pcm_substream *substream)
54{ 54{
55 struct snd_soc_pcm_runtime *rtd = substream->private_data; 55 struct snd_soc_pcm_runtime *rtd = substream->private_data;
56 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; 56 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
57 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 57 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
58 int ret; 58 int ret;
59 59
60 /* cpu clock is the AT91 master clock sent to the SSC */ 60 /* cpu clock is the AT91 master clock sent to the SSC */
61 ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, AT91_SYSCLK_MCK, 61 ret = snd_soc_dai_set_sysclk(cpu_dai, AT91_SYSCLK_MCK,
62 60000000, SND_SOC_CLOCK_IN); 62 60000000, SND_SOC_CLOCK_IN);
63 if (ret < 0) 63 if (ret < 0)
64 return ret; 64 return ret;
65 65
66 /* codec system clock is supplied by PCK1, set to 12MHz */ 66 /* codec system clock is supplied by PCK1, set to 12MHz */
67 ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8731_SYSCLK, 67 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
68 12000000, SND_SOC_CLOCK_IN); 68 12000000, SND_SOC_CLOCK_IN);
69 if (ret < 0) 69 if (ret < 0)
70 return ret; 70 return ret;
@@ -87,8 +87,8 @@ static int eti_b1_hw_params(struct snd_pcm_substream *substream,
87 struct snd_pcm_hw_params *params) 87 struct snd_pcm_hw_params *params)
88{ 88{
89 struct snd_soc_pcm_runtime *rtd = substream->private_data; 89 struct snd_soc_pcm_runtime *rtd = substream->private_data;
90 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; 90 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
91 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 91 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
92 int ret; 92 int ret;
93 93
94#ifdef CONFIG_SND_AT91_SOC_ETI_SLAVE 94#ifdef CONFIG_SND_AT91_SOC_ETI_SLAVE
@@ -96,13 +96,13 @@ static int eti_b1_hw_params(struct snd_pcm_substream *substream,
96 int cmr_div, period; 96 int cmr_div, period;
97 97
98 /* set codec DAI configuration */ 98 /* set codec DAI configuration */
99 ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 99 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
100 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 100 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
101 if (ret < 0) 101 if (ret < 0)
102 return ret; 102 return ret;
103 103
104 /* set cpu DAI configuration */ 104 /* set cpu DAI configuration */
105 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | 105 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
106 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 106 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
107 if (ret < 0) 107 if (ret < 0)
108 return ret; 108 return ret;
@@ -141,17 +141,17 @@ static int eti_b1_hw_params(struct snd_pcm_substream *substream,
141 } 141 }
142 142
143 /* set the MCK divider for BCLK */ 143 /* set the MCK divider for BCLK */
144 ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, AT91SSC_CMR_DIV, cmr_div); 144 ret = snd_soc_dai_set_clkdiv(cpu_dai, AT91SSC_CMR_DIV, cmr_div);
145 if (ret < 0) 145 if (ret < 0)
146 return ret; 146 return ret;
147 147
148 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 148 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
149 /* set the BCLK divider for DACLRC */ 149 /* set the BCLK divider for DACLRC */
150 ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, 150 ret = snd_soc_dai_set_clkdiv(cpu_dai,
151 AT91SSC_TCMR_PERIOD, period); 151 AT91SSC_TCMR_PERIOD, period);
152 } else { 152 } else {
153 /* set the BCLK divider for ADCLRC */ 153 /* set the BCLK divider for ADCLRC */
154 ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, 154 ret = snd_soc_dai_set_clkdiv(cpu_dai,
155 AT91SSC_RCMR_PERIOD, period); 155 AT91SSC_RCMR_PERIOD, period);
156 } 156 }
157 if (ret < 0) 157 if (ret < 0)
@@ -163,13 +163,13 @@ static int eti_b1_hw_params(struct snd_pcm_substream *substream,
163 */ 163 */
164 164
165 /* set codec DAI configuration */ 165 /* set codec DAI configuration */
166 ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 166 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
167 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); 167 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
168 if (ret < 0) 168 if (ret < 0)
169 return ret; 169 return ret;
170 170
171 /* set cpu DAI configuration */ 171 /* set cpu DAI configuration */
172 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | 172 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
173 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); 173 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
174 if (ret < 0) 174 if (ret < 0)
175 return ret; 175 return ret;
@@ -191,7 +191,7 @@ static const struct snd_soc_dapm_widget eti_b1_dapm_widgets[] = {
191 SND_SOC_DAPM_SPK("Ext Spk", NULL), 191 SND_SOC_DAPM_SPK("Ext Spk", NULL),
192}; 192};
193 193
194static const char *intercon[][3] = { 194static const struct snd_soc_dapm_route intercon[] = {
195 195
196 /* speaker connected to LHPOUT */ 196 /* speaker connected to LHPOUT */
197 {"Ext Spk", NULL, "LHPOUT"}, 197 {"Ext Spk", NULL, "LHPOUT"},
@@ -199,9 +199,6 @@ static const char *intercon[][3] = {
199 /* mic is connected to Mic Jack, with WM8731 Mic Bias */ 199 /* mic is connected to Mic Jack, with WM8731 Mic Bias */
200 {"MICIN", NULL, "Mic Bias"}, 200 {"MICIN", NULL, "Mic Bias"},
201 {"Mic Bias", NULL, "Int Mic"}, 201 {"Mic Bias", NULL, "Int Mic"},
202
203 /* terminator */
204 {NULL, NULL, NULL},
205}; 202};
206 203
207/* 204/*
@@ -209,30 +206,24 @@ static const char *intercon[][3] = {
209 */ 206 */
210static int eti_b1_wm8731_init(struct snd_soc_codec *codec) 207static int eti_b1_wm8731_init(struct snd_soc_codec *codec)
211{ 208{
212 int i;
213
214 DBG("eti_b1_wm8731_init() called\n"); 209 DBG("eti_b1_wm8731_init() called\n");
215 210
216 /* Add specific widgets */ 211 /* Add specific widgets */
217 for(i = 0; i < ARRAY_SIZE(eti_b1_dapm_widgets); i++) { 212 snd_soc_dapm_new_controls(codec, eti_b1_dapm_widgets,
218 snd_soc_dapm_new_control(codec, &eti_b1_dapm_widgets[i]); 213 ARRAY_SIZE(eti_b1_dapm_widgets));
219 }
220 214
221 /* Set up specific audio path interconnects */ 215 /* Set up specific audio path interconnects */
222 for(i = 0; intercon[i][0] != NULL; i++) { 216 snd_soc_dapm_add_route(codec, intercon, ARRAY_SIZE(intercon));
223 snd_soc_dapm_connect_input(codec, intercon[i][0],
224 intercon[i][1], intercon[i][2]);
225 }
226 217
227 /* not connected */ 218 /* not connected */
228 snd_soc_dapm_set_endpoint(codec, "RLINEIN", 0); 219 snd_soc_dapm_disable_pin(codec, "RLINEIN");
229 snd_soc_dapm_set_endpoint(codec, "LLINEIN", 0); 220 snd_soc_dapm_disable_pin(codec, "LLINEIN");
230 221
231 /* always connected */ 222 /* always connected */
232 snd_soc_dapm_set_endpoint(codec, "Int Mic", 1); 223 snd_soc_dapm_enable_pin(codec, "Int Mic");
233 snd_soc_dapm_set_endpoint(codec, "Ext Spk", 1); 224 snd_soc_dapm_enable_pin(codec, "Ext Spk");
234 225
235 snd_soc_dapm_sync_endpoints(codec); 226 snd_soc_dapm_sync(codec);
236 227
237 return 0; 228 return 0;
238} 229}
diff --git a/sound/soc/au1x/Kconfig b/sound/soc/au1x/Kconfig
new file mode 100644
index 000000000000..410a893aa66b
--- /dev/null
+++ b/sound/soc/au1x/Kconfig
@@ -0,0 +1,32 @@
1##
2## Au1200/Au1550 PSC + DBDMA
3##
4config SND_SOC_AU1XPSC
5 tristate "SoC Audio for Au1200/Au1250/Au1550"
6 depends on SOC_AU1200 || SOC_AU1550
7 help
8 This option enables support for the Programmable Serial
9 Controllers in AC97 and I2S mode, and the Descriptor-Based DMA
10 Controller (DBDMA) as found on the Au1200/Au1250/Au1550 SoC.
11
12config SND_SOC_AU1XPSC_I2S
13 tristate
14
15config SND_SOC_AU1XPSC_AC97
16 tristate
17 select AC97_BUS
18 select SND_AC97_CODEC
19 select SND_SOC_AC97_BUS
20
21
22##
23## Boards
24##
25config SND_SOC_SAMPLE_PSC_AC97
26 tristate "Sample Au12x0/Au1550 PSC AC97 sound machine"
27 depends on SND_SOC_AU1XPSC
28 select SND_SOC_AU1XPSC_AC97
29 select SND_SOC_AC97_CODEC
30 help
31 This is a sample AC97 sound machine for use in Au12x0/Au1550
32 based systems which have audio on PSC1 (e.g. Db1200 demoboard).
diff --git a/sound/soc/au1x/Makefile b/sound/soc/au1x/Makefile
new file mode 100644
index 000000000000..6c6950b8003a
--- /dev/null
+++ b/sound/soc/au1x/Makefile
@@ -0,0 +1,13 @@
1# Au1200/Au1550 PSC audio
2snd-soc-au1xpsc-dbdma-objs := dbdma2.o
3snd-soc-au1xpsc-i2s-objs := psc-i2s.o
4snd-soc-au1xpsc-ac97-objs := psc-ac97.o
5
6obj-$(CONFIG_SND_SOC_AU1XPSC) += snd-soc-au1xpsc-dbdma.o
7obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o
8obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o
9
10# Boards
11snd-soc-sample-ac97-objs := sample-ac97.o
12
13obj-$(CONFIG_SND_SOC_SAMPLE_PSC_AC97) += snd-soc-sample-ac97.o
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
new file mode 100644
index 000000000000..1466d9328800
--- /dev/null
+++ b/sound/soc/au1x/dbdma2.c
@@ -0,0 +1,421 @@
1/*
2 * Au12x0/Au1550 PSC ALSA ASoC audio support.
3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <mano@roarinelk.homelinux.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * DMA glue for Au1x-PSC audio.
12 *
13 * NOTE: all of these drivers can only work with a SINGLE instance
14 * of a PSC. Multiple independent audio devices are impossible
15 * with ASoC v1.
16 */
17
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23#include <linux/dma-mapping.h>
24
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29
30#include <asm/mach-au1x00/au1000.h>
31#include <asm/mach-au1x00/au1xxx_dbdma.h>
32#include <asm/mach-au1x00/au1xxx_psc.h>
33
34#include "psc.h"
35
36/*#define PCM_DEBUG*/
37
38#define MSG(x...) printk(KERN_INFO "au1xpsc_pcm: " x)
39#ifdef PCM_DEBUG
40#define DBG MSG
41#else
42#define DBG(x...) do {} while (0)
43#endif
44
45struct au1xpsc_audio_dmadata {
46 /* DDMA control data */
47 unsigned int ddma_id; /* DDMA direction ID for this PSC */
48 u32 ddma_chan; /* DDMA context */
49
50 /* PCM context (for irq handlers) */
51 struct snd_pcm_substream *substream;
52 unsigned long curr_period; /* current segment DDMA is working on */
53 unsigned long q_period; /* queue period(s) */
54 unsigned long dma_area; /* address of queued DMA area */
55 unsigned long dma_area_s; /* start address of DMA area */
56 unsigned long pos; /* current byte position being played */
57 unsigned long periods; /* number of SG segments in total */
58 unsigned long period_bytes; /* size in bytes of one SG segment */
59
60 /* runtime data */
61 int msbits;
62};
63
64/* instance data. There can be only one, MacLeod!!!! */
65static struct au1xpsc_audio_dmadata *au1xpsc_audio_pcmdma[2];
66
67/*
68 * These settings are somewhat okay, at least on my machine audio plays
69 * almost skip-free. Especially the 64kB buffer seems to help a LOT.
70 */
71#define AU1XPSC_PERIOD_MIN_BYTES 1024
72#define AU1XPSC_BUFFER_MIN_BYTES 65536
73
74#define AU1XPSC_PCM_FMTS \
75 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
76 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
77 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \
78 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE | \
79 SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE | \
80 0)
81
82/* PCM hardware DMA capabilities - platform specific */
83static const struct snd_pcm_hardware au1xpsc_pcm_hardware = {
84 .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
85 SNDRV_PCM_INFO_INTERLEAVED,
86 .formats = AU1XPSC_PCM_FMTS,
87 .period_bytes_min = AU1XPSC_PERIOD_MIN_BYTES,
88 .period_bytes_max = 4096 * 1024 - 1,
89 .periods_min = 2,
90 .periods_max = 4096, /* 2 to as-much-as-you-like */
91 .buffer_bytes_max = 4096 * 1024 - 1,
92 .fifo_size = 16, /* fifo entries of AC97/I2S PSC */
93};
94
95static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd)
96{
97 au1xxx_dbdma_put_source_flags(cd->ddma_chan,
98 (void *)phys_to_virt(cd->dma_area),
99 cd->period_bytes, DDMA_FLAGS_IE);
100
101 /* update next-to-queue period */
102 ++cd->q_period;
103 cd->dma_area += cd->period_bytes;
104 if (cd->q_period >= cd->periods) {
105 cd->q_period = 0;
106 cd->dma_area = cd->dma_area_s;
107 }
108}
109
110static void au1x_pcm_queue_rx(struct au1xpsc_audio_dmadata *cd)
111{
112 au1xxx_dbdma_put_dest_flags(cd->ddma_chan,
113 (void *)phys_to_virt(cd->dma_area),
114 cd->period_bytes, DDMA_FLAGS_IE);
115
116 /* update next-to-queue period */
117 ++cd->q_period;
118 cd->dma_area += cd->period_bytes;
119 if (cd->q_period >= cd->periods) {
120 cd->q_period = 0;
121 cd->dma_area = cd->dma_area_s;
122 }
123}
124
125static void au1x_pcm_dmatx_cb(int irq, void *dev_id)
126{
127 struct au1xpsc_audio_dmadata *cd = dev_id;
128
129 cd->pos += cd->period_bytes;
130 if (++cd->curr_period >= cd->periods) {
131 cd->pos = 0;
132 cd->curr_period = 0;
133 }
134 snd_pcm_period_elapsed(cd->substream);
135 au1x_pcm_queue_tx(cd);
136}
137
138static void au1x_pcm_dmarx_cb(int irq, void *dev_id)
139{
140 struct au1xpsc_audio_dmadata *cd = dev_id;
141
142 cd->pos += cd->period_bytes;
143 if (++cd->curr_period >= cd->periods) {
144 cd->pos = 0;
145 cd->curr_period = 0;
146 }
147 snd_pcm_period_elapsed(cd->substream);
148 au1x_pcm_queue_rx(cd);
149}
150
151static void au1x_pcm_dbdma_free(struct au1xpsc_audio_dmadata *pcd)
152{
153 if (pcd->ddma_chan) {
154 au1xxx_dbdma_stop(pcd->ddma_chan);
155 au1xxx_dbdma_reset(pcd->ddma_chan);
156 au1xxx_dbdma_chan_free(pcd->ddma_chan);
157 pcd->ddma_chan = 0;
158 pcd->msbits = 0;
159 }
160}
161
162/* in case of missing DMA ring or changed TX-source / RX-dest bit widths,
163 * allocate (or reallocate) a 2-descriptor DMA ring with bit depth according
164 * to ALSA-supplied sample depth. This is due to limitations in the dbdma api
165 * (cannot adjust source/dest widths of already allocated descriptor ring).
166 */
167static int au1x_pcm_dbdma_realloc(struct au1xpsc_audio_dmadata *pcd,
168 int stype, int msbits)
169{
170 /* DMA only in 8/16/32 bit widths */
171 if (msbits == 24)
172 msbits = 32;
173
174 /* check current config: correct bits and descriptors allocated? */
175 if ((pcd->ddma_chan) && (msbits == pcd->msbits))
176 goto out; /* all ok! */
177
178 au1x_pcm_dbdma_free(pcd);
179
180 if (stype == PCM_RX)
181 pcd->ddma_chan = au1xxx_dbdma_chan_alloc(pcd->ddma_id,
182 DSCR_CMD0_ALWAYS,
183 au1x_pcm_dmarx_cb, (void *)pcd);
184 else
185 pcd->ddma_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS,
186 pcd->ddma_id,
187 au1x_pcm_dmatx_cb, (void *)pcd);
188
189 if (!pcd->ddma_chan)
190 return -ENOMEM;;
191
192 au1xxx_dbdma_set_devwidth(pcd->ddma_chan, msbits);
193 au1xxx_dbdma_ring_alloc(pcd->ddma_chan, 2);
194
195 pcd->msbits = msbits;
196
197 au1xxx_dbdma_stop(pcd->ddma_chan);
198 au1xxx_dbdma_reset(pcd->ddma_chan);
199
200out:
201 return 0;
202}
203
204static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
205 struct snd_pcm_hw_params *params)
206{
207 struct snd_pcm_runtime *runtime = substream->runtime;
208 struct au1xpsc_audio_dmadata *pcd;
209 int stype, ret;
210
211 ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
212 if (ret < 0)
213 goto out;
214
215 stype = SUBSTREAM_TYPE(substream);
216 pcd = au1xpsc_audio_pcmdma[stype];
217
218 DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d "
219 "runtime->min_align %d\n",
220 (unsigned long)runtime->dma_area,
221 (unsigned long)runtime->dma_addr, runtime->dma_bytes,
222 runtime->min_align);
223
224 DBG("bits %d frags %d frag_bytes %d is_rx %d\n", params->msbits,
225 params_periods(params), params_period_bytes(params), stype);
226
227 ret = au1x_pcm_dbdma_realloc(pcd, stype, params->msbits);
228 if (ret) {
229 MSG("DDMA channel (re)alloc failed!\n");
230 goto out;
231 }
232
233 pcd->substream = substream;
234 pcd->period_bytes = params_period_bytes(params);
235 pcd->periods = params_periods(params);
236 pcd->dma_area_s = pcd->dma_area = (unsigned long)runtime->dma_addr;
237 pcd->q_period = 0;
238 pcd->curr_period = 0;
239 pcd->pos = 0;
240
241 ret = 0;
242out:
243 return ret;
244}
245
246static int au1xpsc_pcm_hw_free(struct snd_pcm_substream *substream)
247{
248 snd_pcm_lib_free_pages(substream);
249 return 0;
250}
251
252static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream)
253{
254 struct au1xpsc_audio_dmadata *pcd =
255 au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)];
256
257 au1xxx_dbdma_reset(pcd->ddma_chan);
258
259 if (SUBSTREAM_TYPE(substream) == PCM_RX) {
260 au1x_pcm_queue_rx(pcd);
261 au1x_pcm_queue_rx(pcd);
262 } else {
263 au1x_pcm_queue_tx(pcd);
264 au1x_pcm_queue_tx(pcd);
265 }
266
267 return 0;
268}
269
270static int au1xpsc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
271{
272 u32 c = au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]->ddma_chan;
273
274 switch (cmd) {
275 case SNDRV_PCM_TRIGGER_START:
276 case SNDRV_PCM_TRIGGER_RESUME:
277 au1xxx_dbdma_start(c);
278 break;
279 case SNDRV_PCM_TRIGGER_STOP:
280 case SNDRV_PCM_TRIGGER_SUSPEND:
281 au1xxx_dbdma_stop(c);
282 break;
283 default:
284 return -EINVAL;
285 }
286 return 0;
287}
288
289static snd_pcm_uframes_t
290au1xpsc_pcm_pointer(struct snd_pcm_substream *substream)
291{
292 return bytes_to_frames(substream->runtime,
293 au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]->pos);
294}
295
296static int au1xpsc_pcm_open(struct snd_pcm_substream *substream)
297{
298 snd_soc_set_runtime_hwparams(substream, &au1xpsc_pcm_hardware);
299 return 0;
300}
301
302static int au1xpsc_pcm_close(struct snd_pcm_substream *substream)
303{
304 au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]);
305 return 0;
306}
307
308struct snd_pcm_ops au1xpsc_pcm_ops = {
309 .open = au1xpsc_pcm_open,
310 .close = au1xpsc_pcm_close,
311 .ioctl = snd_pcm_lib_ioctl,
312 .hw_params = au1xpsc_pcm_hw_params,
313 .hw_free = au1xpsc_pcm_hw_free,
314 .prepare = au1xpsc_pcm_prepare,
315 .trigger = au1xpsc_pcm_trigger,
316 .pointer = au1xpsc_pcm_pointer,
317};
318
319static void au1xpsc_pcm_free_dma_buffers(struct snd_pcm *pcm)
320{
321 snd_pcm_lib_preallocate_free_for_all(pcm);
322}
323
324static int au1xpsc_pcm_new(struct snd_card *card,
325 struct snd_soc_dai *dai,
326 struct snd_pcm *pcm)
327{
328 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
329 card->dev, AU1XPSC_BUFFER_MIN_BYTES, (4096 * 1024) - 1);
330
331 return 0;
332}
333
334static int au1xpsc_pcm_probe(struct platform_device *pdev)
335{
336 struct resource *r;
337 int ret;
338
339 if (au1xpsc_audio_pcmdma[PCM_TX] || au1xpsc_audio_pcmdma[PCM_RX])
340 return -EBUSY;
341
342 /* TX DMA */
343 au1xpsc_audio_pcmdma[PCM_TX]
344 = kzalloc(sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
345 if (!au1xpsc_audio_pcmdma[PCM_TX])
346 return -ENOMEM;
347
348 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
349 if (!r) {
350 ret = -ENODEV;
351 goto out1;
352 }
353 (au1xpsc_audio_pcmdma[PCM_TX])->ddma_id = r->start;
354
355 /* RX DMA */
356 au1xpsc_audio_pcmdma[PCM_RX]
357 = kzalloc(sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
358 if (!au1xpsc_audio_pcmdma[PCM_RX])
359 return -ENOMEM;
360
361 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
362 if (!r) {
363 ret = -ENODEV;
364 goto out2;
365 }
366 (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start;
367
368 return 0;
369
370out2:
371 kfree(au1xpsc_audio_pcmdma[PCM_RX]);
372 au1xpsc_audio_pcmdma[PCM_RX] = NULL;
373out1:
374 kfree(au1xpsc_audio_pcmdma[PCM_TX]);
375 au1xpsc_audio_pcmdma[PCM_TX] = NULL;
376 return ret;
377}
378
379static int au1xpsc_pcm_remove(struct platform_device *pdev)
380{
381 int i;
382
383 for (i = 0; i < 2; i++) {
384 if (au1xpsc_audio_pcmdma[i]) {
385 au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]);
386 kfree(au1xpsc_audio_pcmdma[i]);
387 au1xpsc_audio_pcmdma[i] = NULL;
388 }
389 }
390
391 return 0;
392}
393
394/* au1xpsc audio platform */
395struct snd_soc_platform au1xpsc_soc_platform = {
396 .name = "au1xpsc-pcm-dbdma",
397 .probe = au1xpsc_pcm_probe,
398 .remove = au1xpsc_pcm_remove,
399 .pcm_ops = &au1xpsc_pcm_ops,
400 .pcm_new = au1xpsc_pcm_new,
401 .pcm_free = au1xpsc_pcm_free_dma_buffers,
402};
403EXPORT_SYMBOL_GPL(au1xpsc_soc_platform);
404
405static int __init au1xpsc_audio_dbdma_init(void)
406{
407 au1xpsc_audio_pcmdma[PCM_TX] = NULL;
408 au1xpsc_audio_pcmdma[PCM_RX] = NULL;
409 return 0;
410}
411
412static void __exit au1xpsc_audio_dbdma_exit(void)
413{
414}
415
416module_init(au1xpsc_audio_dbdma_init);
417module_exit(au1xpsc_audio_dbdma_exit);
418
419MODULE_LICENSE("GPL");
420MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver");
421MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
new file mode 100644
index 000000000000..57facbad6825
--- /dev/null
+++ b/sound/soc/au1x/psc-ac97.c
@@ -0,0 +1,387 @@
1/*
2 * Au12x0/Au1550 PSC ALSA ASoC audio support.
3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <mano@roarinelk.homelinux.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Au1xxx-PSC AC97 glue.
12 *
13 * NOTE: all of these drivers can only work with a SINGLE instance
14 * of a PSC. Multiple independent audio devices are impossible
15 * with ASoC v1.
16 */
17
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/device.h>
21#include <linux/delay.h>
22#include <linux/suspend.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/initval.h>
26#include <sound/soc.h>
27#include <asm/mach-au1x00/au1000.h>
28#include <asm/mach-au1x00/au1xxx_psc.h>
29
30#include "psc.h"
31
32#define AC97_DIR \
33 (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE)
34
35#define AC97_RATES \
36 SNDRV_PCM_RATE_8000_48000
37
38#define AC97_FMTS \
39 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3BE)
40
41#define AC97PCR_START(stype) \
42 ((stype) == PCM_TX ? PSC_AC97PCR_TS : PSC_AC97PCR_RS)
43#define AC97PCR_STOP(stype) \
44 ((stype) == PCM_TX ? PSC_AC97PCR_TP : PSC_AC97PCR_RP)
45#define AC97PCR_CLRFIFO(stype) \
46 ((stype) == PCM_TX ? PSC_AC97PCR_TC : PSC_AC97PCR_RC)
47
48/* instance data. There can be only one, MacLeod!!!! */
49static struct au1xpsc_audio_data *au1xpsc_ac97_workdata;
50
51/* AC97 controller reads codec register */
52static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97,
53 unsigned short reg)
54{
55 /* FIXME */
56 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
57 unsigned short data, tmo;
58
59 au_writel(PSC_AC97CDC_RD | PSC_AC97CDC_INDX(reg), AC97_CDC(pscdata));
60 au_sync();
61
62 tmo = 1000;
63 while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) && --tmo)
64 udelay(2);
65
66 if (!tmo)
67 data = 0xffff;
68 else
69 data = au_readl(AC97_CDC(pscdata)) & 0xffff;
70
71 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
72 au_sync();
73
74 return data;
75}
76
77/* AC97 controller writes to codec register */
78static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
79 unsigned short val)
80{
81 /* FIXME */
82 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
83 unsigned int tmo;
84
85 au_writel(PSC_AC97CDC_INDX(reg) | (val & 0xffff), AC97_CDC(pscdata));
86 au_sync();
87 tmo = 1000;
88 while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) && --tmo)
89 au_sync();
90
91 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
92 au_sync();
93}
94
95/* AC97 controller asserts a warm reset */
96static void au1xpsc_ac97_warm_reset(struct snd_ac97 *ac97)
97{
98 /* FIXME */
99 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
100
101 au_writel(PSC_AC97RST_SNC, AC97_RST(pscdata));
102 au_sync();
103 msleep(10);
104 au_writel(0, AC97_RST(pscdata));
105 au_sync();
106}
107
108static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97)
109{
110 /* FIXME */
111 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
112 int i;
113
114 /* disable PSC during cold reset */
115 au_writel(0, AC97_CFG(au1xpsc_ac97_workdata));
116 au_sync();
117 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(pscdata));
118 au_sync();
119
120 /* issue cold reset */
121 au_writel(PSC_AC97RST_RST, AC97_RST(pscdata));
122 au_sync();
123 msleep(500);
124 au_writel(0, AC97_RST(pscdata));
125 au_sync();
126
127 /* enable PSC */
128 au_writel(PSC_CTRL_ENABLE, PSC_CTRL(pscdata));
129 au_sync();
130
131 /* wait for PSC to indicate it's ready */
132 i = 100000;
133 while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_SR)) && (--i))
134 au_sync();
135
136 if (i == 0) {
137 printk(KERN_ERR "au1xpsc-ac97: PSC not ready!\n");
138 return;
139 }
140
141 /* enable the ac97 function */
142 au_writel(pscdata->cfg | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata));
143 au_sync();
144
145 /* wait for AC97 core to become ready */
146 i = 100000;
147 while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && (--i))
148 au_sync();
149 if (i == 0)
150 printk(KERN_ERR "au1xpsc-ac97: AC97 ctrl not ready\n");
151}
152
153/* AC97 controller operations */
154struct snd_ac97_bus_ops soc_ac97_ops = {
155 .read = au1xpsc_ac97_read,
156 .write = au1xpsc_ac97_write,
157 .reset = au1xpsc_ac97_cold_reset,
158 .warm_reset = au1xpsc_ac97_warm_reset,
159};
160EXPORT_SYMBOL_GPL(soc_ac97_ops);
161
162static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
163 struct snd_pcm_hw_params *params)
164{
165 /* FIXME */
166 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
167 unsigned long r, stat;
168 int chans, stype = SUBSTREAM_TYPE(substream);
169
170 chans = params_channels(params);
171
172 r = au_readl(AC97_CFG(pscdata));
173 stat = au_readl(AC97_STAT(pscdata));
174
175 /* already active? */
176 if (stat & (PSC_AC97STAT_TB | PSC_AC97STAT_RB)) {
177 /* reject parameters not currently set up */
178 if ((PSC_AC97CFG_GET_LEN(r) != params->msbits) ||
179 (pscdata->rate != params_rate(params)))
180 return -EINVAL;
181 } else {
182 /* disable AC97 device controller first */
183 au_writel(r & ~PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata));
184 au_sync();
185
186 /* set sample bitdepth: REG[24:21]=(BITS-2)/2 */
187 r &= ~PSC_AC97CFG_LEN_MASK;
188 r |= PSC_AC97CFG_SET_LEN(params->msbits);
189
190 /* channels: enable slots for front L/R channel */
191 if (stype == PCM_TX) {
192 r &= ~PSC_AC97CFG_TXSLOT_MASK;
193 r |= PSC_AC97CFG_TXSLOT_ENA(3);
194 r |= PSC_AC97CFG_TXSLOT_ENA(4);
195 } else {
196 r &= ~PSC_AC97CFG_RXSLOT_MASK;
197 r |= PSC_AC97CFG_RXSLOT_ENA(3);
198 r |= PSC_AC97CFG_RXSLOT_ENA(4);
199 }
200
201 /* finally enable the AC97 controller again */
202 au_writel(r | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata));
203 au_sync();
204
205 pscdata->cfg = r;
206 pscdata->rate = params_rate(params);
207 }
208
209 return 0;
210}
211
212static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
213 int cmd)
214{
215 /* FIXME */
216 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
217 int ret, stype = SUBSTREAM_TYPE(substream);
218
219 ret = 0;
220
221 switch (cmd) {
222 case SNDRV_PCM_TRIGGER_START:
223 case SNDRV_PCM_TRIGGER_RESUME:
224 au_writel(AC97PCR_START(stype), AC97_PCR(pscdata));
225 au_sync();
226 break;
227 case SNDRV_PCM_TRIGGER_STOP:
228 case SNDRV_PCM_TRIGGER_SUSPEND:
229 au_writel(AC97PCR_STOP(stype), AC97_PCR(pscdata));
230 au_sync();
231 break;
232 default:
233 ret = -EINVAL;
234 }
235 return ret;
236}
237
238static int au1xpsc_ac97_probe(struct platform_device *pdev,
239 struct snd_soc_dai *dai)
240{
241 int ret;
242 struct resource *r;
243 unsigned long sel;
244
245 if (au1xpsc_ac97_workdata)
246 return -EBUSY;
247
248 au1xpsc_ac97_workdata =
249 kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
250 if (!au1xpsc_ac97_workdata)
251 return -ENOMEM;
252
253 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
254 if (!r) {
255 ret = -ENODEV;
256 goto out0;
257 }
258
259 ret = -EBUSY;
260 au1xpsc_ac97_workdata->ioarea =
261 request_mem_region(r->start, r->end - r->start + 1,
262 "au1xpsc_ac97");
263 if (!au1xpsc_ac97_workdata->ioarea)
264 goto out0;
265
266 au1xpsc_ac97_workdata->mmio = ioremap(r->start, 0xffff);
267 if (!au1xpsc_ac97_workdata->mmio)
268 goto out1;
269
270 /* configuration: max dma trigger threshold, enable ac97 */
271 au1xpsc_ac97_workdata->cfg = PSC_AC97CFG_RT_FIFO8 |
272 PSC_AC97CFG_TT_FIFO8 |
273 PSC_AC97CFG_DE_ENABLE;
274
275 /* preserve PSC clock source set up by platform (dev.platform_data
276 * is already occupied by soc layer)
277 */
278 sel = au_readl(PSC_SEL(au1xpsc_ac97_workdata)) & PSC_SEL_CLK_MASK;
279 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_ac97_workdata));
280 au_sync();
281 au_writel(0, PSC_SEL(au1xpsc_ac97_workdata));
282 au_sync();
283 au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(au1xpsc_ac97_workdata));
284 au_sync();
285 /* next up: cold reset. Dont check for PSC-ready now since
286 * there may not be any codec clock yet.
287 */
288
289 return 0;
290
291out1:
292 release_resource(au1xpsc_ac97_workdata->ioarea);
293 kfree(au1xpsc_ac97_workdata->ioarea);
294out0:
295 kfree(au1xpsc_ac97_workdata);
296 au1xpsc_ac97_workdata = NULL;
297 return ret;
298}
299
300static void au1xpsc_ac97_remove(struct platform_device *pdev,
301 struct snd_soc_dai *dai)
302{
303 /* disable PSC completely */
304 au_writel(0, AC97_CFG(au1xpsc_ac97_workdata));
305 au_sync();
306 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_ac97_workdata));
307 au_sync();
308
309 iounmap(au1xpsc_ac97_workdata->mmio);
310 release_resource(au1xpsc_ac97_workdata->ioarea);
311 kfree(au1xpsc_ac97_workdata->ioarea);
312 kfree(au1xpsc_ac97_workdata);
313 au1xpsc_ac97_workdata = NULL;
314}
315
316static int au1xpsc_ac97_suspend(struct platform_device *pdev,
317 struct snd_soc_dai *dai)
318{
319 /* save interesting registers and disable PSC */
320 au1xpsc_ac97_workdata->pm[0] =
321 au_readl(PSC_SEL(au1xpsc_ac97_workdata));
322
323 au_writel(0, AC97_CFG(au1xpsc_ac97_workdata));
324 au_sync();
325 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_ac97_workdata));
326 au_sync();
327
328 return 0;
329}
330
331static int au1xpsc_ac97_resume(struct platform_device *pdev,
332 struct snd_soc_dai *dai)
333{
334 /* restore PSC clock config */
335 au_writel(au1xpsc_ac97_workdata->pm[0] | PSC_SEL_PS_AC97MODE,
336 PSC_SEL(au1xpsc_ac97_workdata));
337 au_sync();
338
339 /* after this point the ac97 core will cold-reset the codec.
340 * During cold-reset the PSC is reinitialized and the last
341 * configuration set up in hw_params() is restored.
342 */
343 return 0;
344}
345
346struct snd_soc_dai au1xpsc_ac97_dai = {
347 .name = "au1xpsc_ac97",
348 .type = SND_SOC_DAI_AC97,
349 .probe = au1xpsc_ac97_probe,
350 .remove = au1xpsc_ac97_remove,
351 .suspend = au1xpsc_ac97_suspend,
352 .resume = au1xpsc_ac97_resume,
353 .playback = {
354 .rates = AC97_RATES,
355 .formats = AC97_FMTS,
356 .channels_min = 2,
357 .channels_max = 2,
358 },
359 .capture = {
360 .rates = AC97_RATES,
361 .formats = AC97_FMTS,
362 .channels_min = 2,
363 .channels_max = 2,
364 },
365 .ops = {
366 .trigger = au1xpsc_ac97_trigger,
367 .hw_params = au1xpsc_ac97_hw_params,
368 },
369};
370EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai);
371
372static int __init au1xpsc_ac97_init(void)
373{
374 au1xpsc_ac97_workdata = NULL;
375 return 0;
376}
377
378static void __exit au1xpsc_ac97_exit(void)
379{
380}
381
382module_init(au1xpsc_ac97_init);
383module_exit(au1xpsc_ac97_exit);
384
385MODULE_LICENSE("GPL");
386MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver");
387MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
new file mode 100644
index 000000000000..ba4b5c199f21
--- /dev/null
+++ b/sound/soc/au1x/psc-i2s.c
@@ -0,0 +1,414 @@
1/*
2 * Au12x0/Au1550 PSC ALSA ASoC audio support.
3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <mano@roarinelk.homelinux.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Au1xxx-PSC I2S glue.
12 *
13 * NOTE: all of these drivers can only work with a SINGLE instance
14 * of a PSC. Multiple independent audio devices are impossible
15 * with ASoC v1.
16 * NOTE: so far only PSC slave mode (bit- and frameclock) is supported.
17 */
18
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/suspend.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/initval.h>
25#include <sound/soc.h>
26#include <asm/mach-au1x00/au1000.h>
27#include <asm/mach-au1x00/au1xxx_psc.h>
28
29#include "psc.h"
30
31/* supported I2S DAI hardware formats */
32#define AU1XPSC_I2S_DAIFMT \
33 (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J | \
34 SND_SOC_DAIFMT_NB_NF)
35
36/* supported I2S direction */
37#define AU1XPSC_I2S_DIR \
38 (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE)
39
40#define AU1XPSC_I2S_RATES \
41 SNDRV_PCM_RATE_8000_192000
42
43#define AU1XPSC_I2S_FMTS \
44 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
45
46#define I2SSTAT_BUSY(stype) \
47 ((stype) == PCM_TX ? PSC_I2SSTAT_TB : PSC_I2SSTAT_RB)
48#define I2SPCR_START(stype) \
49 ((stype) == PCM_TX ? PSC_I2SPCR_TS : PSC_I2SPCR_RS)
50#define I2SPCR_STOP(stype) \
51 ((stype) == PCM_TX ? PSC_I2SPCR_TP : PSC_I2SPCR_RP)
52#define I2SPCR_CLRFIFO(stype) \
53 ((stype) == PCM_TX ? PSC_I2SPCR_TC : PSC_I2SPCR_RC)
54
55
56/* instance data. There can be only one, MacLeod!!!! */
57static struct au1xpsc_audio_data *au1xpsc_i2s_workdata;
58
59static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
60 unsigned int fmt)
61{
62 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata;
63 unsigned long ct;
64 int ret;
65
66 ret = -EINVAL;
67
68 ct = pscdata->cfg;
69
70 ct &= ~(PSC_I2SCFG_XM | PSC_I2SCFG_MLJ); /* left-justified */
71 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
72 case SND_SOC_DAIFMT_I2S:
73 ct |= PSC_I2SCFG_XM; /* enable I2S mode */
74 break;
75 case SND_SOC_DAIFMT_MSB:
76 break;
77 case SND_SOC_DAIFMT_LSB:
78 ct |= PSC_I2SCFG_MLJ; /* LSB (right-) justified */
79 break;
80 default:
81 goto out;
82 }
83
84 ct &= ~(PSC_I2SCFG_BI | PSC_I2SCFG_WI); /* IB-IF */
85 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
86 case SND_SOC_DAIFMT_NB_NF:
87 ct |= PSC_I2SCFG_BI | PSC_I2SCFG_WI;
88 break;
89 case SND_SOC_DAIFMT_NB_IF:
90 ct |= PSC_I2SCFG_BI;
91 break;
92 case SND_SOC_DAIFMT_IB_NF:
93 ct |= PSC_I2SCFG_WI;
94 break;
95 case SND_SOC_DAIFMT_IB_IF:
96 break;
97 default:
98 goto out;
99 }
100
101 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
102 case SND_SOC_DAIFMT_CBM_CFM: /* CODEC master */
103 ct |= PSC_I2SCFG_MS; /* PSC I2S slave mode */
104 break;
105 case SND_SOC_DAIFMT_CBS_CFS: /* CODEC slave */
106 ct &= ~PSC_I2SCFG_MS; /* PSC I2S Master mode */
107 break;
108 default:
109 goto out;
110 }
111
112 pscdata->cfg = ct;
113 ret = 0;
114out:
115 return ret;
116}
117
118static int au1xpsc_i2s_hw_params(struct snd_pcm_substream *substream,
119 struct snd_pcm_hw_params *params)
120{
121 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata;
122
123 int cfgbits;
124 unsigned long stat;
125
126 /* check if the PSC is already streaming data */
127 stat = au_readl(I2S_STAT(pscdata));
128 if (stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB)) {
129 /* reject parameters not currently set up in hardware */
130 cfgbits = au_readl(I2S_CFG(pscdata));
131 if ((PSC_I2SCFG_GET_LEN(cfgbits) != params->msbits) ||
132 (params_rate(params) != pscdata->rate))
133 return -EINVAL;
134 } else {
135 /* set sample bitdepth */
136 pscdata->cfg &= ~(0x1f << 4);
137 pscdata->cfg |= PSC_I2SCFG_SET_LEN(params->msbits);
138 /* remember current rate for other stream */
139 pscdata->rate = params_rate(params);
140 }
141 return 0;
142}
143
144/* Configure PSC late: on my devel systems the codec is I2S master and
145 * supplies the i2sbitclock __AND__ i2sMclk (!) to the PSC unit. ASoC
146 * uses aggressive PM and switches the codec off when it is not in use
147 * which also means the PSC unit doesn't get any clocks and is therefore
148 * dead. That's why this chunk here gets called from the trigger callback
149 * because I can be reasonably certain the codec is driving the clocks.
150 */
151static int au1xpsc_i2s_configure(struct au1xpsc_audio_data *pscdata)
152{
153 unsigned long tmo;
154
155 /* bring PSC out of sleep, and configure I2S unit */
156 au_writel(PSC_CTRL_ENABLE, PSC_CTRL(pscdata));
157 au_sync();
158
159 tmo = 1000000;
160 while (!(au_readl(I2S_STAT(pscdata)) & PSC_I2SSTAT_SR) && tmo)
161 tmo--;
162
163 if (!tmo)
164 goto psc_err;
165
166 au_writel(0, I2S_CFG(pscdata));
167 au_sync();
168 au_writel(pscdata->cfg | PSC_I2SCFG_DE_ENABLE, I2S_CFG(pscdata));
169 au_sync();
170
171 /* wait for I2S controller to become ready */
172 tmo = 1000000;
173 while (!(au_readl(I2S_STAT(pscdata)) & PSC_I2SSTAT_DR) && tmo)
174 tmo--;
175
176 if (tmo)
177 return 0;
178
179psc_err:
180 au_writel(0, I2S_CFG(pscdata));
181 au_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata));
182 au_sync();
183 return -ETIMEDOUT;
184}
185
186static int au1xpsc_i2s_start(struct au1xpsc_audio_data *pscdata, int stype)
187{
188 unsigned long tmo, stat;
189 int ret;
190
191 ret = 0;
192
193 /* if both TX and RX are idle, configure the PSC */
194 stat = au_readl(I2S_STAT(pscdata));
195 if (!(stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB))) {
196 ret = au1xpsc_i2s_configure(pscdata);
197 if (ret)
198 goto out;
199 }
200
201 au_writel(I2SPCR_CLRFIFO(stype), I2S_PCR(pscdata));
202 au_sync();
203 au_writel(I2SPCR_START(stype), I2S_PCR(pscdata));
204 au_sync();
205
206 /* wait for start confirmation */
207 tmo = 1000000;
208 while (!(au_readl(I2S_STAT(pscdata)) & I2SSTAT_BUSY(stype)) && tmo)
209 tmo--;
210
211 if (!tmo) {
212 au_writel(I2SPCR_STOP(stype), I2S_PCR(pscdata));
213 au_sync();
214 ret = -ETIMEDOUT;
215 }
216out:
217 return ret;
218}
219
220static int au1xpsc_i2s_stop(struct au1xpsc_audio_data *pscdata, int stype)
221{
222 unsigned long tmo, stat;
223
224 au_writel(I2SPCR_STOP(stype), I2S_PCR(pscdata));
225 au_sync();
226
227 /* wait for stop confirmation */
228 tmo = 1000000;
229 while ((au_readl(I2S_STAT(pscdata)) & I2SSTAT_BUSY(stype)) && tmo)
230 tmo--;
231
232 /* if both TX and RX are idle, disable PSC */
233 stat = au_readl(I2S_STAT(pscdata));
234 if (!(stat & (PSC_I2SSTAT_RB | PSC_I2SSTAT_RB))) {
235 au_writel(0, I2S_CFG(pscdata));
236 au_sync();
237 au_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata));
238 au_sync();
239 }
240 return 0;
241}
242
243static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
244{
245 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata;
246 int ret, stype = SUBSTREAM_TYPE(substream);
247
248 switch (cmd) {
249 case SNDRV_PCM_TRIGGER_START:
250 case SNDRV_PCM_TRIGGER_RESUME:
251 ret = au1xpsc_i2s_start(pscdata, stype);
252 break;
253 case SNDRV_PCM_TRIGGER_STOP:
254 case SNDRV_PCM_TRIGGER_SUSPEND:
255 ret = au1xpsc_i2s_stop(pscdata, stype);
256 break;
257 default:
258 ret = -EINVAL;
259 }
260 return ret;
261}
262
263static int au1xpsc_i2s_probe(struct platform_device *pdev,
264 struct snd_soc_dai *dai)
265{
266 struct resource *r;
267 unsigned long sel;
268 int ret;
269
270 if (au1xpsc_i2s_workdata)
271 return -EBUSY;
272
273 au1xpsc_i2s_workdata =
274 kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
275 if (!au1xpsc_i2s_workdata)
276 return -ENOMEM;
277
278 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
279 if (!r) {
280 ret = -ENODEV;
281 goto out0;
282 }
283
284 ret = -EBUSY;
285 au1xpsc_i2s_workdata->ioarea =
286 request_mem_region(r->start, r->end - r->start + 1,
287 "au1xpsc_i2s");
288 if (!au1xpsc_i2s_workdata->ioarea)
289 goto out0;
290
291 au1xpsc_i2s_workdata->mmio = ioremap(r->start, 0xffff);
292 if (!au1xpsc_i2s_workdata->mmio)
293 goto out1;
294
295 /* preserve PSC clock source set up by platform (dev.platform_data
296 * is already occupied by soc layer)
297 */
298 sel = au_readl(PSC_SEL(au1xpsc_i2s_workdata)) & PSC_SEL_CLK_MASK;
299 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata));
300 au_sync();
301 au_writel(PSC_SEL_PS_I2SMODE | sel, PSC_SEL(au1xpsc_i2s_workdata));
302 au_writel(0, I2S_CFG(au1xpsc_i2s_workdata));
303 au_sync();
304
305 /* preconfigure: set max rx/tx fifo depths */
306 au1xpsc_i2s_workdata->cfg |=
307 PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8;
308
309 /* don't wait for I2S core to become ready now; clocks may not
310 * be running yet; depending on clock input for PSC a wait might
311 * time out.
312 */
313
314 return 0;
315
316out1:
317 release_resource(au1xpsc_i2s_workdata->ioarea);
318 kfree(au1xpsc_i2s_workdata->ioarea);
319out0:
320 kfree(au1xpsc_i2s_workdata);
321 au1xpsc_i2s_workdata = NULL;
322 return ret;
323}
324
325static void au1xpsc_i2s_remove(struct platform_device *pdev,
326 struct snd_soc_dai *dai)
327{
328 au_writel(0, I2S_CFG(au1xpsc_i2s_workdata));
329 au_sync();
330 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata));
331 au_sync();
332
333 iounmap(au1xpsc_i2s_workdata->mmio);
334 release_resource(au1xpsc_i2s_workdata->ioarea);
335 kfree(au1xpsc_i2s_workdata->ioarea);
336 kfree(au1xpsc_i2s_workdata);
337 au1xpsc_i2s_workdata = NULL;
338}
339
340static int au1xpsc_i2s_suspend(struct platform_device *pdev,
341 struct snd_soc_dai *cpu_dai)
342{
343 /* save interesting register and disable PSC */
344 au1xpsc_i2s_workdata->pm[0] =
345 au_readl(PSC_SEL(au1xpsc_i2s_workdata));
346
347 au_writel(0, I2S_CFG(au1xpsc_i2s_workdata));
348 au_sync();
349 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata));
350 au_sync();
351
352 return 0;
353}
354
355static int au1xpsc_i2s_resume(struct platform_device *pdev,
356 struct snd_soc_dai *cpu_dai)
357{
358 /* select I2S mode and PSC clock */
359 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata));
360 au_sync();
361 au_writel(0, PSC_SEL(au1xpsc_i2s_workdata));
362 au_sync();
363 au_writel(au1xpsc_i2s_workdata->pm[0],
364 PSC_SEL(au1xpsc_i2s_workdata));
365 au_sync();
366
367 return 0;
368}
369
370struct snd_soc_dai au1xpsc_i2s_dai = {
371 .name = "au1xpsc_i2s",
372 .type = SND_SOC_DAI_I2S,
373 .probe = au1xpsc_i2s_probe,
374 .remove = au1xpsc_i2s_remove,
375 .suspend = au1xpsc_i2s_suspend,
376 .resume = au1xpsc_i2s_resume,
377 .playback = {
378 .rates = AU1XPSC_I2S_RATES,
379 .formats = AU1XPSC_I2S_FMTS,
380 .channels_min = 2,
381 .channels_max = 8, /* 2 without external help */
382 },
383 .capture = {
384 .rates = AU1XPSC_I2S_RATES,
385 .formats = AU1XPSC_I2S_FMTS,
386 .channels_min = 2,
387 .channels_max = 8, /* 2 without external help */
388 },
389 .ops = {
390 .trigger = au1xpsc_i2s_trigger,
391 .hw_params = au1xpsc_i2s_hw_params,
392 },
393 .dai_ops = {
394 .set_fmt = au1xpsc_i2s_set_fmt,
395 },
396};
397EXPORT_SYMBOL(au1xpsc_i2s_dai);
398
399static int __init au1xpsc_i2s_init(void)
400{
401 au1xpsc_i2s_workdata = NULL;
402 return 0;
403}
404
405static void __exit au1xpsc_i2s_exit(void)
406{
407}
408
409module_init(au1xpsc_i2s_init);
410module_exit(au1xpsc_i2s_exit);
411
412MODULE_LICENSE("GPL");
413MODULE_DESCRIPTION("Au12x0/Au1550 PSC I2S ALSA ASoC audio driver");
414MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h
new file mode 100644
index 000000000000..8fdb1a04a07b
--- /dev/null
+++ b/sound/soc/au1x/psc.h
@@ -0,0 +1,53 @@
1/*
2 * Au12x0/Au1550 PSC ALSA ASoC audio support.
3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <mano@roarinelk.homelinux.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * NOTE: all of these drivers can only work with a SINGLE instance
12 * of a PSC. Multiple independent audio devices are impossible
13 * with ASoC v1.
14 */
15
16#ifndef _AU1X_PCM_H
17#define _AU1X_PCM_H
18
19extern struct snd_soc_dai au1xpsc_ac97_dai;
20extern struct snd_soc_dai au1xpsc_i2s_dai;
21extern struct snd_soc_platform au1xpsc_soc_platform;
22extern struct snd_ac97_bus_ops soc_ac97_ops;
23
24struct au1xpsc_audio_data {
25 void __iomem *mmio;
26
27 unsigned long cfg;
28 unsigned long rate;
29
30 unsigned long pm[2];
31 struct resource *ioarea;
32};
33
34#define PCM_TX 0
35#define PCM_RX 1
36
37#define SUBSTREAM_TYPE(substream) \
38 ((substream)->stream == SNDRV_PCM_STREAM_PLAYBACK ? PCM_TX : PCM_RX)
39
40/* easy access macros */
41#define PSC_CTRL(x) ((unsigned long)((x)->mmio) + PSC_CTRL_OFFSET)
42#define PSC_SEL(x) ((unsigned long)((x)->mmio) + PSC_SEL_OFFSET)
43#define I2S_STAT(x) ((unsigned long)((x)->mmio) + PSC_I2SSTAT_OFFSET)
44#define I2S_CFG(x) ((unsigned long)((x)->mmio) + PSC_I2SCFG_OFFSET)
45#define I2S_PCR(x) ((unsigned long)((x)->mmio) + PSC_I2SPCR_OFFSET)
46#define AC97_CFG(x) ((unsigned long)((x)->mmio) + PSC_AC97CFG_OFFSET)
47#define AC97_CDC(x) ((unsigned long)((x)->mmio) + PSC_AC97CDC_OFFSET)
48#define AC97_EVNT(x) ((unsigned long)((x)->mmio) + PSC_AC97EVNT_OFFSET)
49#define AC97_PCR(x) ((unsigned long)((x)->mmio) + PSC_AC97PCR_OFFSET)
50#define AC97_RST(x) ((unsigned long)((x)->mmio) + PSC_AC97RST_OFFSET)
51#define AC97_STAT(x) ((unsigned long)((x)->mmio) + PSC_AC97STAT_OFFSET)
52
53#endif
diff --git a/sound/soc/au1x/sample-ac97.c b/sound/soc/au1x/sample-ac97.c
new file mode 100644
index 000000000000..f75ae7f62c3d
--- /dev/null
+++ b/sound/soc/au1x/sample-ac97.c
@@ -0,0 +1,144 @@
1/*
2 * Sample Au12x0/Au1550 PSC AC97 sound machine.
3 *
4 * Copyright (c) 2007-2008 Manuel Lauss <mano@roarinelk.homelinux.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms outlined in the file COPYING at the root of this
8 * source archive.
9 *
10 * This is a very generic AC97 sound machine driver for boards which
11 * have (AC97) audio at PSC1 (e.g. DB1200 demoboards).
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/timer.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23#include <asm/mach-au1x00/au1000.h>
24#include <asm/mach-au1x00/au1xxx_psc.h>
25#include <asm/mach-au1x00/au1xxx_dbdma.h>
26
27#include "../codecs/ac97.h"
28#include "psc.h"
29
30static int au1xpsc_sample_ac97_init(struct snd_soc_codec *codec)
31{
32 snd_soc_dapm_sync(codec);
33 return 0;
34}
35
36static struct snd_soc_dai_link au1xpsc_sample_ac97_dai = {
37 .name = "AC97",
38 .stream_name = "AC97 HiFi",
39 .cpu_dai = &au1xpsc_ac97_dai, /* see psc-ac97.c */
40 .codec_dai = &ac97_dai, /* see codecs/ac97.c */
41 .init = au1xpsc_sample_ac97_init,
42 .ops = NULL,
43};
44
45static struct snd_soc_machine au1xpsc_sample_ac97_machine = {
46 .name = "Au1xxx PSC AC97 Audio",
47 .dai_link = &au1xpsc_sample_ac97_dai,
48 .num_links = 1,
49};
50
51static struct snd_soc_device au1xpsc_sample_ac97_devdata = {
52 .machine = &au1xpsc_sample_ac97_machine,
53 .platform = &au1xpsc_soc_platform, /* see dbdma2.c */
54 .codec_dev = &soc_codec_dev_ac97,
55};
56
57static struct resource au1xpsc_psc1_res[] = {
58 [0] = {
59 .start = CPHYSADDR(PSC1_BASE_ADDR),
60 .end = CPHYSADDR(PSC1_BASE_ADDR) + 0x000fffff,
61 .flags = IORESOURCE_MEM,
62 },
63 [1] = {
64#ifdef CONFIG_SOC_AU1200
65 .start = AU1200_PSC1_INT,
66 .end = AU1200_PSC1_INT,
67#elif defined(CONFIG_SOC_AU1550)
68 .start = AU1550_PSC1_INT,
69 .end = AU1550_PSC1_INT,
70#endif
71 .flags = IORESOURCE_IRQ,
72 },
73 [2] = {
74 .start = DSCR_CMD0_PSC1_TX,
75 .end = DSCR_CMD0_PSC1_TX,
76 .flags = IORESOURCE_DMA,
77 },
78 [3] = {
79 .start = DSCR_CMD0_PSC1_RX,
80 .end = DSCR_CMD0_PSC1_RX,
81 .flags = IORESOURCE_DMA,
82 },
83};
84
85static struct platform_device *au1xpsc_sample_ac97_dev;
86
87static int __init au1xpsc_sample_ac97_load(void)
88{
89 int ret;
90
91#ifdef CONFIG_SOC_AU1200
92 unsigned long io;
93
94 /* modify sys_pinfunc for AC97 on PSC1 */
95 io = au_readl(SYS_PINFUNC);
96 io |= SYS_PINFUNC_P1C;
97 io &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B);
98 au_writel(io, SYS_PINFUNC);
99 au_sync();
100#endif
101
102 ret = -ENOMEM;
103
104 /* setup PSC clock source for AC97 part: external clock provided
105 * by codec. The psc-ac97.c driver depends on this setting!
106 */
107 au_writel(PSC_SEL_CLK_SERCLK, PSC1_BASE_ADDR + PSC_SEL_OFFSET);
108 au_sync();
109
110 au1xpsc_sample_ac97_dev = platform_device_alloc("soc-audio", -1);
111 if (!au1xpsc_sample_ac97_dev)
112 goto out;
113
114 au1xpsc_sample_ac97_dev->resource =
115 kmemdup(au1xpsc_psc1_res, sizeof(struct resource) *
116 ARRAY_SIZE(au1xpsc_psc1_res), GFP_KERNEL);
117 au1xpsc_sample_ac97_dev->num_resources = ARRAY_SIZE(au1xpsc_psc1_res);
118 au1xpsc_sample_ac97_dev->id = 1;
119
120 platform_set_drvdata(au1xpsc_sample_ac97_dev,
121 &au1xpsc_sample_ac97_devdata);
122 au1xpsc_sample_ac97_devdata.dev = &au1xpsc_sample_ac97_dev->dev;
123 ret = platform_device_add(au1xpsc_sample_ac97_dev);
124
125 if (ret) {
126 platform_device_put(au1xpsc_sample_ac97_dev);
127 au1xpsc_sample_ac97_dev = NULL;
128 }
129
130out:
131 return ret;
132}
133
134static void __exit au1xpsc_sample_ac97_exit(void)
135{
136 platform_device_unregister(au1xpsc_sample_ac97_dev);
137}
138
139module_init(au1xpsc_sample_ac97_load);
140module_exit(au1xpsc_sample_ac97_exit);
141
142MODULE_LICENSE("GPL");
143MODULE_DESCRIPTION("Au1xxx PSC sample AC97 machine");
144MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 3903ab7dfa4a..1db04a28a53d 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -1,31 +1,37 @@
1config SND_SOC_AC97_CODEC 1config SND_SOC_AC97_CODEC
2 tristate 2 tristate
3 depends on SND_SOC 3 select SND_AC97_CODEC
4
5config SND_SOC_AK4535
6 tristate
7
8config SND_SOC_UDA1380
9 tristate
10
11config SND_SOC_WM8510
12 tristate
4 13
5config SND_SOC_WM8731 14config SND_SOC_WM8731
6 tristate 15 tristate
7 depends on SND_SOC
8 16
9config SND_SOC_WM8750 17config SND_SOC_WM8750
10 tristate 18 tristate
11 depends on SND_SOC
12 19
13config SND_SOC_WM8753 20config SND_SOC_WM8753
14 tristate 21 tristate
15 depends on SND_SOC 22
23config SND_SOC_WM8990
24 tristate
16 25
17config SND_SOC_WM9712 26config SND_SOC_WM9712
18 tristate 27 tristate
19 depends on SND_SOC
20 28
21config SND_SOC_WM9713 29config SND_SOC_WM9713
22 tristate 30 tristate
23 depends on SND_SOC
24 31
25# Cirrus Logic CS4270 Codec 32# Cirrus Logic CS4270 Codec
26config SND_SOC_CS4270 33config SND_SOC_CS4270
27 tristate 34 tristate
28 depends on SND_SOC
29 35
30# Cirrus Logic CS4270 Codec Hardware Mute Support 36# Cirrus Logic CS4270 Codec Hardware Mute Support
31# Select if you have external muting circuitry attached to your CS4270. 37# Select if you have external muting circuitry attached to your CS4270.
@@ -43,4 +49,4 @@ config SND_SOC_CS4270_VD33_ERRATA
43 49
44config SND_SOC_TLV320AIC3X 50config SND_SOC_TLV320AIC3X
45 tristate 51 tristate
46 depends on SND_SOC && I2C 52 depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 4e1314c9d3ec..d7b97abcf729 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,16 +1,24 @@
1snd-soc-ac97-objs := ac97.o 1snd-soc-ac97-objs := ac97.o
2snd-soc-ak4535-objs := ak4535.o
3snd-soc-uda1380-objs := uda1380.o
4snd-soc-wm8510-objs := wm8510.o
2snd-soc-wm8731-objs := wm8731.o 5snd-soc-wm8731-objs := wm8731.o
3snd-soc-wm8750-objs := wm8750.o 6snd-soc-wm8750-objs := wm8750.o
4snd-soc-wm8753-objs := wm8753.o 7snd-soc-wm8753-objs := wm8753.o
8snd-soc-wm8990-objs := wm8990.o
5snd-soc-wm9712-objs := wm9712.o 9snd-soc-wm9712-objs := wm9712.o
6snd-soc-wm9713-objs := wm9713.o 10snd-soc-wm9713-objs := wm9713.o
7snd-soc-cs4270-objs := cs4270.o 11snd-soc-cs4270-objs := cs4270.o
8snd-soc-tlv320aic3x-objs := tlv320aic3x.o 12snd-soc-tlv320aic3x-objs := tlv320aic3x.o
9 13
10obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 14obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
15obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
16obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
17obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
11obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 18obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
12obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 19obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
13obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o 20obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
21obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
14obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o 22obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
15obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o 23obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
16obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 24obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 2a1ffe396908..61fd96ca7bc7 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -10,9 +10,6 @@
10 * Free Software Foundation; either version 2 of the License, or (at your 10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
12 * 12 *
13 * Revision history
14 * 17th Oct 2005 Initial version.
15 *
16 * Generic AC97 support. 13 * Generic AC97 support.
17 */ 14 */
18 15
@@ -24,6 +21,7 @@
24#include <sound/ac97_codec.h> 21#include <sound/ac97_codec.h>
25#include <sound/initval.h> 22#include <sound/initval.h>
26#include <sound/soc.h> 23#include <sound/soc.h>
24#include "ac97.h"
27 25
28#define AC97_VERSION "0.6" 26#define AC97_VERSION "0.6"
29 27
@@ -43,7 +41,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream)
43 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\ 41 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\
44 SNDRV_PCM_RATE_48000) 42 SNDRV_PCM_RATE_48000)
45 43
46struct snd_soc_codec_dai ac97_dai = { 44struct snd_soc_dai ac97_dai = {
47 .name = "AC97 HiFi", 45 .name = "AC97 HiFi",
48 .type = SND_SOC_DAI_AC97, 46 .type = SND_SOC_DAI_AC97,
49 .playback = { 47 .playback = {
@@ -146,9 +144,34 @@ static int ac97_soc_remove(struct platform_device *pdev)
146 return 0; 144 return 0;
147} 145}
148 146
147#ifdef CONFIG_PM
148static int ac97_soc_suspend(struct platform_device *pdev, pm_message_t msg)
149{
150 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
151
152 snd_ac97_suspend(socdev->codec->ac97);
153
154 return 0;
155}
156
157static int ac97_soc_resume(struct platform_device *pdev)
158{
159 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
160
161 snd_ac97_resume(socdev->codec->ac97);
162
163 return 0;
164}
165#else
166#define ac97_soc_suspend NULL
167#define ac97_soc_resume NULL
168#endif
169
149struct snd_soc_codec_device soc_codec_dev_ac97 = { 170struct snd_soc_codec_device soc_codec_dev_ac97 = {
150 .probe = ac97_soc_probe, 171 .probe = ac97_soc_probe,
151 .remove = ac97_soc_remove, 172 .remove = ac97_soc_remove,
173 .suspend = ac97_soc_suspend,
174 .resume = ac97_soc_resume,
152}; 175};
153EXPORT_SYMBOL_GPL(soc_codec_dev_ac97); 176EXPORT_SYMBOL_GPL(soc_codec_dev_ac97);
154 177
diff --git a/sound/soc/codecs/ac97.h b/sound/soc/codecs/ac97.h
index 2bf6d69fd069..281aa42e2bbb 100644
--- a/sound/soc/codecs/ac97.h
+++ b/sound/soc/codecs/ac97.h
@@ -14,6 +14,6 @@
14#define __LINUX_SND_SOC_AC97_H 14#define __LINUX_SND_SOC_AC97_H
15 15
16extern struct snd_soc_codec_device soc_codec_dev_ac97; 16extern struct snd_soc_codec_device soc_codec_dev_ac97;
17extern struct snd_soc_codec_dai ac97_dai; 17extern struct snd_soc_dai ac97_dai;
18 18
19#endif 19#endif
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
new file mode 100644
index 000000000000..b26003c4f3e8
--- /dev/null
+++ b/sound/soc/codecs/ak4535.c
@@ -0,0 +1,696 @@
1/*
2 * ak4535.c -- AK4535 ALSA Soc Audio driver
3 *
4 * Copyright 2005 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <richard@openedhand.com>
7 *
8 * Based on wm8753.c by Liam Girdwood
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.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/soc-dapm.h>
27#include <sound/initval.h>
28
29#include "ak4535.h"
30
31#define AUDIO_NAME "ak4535"
32#define AK4535_VERSION "0.3"
33
34struct snd_soc_codec_device soc_codec_dev_ak4535;
35
36/* codec private data */
37struct ak4535_priv {
38 unsigned int sysclk;
39};
40
41/*
42 * ak4535 register cache
43 */
44static const u16 ak4535_reg[AK4535_CACHEREGNUM] = {
45 0x0000, 0x0080, 0x0000, 0x0003,
46 0x0002, 0x0000, 0x0011, 0x0001,
47 0x0000, 0x0040, 0x0036, 0x0010,
48 0x0000, 0x0000, 0x0057, 0x0000,
49};
50
51/*
52 * read ak4535 register cache
53 */
54static inline unsigned int ak4535_read_reg_cache(struct snd_soc_codec *codec,
55 unsigned int reg)
56{
57 u16 *cache = codec->reg_cache;
58 if (reg >= AK4535_CACHEREGNUM)
59 return -1;
60 return cache[reg];
61}
62
63static inline unsigned int ak4535_read(struct snd_soc_codec *codec,
64 unsigned int reg)
65{
66 u8 data;
67 data = reg;
68
69 if (codec->hw_write(codec->control_data, &data, 1) != 1)
70 return -EIO;
71
72 if (codec->hw_read(codec->control_data, &data, 1) != 1)
73 return -EIO;
74
75 return data;
76};
77
78/*
79 * write ak4535 register cache
80 */
81static inline void ak4535_write_reg_cache(struct snd_soc_codec *codec,
82 u16 reg, unsigned int value)
83{
84 u16 *cache = codec->reg_cache;
85 if (reg >= AK4535_CACHEREGNUM)
86 return;
87 cache[reg] = value;
88}
89
90/*
91 * write to the AK4535 register space
92 */
93static int ak4535_write(struct snd_soc_codec *codec, unsigned int reg,
94 unsigned int value)
95{
96 u8 data[2];
97
98 /* data is
99 * D15..D8 AK4535 register offset
100 * D7...D0 register data
101 */
102 data[0] = reg & 0xff;
103 data[1] = value & 0xff;
104
105 ak4535_write_reg_cache(codec, reg, value);
106 if (codec->hw_write(codec->control_data, data, 2) == 2)
107 return 0;
108 else
109 return -EIO;
110}
111
112static int ak4535_sync(struct snd_soc_codec *codec)
113{
114 u16 *cache = codec->reg_cache;
115 int i, r = 0;
116
117 for (i = 0; i < AK4535_CACHEREGNUM; i++)
118 r |= ak4535_write(codec, i, cache[i]);
119
120 return r;
121};
122
123static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"};
124static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"};
125static const char *ak4535_hp_out[] = {"Stereo", "Mono"};
126static const char *ak4535_deemp[] = {"44.1kHz", "Off", "48kHz", "32kHz"};
127static const char *ak4535_mic_select[] = {"Internal", "External"};
128
129static const struct soc_enum ak4535_enum[] = {
130 SOC_ENUM_SINGLE(AK4535_SIG1, 7, 2, ak4535_mono_gain),
131 SOC_ENUM_SINGLE(AK4535_SIG1, 6, 2, ak4535_mono_out),
132 SOC_ENUM_SINGLE(AK4535_MODE2, 2, 2, ak4535_hp_out),
133 SOC_ENUM_SINGLE(AK4535_DAC, 0, 4, ak4535_deemp),
134 SOC_ENUM_SINGLE(AK4535_MIC, 1, 2, ak4535_mic_select),
135};
136
137static const struct snd_kcontrol_new ak4535_snd_controls[] = {
138 SOC_SINGLE("ALC2 Switch", AK4535_SIG1, 1, 1, 0),
139 SOC_ENUM("Mono 1 Output", ak4535_enum[1]),
140 SOC_ENUM("Mono 1 Gain", ak4535_enum[0]),
141 SOC_ENUM("Headphone Output", ak4535_enum[2]),
142 SOC_ENUM("Playback Deemphasis", ak4535_enum[3]),
143 SOC_SINGLE("Bass Volume", AK4535_DAC, 2, 3, 0),
144 SOC_SINGLE("Mic Boost (+20dB) Switch", AK4535_MIC, 0, 1, 0),
145 SOC_ENUM("Mic Select", ak4535_enum[4]),
146 SOC_SINGLE("ALC Operation Time", AK4535_TIMER, 0, 3, 0),
147 SOC_SINGLE("ALC Recovery Time", AK4535_TIMER, 2, 3, 0),
148 SOC_SINGLE("ALC ZC Time", AK4535_TIMER, 4, 3, 0),
149 SOC_SINGLE("ALC 1 Switch", AK4535_ALC1, 5, 1, 0),
150 SOC_SINGLE("ALC 2 Switch", AK4535_ALC1, 6, 1, 0),
151 SOC_SINGLE("ALC Volume", AK4535_ALC2, 0, 127, 0),
152 SOC_SINGLE("Capture Volume", AK4535_PGA, 0, 127, 0),
153 SOC_SINGLE("Left Playback Volume", AK4535_LATT, 0, 127, 1),
154 SOC_SINGLE("Right Playback Volume", AK4535_RATT, 0, 127, 1),
155 SOC_SINGLE("AUX Bypass Volume", AK4535_VOL, 0, 15, 0),
156 SOC_SINGLE("Mic Sidetone Volume", AK4535_VOL, 4, 7, 0),
157};
158
159/* add non dapm controls */
160static int ak4535_add_controls(struct snd_soc_codec *codec)
161{
162 int err, i;
163
164 for (i = 0; i < ARRAY_SIZE(ak4535_snd_controls); i++) {
165 err = snd_ctl_add(codec->card,
166 snd_soc_cnew(&ak4535_snd_controls[i], codec, NULL));
167 if (err < 0)
168 return err;
169 }
170
171 return 0;
172}
173
174/* Mono 1 Mixer */
175static const struct snd_kcontrol_new ak4535_mono1_mixer_controls[] = {
176 SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4535_SIG1, 4, 1, 0),
177 SOC_DAPM_SINGLE("Mono Playback Switch", AK4535_SIG1, 5, 1, 0),
178};
179
180/* Stereo Mixer */
181static const struct snd_kcontrol_new ak4535_stereo_mixer_controls[] = {
182 SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4535_SIG2, 4, 1, 0),
183 SOC_DAPM_SINGLE("Playback Switch", AK4535_SIG2, 7, 1, 0),
184 SOC_DAPM_SINGLE("Aux Bypass Switch", AK4535_SIG2, 5, 1, 0),
185};
186
187/* Input Mixer */
188static const struct snd_kcontrol_new ak4535_input_mixer_controls[] = {
189 SOC_DAPM_SINGLE("Mic Capture Switch", AK4535_MIC, 2, 1, 0),
190 SOC_DAPM_SINGLE("Aux Capture Switch", AK4535_MIC, 5, 1, 0),
191};
192
193/* Input mux */
194static const struct snd_kcontrol_new ak4535_input_mux_control =
195 SOC_DAPM_ENUM("Input Select", ak4535_enum[4]);
196
197/* HP L switch */
198static const struct snd_kcontrol_new ak4535_hpl_control =
199 SOC_DAPM_SINGLE("Switch", AK4535_SIG2, 1, 1, 1);
200
201/* HP R switch */
202static const struct snd_kcontrol_new ak4535_hpr_control =
203 SOC_DAPM_SINGLE("Switch", AK4535_SIG2, 0, 1, 1);
204
205/* mono 2 switch */
206static const struct snd_kcontrol_new ak4535_mono2_control =
207 SOC_DAPM_SINGLE("Switch", AK4535_SIG1, 0, 1, 0);
208
209/* Line out switch */
210static const struct snd_kcontrol_new ak4535_line_control =
211 SOC_DAPM_SINGLE("Switch", AK4535_SIG2, 6, 1, 0);
212
213/* ak4535 dapm widgets */
214static const struct snd_soc_dapm_widget ak4535_dapm_widgets[] = {
215 SND_SOC_DAPM_MIXER("Stereo Mixer", SND_SOC_NOPM, 0, 0,
216 &ak4535_stereo_mixer_controls[0],
217 ARRAY_SIZE(ak4535_stereo_mixer_controls)),
218 SND_SOC_DAPM_MIXER("Mono1 Mixer", SND_SOC_NOPM, 0, 0,
219 &ak4535_mono1_mixer_controls[0],
220 ARRAY_SIZE(ak4535_mono1_mixer_controls)),
221 SND_SOC_DAPM_MIXER("Input Mixer", SND_SOC_NOPM, 0, 0,
222 &ak4535_input_mixer_controls[0],
223 ARRAY_SIZE(ak4535_input_mixer_controls)),
224 SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
225 &ak4535_input_mux_control),
226 SND_SOC_DAPM_DAC("DAC", "Playback", AK4535_PM2, 0, 0),
227 SND_SOC_DAPM_SWITCH("Mono 2 Enable", SND_SOC_NOPM, 0, 0,
228 &ak4535_mono2_control),
229 /* speaker powersave bit */
230 SND_SOC_DAPM_PGA("Speaker Enable", AK4535_MODE2, 0, 0, NULL, 0),
231 SND_SOC_DAPM_SWITCH("Line Out Enable", SND_SOC_NOPM, 0, 0,
232 &ak4535_line_control),
233 SND_SOC_DAPM_SWITCH("Left HP Enable", SND_SOC_NOPM, 0, 0,
234 &ak4535_hpl_control),
235 SND_SOC_DAPM_SWITCH("Right HP Enable", SND_SOC_NOPM, 0, 0,
236 &ak4535_hpr_control),
237 SND_SOC_DAPM_OUTPUT("LOUT"),
238 SND_SOC_DAPM_OUTPUT("HPL"),
239 SND_SOC_DAPM_OUTPUT("ROUT"),
240 SND_SOC_DAPM_OUTPUT("HPR"),
241 SND_SOC_DAPM_OUTPUT("SPP"),
242 SND_SOC_DAPM_OUTPUT("SPN"),
243 SND_SOC_DAPM_OUTPUT("MOUT1"),
244 SND_SOC_DAPM_OUTPUT("MOUT2"),
245 SND_SOC_DAPM_OUTPUT("MICOUT"),
246 SND_SOC_DAPM_ADC("ADC", "Capture", AK4535_PM1, 0, 0),
247 SND_SOC_DAPM_PGA("Spk Amp", AK4535_PM2, 3, 0, NULL, 0),
248 SND_SOC_DAPM_PGA("HP R Amp", AK4535_PM2, 1, 0, NULL, 0),
249 SND_SOC_DAPM_PGA("HP L Amp", AK4535_PM2, 2, 0, NULL, 0),
250 SND_SOC_DAPM_PGA("Mic", AK4535_PM1, 1, 0, NULL, 0),
251 SND_SOC_DAPM_PGA("Line Out", AK4535_PM1, 4, 0, NULL, 0),
252 SND_SOC_DAPM_PGA("Mono Out", AK4535_PM1, 3, 0, NULL, 0),
253 SND_SOC_DAPM_PGA("AUX In", AK4535_PM1, 2, 0, NULL, 0),
254
255 SND_SOC_DAPM_MICBIAS("Mic Int Bias", AK4535_MIC, 3, 0),
256 SND_SOC_DAPM_MICBIAS("Mic Ext Bias", AK4535_MIC, 4, 0),
257 SND_SOC_DAPM_INPUT("MICIN"),
258 SND_SOC_DAPM_INPUT("MICEXT"),
259 SND_SOC_DAPM_INPUT("AUX"),
260 SND_SOC_DAPM_INPUT("MIN"),
261 SND_SOC_DAPM_INPUT("AIN"),
262};
263
264static const struct snd_soc_dapm_route audio_map[] = {
265 /*stereo mixer */
266 {"Stereo Mixer", "Playback Switch", "DAC"},
267 {"Stereo Mixer", "Mic Sidetone Switch", "Mic"},
268 {"Stereo Mixer", "Aux Bypass Switch", "AUX In"},
269
270 /* mono1 mixer */
271 {"Mono1 Mixer", "Mic Sidetone Switch", "Mic"},
272 {"Mono1 Mixer", "Mono Playback Switch", "DAC"},
273
274 /* Mic */
275 {"Mic", NULL, "AIN"},
276 {"Input Mux", "Internal", "Mic Int Bias"},
277 {"Input Mux", "External", "Mic Ext Bias"},
278 {"Mic Int Bias", NULL, "MICIN"},
279 {"Mic Ext Bias", NULL, "MICEXT"},
280 {"MICOUT", NULL, "Input Mux"},
281
282 /* line out */
283 {"LOUT", NULL, "Line Out Enable"},
284 {"ROUT", NULL, "Line Out Enable"},
285 {"Line Out Enable", "Switch", "Line Out"},
286 {"Line Out", NULL, "Stereo Mixer"},
287
288 /* mono1 out */
289 {"MOUT1", NULL, "Mono Out"},
290 {"Mono Out", NULL, "Mono1 Mixer"},
291
292 /* left HP */
293 {"HPL", NULL, "Left HP Enable"},
294 {"Left HP Enable", "Switch", "HP L Amp"},
295 {"HP L Amp", NULL, "Stereo Mixer"},
296
297 /* right HP */
298 {"HPR", NULL, "Right HP Enable"},
299 {"Right HP Enable", "Switch", "HP R Amp"},
300 {"HP R Amp", NULL, "Stereo Mixer"},
301
302 /* speaker */
303 {"SPP", NULL, "Speaker Enable"},
304 {"SPN", NULL, "Speaker Enable"},
305 {"Speaker Enable", "Switch", "Spk Amp"},
306 {"Spk Amp", NULL, "MIN"},
307
308 /* mono 2 */
309 {"MOUT2", NULL, "Mono 2 Enable"},
310 {"Mono 2 Enable", "Switch", "Stereo Mixer"},
311
312 /* Aux In */
313 {"Aux In", NULL, "AUX"},
314
315 /* ADC */
316 {"ADC", NULL, "Input Mixer"},
317 {"Input Mixer", "Mic Capture Switch", "Mic"},
318 {"Input Mixer", "Aux Capture Switch", "Aux In"},
319};
320
321static int ak4535_add_widgets(struct snd_soc_codec *codec)
322{
323 snd_soc_dapm_new_controls(codec, ak4535_dapm_widgets,
324 ARRAY_SIZE(ak4535_dapm_widgets));
325
326 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
327
328 snd_soc_dapm_new_widgets(codec);
329 return 0;
330}
331
332static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai,
333 int clk_id, unsigned int freq, int dir)
334{
335 struct snd_soc_codec *codec = codec_dai->codec;
336 struct ak4535_priv *ak4535 = codec->private_data;
337
338 ak4535->sysclk = freq;
339 return 0;
340}
341
342static int ak4535_hw_params(struct snd_pcm_substream *substream,
343 struct snd_pcm_hw_params *params)
344{
345 struct snd_soc_pcm_runtime *rtd = substream->private_data;
346 struct snd_soc_device *socdev = rtd->socdev;
347 struct snd_soc_codec *codec = socdev->codec;
348 struct ak4535_priv *ak4535 = codec->private_data;
349 u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5);
350 int rate = params_rate(params), fs = 256;
351
352 if (rate)
353 fs = ak4535->sysclk / rate;
354
355 /* set fs */
356 switch (fs) {
357 case 1024:
358 mode2 |= (0x2 << 5);
359 break;
360 case 512:
361 mode2 |= (0x1 << 5);
362 break;
363 case 256:
364 break;
365 }
366
367 /* set rate */
368 ak4535_write(codec, AK4535_MODE2, mode2);
369 return 0;
370}
371
372static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai,
373 unsigned int fmt)
374{
375 struct snd_soc_codec *codec = codec_dai->codec;
376 u8 mode1 = 0;
377
378 /* interface format */
379 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
380 case SND_SOC_DAIFMT_I2S:
381 mode1 = 0x0002;
382 break;
383 case SND_SOC_DAIFMT_LEFT_J:
384 mode1 = 0x0001;
385 break;
386 default:
387 return -EINVAL;
388 }
389
390 /* use 32 fs for BCLK to save power */
391 mode1 |= 0x4;
392
393 ak4535_write(codec, AK4535_MODE1, mode1);
394 return 0;
395}
396
397static int ak4535_mute(struct snd_soc_dai *dai, int mute)
398{
399 struct snd_soc_codec *codec = dai->codec;
400 u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
401 if (!mute)
402 ak4535_write(codec, AK4535_DAC, mute_reg);
403 else
404 ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
405 return 0;
406}
407
408static int ak4535_set_bias_level(struct snd_soc_codec *codec,
409 enum snd_soc_bias_level level)
410{
411 u16 i;
412
413 switch (level) {
414 case SND_SOC_BIAS_ON:
415 ak4535_mute(codec->dai, 0);
416 break;
417 case SND_SOC_BIAS_PREPARE:
418 ak4535_mute(codec->dai, 1);
419 break;
420 case SND_SOC_BIAS_STANDBY:
421 i = ak4535_read_reg_cache(codec, AK4535_PM1);
422 ak4535_write(codec, AK4535_PM1, i | 0x80);
423 i = ak4535_read_reg_cache(codec, AK4535_PM2);
424 ak4535_write(codec, AK4535_PM2, i & (~0x80));
425 break;
426 case SND_SOC_BIAS_OFF:
427 i = ak4535_read_reg_cache(codec, AK4535_PM1);
428 ak4535_write(codec, AK4535_PM1, i & (~0x80));
429 break;
430 }
431 codec->bias_level = level;
432 return 0;
433}
434
435#define AK4535_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
436 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
437 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
438
439struct snd_soc_dai ak4535_dai = {
440 .name = "AK4535",
441 .playback = {
442 .stream_name = "Playback",
443 .channels_min = 1,
444 .channels_max = 2,
445 .rates = AK4535_RATES,
446 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
447 .capture = {
448 .stream_name = "Capture",
449 .channels_min = 1,
450 .channels_max = 2,
451 .rates = AK4535_RATES,
452 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
453 .ops = {
454 .hw_params = ak4535_hw_params,
455 },
456 .dai_ops = {
457 .set_fmt = ak4535_set_dai_fmt,
458 .digital_mute = ak4535_mute,
459 .set_sysclk = ak4535_set_dai_sysclk,
460 },
461};
462EXPORT_SYMBOL_GPL(ak4535_dai);
463
464static int ak4535_suspend(struct platform_device *pdev, pm_message_t state)
465{
466 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
467 struct snd_soc_codec *codec = socdev->codec;
468
469 ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
470 return 0;
471}
472
473static int ak4535_resume(struct platform_device *pdev)
474{
475 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
476 struct snd_soc_codec *codec = socdev->codec;
477 ak4535_sync(codec);
478 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
479 ak4535_set_bias_level(codec, codec->suspend_bias_level);
480 return 0;
481}
482
483/*
484 * initialise the AK4535 driver
485 * register the mixer and dsp interfaces with the kernel
486 */
487static int ak4535_init(struct snd_soc_device *socdev)
488{
489 struct snd_soc_codec *codec = socdev->codec;
490 int ret = 0;
491
492 codec->name = "AK4535";
493 codec->owner = THIS_MODULE;
494 codec->read = ak4535_read_reg_cache;
495 codec->write = ak4535_write;
496 codec->set_bias_level = ak4535_set_bias_level;
497 codec->dai = &ak4535_dai;
498 codec->num_dai = 1;
499 codec->reg_cache_size = ARRAY_SIZE(ak4535_reg);
500 codec->reg_cache = kmemdup(ak4535_reg, sizeof(ak4535_reg), GFP_KERNEL);
501
502 if (codec->reg_cache == NULL)
503 return -ENOMEM;
504
505 /* register pcms */
506 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
507 if (ret < 0) {
508 printk(KERN_ERR "ak4535: failed to create pcms\n");
509 goto pcm_err;
510 }
511
512 /* power on device */
513 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
514
515 ak4535_add_controls(codec);
516 ak4535_add_widgets(codec);
517 ret = snd_soc_register_card(socdev);
518 if (ret < 0) {
519 printk(KERN_ERR "ak4535: failed to register card\n");
520 goto card_err;
521 }
522
523 return ret;
524
525card_err:
526 snd_soc_free_pcms(socdev);
527 snd_soc_dapm_free(socdev);
528pcm_err:
529 kfree(codec->reg_cache);
530
531 return ret;
532}
533
534static struct snd_soc_device *ak4535_socdev;
535
536#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
537
538#define I2C_DRIVERID_AK4535 0xfefe /* liam - need a proper id */
539
540static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
541
542/* Magic definition of all other variables and things */
543I2C_CLIENT_INSMOD;
544
545static struct i2c_driver ak4535_i2c_driver;
546static struct i2c_client client_template;
547
548/* If the i2c layer weren't so broken, we could pass this kind of data
549 around */
550static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind)
551{
552 struct snd_soc_device *socdev = ak4535_socdev;
553 struct ak4535_setup_data *setup = socdev->codec_data;
554 struct snd_soc_codec *codec = socdev->codec;
555 struct i2c_client *i2c;
556 int ret;
557
558 if (addr != setup->i2c_address)
559 return -ENODEV;
560
561 client_template.adapter = adap;
562 client_template.addr = addr;
563
564 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
565 if (i2c == NULL) {
566 kfree(codec);
567 return -ENOMEM;
568 }
569 i2c_set_clientdata(i2c, codec);
570 codec->control_data = i2c;
571
572 ret = i2c_attach_client(i2c);
573 if (ret < 0) {
574 printk(KERN_ERR "failed to attach codec at addr %x\n", addr);
575 goto err;
576 }
577
578 ret = ak4535_init(socdev);
579 if (ret < 0) {
580 printk(KERN_ERR "failed to initialise AK4535\n");
581 goto err;
582 }
583 return ret;
584
585err:
586 kfree(codec);
587 kfree(i2c);
588 return ret;
589}
590
591static int ak4535_i2c_detach(struct i2c_client *client)
592{
593 struct snd_soc_codec *codec = i2c_get_clientdata(client);
594 i2c_detach_client(client);
595 kfree(codec->reg_cache);
596 kfree(client);
597 return 0;
598}
599
600static int ak4535_i2c_attach(struct i2c_adapter *adap)
601{
602 return i2c_probe(adap, &addr_data, ak4535_codec_probe);
603}
604
605/* corgi i2c codec control layer */
606static struct i2c_driver ak4535_i2c_driver = {
607 .driver = {
608 .name = "AK4535 I2C Codec",
609 .owner = THIS_MODULE,
610 },
611 .id = I2C_DRIVERID_AK4535,
612 .attach_adapter = ak4535_i2c_attach,
613 .detach_client = ak4535_i2c_detach,
614 .command = NULL,
615};
616
617static struct i2c_client client_template = {
618 .name = "AK4535",
619 .driver = &ak4535_i2c_driver,
620};
621#endif
622
623static int ak4535_probe(struct platform_device *pdev)
624{
625 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
626 struct ak4535_setup_data *setup;
627 struct snd_soc_codec *codec;
628 struct ak4535_priv *ak4535;
629 int ret = 0;
630
631 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
632
633 setup = socdev->codec_data;
634 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
635 if (codec == NULL)
636 return -ENOMEM;
637
638 ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL);
639 if (ak4535 == NULL) {
640 kfree(codec);
641 return -ENOMEM;
642 }
643
644 codec->private_data = ak4535;
645 socdev->codec = codec;
646 mutex_init(&codec->mutex);
647 INIT_LIST_HEAD(&codec->dapm_widgets);
648 INIT_LIST_HEAD(&codec->dapm_paths);
649
650 ak4535_socdev = socdev;
651#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
652 if (setup->i2c_address) {
653 normal_i2c[0] = setup->i2c_address;
654 codec->hw_write = (hw_write_t)i2c_master_send;
655 codec->hw_read = (hw_read_t)i2c_master_recv;
656 ret = i2c_add_driver(&ak4535_i2c_driver);
657 if (ret != 0)
658 printk(KERN_ERR "can't add i2c driver");
659 }
660#else
661 /* Add other interfaces here */
662#endif
663 return ret;
664}
665
666/* power down chip */
667static int ak4535_remove(struct platform_device *pdev)
668{
669 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
670 struct snd_soc_codec *codec = socdev->codec;
671
672 if (codec->control_data)
673 ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
674
675 snd_soc_free_pcms(socdev);
676 snd_soc_dapm_free(socdev);
677#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
678 i2c_del_driver(&ak4535_i2c_driver);
679#endif
680 kfree(codec->private_data);
681 kfree(codec);
682
683 return 0;
684}
685
686struct snd_soc_codec_device soc_codec_dev_ak4535 = {
687 .probe = ak4535_probe,
688 .remove = ak4535_remove,
689 .suspend = ak4535_suspend,
690 .resume = ak4535_resume,
691};
692EXPORT_SYMBOL_GPL(soc_codec_dev_ak4535);
693
694MODULE_DESCRIPTION("Soc AK4535 driver");
695MODULE_AUTHOR("Richard Purdie");
696MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4535.h b/sound/soc/codecs/ak4535.h
new file mode 100644
index 000000000000..e9fe30e2c056
--- /dev/null
+++ b/sound/soc/codecs/ak4535.h
@@ -0,0 +1,46 @@
1/*
2 * ak4535.h -- AK4535 Soc Audio driver
3 *
4 * Copyright 2005 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <richard@openedhand.com>
7 *
8 * Based on wm8753.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef _AK4535_H
16#define _AK4535_H
17
18/* AK4535 register space */
19
20#define AK4535_PM1 0x0
21#define AK4535_PM2 0x1
22#define AK4535_SIG1 0x2
23#define AK4535_SIG2 0x3
24#define AK4535_MODE1 0x4
25#define AK4535_MODE2 0x5
26#define AK4535_DAC 0x6
27#define AK4535_MIC 0x7
28#define AK4535_TIMER 0x8
29#define AK4535_ALC1 0x9
30#define AK4535_ALC2 0xa
31#define AK4535_PGA 0xb
32#define AK4535_LATT 0xc
33#define AK4535_RATT 0xd
34#define AK4535_VOL 0xe
35#define AK4535_STATUS 0xf
36
37#define AK4535_CACHEREGNUM 0x10
38
39struct ak4535_setup_data {
40 unsigned short i2c_address;
41};
42
43extern struct snd_soc_dai ak4535_dai;
44extern struct snd_soc_codec_device soc_codec_dev_ak4535;
45
46#endif
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index e73fcfd9f5cd..9deb8c74fdfd 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -201,7 +201,7 @@ static struct {
201 * driver what the input settings can be. This would need to be implemented 201 * driver what the input settings can be. This would need to be implemented
202 * for stand-alone mode to work. 202 * for stand-alone mode to work.
203 */ 203 */
204static int cs4270_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, 204static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
205 int clk_id, unsigned int freq, int dir) 205 int clk_id, unsigned int freq, int dir)
206{ 206{
207 struct snd_soc_codec *codec = codec_dai->codec; 207 struct snd_soc_codec *codec = codec_dai->codec;
@@ -251,7 +251,7 @@ static int cs4270_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
251 * data for playback only, but ASoC currently does not support different 251 * data for playback only, but ASoC currently does not support different
252 * formats for playback vs. record. 252 * formats for playback vs. record.
253 */ 253 */
254static int cs4270_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, 254static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
255 unsigned int format) 255 unsigned int format)
256{ 256{
257 struct snd_soc_codec *codec = codec_dai->codec; 257 struct snd_soc_codec *codec = codec_dai->codec;
@@ -471,7 +471,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
471 * board does not have the MUTEA or MUTEB pins connected to such circuitry, 471 * board does not have the MUTEA or MUTEB pins connected to such circuitry,
472 * then this function will do nothing. 472 * then this function will do nothing.
473 */ 473 */
474static int cs4270_mute(struct snd_soc_codec_dai *dai, int mute) 474static int cs4270_mute(struct snd_soc_dai *dai, int mute)
475{ 475{
476 struct snd_soc_codec *codec = dai->codec; 476 struct snd_soc_codec *codec = dai->codec;
477 int reg6; 477 int reg6;
@@ -667,7 +667,7 @@ error:
667 667
668#endif /* USE_I2C*/ 668#endif /* USE_I2C*/
669 669
670struct snd_soc_codec_dai cs4270_dai = { 670struct snd_soc_dai cs4270_dai = {
671 .name = "CS4270", 671 .name = "CS4270",
672 .playback = { 672 .playback = {
673 .stream_name = "Playback", 673 .stream_name = "Playback",
diff --git a/sound/soc/codecs/cs4270.h b/sound/soc/codecs/cs4270.h
index 0ced49b7804d..adc6cd9667d4 100644
--- a/sound/soc/codecs/cs4270.h
+++ b/sound/soc/codecs/cs4270.h
@@ -16,7 +16,7 @@
16 * The ASoC codec DAI structure for the CS4270. Assign this structure to 16 * The ASoC codec DAI structure for the CS4270. Assign this structure to
17 * the .codec_dai field of your machine driver's snd_soc_dai_link structure. 17 * the .codec_dai field of your machine driver's snd_soc_dai_link structure.
18 */ 18 */
19extern struct snd_soc_codec_dai cs4270_dai; 19extern struct snd_soc_dai cs4270_dai;
20 20
21/* 21/*
22 * The ASoC codec device structure for the CS4270. Assign this structure 22 * The ASoC codec device structure for the CS4270. Assign this structure
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 09b1661b8a3a..b1dce5f459db 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -29,7 +29,7 @@
29 * --------------------------------------- 29 * ---------------------------------------
30 * 30 *
31 * Hence the machine layer should disable unsupported inputs/outputs by 31 * Hence the machine layer should disable unsupported inputs/outputs by
32 * snd_soc_dapm_set_endpoint(codec, "MONO_LOUT", 0), etc. 32 * snd_soc_dapm_disable_pin(codec, "MONO_LOUT"), etc.
33 */ 33 */
34 34
35#include <linux/module.h> 35#include <linux/module.h>
@@ -49,7 +49,7 @@
49#include "tlv320aic3x.h" 49#include "tlv320aic3x.h"
50 50
51#define AUDIO_NAME "aic3x" 51#define AUDIO_NAME "aic3x"
52#define AIC3X_VERSION "0.1" 52#define AIC3X_VERSION "0.2"
53 53
54/* codec private data */ 54/* codec private data */
55struct aic3x_priv { 55struct aic3x_priv {
@@ -138,6 +138,20 @@ static int aic3x_write(struct snd_soc_codec *codec, unsigned int reg,
138 return -EIO; 138 return -EIO;
139} 139}
140 140
141/*
142 * read from the aic3x register space
143 */
144static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
145 u8 *value)
146{
147 *value = reg & 0xff;
148 if (codec->hw_read(codec->control_data, value, 1) != 1)
149 return -EIO;
150
151 aic3x_write_reg_cache(codec, reg, *value);
152 return 0;
153}
154
141#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \ 155#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \
142{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 156{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
143 .info = snd_soc_info_volsw, \ 157 .info = snd_soc_info_volsw, \
@@ -192,7 +206,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
192 } 206 }
193 207
194 if (found) 208 if (found)
195 snd_soc_dapm_sync_endpoints(widget->codec); 209 snd_soc_dapm_sync(widget->codec);
196 } 210 }
197 211
198 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); 212 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
@@ -209,6 +223,8 @@ static const char *aic3x_right_hpcom_mux[] =
209 { "differential of HPROUT", "constant VCM", "single-ended", 223 { "differential of HPROUT", "constant VCM", "single-ended",
210 "differential of HPLCOM", "external feedback" }; 224 "differential of HPLCOM", "external feedback" };
211static const char *aic3x_linein_mode_mux[] = { "single-ended", "differential" }; 225static const char *aic3x_linein_mode_mux[] = { "single-ended", "differential" };
226static const char *aic3x_adc_hpf[] =
227 { "Disabled", "0.0045xFs", "0.0125xFs", "0.025xFs" };
212 228
213#define LDAC_ENUM 0 229#define LDAC_ENUM 0
214#define RDAC_ENUM 1 230#define RDAC_ENUM 1
@@ -218,6 +234,7 @@ static const char *aic3x_linein_mode_mux[] = { "single-ended", "differential" };
218#define LINE1R_ENUM 5 234#define LINE1R_ENUM 5
219#define LINE2L_ENUM 6 235#define LINE2L_ENUM 6
220#define LINE2R_ENUM 7 236#define LINE2R_ENUM 7
237#define ADC_HPF_ENUM 8
221 238
222static const struct soc_enum aic3x_enum[] = { 239static const struct soc_enum aic3x_enum[] = {
223 SOC_ENUM_SINGLE(DAC_LINE_MUX, 6, 3, aic3x_left_dac_mux), 240 SOC_ENUM_SINGLE(DAC_LINE_MUX, 6, 3, aic3x_left_dac_mux),
@@ -228,6 +245,7 @@ static const struct soc_enum aic3x_enum[] = {
228 SOC_ENUM_SINGLE(LINE1R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux), 245 SOC_ENUM_SINGLE(LINE1R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux),
229 SOC_ENUM_SINGLE(LINE2L_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux), 246 SOC_ENUM_SINGLE(LINE2L_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux),
230 SOC_ENUM_SINGLE(LINE2R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux), 247 SOC_ENUM_SINGLE(LINE2R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux),
248 SOC_ENUM_DOUBLE(AIC3X_CODEC_DFILT_CTRL, 6, 4, 4, aic3x_adc_hpf),
231}; 249};
232 250
233static const struct snd_kcontrol_new aic3x_snd_controls[] = { 251static const struct snd_kcontrol_new aic3x_snd_controls[] = {
@@ -278,6 +296,8 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
278 /* Input */ 296 /* Input */
279 SOC_DOUBLE_R("PGA Capture Volume", LADC_VOL, RADC_VOL, 0, 0x7f, 0), 297 SOC_DOUBLE_R("PGA Capture Volume", LADC_VOL, RADC_VOL, 0, 0x7f, 0),
280 SOC_DOUBLE_R("PGA Capture Switch", LADC_VOL, RADC_VOL, 7, 0x01, 1), 298 SOC_DOUBLE_R("PGA Capture Switch", LADC_VOL, RADC_VOL, 7, 0x01, 1),
299
300 SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]),
281}; 301};
282 302
283/* add non dapm controls */ 303/* add non dapm controls */
@@ -441,11 +461,34 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
441 SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0, 461 SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0,
442 &aic3x_right_line2_mux_controls), 462 &aic3x_right_line2_mux_controls),
443 463
464 /*
465 * Not a real mic bias widget but similar function. This is for dynamic
466 * control of GPIO1 digital mic modulator clock output function when
467 * using digital mic.
468 */
469 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "GPIO1 dmic modclk",
470 AIC3X_GPIO1_REG, 4, 0xf,
471 AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK,
472 AIC3X_GPIO1_FUNC_DISABLED),
473
474 /*
475 * Also similar function like mic bias. Selects digital mic with
476 * configurable oversampling rate instead of ADC converter.
477 */
478 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "DMic Rate 128",
479 AIC3X_ASD_INTF_CTRLA, 0, 3, 1, 0),
480 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "DMic Rate 64",
481 AIC3X_ASD_INTF_CTRLA, 0, 3, 2, 0),
482 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "DMic Rate 32",
483 AIC3X_ASD_INTF_CTRLA, 0, 3, 3, 0),
484
444 /* Mic Bias */ 485 /* Mic Bias */
445 SND_SOC_DAPM_MICBIAS("Mic Bias 2V", MICBIAS_CTRL, 6, 0), 486 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2V",
446 SND_SOC_DAPM_MICBIAS("Mic Bias 2.5V", MICBIAS_CTRL, 7, 0), 487 MICBIAS_CTRL, 6, 3, 1, 0),
447 SND_SOC_DAPM_MICBIAS("Mic Bias AVDD", MICBIAS_CTRL, 6, 0), 488 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2.5V",
448 SND_SOC_DAPM_MICBIAS("Mic Bias AVDD", MICBIAS_CTRL, 7, 0), 489 MICBIAS_CTRL, 6, 3, 2, 0),
490 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias AVDD",
491 MICBIAS_CTRL, 6, 3, 3, 0),
449 492
450 /* Left PGA to Left Output bypass */ 493 /* Left PGA to Left Output bypass */
451 SND_SOC_DAPM_MIXER("Left PGA Bypass Mixer", SND_SOC_NOPM, 0, 0, 494 SND_SOC_DAPM_MIXER("Left PGA Bypass Mixer", SND_SOC_NOPM, 0, 0,
@@ -483,7 +526,7 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
483 SND_SOC_DAPM_INPUT("LINE2R"), 526 SND_SOC_DAPM_INPUT("LINE2R"),
484}; 527};
485 528
486static const char *intercon[][3] = { 529static const struct snd_soc_dapm_route intercon[] = {
487 /* Left Output */ 530 /* Left Output */
488 {"Left DAC Mux", "DAC_L1", "Left DAC"}, 531 {"Left DAC Mux", "DAC_L1", "Left DAC"},
489 {"Left DAC Mux", "DAC_L2", "Left DAC"}, 532 {"Left DAC Mux", "DAC_L2", "Left DAC"},
@@ -554,6 +597,7 @@ static const char *intercon[][3] = {
554 {"Left PGA Mixer", "Mic3L Switch", "MIC3L"}, 597 {"Left PGA Mixer", "Mic3L Switch", "MIC3L"},
555 598
556 {"Left ADC", NULL, "Left PGA Mixer"}, 599 {"Left ADC", NULL, "Left PGA Mixer"},
600 {"Left ADC", NULL, "GPIO1 dmic modclk"},
557 601
558 /* Right Input */ 602 /* Right Input */
559 {"Right Line1R Mux", "single-ended", "LINE1R"}, 603 {"Right Line1R Mux", "single-ended", "LINE1R"},
@@ -567,6 +611,7 @@ static const char *intercon[][3] = {
567 {"Right PGA Mixer", "Mic3R Switch", "MIC3R"}, 611 {"Right PGA Mixer", "Mic3R Switch", "MIC3R"},
568 612
569 {"Right ADC", NULL, "Right PGA Mixer"}, 613 {"Right ADC", NULL, "Right PGA Mixer"},
614 {"Right ADC", NULL, "GPIO1 dmic modclk"},
570 615
571 /* Left PGA Bypass */ 616 /* Left PGA Bypass */
572 {"Left PGA Bypass Mixer", "Line Switch", "Left PGA Mixer"}, 617 {"Left PGA Bypass Mixer", "Line Switch", "Left PGA Mixer"},
@@ -628,101 +673,27 @@ static const char *intercon[][3] = {
628 {"Mono Out", NULL, "Right Line2 Bypass Mixer"}, 673 {"Mono Out", NULL, "Right Line2 Bypass Mixer"},
629 {"Right HP Out", NULL, "Right Line2 Bypass Mixer"}, 674 {"Right HP Out", NULL, "Right Line2 Bypass Mixer"},
630 675
631 /* terminator */ 676 /*
632 {NULL, NULL, NULL}, 677 * Logical path between digital mic enable and GPIO1 modulator clock
678 * output function
679 */
680 {"GPIO1 dmic modclk", NULL, "DMic Rate 128"},
681 {"GPIO1 dmic modclk", NULL, "DMic Rate 64"},
682 {"GPIO1 dmic modclk", NULL, "DMic Rate 32"},
633}; 683};
634 684
635static int aic3x_add_widgets(struct snd_soc_codec *codec) 685static int aic3x_add_widgets(struct snd_soc_codec *codec)
636{ 686{
637 int i; 687 snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets,
638 688 ARRAY_SIZE(aic3x_dapm_widgets));
639 for (i = 0; i < ARRAY_SIZE(aic3x_dapm_widgets); i++)
640 snd_soc_dapm_new_control(codec, &aic3x_dapm_widgets[i]);
641 689
642 /* set up audio path interconnects */ 690 /* set up audio path interconnects */
643 for (i = 0; intercon[i][0] != NULL; i++) 691 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
644 snd_soc_dapm_connect_input(codec, intercon[i][0],
645 intercon[i][1], intercon[i][2]);
646 692
647 snd_soc_dapm_new_widgets(codec); 693 snd_soc_dapm_new_widgets(codec);
648 return 0; 694 return 0;
649} 695}
650 696
651struct aic3x_rate_divs {
652 u32 mclk;
653 u32 rate;
654 u32 fsref_reg;
655 u8 sr_reg:4;
656 u8 pllj_reg;
657 u16 plld_reg;
658};
659
660/* AIC3X codec mclk clock divider coefficients */
661static const struct aic3x_rate_divs aic3x_divs[] = {
662 /* 8k */
663 {12000000, 8000, 48000, 0xa, 16, 3840},
664 {19200000, 8000, 48000, 0xa, 10, 2400},
665 {22579200, 8000, 48000, 0xa, 8, 7075},
666 {33868800, 8000, 48000, 0xa, 5, 8049},
667 /* 11.025k */
668 {12000000, 11025, 44100, 0x6, 15, 528},
669 {19200000, 11025, 44100, 0x6, 9, 4080},
670 {22579200, 11025, 44100, 0x6, 8, 0},
671 {33868800, 11025, 44100, 0x6, 5, 3333},
672 /* 16k */
673 {12000000, 16000, 48000, 0x4, 16, 3840},
674 {19200000, 16000, 48000, 0x4, 10, 2400},
675 {22579200, 16000, 48000, 0x4, 8, 7075},
676 {33868800, 16000, 48000, 0x4, 5, 8049},
677 /* 22.05k */
678 {12000000, 22050, 44100, 0x2, 15, 528},
679 {19200000, 22050, 44100, 0x2, 9, 4080},
680 {22579200, 22050, 44100, 0x2, 8, 0},
681 {33868800, 22050, 44100, 0x2, 5, 3333},
682 /* 32k */
683 {12000000, 32000, 48000, 0x1, 16, 3840},
684 {19200000, 32000, 48000, 0x1, 10, 2400},
685 {22579200, 32000, 48000, 0x1, 8, 7075},
686 {33868800, 32000, 48000, 0x1, 5, 8049},
687 /* 44.1k */
688 {12000000, 44100, 44100, 0x0, 15, 528},
689 {19200000, 44100, 44100, 0x0, 9, 4080},
690 {22579200, 44100, 44100, 0x0, 8, 0},
691 {33868800, 44100, 44100, 0x0, 5, 3333},
692 /* 48k */
693 {12000000, 48000, 48000, 0x0, 16, 3840},
694 {19200000, 48000, 48000, 0x0, 10, 2400},
695 {22579200, 48000, 48000, 0x0, 8, 7075},
696 {33868800, 48000, 48000, 0x0, 5, 8049},
697 /* 64k */
698 {12000000, 64000, 96000, 0x1, 16, 3840},
699 {19200000, 64000, 96000, 0x1, 10, 2400},
700 {22579200, 64000, 96000, 0x1, 8, 7075},
701 {33868800, 64000, 96000, 0x1, 5, 8049},
702 /* 88.2k */
703 {12000000, 88200, 88200, 0x0, 15, 528},
704 {19200000, 88200, 88200, 0x0, 9, 4080},
705 {22579200, 88200, 88200, 0x0, 8, 0},
706 {33868800, 88200, 88200, 0x0, 5, 3333},
707 /* 96k */
708 {12000000, 96000, 96000, 0x0, 16, 3840},
709 {19200000, 96000, 96000, 0x0, 10, 2400},
710 {22579200, 96000, 96000, 0x0, 8, 7075},
711 {33868800, 96000, 96000, 0x0, 5, 8049},
712};
713
714static inline int aic3x_get_divs(int mclk, int rate)
715{
716 int i;
717
718 for (i = 0; i < ARRAY_SIZE(aic3x_divs); i++) {
719 if (aic3x_divs[i].rate == rate && aic3x_divs[i].mclk == mclk)
720 return i;
721 }
722
723 return 0;
724}
725
726static int aic3x_hw_params(struct snd_pcm_substream *substream, 697static int aic3x_hw_params(struct snd_pcm_substream *substream,
727 struct snd_pcm_hw_params *params) 698 struct snd_pcm_hw_params *params)
728{ 699{
@@ -730,49 +701,107 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
730 struct snd_soc_device *socdev = rtd->socdev; 701 struct snd_soc_device *socdev = rtd->socdev;
731 struct snd_soc_codec *codec = socdev->codec; 702 struct snd_soc_codec *codec = socdev->codec;
732 struct aic3x_priv *aic3x = codec->private_data; 703 struct aic3x_priv *aic3x = codec->private_data;
733 int i; 704 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
734 u8 data, pll_p, pll_r, pll_j; 705 u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
735 u16 pll_d; 706 u16 pll_d = 1;
736
737 i = aic3x_get_divs(aic3x->sysclk, params_rate(params));
738 707
739 /* Route Left DAC to left channel input and 708 /* select data word length */
740 * right DAC to right channel input */ 709 data =
741 data = (LDAC2LCH | RDAC2RCH); 710 aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
742 switch (aic3x_divs[i].fsref_reg) { 711 switch (params_format(params)) {
743 case 44100: 712 case SNDRV_PCM_FORMAT_S16_LE:
744 data |= FSREF_44100;
745 break; 713 break;
746 case 48000: 714 case SNDRV_PCM_FORMAT_S20_3LE:
747 data |= FSREF_48000; 715 data |= (0x01 << 4);
748 break; 716 break;
749 case 88200: 717 case SNDRV_PCM_FORMAT_S24_LE:
750 data |= FSREF_44100 | DUAL_RATE_MODE; 718 data |= (0x02 << 4);
751 break; 719 break;
752 case 96000: 720 case SNDRV_PCM_FORMAT_S32_LE:
753 data |= FSREF_48000 | DUAL_RATE_MODE; 721 data |= (0x03 << 4);
754 break; 722 break;
755 } 723 }
724 aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, data);
725
726 /* Fsref can be 44100 or 48000 */
727 fsref = (params_rate(params) % 11025 == 0) ? 44100 : 48000;
728
729 /* Try to find a value for Q which allows us to bypass the PLL and
730 * generate CODEC_CLK directly. */
731 for (pll_q = 2; pll_q < 18; pll_q++)
732 if (aic3x->sysclk / (128 * pll_q) == fsref) {
733 bypass_pll = 1;
734 break;
735 }
736
737 if (bypass_pll) {
738 pll_q &= 0xf;
739 aic3x_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
740 aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
741 } else
742 aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
743
744 /* Route Left DAC to left channel input and
745 * right DAC to right channel input */
746 data = (LDAC2LCH | RDAC2RCH);
747 data |= (fsref == 44100) ? FSREF_44100 : FSREF_48000;
748 if (params_rate(params) >= 64000)
749 data |= DUAL_RATE_MODE;
756 aic3x_write(codec, AIC3X_CODEC_DATAPATH_REG, data); 750 aic3x_write(codec, AIC3X_CODEC_DATAPATH_REG, data);
757 751
758 /* codec sample rate select */ 752 /* codec sample rate select */
759 data = aic3x_divs[i].sr_reg; 753 data = (fsref * 20) / params_rate(params);
754 if (params_rate(params) < 64000)
755 data /= 2;
756 data /= 5;
757 data -= 2;
760 data |= (data << 4); 758 data |= (data << 4);
761 aic3x_write(codec, AIC3X_SAMPLE_RATE_SEL_REG, data); 759 aic3x_write(codec, AIC3X_SAMPLE_RATE_SEL_REG, data);
762 760
763 /* Use PLL for generation Fsref by equation: 761 if (bypass_pll)
764 * Fsref = (MCLK * K * R)/(2048 * P); 762 return 0;
765 * Fix P = 2 and R = 1 and calculate K, if 763
766 * K = J.D, i.e. J - an interger portion of K and D is the fractional 764 /* Use PLL
767 * one with 4 digits of precision; 765 * find an apropriate setup for j, d, r and p by iterating over
768 * Example: 766 * p and r - j and d are calculated for each fraction.
769 * For MCLK = 22.5792 MHz and Fsref = 48kHz: 767 * Up to 128 values are probed, the closest one wins the game.
770 * Select P = 2, R= 1, K = 8.7074, which results in J = 8, D = 7074 768 * The sysclk is divided by 1000 to prevent integer overflows.
771 */ 769 */
772 pll_p = 2; 770 codec_clk = (2048 * fsref) / (aic3x->sysclk / 1000);
773 pll_r = 1; 771
774 pll_j = aic3x_divs[i].pllj_reg; 772 for (r = 1; r <= 16; r++)
775 pll_d = aic3x_divs[i].plld_reg; 773 for (p = 1; p <= 8; p++) {
774 int clk, tmp = (codec_clk * pll_r * 10) / pll_p;
775 u8 j = tmp / 10000;
776 u16 d = tmp % 10000;
777
778 if (j > 63)
779 continue;
780
781 if (d != 0 && aic3x->sysclk < 10000000)
782 continue;
783
784 /* This is actually 1000 * ((j + (d/10000)) * r) / p
785 * The term had to be converted to get rid of the
786 * division by 10000 */
787 clk = ((10000 * j * r) + (d * r)) / (10 * p);
788
789 /* check whether this values get closer than the best
790 * ones we had before */
791 if (abs(codec_clk - clk) < abs(codec_clk - last_clk)) {
792 pll_j = j; pll_d = d; pll_r = r; pll_p = p;
793 last_clk = clk;
794 }
795
796 /* Early exit for exact matches */
797 if (clk == codec_clk)
798 break;
799 }
800
801 if (last_clk == 0) {
802 printk(KERN_ERR "%s(): unable to setup PLL\n", __func__);
803 return -EINVAL;
804 }
776 805
777 data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 806 data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
778 aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT)); 807 aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT));
@@ -782,28 +811,10 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
782 aic3x_write(codec, AIC3X_PLL_PROGD_REG, 811 aic3x_write(codec, AIC3X_PLL_PROGD_REG,
783 (pll_d & 0x3F) << PLLD_LSB_SHIFT); 812 (pll_d & 0x3F) << PLLD_LSB_SHIFT);
784 813
785 /* select data word length */
786 data =
787 aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
788 switch (params_format(params)) {
789 case SNDRV_PCM_FORMAT_S16_LE:
790 break;
791 case SNDRV_PCM_FORMAT_S20_3LE:
792 data |= (0x01 << 4);
793 break;
794 case SNDRV_PCM_FORMAT_S24_LE:
795 data |= (0x02 << 4);
796 break;
797 case SNDRV_PCM_FORMAT_S32_LE:
798 data |= (0x03 << 4);
799 break;
800 }
801 aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, data);
802
803 return 0; 814 return 0;
804} 815}
805 816
806static int aic3x_mute(struct snd_soc_codec_dai *dai, int mute) 817static int aic3x_mute(struct snd_soc_dai *dai, int mute)
807{ 818{
808 struct snd_soc_codec *codec = dai->codec; 819 struct snd_soc_codec *codec = dai->codec;
809 u8 ldac_reg = aic3x_read_reg_cache(codec, LDAC_VOL) & ~MUTE_ON; 820 u8 ldac_reg = aic3x_read_reg_cache(codec, LDAC_VOL) & ~MUTE_ON;
@@ -820,31 +831,25 @@ static int aic3x_mute(struct snd_soc_codec_dai *dai, int mute)
820 return 0; 831 return 0;
821} 832}
822 833
823static int aic3x_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, 834static int aic3x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
824 int clk_id, unsigned int freq, int dir) 835 int clk_id, unsigned int freq, int dir)
825{ 836{
826 struct snd_soc_codec *codec = codec_dai->codec; 837 struct snd_soc_codec *codec = codec_dai->codec;
827 struct aic3x_priv *aic3x = codec->private_data; 838 struct aic3x_priv *aic3x = codec->private_data;
828 839
829 switch (freq) { 840 aic3x->sysclk = freq;
830 case 12000000: 841 return 0;
831 case 19200000:
832 case 22579200:
833 case 33868800:
834 aic3x->sysclk = freq;
835 return 0;
836 }
837
838 return -EINVAL;
839} 842}
840 843
841static int aic3x_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, 844static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
842 unsigned int fmt) 845 unsigned int fmt)
843{ 846{
844 struct snd_soc_codec *codec = codec_dai->codec; 847 struct snd_soc_codec *codec = codec_dai->codec;
845 struct aic3x_priv *aic3x = codec->private_data; 848 struct aic3x_priv *aic3x = codec->private_data;
846 u8 iface_areg = 0; 849 u8 iface_areg, iface_breg;
847 u8 iface_breg = 0; 850
851 iface_areg = aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLA) & 0x3f;
852 iface_breg = aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & 0x3f;
848 853
849 /* set master/slave audio interface */ 854 /* set master/slave audio interface */
850 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 855 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -883,13 +888,14 @@ static int aic3x_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
883 return 0; 888 return 0;
884} 889}
885 890
886static int aic3x_dapm_event(struct snd_soc_codec *codec, int event) 891static int aic3x_set_bias_level(struct snd_soc_codec *codec,
892 enum snd_soc_bias_level level)
887{ 893{
888 struct aic3x_priv *aic3x = codec->private_data; 894 struct aic3x_priv *aic3x = codec->private_data;
889 u8 reg; 895 u8 reg;
890 896
891 switch (event) { 897 switch (level) {
892 case SNDRV_CTL_POWER_D0: 898 case SND_SOC_BIAS_ON:
893 /* all power is driven by DAPM system */ 899 /* all power is driven by DAPM system */
894 if (aic3x->master) { 900 if (aic3x->master) {
895 /* enable pll */ 901 /* enable pll */
@@ -898,10 +904,9 @@ static int aic3x_dapm_event(struct snd_soc_codec *codec, int event)
898 reg | PLL_ENABLE); 904 reg | PLL_ENABLE);
899 } 905 }
900 break; 906 break;
901 case SNDRV_CTL_POWER_D1: 907 case SND_SOC_BIAS_PREPARE:
902 case SNDRV_CTL_POWER_D2:
903 break; 908 break;
904 case SNDRV_CTL_POWER_D3hot: 909 case SND_SOC_BIAS_STANDBY:
905 /* 910 /*
906 * all power is driven by DAPM system, 911 * all power is driven by DAPM system,
907 * so output power is safe if bypass was set 912 * so output power is safe if bypass was set
@@ -913,7 +918,7 @@ static int aic3x_dapm_event(struct snd_soc_codec *codec, int event)
913 reg & ~PLL_ENABLE); 918 reg & ~PLL_ENABLE);
914 } 919 }
915 break; 920 break;
916 case SNDRV_CTL_POWER_D3cold: 921 case SND_SOC_BIAS_OFF:
917 /* force all power off */ 922 /* force all power off */
918 reg = aic3x_read_reg_cache(codec, LINE1L_2_LADC_CTRL); 923 reg = aic3x_read_reg_cache(codec, LINE1L_2_LADC_CTRL);
919 aic3x_write(codec, LINE1L_2_LADC_CTRL, reg & ~LADC_PWR_ON); 924 aic3x_write(codec, LINE1L_2_LADC_CTRL, reg & ~LADC_PWR_ON);
@@ -949,16 +954,43 @@ static int aic3x_dapm_event(struct snd_soc_codec *codec, int event)
949 } 954 }
950 break; 955 break;
951 } 956 }
952 codec->dapm_state = event; 957 codec->bias_level = level;
953 958
954 return 0; 959 return 0;
955} 960}
956 961
962void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state)
963{
964 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
965 u8 bit = gpio ? 3: 0;
966 u8 val = aic3x_read_reg_cache(codec, reg) & ~(1 << bit);
967 aic3x_write(codec, reg, val | (!!state << bit));
968}
969EXPORT_SYMBOL_GPL(aic3x_set_gpio);
970
971int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio)
972{
973 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
974 u8 val, bit = gpio ? 2: 1;
975
976 aic3x_read(codec, reg, &val);
977 return (val >> bit) & 1;
978}
979EXPORT_SYMBOL_GPL(aic3x_get_gpio);
980
981int aic3x_headset_detected(struct snd_soc_codec *codec)
982{
983 u8 val;
984 aic3x_read(codec, AIC3X_RT_IRQ_FLAGS_REG, &val);
985 return (val >> 2) & 1;
986}
987EXPORT_SYMBOL_GPL(aic3x_headset_detected);
988
957#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000 989#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000
958#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 990#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
959 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 991 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
960 992
961struct snd_soc_codec_dai aic3x_dai = { 993struct snd_soc_dai aic3x_dai = {
962 .name = "aic3x", 994 .name = "aic3x",
963 .playback = { 995 .playback = {
964 .stream_name = "Playback", 996 .stream_name = "Playback",
@@ -988,7 +1020,7 @@ static int aic3x_suspend(struct platform_device *pdev, pm_message_t state)
988 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1020 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
989 struct snd_soc_codec *codec = socdev->codec; 1021 struct snd_soc_codec *codec = socdev->codec;
990 1022
991 aic3x_dapm_event(codec, SNDRV_CTL_POWER_D3cold); 1023 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
992 1024
993 return 0; 1025 return 0;
994} 1026}
@@ -1008,7 +1040,7 @@ static int aic3x_resume(struct platform_device *pdev)
1008 codec->hw_write(codec->control_data, data, 2); 1040 codec->hw_write(codec->control_data, data, 2);
1009 } 1041 }
1010 1042
1011 aic3x_dapm_event(codec, codec->suspend_dapm_state); 1043 aic3x_set_bias_level(codec, codec->suspend_bias_level);
1012 1044
1013 return 0; 1045 return 0;
1014} 1046}
@@ -1020,16 +1052,17 @@ static int aic3x_resume(struct platform_device *pdev)
1020static int aic3x_init(struct snd_soc_device *socdev) 1052static int aic3x_init(struct snd_soc_device *socdev)
1021{ 1053{
1022 struct snd_soc_codec *codec = socdev->codec; 1054 struct snd_soc_codec *codec = socdev->codec;
1055 struct aic3x_setup_data *setup = socdev->codec_data;
1023 int reg, ret = 0; 1056 int reg, ret = 0;
1024 1057
1025 codec->name = "aic3x"; 1058 codec->name = "aic3x";
1026 codec->owner = THIS_MODULE; 1059 codec->owner = THIS_MODULE;
1027 codec->read = aic3x_read_reg_cache; 1060 codec->read = aic3x_read_reg_cache;
1028 codec->write = aic3x_write; 1061 codec->write = aic3x_write;
1029 codec->dapm_event = aic3x_dapm_event; 1062 codec->set_bias_level = aic3x_set_bias_level;
1030 codec->dai = &aic3x_dai; 1063 codec->dai = &aic3x_dai;
1031 codec->num_dai = 1; 1064 codec->num_dai = 1;
1032 codec->reg_cache_size = sizeof(aic3x_reg); 1065 codec->reg_cache_size = ARRAY_SIZE(aic3x_reg);
1033 codec->reg_cache = kmemdup(aic3x_reg, sizeof(aic3x_reg), GFP_KERNEL); 1066 codec->reg_cache = kmemdup(aic3x_reg, sizeof(aic3x_reg), GFP_KERNEL);
1034 if (codec->reg_cache == NULL) 1067 if (codec->reg_cache == NULL)
1035 return -ENOMEM; 1068 return -ENOMEM;
@@ -1108,7 +1141,11 @@ static int aic3x_init(struct snd_soc_device *socdev)
1108 aic3x_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL); 1141 aic3x_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL);
1109 1142
1110 /* off, with power on */ 1143 /* off, with power on */
1111 aic3x_dapm_event(codec, SNDRV_CTL_POWER_D3hot); 1144 aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1145
1146 /* setup GPIO functions */
1147 aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4);
1148 aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4);
1112 1149
1113 aic3x_add_controls(codec); 1150 aic3x_add_controls(codec);
1114 aic3x_add_widgets(codec); 1151 aic3x_add_widgets(codec);
@@ -1217,6 +1254,12 @@ static struct i2c_client client_template = {
1217 .name = "AIC3X", 1254 .name = "AIC3X",
1218 .driver = &aic3x_i2c_driver, 1255 .driver = &aic3x_i2c_driver,
1219}; 1256};
1257
1258static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len)
1259{
1260 value[0] = i2c_smbus_read_byte_data(client, value[0]);
1261 return (len == 1);
1262}
1220#endif 1263#endif
1221 1264
1222static int aic3x_probe(struct platform_device *pdev) 1265static int aic3x_probe(struct platform_device *pdev)
@@ -1251,6 +1294,7 @@ static int aic3x_probe(struct platform_device *pdev)
1251 if (setup->i2c_address) { 1294 if (setup->i2c_address) {
1252 normal_i2c[0] = setup->i2c_address; 1295 normal_i2c[0] = setup->i2c_address;
1253 codec->hw_write = (hw_write_t) i2c_master_send; 1296 codec->hw_write = (hw_write_t) i2c_master_send;
1297 codec->hw_read = (hw_read_t) aic3x_i2c_read;
1254 ret = i2c_add_driver(&aic3x_i2c_driver); 1298 ret = i2c_add_driver(&aic3x_i2c_driver);
1255 if (ret != 0) 1299 if (ret != 0)
1256 printk(KERN_ERR "can't add i2c driver"); 1300 printk(KERN_ERR "can't add i2c driver");
@@ -1268,7 +1312,7 @@ static int aic3x_remove(struct platform_device *pdev)
1268 1312
1269 /* power down chip */ 1313 /* power down chip */
1270 if (codec->control_data) 1314 if (codec->control_data)
1271 aic3x_dapm_event(codec, SNDRV_CTL_POWER_D3); 1315 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1272 1316
1273 snd_soc_free_pcms(socdev); 1317 snd_soc_free_pcms(socdev);
1274 snd_soc_dapm_free(socdev); 1318 snd_soc_dapm_free(socdev);
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index d0cdeeb629de..d76c079b86e7 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -37,6 +37,8 @@
37#define AIC3X_ASD_INTF_CTRLB 9 37#define AIC3X_ASD_INTF_CTRLB 9
38/* Audio overflow status and PLL R value programming register */ 38/* Audio overflow status and PLL R value programming register */
39#define AIC3X_OVRF_STATUS_AND_PLLR_REG 11 39#define AIC3X_OVRF_STATUS_AND_PLLR_REG 11
40/* Audio codec digital filter control register */
41#define AIC3X_CODEC_DFILT_CTRL 12
40 42
41/* ADC PGA Gain control registers */ 43/* ADC PGA Gain control registers */
42#define LADC_VOL 15 44#define LADC_VOL 15
@@ -108,6 +110,13 @@
108#define DACR1_2_RLOPM_VOL 92 110#define DACR1_2_RLOPM_VOL 92
109#define LLOPM_CTRL 86 111#define LLOPM_CTRL 86
110#define RLOPM_CTRL 93 112#define RLOPM_CTRL 93
113/* GPIO/IRQ registers */
114#define AIC3X_STICKY_IRQ_FLAGS_REG 96
115#define AIC3X_RT_IRQ_FLAGS_REG 97
116#define AIC3X_GPIO1_REG 98
117#define AIC3X_GPIO2_REG 99
118#define AIC3X_GPIOA_REG 100
119#define AIC3X_GPIOB_REG 101
111/* Clock generation control register */ 120/* Clock generation control register */
112#define AIC3X_CLKGEN_CTRL_REG 102 121#define AIC3X_CLKGEN_CTRL_REG 102
113 122
@@ -128,12 +137,15 @@
128 137
129/* PLL registers bitfields */ 138/* PLL registers bitfields */
130#define PLLP_SHIFT 0 139#define PLLP_SHIFT 0
140#define PLLQ_SHIFT 3
131#define PLLR_SHIFT 0 141#define PLLR_SHIFT 0
132#define PLLJ_SHIFT 2 142#define PLLJ_SHIFT 2
133#define PLLD_MSB_SHIFT 0 143#define PLLD_MSB_SHIFT 0
134#define PLLD_LSB_SHIFT 2 144#define PLLD_LSB_SHIFT 2
135 145
136/* Clock generation register bits */ 146/* Clock generation register bits */
147#define CODEC_CLKIN_PLLDIV 0
148#define CODEC_CLKIN_CLKDIV 1
137#define PLL_CLKIN_SHIFT 4 149#define PLL_CLKIN_SHIFT 4
138#define MCLK_SOURCE 0x0 150#define MCLK_SOURCE 0x0
139#define PLL_CLKDIV_SHIFT 0 151#define PLL_CLKDIV_SHIFT 0
@@ -171,11 +183,52 @@
171/* Default input volume */ 183/* Default input volume */
172#define DEFAULT_GAIN 0x20 184#define DEFAULT_GAIN 0x20
173 185
186/* GPIO API */
187enum {
188 AIC3X_GPIO1_FUNC_DISABLED = 0,
189 AIC3X_GPIO1_FUNC_AUDIO_WORDCLK_ADC = 1,
190 AIC3X_GPIO1_FUNC_CLOCK_MUX = 2,
191 AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV2 = 3,
192 AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV4 = 4,
193 AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV8 = 5,
194 AIC3X_GPIO1_FUNC_SHORT_CIRCUIT_IRQ = 6,
195 AIC3X_GPIO1_FUNC_AGC_NOISE_IRQ = 7,
196 AIC3X_GPIO1_FUNC_INPUT = 8,
197 AIC3X_GPIO1_FUNC_OUTPUT = 9,
198 AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK = 10,
199 AIC3X_GPIO1_FUNC_AUDIO_WORDCLK = 11,
200 AIC3X_GPIO1_FUNC_BUTTON_IRQ = 12,
201 AIC3X_GPIO1_FUNC_HEADSET_DETECT_IRQ = 13,
202 AIC3X_GPIO1_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 14,
203 AIC3X_GPIO1_FUNC_ALL_IRQ = 16
204};
205
206enum {
207 AIC3X_GPIO2_FUNC_DISABLED = 0,
208 AIC3X_GPIO2_FUNC_HEADSET_DETECT_IRQ = 2,
209 AIC3X_GPIO2_FUNC_INPUT = 3,
210 AIC3X_GPIO2_FUNC_OUTPUT = 4,
211 AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT = 5,
212 AIC3X_GPIO2_FUNC_AUDIO_BITCLK = 8,
213 AIC3X_GPIO2_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 9,
214 AIC3X_GPIO2_FUNC_ALL_IRQ = 10,
215 AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_OR_AGC_IRQ = 11,
216 AIC3X_GPIO2_FUNC_HEADSET_OR_BUTTON_PRESS_OR_SHORT_CIRCUIT_IRQ = 12,
217 AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_IRQ = 13,
218 AIC3X_GPIO2_FUNC_AGC_NOISE_IRQ = 14,
219 AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15
220};
221
222void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state);
223int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
224int aic3x_headset_detected(struct snd_soc_codec *codec);
225
174struct aic3x_setup_data { 226struct aic3x_setup_data {
175 unsigned short i2c_address; 227 unsigned short i2c_address;
228 unsigned int gpio_func[2];
176}; 229};
177 230
178extern struct snd_soc_codec_dai aic3x_dai; 231extern struct snd_soc_dai aic3x_dai;
179extern struct snd_soc_codec_device soc_codec_dev_aic3x; 232extern struct snd_soc_codec_device soc_codec_dev_aic3x;
180 233
181#endif /* _AIC3X_H */ 234#endif /* _AIC3X_H */
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
new file mode 100644
index 000000000000..a52d6d9e007a
--- /dev/null
+++ b/sound/soc/codecs/uda1380.c
@@ -0,0 +1,852 @@
1/*
2 * uda1380.c - Philips UDA1380 ALSA SoC audio driver
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Copyright (c) 2007 Philipp Zabel <philipp.zabel@gmail.com>
9 * Improved support for DAPM and audio routing/mixing capabilities,
10 * added TLV support.
11 *
12 * Modified by Richard Purdie <richard@openedhand.com> to fit into SoC
13 * codec model.
14 *
15 * Copyright (c) 2005 Giorgio Padrin <giorgio@mandarinlogiq.org>
16 * Copyright 2005 Openedhand Ltd.
17 */
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/types.h>
22#include <linux/string.h>
23#include <linux/slab.h>
24#include <linux/errno.h>
25#include <linux/ioctl.h>
26#include <linux/delay.h>
27#include <linux/i2c.h>
28#include <sound/core.h>
29#include <sound/control.h>
30#include <sound/initval.h>
31#include <sound/info.h>
32#include <sound/soc.h>
33#include <sound/soc-dapm.h>
34#include <sound/tlv.h>
35
36#include "uda1380.h"
37
38#define UDA1380_VERSION "0.6"
39#define AUDIO_NAME "uda1380"
40
41/*
42 * uda1380 register cache
43 */
44static const u16 uda1380_reg[UDA1380_CACHEREGNUM] = {
45 0x0502, 0x0000, 0x0000, 0x3f3f,
46 0x0202, 0x0000, 0x0000, 0x0000,
47 0x0000, 0x0000, 0x0000, 0x0000,
48 0x0000, 0x0000, 0x0000, 0x0000,
49 0x0000, 0xff00, 0x0000, 0x4800,
50 0x0000, 0x0000, 0x0000, 0x0000,
51 0x0000, 0x0000, 0x0000, 0x0000,
52 0x0000, 0x0000, 0x0000, 0x0000,
53 0x0000, 0x8000, 0x0002, 0x0000,
54};
55
56/*
57 * read uda1380 register cache
58 */
59static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec,
60 unsigned int reg)
61{
62 u16 *cache = codec->reg_cache;
63 if (reg == UDA1380_RESET)
64 return 0;
65 if (reg >= UDA1380_CACHEREGNUM)
66 return -1;
67 return cache[reg];
68}
69
70/*
71 * write uda1380 register cache
72 */
73static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec,
74 u16 reg, unsigned int value)
75{
76 u16 *cache = codec->reg_cache;
77 if (reg >= UDA1380_CACHEREGNUM)
78 return;
79 cache[reg] = value;
80}
81
82/*
83 * write to the UDA1380 register space
84 */
85static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
86 unsigned int value)
87{
88 u8 data[3];
89
90 /* data is
91 * data[0] is register offset
92 * data[1] is MS byte
93 * data[2] is LS byte
94 */
95 data[0] = reg;
96 data[1] = (value & 0xff00) >> 8;
97 data[2] = value & 0x00ff;
98
99 uda1380_write_reg_cache(codec, reg, value);
100
101 /* the interpolator & decimator regs must only be written when the
102 * codec DAI is active.
103 */
104 if (!codec->active && (reg >= UDA1380_MVOL))
105 return 0;
106 pr_debug("uda1380: hw write %x val %x\n", reg, value);
107 if (codec->hw_write(codec->control_data, data, 3) == 3) {
108 unsigned int val;
109 i2c_master_send(codec->control_data, data, 1);
110 i2c_master_recv(codec->control_data, data, 2);
111 val = (data[0]<<8) | data[1];
112 if (val != value) {
113 pr_debug("uda1380: READ BACK VAL %x\n",
114 (data[0]<<8) | data[1]);
115 return -EIO;
116 }
117 return 0;
118 } else
119 return -EIO;
120}
121
122#define uda1380_reset(c) uda1380_write(c, UDA1380_RESET, 0)
123
124/* declarations of ALSA reg_elem_REAL controls */
125static const char *uda1380_deemp[] = {
126 "None",
127 "32kHz",
128 "44.1kHz",
129 "48kHz",
130 "96kHz",
131};
132static const char *uda1380_input_sel[] = {
133 "Line",
134 "Mic + Line R",
135 "Line L",
136 "Mic",
137};
138static const char *uda1380_output_sel[] = {
139 "DAC",
140 "Analog Mixer",
141};
142static const char *uda1380_spf_mode[] = {
143 "Flat",
144 "Minimum1",
145 "Minimum2",
146 "Maximum"
147};
148static const char *uda1380_capture_sel[] = {
149 "ADC",
150 "Digital Mixer"
151};
152static const char *uda1380_sel_ns[] = {
153 "3rd-order",
154 "5th-order"
155};
156static const char *uda1380_mix_control[] = {
157 "off",
158 "PCM only",
159 "before sound processing",
160 "after sound processing"
161};
162static const char *uda1380_sdet_setting[] = {
163 "3200",
164 "4800",
165 "9600",
166 "19200"
167};
168static const char *uda1380_os_setting[] = {
169 "single-speed",
170 "double-speed (no mixing)",
171 "quad-speed (no mixing)"
172};
173
174static const struct soc_enum uda1380_deemp_enum[] = {
175 SOC_ENUM_SINGLE(UDA1380_DEEMP, 8, 5, uda1380_deemp),
176 SOC_ENUM_SINGLE(UDA1380_DEEMP, 0, 5, uda1380_deemp),
177};
178static const struct soc_enum uda1380_input_sel_enum =
179 SOC_ENUM_SINGLE(UDA1380_ADC, 2, 4, uda1380_input_sel); /* SEL_MIC, SEL_LNA */
180static const struct soc_enum uda1380_output_sel_enum =
181 SOC_ENUM_SINGLE(UDA1380_PM, 7, 2, uda1380_output_sel); /* R02_EN_AVC */
182static const struct soc_enum uda1380_spf_enum =
183 SOC_ENUM_SINGLE(UDA1380_MODE, 14, 4, uda1380_spf_mode); /* M */
184static const struct soc_enum uda1380_capture_sel_enum =
185 SOC_ENUM_SINGLE(UDA1380_IFACE, 6, 2, uda1380_capture_sel); /* SEL_SOURCE */
186static const struct soc_enum uda1380_sel_ns_enum =
187 SOC_ENUM_SINGLE(UDA1380_MIXER, 14, 2, uda1380_sel_ns); /* SEL_NS */
188static const struct soc_enum uda1380_mix_enum =
189 SOC_ENUM_SINGLE(UDA1380_MIXER, 12, 4, uda1380_mix_control); /* MIX, MIX_POS */
190static const struct soc_enum uda1380_sdet_enum =
191 SOC_ENUM_SINGLE(UDA1380_MIXER, 4, 4, uda1380_sdet_setting); /* SD_VALUE */
192static const struct soc_enum uda1380_os_enum =
193 SOC_ENUM_SINGLE(UDA1380_MIXER, 0, 3, uda1380_os_setting); /* OS */
194
195/*
196 * from -48 dB in 1.5 dB steps (mute instead of -49.5 dB)
197 */
198static DECLARE_TLV_DB_SCALE(amix_tlv, -4950, 150, 1);
199
200/*
201 * from -78 dB in 1 dB steps (3 dB steps, really. LSB are ignored),
202 * from -66 dB in 0.5 dB steps (2 dB steps, really) and
203 * from -52 dB in 0.25 dB steps
204 */
205static const unsigned int mvol_tlv[] = {
206 TLV_DB_RANGE_HEAD(3),
207 0, 15, TLV_DB_SCALE_ITEM(-8200, 100, 1),
208 16, 43, TLV_DB_SCALE_ITEM(-6600, 50, 0),
209 44, 252, TLV_DB_SCALE_ITEM(-5200, 25, 0),
210};
211
212/*
213 * from -72 dB in 1.5 dB steps (6 dB steps really),
214 * from -66 dB in 0.75 dB steps (3 dB steps really),
215 * from -60 dB in 0.5 dB steps (2 dB steps really) and
216 * from -46 dB in 0.25 dB steps
217 */
218static const unsigned int vc_tlv[] = {
219 TLV_DB_RANGE_HEAD(4),
220 0, 7, TLV_DB_SCALE_ITEM(-7800, 150, 1),
221 8, 15, TLV_DB_SCALE_ITEM(-6600, 75, 0),
222 16, 43, TLV_DB_SCALE_ITEM(-6000, 50, 0),
223 44, 228, TLV_DB_SCALE_ITEM(-4600, 25, 0),
224};
225
226/* from 0 to 6 dB in 2 dB steps if SPF mode != flat */
227static DECLARE_TLV_DB_SCALE(tr_tlv, 0, 200, 0);
228
229/* from 0 to 24 dB in 2 dB steps, if SPF mode == maximum, otherwise cuts
230 * off at 18 dB max) */
231static DECLARE_TLV_DB_SCALE(bb_tlv, 0, 200, 0);
232
233/* from -63 to 24 dB in 0.5 dB steps (-128...48) */
234static DECLARE_TLV_DB_SCALE(dec_tlv, -6400, 50, 1);
235
236/* from 0 to 24 dB in 3 dB steps */
237static DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0);
238
239/* from 0 to 30 dB in 2 dB steps */
240static DECLARE_TLV_DB_SCALE(vga_tlv, 0, 200, 0);
241
242static const struct snd_kcontrol_new uda1380_snd_controls[] = {
243 SOC_DOUBLE_TLV("Analog Mixer Volume", UDA1380_AMIX, 0, 8, 44, 1, amix_tlv), /* AVCR, AVCL */
244 SOC_DOUBLE_TLV("Master Playback Volume", UDA1380_MVOL, 0, 8, 252, 1, mvol_tlv), /* MVCL, MVCR */
245 SOC_SINGLE_TLV("ADC Playback Volume", UDA1380_MIXVOL, 8, 228, 1, vc_tlv), /* VC2 */
246 SOC_SINGLE_TLV("PCM Playback Volume", UDA1380_MIXVOL, 0, 228, 1, vc_tlv), /* VC1 */
247 SOC_ENUM("Sound Processing Filter", uda1380_spf_enum), /* M */
248 SOC_DOUBLE_TLV("Tone Control - Treble", UDA1380_MODE, 4, 12, 3, 0, tr_tlv), /* TRL, TRR */
249 SOC_DOUBLE_TLV("Tone Control - Bass", UDA1380_MODE, 0, 8, 15, 0, bb_tlv), /* BBL, BBR */
250/**/ SOC_SINGLE("Master Playback Switch", UDA1380_DEEMP, 14, 1, 1), /* MTM */
251 SOC_SINGLE("ADC Playback Switch", UDA1380_DEEMP, 11, 1, 1), /* MT2 from decimation filter */
252 SOC_ENUM("ADC Playback De-emphasis", uda1380_deemp_enum[0]), /* DE2 */
253 SOC_SINGLE("PCM Playback Switch", UDA1380_DEEMP, 3, 1, 1), /* MT1, from digital data input */
254 SOC_ENUM("PCM Playback De-emphasis", uda1380_deemp_enum[1]), /* DE1 */
255 SOC_SINGLE("DAC Polarity inverting Switch", UDA1380_MIXER, 15, 1, 0), /* DA_POL_INV */
256 SOC_ENUM("Noise Shaper", uda1380_sel_ns_enum), /* SEL_NS */
257 SOC_ENUM("Digital Mixer Signal Control", uda1380_mix_enum), /* MIX_POS, MIX */
258 SOC_SINGLE("Silence Switch", UDA1380_MIXER, 7, 1, 0), /* SILENCE, force DAC output to silence */
259 SOC_SINGLE("Silence Detector Switch", UDA1380_MIXER, 6, 1, 0), /* SDET_ON */
260 SOC_ENUM("Silence Detector Setting", uda1380_sdet_enum), /* SD_VALUE */
261 SOC_ENUM("Oversampling Input", uda1380_os_enum), /* OS */
262 SOC_DOUBLE_S8_TLV("ADC Capture Volume", UDA1380_DEC, -128, 48, dec_tlv), /* ML_DEC, MR_DEC */
263/**/ SOC_SINGLE("ADC Capture Switch", UDA1380_PGA, 15, 1, 1), /* MT_ADC */
264 SOC_DOUBLE_TLV("Line Capture Volume", UDA1380_PGA, 0, 8, 8, 0, pga_tlv), /* PGA_GAINCTRLL, PGA_GAINCTRLR */
265 SOC_SINGLE("ADC Polarity inverting Switch", UDA1380_ADC, 12, 1, 0), /* ADCPOL_INV */
266 SOC_SINGLE_TLV("Mic Capture Volume", UDA1380_ADC, 8, 15, 0, vga_tlv), /* VGA_CTRL */
267 SOC_SINGLE("DC Filter Bypass Switch", UDA1380_ADC, 1, 1, 0), /* SKIP_DCFIL (before decimator) */
268 SOC_SINGLE("DC Filter Enable Switch", UDA1380_ADC, 0, 1, 0), /* EN_DCFIL (at output of decimator) */
269 SOC_SINGLE("AGC Timing", UDA1380_AGC, 8, 7, 0), /* TODO: enum, see table 62 */
270 SOC_SINGLE("AGC Target level", UDA1380_AGC, 2, 3, 1), /* AGC_LEVEL */
271 /* -5.5, -8, -11.5, -14 dBFS */
272 SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0),
273};
274
275/* add non dapm controls */
276static int uda1380_add_controls(struct snd_soc_codec *codec)
277{
278 int err, i;
279
280 for (i = 0; i < ARRAY_SIZE(uda1380_snd_controls); i++) {
281 err = snd_ctl_add(codec->card,
282 snd_soc_cnew(&uda1380_snd_controls[i], codec, NULL));
283 if (err < 0)
284 return err;
285 }
286
287 return 0;
288}
289
290/* Input mux */
291static const struct snd_kcontrol_new uda1380_input_mux_control =
292 SOC_DAPM_ENUM("Route", uda1380_input_sel_enum);
293
294/* Output mux */
295static const struct snd_kcontrol_new uda1380_output_mux_control =
296 SOC_DAPM_ENUM("Route", uda1380_output_sel_enum);
297
298/* Capture mux */
299static const struct snd_kcontrol_new uda1380_capture_mux_control =
300 SOC_DAPM_ENUM("Route", uda1380_capture_sel_enum);
301
302
303static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
304 SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
305 &uda1380_input_mux_control),
306 SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM, 0, 0,
307 &uda1380_output_mux_control),
308 SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0,
309 &uda1380_capture_mux_control),
310 SND_SOC_DAPM_PGA("Left PGA", UDA1380_PM, 3, 0, NULL, 0),
311 SND_SOC_DAPM_PGA("Right PGA", UDA1380_PM, 1, 0, NULL, 0),
312 SND_SOC_DAPM_PGA("Mic LNA", UDA1380_PM, 4, 0, NULL, 0),
313 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", UDA1380_PM, 2, 0),
314 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", UDA1380_PM, 0, 0),
315 SND_SOC_DAPM_INPUT("VINM"),
316 SND_SOC_DAPM_INPUT("VINL"),
317 SND_SOC_DAPM_INPUT("VINR"),
318 SND_SOC_DAPM_MIXER("Analog Mixer", UDA1380_PM, 6, 0, NULL, 0),
319 SND_SOC_DAPM_OUTPUT("VOUTLHP"),
320 SND_SOC_DAPM_OUTPUT("VOUTRHP"),
321 SND_SOC_DAPM_OUTPUT("VOUTL"),
322 SND_SOC_DAPM_OUTPUT("VOUTR"),
323 SND_SOC_DAPM_DAC("DAC", "Playback", UDA1380_PM, 10, 0),
324 SND_SOC_DAPM_PGA("HeadPhone Driver", UDA1380_PM, 13, 0, NULL, 0),
325};
326
327static const struct snd_soc_dapm_route audio_map[] = {
328
329 /* output mux */
330 {"HeadPhone Driver", NULL, "Output Mux"},
331 {"VOUTR", NULL, "Output Mux"},
332 {"VOUTL", NULL, "Output Mux"},
333
334 {"Analog Mixer", NULL, "VINR"},
335 {"Analog Mixer", NULL, "VINL"},
336 {"Analog Mixer", NULL, "DAC"},
337
338 {"Output Mux", "DAC", "DAC"},
339 {"Output Mux", "Analog Mixer", "Analog Mixer"},
340
341 /* {"DAC", "Digital Mixer", "I2S" } */
342
343 /* headphone driver */
344 {"VOUTLHP", NULL, "HeadPhone Driver"},
345 {"VOUTRHP", NULL, "HeadPhone Driver"},
346
347 /* input mux */
348 {"Left ADC", NULL, "Input Mux"},
349 {"Input Mux", "Mic", "Mic LNA"},
350 {"Input Mux", "Mic + Line R", "Mic LNA"},
351 {"Input Mux", "Line L", "Left PGA"},
352 {"Input Mux", "Line", "Left PGA"},
353
354 /* right input */
355 {"Right ADC", "Mic + Line R", "Right PGA"},
356 {"Right ADC", "Line", "Right PGA"},
357
358 /* inputs */
359 {"Mic LNA", NULL, "VINM"},
360 {"Left PGA", NULL, "VINL"},
361 {"Right PGA", NULL, "VINR"},
362};
363
364static int uda1380_add_widgets(struct snd_soc_codec *codec)
365{
366 snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets,
367 ARRAY_SIZE(uda1380_dapm_widgets));
368
369 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
370
371 snd_soc_dapm_new_widgets(codec);
372 return 0;
373}
374
375static int uda1380_set_dai_fmt(struct snd_soc_dai *codec_dai,
376 unsigned int fmt)
377{
378 struct snd_soc_codec *codec = codec_dai->codec;
379 int iface;
380
381 /* set up DAI based upon fmt */
382 iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
383 iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK);
384
385 /* FIXME: how to select I2S for DATAO and MSB for DATAI correctly? */
386 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
387 case SND_SOC_DAIFMT_I2S:
388 iface |= R01_SFORI_I2S | R01_SFORO_I2S;
389 break;
390 case SND_SOC_DAIFMT_LSB:
391 iface |= R01_SFORI_LSB16 | R01_SFORO_I2S;
392 break;
393 case SND_SOC_DAIFMT_MSB:
394 iface |= R01_SFORI_MSB | R01_SFORO_I2S;
395 }
396
397 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
398 iface |= R01_SIM;
399
400 uda1380_write(codec, UDA1380_IFACE, iface);
401
402 return 0;
403}
404
405/*
406 * Flush reg cache
407 * We can only write the interpolator and decimator registers
408 * when the DAI is being clocked by the CPU DAI. It's up to the
409 * machine and cpu DAI driver to do this before we are called.
410 */
411static int uda1380_pcm_prepare(struct snd_pcm_substream *substream)
412{
413 struct snd_soc_pcm_runtime *rtd = substream->private_data;
414 struct snd_soc_device *socdev = rtd->socdev;
415 struct snd_soc_codec *codec = socdev->codec;
416 int reg, reg_start, reg_end, clk;
417
418 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
419 reg_start = UDA1380_MVOL;
420 reg_end = UDA1380_MIXER;
421 } else {
422 reg_start = UDA1380_DEC;
423 reg_end = UDA1380_AGC;
424 }
425
426 /* FIXME disable DAC_CLK */
427 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
428 uda1380_write(codec, UDA1380_CLK, clk & ~R00_DAC_CLK);
429
430 for (reg = reg_start; reg <= reg_end; reg++) {
431 pr_debug("uda1380: flush reg %x val %x:", reg,
432 uda1380_read_reg_cache(codec, reg));
433 uda1380_write(codec, reg, uda1380_read_reg_cache(codec, reg));
434 }
435
436 /* FIXME enable DAC_CLK */
437 uda1380_write(codec, UDA1380_CLK, clk | R00_DAC_CLK);
438
439 return 0;
440}
441
442static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
443 struct snd_pcm_hw_params *params)
444{
445 struct snd_soc_pcm_runtime *rtd = substream->private_data;
446 struct snd_soc_device *socdev = rtd->socdev;
447 struct snd_soc_codec *codec = socdev->codec;
448 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
449
450 /* set WSPLL power and divider if running from this clock */
451 if (clk & R00_DAC_CLK) {
452 int rate = params_rate(params);
453 u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
454 clk &= ~0x3; /* clear SEL_LOOP_DIV */
455 switch (rate) {
456 case 6250 ... 12500:
457 clk |= 0x0;
458 break;
459 case 12501 ... 25000:
460 clk |= 0x1;
461 break;
462 case 25001 ... 50000:
463 clk |= 0x2;
464 break;
465 case 50001 ... 100000:
466 clk |= 0x3;
467 break;
468 }
469 uda1380_write(codec, UDA1380_PM, R02_PON_PLL | pm);
470 }
471
472 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
473 clk |= R00_EN_DAC | R00_EN_INT;
474 else
475 clk |= R00_EN_ADC | R00_EN_DEC;
476
477 uda1380_write(codec, UDA1380_CLK, clk);
478 return 0;
479}
480
481static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream)
482{
483 struct snd_soc_pcm_runtime *rtd = substream->private_data;
484 struct snd_soc_device *socdev = rtd->socdev;
485 struct snd_soc_codec *codec = socdev->codec;
486 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
487
488 /* shut down WSPLL power if running from this clock */
489 if (clk & R00_DAC_CLK) {
490 u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
491 uda1380_write(codec, UDA1380_PM, ~R02_PON_PLL & pm);
492 }
493
494 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
495 clk &= ~(R00_EN_DAC | R00_EN_INT);
496 else
497 clk &= ~(R00_EN_ADC | R00_EN_DEC);
498
499 uda1380_write(codec, UDA1380_CLK, clk);
500}
501
502static int uda1380_mute(struct snd_soc_dai *codec_dai, int mute)
503{
504 struct snd_soc_codec *codec = codec_dai->codec;
505 u16 mute_reg = uda1380_read_reg_cache(codec, UDA1380_DEEMP) & ~R13_MTM;
506
507 /* FIXME: mute(codec,0) is called when the magician clock is already
508 * set to WSPLL, but for some unknown reason writing to interpolator
509 * registers works only when clocked by SYSCLK */
510 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
511 uda1380_write(codec, UDA1380_CLK, ~R00_DAC_CLK & clk);
512 if (mute)
513 uda1380_write(codec, UDA1380_DEEMP, mute_reg | R13_MTM);
514 else
515 uda1380_write(codec, UDA1380_DEEMP, mute_reg);
516 uda1380_write(codec, UDA1380_CLK, clk);
517 return 0;
518}
519
520static int uda1380_set_bias_level(struct snd_soc_codec *codec,
521 enum snd_soc_bias_level level)
522{
523 int pm = uda1380_read_reg_cache(codec, UDA1380_PM);
524
525 switch (level) {
526 case SND_SOC_BIAS_ON:
527 case SND_SOC_BIAS_PREPARE:
528 uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
529 break;
530 case SND_SOC_BIAS_STANDBY:
531 uda1380_write(codec, UDA1380_PM, R02_PON_BIAS);
532 break;
533 case SND_SOC_BIAS_OFF:
534 uda1380_write(codec, UDA1380_PM, 0x0);
535 break;
536 }
537 codec->bias_level = level;
538 return 0;
539}
540
541#define UDA1380_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
542 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
543 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
544
545struct snd_soc_dai uda1380_dai[] = {
546{
547 .name = "UDA1380",
548 .playback = {
549 .stream_name = "Playback",
550 .channels_min = 1,
551 .channels_max = 2,
552 .rates = UDA1380_RATES,
553 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
554 .capture = {
555 .stream_name = "Capture",
556 .channels_min = 1,
557 .channels_max = 2,
558 .rates = UDA1380_RATES,
559 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
560 .ops = {
561 .hw_params = uda1380_pcm_hw_params,
562 .shutdown = uda1380_pcm_shutdown,
563 .prepare = uda1380_pcm_prepare,
564 },
565 .dai_ops = {
566 .digital_mute = uda1380_mute,
567 .set_fmt = uda1380_set_dai_fmt,
568 },
569},
570{ /* playback only - dual interface */
571 .name = "UDA1380",
572 .playback = {
573 .stream_name = "Playback",
574 .channels_min = 1,
575 .channels_max = 2,
576 .rates = UDA1380_RATES,
577 .formats = SNDRV_PCM_FMTBIT_S16_LE,
578 },
579 .ops = {
580 .hw_params = uda1380_pcm_hw_params,
581 .shutdown = uda1380_pcm_shutdown,
582 .prepare = uda1380_pcm_prepare,
583 },
584 .dai_ops = {
585 .digital_mute = uda1380_mute,
586 .set_fmt = uda1380_set_dai_fmt,
587 },
588},
589{ /* capture only - dual interface*/
590 .name = "UDA1380",
591 .capture = {
592 .stream_name = "Capture",
593 .channels_min = 1,
594 .channels_max = 2,
595 .rates = UDA1380_RATES,
596 .formats = SNDRV_PCM_FMTBIT_S16_LE,
597 },
598 .ops = {
599 .hw_params = uda1380_pcm_hw_params,
600 .shutdown = uda1380_pcm_shutdown,
601 .prepare = uda1380_pcm_prepare,
602 },
603 .dai_ops = {
604 .set_fmt = uda1380_set_dai_fmt,
605 },
606},
607};
608EXPORT_SYMBOL_GPL(uda1380_dai);
609
610static int uda1380_suspend(struct platform_device *pdev, pm_message_t state)
611{
612 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
613 struct snd_soc_codec *codec = socdev->codec;
614
615 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
616 return 0;
617}
618
619static int uda1380_resume(struct platform_device *pdev)
620{
621 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
622 struct snd_soc_codec *codec = socdev->codec;
623 int i;
624 u8 data[2];
625 u16 *cache = codec->reg_cache;
626
627 /* Sync reg_cache with the hardware */
628 for (i = 0; i < ARRAY_SIZE(uda1380_reg); i++) {
629 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
630 data[1] = cache[i] & 0x00ff;
631 codec->hw_write(codec->control_data, data, 2);
632 }
633 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
634 uda1380_set_bias_level(codec, codec->suspend_bias_level);
635 return 0;
636}
637
638/*
639 * initialise the UDA1380 driver
640 * register mixer and dsp interfaces with the kernel
641 */
642static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
643{
644 struct snd_soc_codec *codec = socdev->codec;
645 int ret = 0;
646
647 codec->name = "UDA1380";
648 codec->owner = THIS_MODULE;
649 codec->read = uda1380_read_reg_cache;
650 codec->write = uda1380_write;
651 codec->set_bias_level = uda1380_set_bias_level;
652 codec->dai = uda1380_dai;
653 codec->num_dai = ARRAY_SIZE(uda1380_dai);
654 codec->reg_cache = kmemdup(uda1380_reg, sizeof(uda1380_reg),
655 GFP_KERNEL);
656 if (codec->reg_cache == NULL)
657 return -ENOMEM;
658 codec->reg_cache_size = ARRAY_SIZE(uda1380_reg);
659 codec->reg_cache_step = 1;
660 uda1380_reset(codec);
661
662 /* register pcms */
663 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
664 if (ret < 0) {
665 pr_err("uda1380: failed to create pcms\n");
666 goto pcm_err;
667 }
668
669 /* power on device */
670 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
671 /* set clock input */
672 switch (dac_clk) {
673 case UDA1380_DAC_CLK_SYSCLK:
674 uda1380_write(codec, UDA1380_CLK, 0);
675 break;
676 case UDA1380_DAC_CLK_WSPLL:
677 uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK);
678 break;
679 }
680
681 /* uda1380 init */
682 uda1380_add_controls(codec);
683 uda1380_add_widgets(codec);
684 ret = snd_soc_register_card(socdev);
685 if (ret < 0) {
686 pr_err("uda1380: failed to register card\n");
687 goto card_err;
688 }
689
690 return ret;
691
692card_err:
693 snd_soc_free_pcms(socdev);
694 snd_soc_dapm_free(socdev);
695pcm_err:
696 kfree(codec->reg_cache);
697 return ret;
698}
699
700static struct snd_soc_device *uda1380_socdev;
701
702#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
703
704#define I2C_DRIVERID_UDA1380 0xfefe /* liam - need a proper id */
705
706static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
707
708/* Magic definition of all other variables and things */
709I2C_CLIENT_INSMOD;
710
711static struct i2c_driver uda1380_i2c_driver;
712static struct i2c_client client_template;
713
714/* If the i2c layer weren't so broken, we could pass this kind of data
715 around */
716
717static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind)
718{
719 struct snd_soc_device *socdev = uda1380_socdev;
720 struct uda1380_setup_data *setup = socdev->codec_data;
721 struct snd_soc_codec *codec = socdev->codec;
722 struct i2c_client *i2c;
723 int ret;
724
725 if (addr != setup->i2c_address)
726 return -ENODEV;
727
728 client_template.adapter = adap;
729 client_template.addr = addr;
730
731 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
732 if (i2c == NULL) {
733 kfree(codec);
734 return -ENOMEM;
735 }
736 i2c_set_clientdata(i2c, codec);
737 codec->control_data = i2c;
738
739 ret = i2c_attach_client(i2c);
740 if (ret < 0) {
741 pr_err("uda1380: failed to attach codec at addr %x\n", addr);
742 goto err;
743 }
744
745 ret = uda1380_init(socdev, setup->dac_clk);
746 if (ret < 0) {
747 pr_err("uda1380: failed to initialise UDA1380\n");
748 goto err;
749 }
750 return ret;
751
752err:
753 kfree(codec);
754 kfree(i2c);
755 return ret;
756}
757
758static int uda1380_i2c_detach(struct i2c_client *client)
759{
760 struct snd_soc_codec *codec = i2c_get_clientdata(client);
761 i2c_detach_client(client);
762 kfree(codec->reg_cache);
763 kfree(client);
764 return 0;
765}
766
767static int uda1380_i2c_attach(struct i2c_adapter *adap)
768{
769 return i2c_probe(adap, &addr_data, uda1380_codec_probe);
770}
771
772static struct i2c_driver uda1380_i2c_driver = {
773 .driver = {
774 .name = "UDA1380 I2C Codec",
775 .owner = THIS_MODULE,
776 },
777 .id = I2C_DRIVERID_UDA1380,
778 .attach_adapter = uda1380_i2c_attach,
779 .detach_client = uda1380_i2c_detach,
780 .command = NULL,
781};
782
783static struct i2c_client client_template = {
784 .name = "UDA1380",
785 .driver = &uda1380_i2c_driver,
786};
787#endif
788
789static int uda1380_probe(struct platform_device *pdev)
790{
791 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
792 struct uda1380_setup_data *setup;
793 struct snd_soc_codec *codec;
794 int ret = 0;
795
796 pr_info("UDA1380 Audio Codec %s", UDA1380_VERSION);
797
798 setup = socdev->codec_data;
799 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
800 if (codec == NULL)
801 return -ENOMEM;
802
803 socdev->codec = codec;
804 mutex_init(&codec->mutex);
805 INIT_LIST_HEAD(&codec->dapm_widgets);
806 INIT_LIST_HEAD(&codec->dapm_paths);
807
808 uda1380_socdev = socdev;
809#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
810 if (setup->i2c_address) {
811 normal_i2c[0] = setup->i2c_address;
812 codec->hw_write = (hw_write_t)i2c_master_send;
813 ret = i2c_add_driver(&uda1380_i2c_driver);
814 if (ret != 0)
815 printk(KERN_ERR "can't add i2c driver");
816 }
817#else
818 /* Add other interfaces here */
819#endif
820 return ret;
821}
822
823/* power down chip */
824static int uda1380_remove(struct platform_device *pdev)
825{
826 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
827 struct snd_soc_codec *codec = socdev->codec;
828
829 if (codec->control_data)
830 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
831
832 snd_soc_free_pcms(socdev);
833 snd_soc_dapm_free(socdev);
834#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
835 i2c_del_driver(&uda1380_i2c_driver);
836#endif
837 kfree(codec);
838
839 return 0;
840}
841
842struct snd_soc_codec_device soc_codec_dev_uda1380 = {
843 .probe = uda1380_probe,
844 .remove = uda1380_remove,
845 .suspend = uda1380_suspend,
846 .resume = uda1380_resume,
847};
848EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
849
850MODULE_AUTHOR("Giorgio Padrin");
851MODULE_DESCRIPTION("Audio support for codec Philips UDA1380");
852MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/uda1380.h b/sound/soc/codecs/uda1380.h
new file mode 100644
index 000000000000..50c603e2c9f2
--- /dev/null
+++ b/sound/soc/codecs/uda1380.h
@@ -0,0 +1,89 @@
1/*
2 * Audio support for Philips UDA1380
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Copyright (c) 2005 Giorgio Padrin <giorgio@mandarinlogiq.org>
9 */
10
11#ifndef _UDA1380_H
12#define _UDA1380_H
13
14#define UDA1380_CLK 0x00
15#define UDA1380_IFACE 0x01
16#define UDA1380_PM 0x02
17#define UDA1380_AMIX 0x03
18#define UDA1380_HP 0x04
19#define UDA1380_MVOL 0x10
20#define UDA1380_MIXVOL 0x11
21#define UDA1380_MODE 0x12
22#define UDA1380_DEEMP 0x13
23#define UDA1380_MIXER 0x14
24#define UDA1380_INTSTAT 0x18
25#define UDA1380_DEC 0x20
26#define UDA1380_PGA 0x21
27#define UDA1380_ADC 0x22
28#define UDA1380_AGC 0x23
29#define UDA1380_DECSTAT 0x28
30#define UDA1380_RESET 0x7f
31
32#define UDA1380_CACHEREGNUM 0x24
33
34/* Register flags */
35#define R00_EN_ADC 0x0800
36#define R00_EN_DEC 0x0400
37#define R00_EN_DAC 0x0200
38#define R00_EN_INT 0x0100
39#define R00_DAC_CLK 0x0010
40#define R01_SFORI_I2S 0x0000
41#define R01_SFORI_LSB16 0x0100
42#define R01_SFORI_LSB18 0x0200
43#define R01_SFORI_LSB20 0x0300
44#define R01_SFORI_MSB 0x0500
45#define R01_SFORI_MASK 0x0700
46#define R01_SFORO_I2S 0x0000
47#define R01_SFORO_LSB16 0x0001
48#define R01_SFORO_LSB18 0x0002
49#define R01_SFORO_LSB20 0x0003
50#define R01_SFORO_LSB24 0x0004
51#define R01_SFORO_MSB 0x0005
52#define R01_SFORO_MASK 0x0007
53#define R01_SEL_SOURCE 0x0040
54#define R01_SIM 0x0010
55#define R02_PON_PLL 0x8000
56#define R02_PON_HP 0x2000
57#define R02_PON_DAC 0x0400
58#define R02_PON_BIAS 0x0100
59#define R02_EN_AVC 0x0080
60#define R02_PON_AVC 0x0040
61#define R02_PON_LNA 0x0010
62#define R02_PON_PGAL 0x0008
63#define R02_PON_ADCL 0x0004
64#define R02_PON_PGAR 0x0002
65#define R02_PON_ADCR 0x0001
66#define R13_MTM 0x4000
67#define R14_SILENCE 0x0080
68#define R14_SDET_ON 0x0040
69#define R21_MT_ADC 0x8000
70#define R22_SEL_LNA 0x0008
71#define R22_SEL_MIC 0x0004
72#define R22_SKIP_DCFIL 0x0002
73#define R23_AGC_EN 0x0001
74
75struct uda1380_setup_data {
76 unsigned short i2c_address;
77 int dac_clk;
78#define UDA1380_DAC_CLK_SYSCLK 0
79#define UDA1380_DAC_CLK_WSPLL 1
80};
81
82#define UDA1380_DAI_DUPLEX 0 /* playback and capture on single DAI */
83#define UDA1380_DAI_PLAYBACK 1 /* playback DAI */
84#define UDA1380_DAI_CAPTURE 2 /* capture DAI */
85
86extern struct snd_soc_dai uda1380_dai[3];
87extern struct snd_soc_codec_device soc_codec_dev_uda1380;
88
89#endif /* _UDA1380_H */
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
new file mode 100644
index 000000000000..67325fd95447
--- /dev/null
+++ b/sound/soc/codecs/wm8510.c
@@ -0,0 +1,817 @@
1/*
2 * wm8510.c -- WM8510 ALSA Soc Audio driver
3 *
4 * Copyright 2006 Wolfson Microelectronics PLC.
5 *
6 * Author: Liam Girdwood <liam.girdwood@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/kernel.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/initval.h>
27
28#include "wm8510.h"
29
30#define AUDIO_NAME "wm8510"
31#define WM8510_VERSION "0.6"
32
33struct snd_soc_codec_device soc_codec_dev_wm8510;
34
35/*
36 * wm8510 register cache
37 * We can't read the WM8510 register space when we are
38 * using 2 wire for device control, so we cache them instead.
39 */
40static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
41 0x0000, 0x0000, 0x0000, 0x0000,
42 0x0050, 0x0000, 0x0140, 0x0000,
43 0x0000, 0x0000, 0x0000, 0x00ff,
44 0x0000, 0x0000, 0x0100, 0x00ff,
45 0x0000, 0x0000, 0x012c, 0x002c,
46 0x002c, 0x002c, 0x002c, 0x0000,
47 0x0032, 0x0000, 0x0000, 0x0000,
48 0x0000, 0x0000, 0x0000, 0x0000,
49 0x0038, 0x000b, 0x0032, 0x0000,
50 0x0008, 0x000c, 0x0093, 0x00e9,
51 0x0000, 0x0000, 0x0000, 0x0000,
52 0x0003, 0x0010, 0x0000, 0x0000,
53 0x0000, 0x0002, 0x0001, 0x0000,
54 0x0000, 0x0000, 0x0039, 0x0000,
55 0x0001,
56};
57
58/*
59 * read wm8510 register cache
60 */
61static inline unsigned int wm8510_read_reg_cache(struct snd_soc_codec *codec,
62 unsigned int reg)
63{
64 u16 *cache = codec->reg_cache;
65 if (reg == WM8510_RESET)
66 return 0;
67 if (reg >= WM8510_CACHEREGNUM)
68 return -1;
69 return cache[reg];
70}
71
72/*
73 * write wm8510 register cache
74 */
75static inline void wm8510_write_reg_cache(struct snd_soc_codec *codec,
76 u16 reg, unsigned int value)
77{
78 u16 *cache = codec->reg_cache;
79 if (reg >= WM8510_CACHEREGNUM)
80 return;
81 cache[reg] = value;
82}
83
84/*
85 * write to the WM8510 register space
86 */
87static int wm8510_write(struct snd_soc_codec *codec, unsigned int reg,
88 unsigned int value)
89{
90 u8 data[2];
91
92 /* data is
93 * D15..D9 WM8510 register offset
94 * D8...D0 register data
95 */
96 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
97 data[1] = value & 0x00ff;
98
99 wm8510_write_reg_cache(codec, reg, value);
100 if (codec->hw_write(codec->control_data, data, 2) == 2)
101 return 0;
102 else
103 return -EIO;
104}
105
106#define wm8510_reset(c) wm8510_write(c, WM8510_RESET, 0)
107
108static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" };
109static const char *wm8510_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
110static const char *wm8510_alc[] = { "ALC", "Limiter" };
111
112static const struct soc_enum wm8510_enum[] = {
113 SOC_ENUM_SINGLE(WM8510_COMP, 1, 4, wm8510_companding), /* adc */
114 SOC_ENUM_SINGLE(WM8510_COMP, 3, 4, wm8510_companding), /* dac */
115 SOC_ENUM_SINGLE(WM8510_DAC, 4, 4, wm8510_deemp),
116 SOC_ENUM_SINGLE(WM8510_ALC3, 8, 2, wm8510_alc),
117};
118
119static const struct snd_kcontrol_new wm8510_snd_controls[] = {
120
121SOC_SINGLE("Digital Loopback Switch", WM8510_COMP, 0, 1, 0),
122
123SOC_ENUM("DAC Companding", wm8510_enum[1]),
124SOC_ENUM("ADC Companding", wm8510_enum[0]),
125
126SOC_ENUM("Playback De-emphasis", wm8510_enum[2]),
127SOC_SINGLE("DAC Inversion Switch", WM8510_DAC, 0, 1, 0),
128
129SOC_SINGLE("Master Playback Volume", WM8510_DACVOL, 0, 127, 0),
130
131SOC_SINGLE("High Pass Filter Switch", WM8510_ADC, 8, 1, 0),
132SOC_SINGLE("High Pass Cut Off", WM8510_ADC, 4, 7, 0),
133SOC_SINGLE("ADC Inversion Switch", WM8510_COMP, 0, 1, 0),
134
135SOC_SINGLE("Capture Volume", WM8510_ADCVOL, 0, 127, 0),
136
137SOC_SINGLE("DAC Playback Limiter Switch", WM8510_DACLIM1, 8, 1, 0),
138SOC_SINGLE("DAC Playback Limiter Decay", WM8510_DACLIM1, 4, 15, 0),
139SOC_SINGLE("DAC Playback Limiter Attack", WM8510_DACLIM1, 0, 15, 0),
140
141SOC_SINGLE("DAC Playback Limiter Threshold", WM8510_DACLIM2, 4, 7, 0),
142SOC_SINGLE("DAC Playback Limiter Boost", WM8510_DACLIM2, 0, 15, 0),
143
144SOC_SINGLE("ALC Enable Switch", WM8510_ALC1, 8, 1, 0),
145SOC_SINGLE("ALC Capture Max Gain", WM8510_ALC1, 3, 7, 0),
146SOC_SINGLE("ALC Capture Min Gain", WM8510_ALC1, 0, 7, 0),
147
148SOC_SINGLE("ALC Capture ZC Switch", WM8510_ALC2, 8, 1, 0),
149SOC_SINGLE("ALC Capture Hold", WM8510_ALC2, 4, 7, 0),
150SOC_SINGLE("ALC Capture Target", WM8510_ALC2, 0, 15, 0),
151
152SOC_ENUM("ALC Capture Mode", wm8510_enum[3]),
153SOC_SINGLE("ALC Capture Decay", WM8510_ALC3, 4, 15, 0),
154SOC_SINGLE("ALC Capture Attack", WM8510_ALC3, 0, 15, 0),
155
156SOC_SINGLE("ALC Capture Noise Gate Switch", WM8510_NGATE, 3, 1, 0),
157SOC_SINGLE("ALC Capture Noise Gate Threshold", WM8510_NGATE, 0, 7, 0),
158
159SOC_SINGLE("Capture PGA ZC Switch", WM8510_INPPGA, 7, 1, 0),
160SOC_SINGLE("Capture PGA Volume", WM8510_INPPGA, 0, 63, 0),
161
162SOC_SINGLE("Speaker Playback ZC Switch", WM8510_SPKVOL, 7, 1, 0),
163SOC_SINGLE("Speaker Playback Switch", WM8510_SPKVOL, 6, 1, 1),
164SOC_SINGLE("Speaker Playback Volume", WM8510_SPKVOL, 0, 63, 0),
165SOC_SINGLE("Speaker Boost", WM8510_OUTPUT, 2, 1, 0),
166
167SOC_SINGLE("Capture Boost(+20dB)", WM8510_ADCBOOST, 8, 1, 0),
168SOC_SINGLE("Mono Playback Switch", WM8510_MONOMIX, 6, 1, 1),
169};
170
171/* add non dapm controls */
172static int wm8510_add_controls(struct snd_soc_codec *codec)
173{
174 int err, i;
175
176 for (i = 0; i < ARRAY_SIZE(wm8510_snd_controls); i++) {
177 err = snd_ctl_add(codec->card,
178 snd_soc_cnew(&wm8510_snd_controls[i], codec,
179 NULL));
180 if (err < 0)
181 return err;
182 }
183
184 return 0;
185}
186
187/* Speaker Output Mixer */
188static const struct snd_kcontrol_new wm8510_speaker_mixer_controls[] = {
189SOC_DAPM_SINGLE("Line Bypass Switch", WM8510_SPKMIX, 1, 1, 0),
190SOC_DAPM_SINGLE("Aux Playback Switch", WM8510_SPKMIX, 5, 1, 0),
191SOC_DAPM_SINGLE("PCM Playback Switch", WM8510_SPKMIX, 0, 1, 0),
192};
193
194/* Mono Output Mixer */
195static const struct snd_kcontrol_new wm8510_mono_mixer_controls[] = {
196SOC_DAPM_SINGLE("Line Bypass Switch", WM8510_MONOMIX, 1, 1, 0),
197SOC_DAPM_SINGLE("Aux Playback Switch", WM8510_MONOMIX, 2, 1, 0),
198SOC_DAPM_SINGLE("PCM Playback Switch", WM8510_MONOMIX, 0, 1, 0),
199};
200
201static const struct snd_kcontrol_new wm8510_boost_controls[] = {
202SOC_DAPM_SINGLE("Mic PGA Switch", WM8510_INPPGA, 6, 1, 0),
203SOC_DAPM_SINGLE("Aux Volume", WM8510_ADCBOOST, 0, 7, 0),
204SOC_DAPM_SINGLE("Mic Volume", WM8510_ADCBOOST, 4, 7, 0),
205};
206
207static const struct snd_kcontrol_new wm8510_micpga_controls[] = {
208SOC_DAPM_SINGLE("MICP Switch", WM8510_INPUT, 0, 1, 0),
209SOC_DAPM_SINGLE("MICN Switch", WM8510_INPUT, 1, 1, 0),
210SOC_DAPM_SINGLE("AUX Switch", WM8510_INPUT, 2, 1, 0),
211};
212
213static const struct snd_soc_dapm_widget wm8510_dapm_widgets[] = {
214SND_SOC_DAPM_MIXER("Speaker Mixer", WM8510_POWER3, 2, 0,
215 &wm8510_speaker_mixer_controls[0],
216 ARRAY_SIZE(wm8510_speaker_mixer_controls)),
217SND_SOC_DAPM_MIXER("Mono Mixer", WM8510_POWER3, 3, 0,
218 &wm8510_mono_mixer_controls[0],
219 ARRAY_SIZE(wm8510_mono_mixer_controls)),
220SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8510_POWER3, 0, 0),
221SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8510_POWER2, 0, 0),
222SND_SOC_DAPM_PGA("Aux Input", WM8510_POWER1, 6, 0, NULL, 0),
223SND_SOC_DAPM_PGA("SpkN Out", WM8510_POWER3, 5, 0, NULL, 0),
224SND_SOC_DAPM_PGA("SpkP Out", WM8510_POWER3, 6, 0, NULL, 0),
225SND_SOC_DAPM_PGA("Mono Out", WM8510_POWER3, 7, 0, NULL, 0),
226
227SND_SOC_DAPM_PGA("Mic PGA", WM8510_POWER2, 2, 0,
228 &wm8510_micpga_controls[0],
229 ARRAY_SIZE(wm8510_micpga_controls)),
230SND_SOC_DAPM_MIXER("Boost Mixer", WM8510_POWER2, 4, 0,
231 &wm8510_boost_controls[0],
232 ARRAY_SIZE(wm8510_boost_controls)),
233
234SND_SOC_DAPM_MICBIAS("Mic Bias", WM8510_POWER1, 4, 0),
235
236SND_SOC_DAPM_INPUT("MICN"),
237SND_SOC_DAPM_INPUT("MICP"),
238SND_SOC_DAPM_INPUT("AUX"),
239SND_SOC_DAPM_OUTPUT("MONOOUT"),
240SND_SOC_DAPM_OUTPUT("SPKOUTP"),
241SND_SOC_DAPM_OUTPUT("SPKOUTN"),
242};
243
244static const struct snd_soc_dapm_route audio_map[] = {
245 /* Mono output mixer */
246 {"Mono Mixer", "PCM Playback Switch", "DAC"},
247 {"Mono Mixer", "Aux Playback Switch", "Aux Input"},
248 {"Mono Mixer", "Line Bypass Switch", "Boost Mixer"},
249
250 /* Speaker output mixer */
251 {"Speaker Mixer", "PCM Playback Switch", "DAC"},
252 {"Speaker Mixer", "Aux Playback Switch", "Aux Input"},
253 {"Speaker Mixer", "Line Bypass Switch", "Boost Mixer"},
254
255 /* Outputs */
256 {"Mono Out", NULL, "Mono Mixer"},
257 {"MONOOUT", NULL, "Mono Out"},
258 {"SpkN Out", NULL, "Speaker Mixer"},
259 {"SpkP Out", NULL, "Speaker Mixer"},
260 {"SPKOUTN", NULL, "SpkN Out"},
261 {"SPKOUTP", NULL, "SpkP Out"},
262
263 /* Microphone PGA */
264 {"Mic PGA", "MICN Switch", "MICN"},
265 {"Mic PGA", "MICP Switch", "MICP"},
266 { "Mic PGA", "AUX Switch", "Aux Input" },
267
268 /* Boost Mixer */
269 {"Boost Mixer", "Mic PGA Switch", "Mic PGA"},
270 {"Boost Mixer", "Mic Volume", "MICP"},
271 {"Boost Mixer", "Aux Volume", "Aux Input"},
272
273 {"ADC", NULL, "Boost Mixer"},
274};
275
276static int wm8510_add_widgets(struct snd_soc_codec *codec)
277{
278 snd_soc_dapm_new_controls(codec, wm8510_dapm_widgets,
279 ARRAY_SIZE(wm8510_dapm_widgets));
280
281 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
282
283 snd_soc_dapm_new_widgets(codec);
284 return 0;
285}
286
287struct pll_ {
288 unsigned int pre_div:4; /* prescale - 1 */
289 unsigned int n:4;
290 unsigned int k;
291};
292
293static struct pll_ pll_div;
294
295/* The size in bits of the pll divide multiplied by 10
296 * to allow rounding later */
297#define FIXED_PLL_SIZE ((1 << 24) * 10)
298
299static void pll_factors(unsigned int target, unsigned int source)
300{
301 unsigned long long Kpart;
302 unsigned int K, Ndiv, Nmod;
303
304 Ndiv = target / source;
305 if (Ndiv < 6) {
306 source >>= 1;
307 pll_div.pre_div = 1;
308 Ndiv = target / source;
309 } else
310 pll_div.pre_div = 0;
311
312 if ((Ndiv < 6) || (Ndiv > 12))
313 printk(KERN_WARNING
314 "WM8510 N value %d outwith recommended range!d\n",
315 Ndiv);
316
317 pll_div.n = Ndiv;
318 Nmod = target % source;
319 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
320
321 do_div(Kpart, source);
322
323 K = Kpart & 0xFFFFFFFF;
324
325 /* Check if we need to round */
326 if ((K % 10) >= 5)
327 K += 5;
328
329 /* Move down to proper range now rounding is done */
330 K /= 10;
331
332 pll_div.k = K;
333}
334
335static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai,
336 int pll_id, unsigned int freq_in, unsigned int freq_out)
337{
338 struct snd_soc_codec *codec = codec_dai->codec;
339 u16 reg;
340
341 if (freq_in == 0 || freq_out == 0) {
342 /* Clock CODEC directly from MCLK */
343 reg = wm8510_read_reg_cache(codec, WM8510_CLOCK);
344 wm8510_write(codec, WM8510_CLOCK, reg & 0x0ff);
345
346 /* Turn off PLL */
347 reg = wm8510_read_reg_cache(codec, WM8510_POWER1);
348 wm8510_write(codec, WM8510_POWER1, reg & 0x1df);
349 return 0;
350 }
351
352 pll_factors(freq_out*8, freq_in);
353
354 wm8510_write(codec, WM8510_PLLN, (pll_div.pre_div << 4) | pll_div.n);
355 wm8510_write(codec, WM8510_PLLK1, pll_div.k >> 18);
356 wm8510_write(codec, WM8510_PLLK2, (pll_div.k >> 9) & 0x1ff);
357 wm8510_write(codec, WM8510_PLLK3, pll_div.k & 0x1ff);
358 reg = wm8510_read_reg_cache(codec, WM8510_POWER1);
359 wm8510_write(codec, WM8510_POWER1, reg | 0x020);
360
361 /* Run CODEC from PLL instead of MCLK */
362 reg = wm8510_read_reg_cache(codec, WM8510_CLOCK);
363 wm8510_write(codec, WM8510_CLOCK, reg | 0x100);
364
365 return 0;
366}
367
368/*
369 * Configure WM8510 clock dividers.
370 */
371static int wm8510_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
372 int div_id, int div)
373{
374 struct snd_soc_codec *codec = codec_dai->codec;
375 u16 reg;
376
377 switch (div_id) {
378 case WM8510_OPCLKDIV:
379 reg = wm8510_read_reg_cache(codec, WM8510_GPIO) & 0x1cf;
380 wm8510_write(codec, WM8510_GPIO, reg | div);
381 break;
382 case WM8510_MCLKDIV:
383 reg = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x1f;
384 wm8510_write(codec, WM8510_CLOCK, reg | div);
385 break;
386 case WM8510_ADCCLK:
387 reg = wm8510_read_reg_cache(codec, WM8510_ADC) & 0x1f7;
388 wm8510_write(codec, WM8510_ADC, reg | div);
389 break;
390 case WM8510_DACCLK:
391 reg = wm8510_read_reg_cache(codec, WM8510_DAC) & 0x1f7;
392 wm8510_write(codec, WM8510_DAC, reg | div);
393 break;
394 case WM8510_BCLKDIV:
395 reg = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x1e3;
396 wm8510_write(codec, WM8510_CLOCK, reg | div);
397 break;
398 default:
399 return -EINVAL;
400 }
401
402 return 0;
403}
404
405static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
406 unsigned int fmt)
407{
408 struct snd_soc_codec *codec = codec_dai->codec;
409 u16 iface = 0;
410 u16 clk = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x1fe;
411
412 /* set master/slave audio interface */
413 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
414 case SND_SOC_DAIFMT_CBM_CFM:
415 clk |= 0x0001;
416 break;
417 case SND_SOC_DAIFMT_CBS_CFS:
418 break;
419 default:
420 return -EINVAL;
421 }
422
423 /* interface format */
424 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
425 case SND_SOC_DAIFMT_I2S:
426 iface |= 0x0010;
427 break;
428 case SND_SOC_DAIFMT_RIGHT_J:
429 break;
430 case SND_SOC_DAIFMT_LEFT_J:
431 iface |= 0x0008;
432 break;
433 case SND_SOC_DAIFMT_DSP_A:
434 iface |= 0x00018;
435 break;
436 default:
437 return -EINVAL;
438 }
439
440 /* clock inversion */
441 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
442 case SND_SOC_DAIFMT_NB_NF:
443 break;
444 case SND_SOC_DAIFMT_IB_IF:
445 iface |= 0x0180;
446 break;
447 case SND_SOC_DAIFMT_IB_NF:
448 iface |= 0x0100;
449 break;
450 case SND_SOC_DAIFMT_NB_IF:
451 iface |= 0x0080;
452 break;
453 default:
454 return -EINVAL;
455 }
456
457 wm8510_write(codec, WM8510_IFACE, iface);
458 wm8510_write(codec, WM8510_CLOCK, clk);
459 return 0;
460}
461
462static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
463 struct snd_pcm_hw_params *params)
464{
465 struct snd_soc_pcm_runtime *rtd = substream->private_data;
466 struct snd_soc_device *socdev = rtd->socdev;
467 struct snd_soc_codec *codec = socdev->codec;
468 u16 iface = wm8510_read_reg_cache(codec, WM8510_IFACE) & 0x19f;
469 u16 adn = wm8510_read_reg_cache(codec, WM8510_ADD) & 0x1f1;
470
471 /* bit size */
472 switch (params_format(params)) {
473 case SNDRV_PCM_FORMAT_S16_LE:
474 break;
475 case SNDRV_PCM_FORMAT_S20_3LE:
476 iface |= 0x0020;
477 break;
478 case SNDRV_PCM_FORMAT_S24_LE:
479 iface |= 0x0040;
480 break;
481 case SNDRV_PCM_FORMAT_S32_LE:
482 iface |= 0x0060;
483 break;
484 }
485
486 /* filter coefficient */
487 switch (params_rate(params)) {
488 case SNDRV_PCM_RATE_8000:
489 adn |= 0x5 << 1;
490 break;
491 case SNDRV_PCM_RATE_11025:
492 adn |= 0x4 << 1;
493 break;
494 case SNDRV_PCM_RATE_16000:
495 adn |= 0x3 << 1;
496 break;
497 case SNDRV_PCM_RATE_22050:
498 adn |= 0x2 << 1;
499 break;
500 case SNDRV_PCM_RATE_32000:
501 adn |= 0x1 << 1;
502 break;
503 case SNDRV_PCM_RATE_44100:
504 case SNDRV_PCM_RATE_48000:
505 break;
506 }
507
508 wm8510_write(codec, WM8510_IFACE, iface);
509 wm8510_write(codec, WM8510_ADD, adn);
510 return 0;
511}
512
513static int wm8510_mute(struct snd_soc_dai *dai, int mute)
514{
515 struct snd_soc_codec *codec = dai->codec;
516 u16 mute_reg = wm8510_read_reg_cache(codec, WM8510_DAC) & 0xffbf;
517
518 if (mute)
519 wm8510_write(codec, WM8510_DAC, mute_reg | 0x40);
520 else
521 wm8510_write(codec, WM8510_DAC, mute_reg);
522 return 0;
523}
524
525/* liam need to make this lower power with dapm */
526static int wm8510_set_bias_level(struct snd_soc_codec *codec,
527 enum snd_soc_bias_level level)
528{
529
530 switch (level) {
531 case SND_SOC_BIAS_ON:
532 wm8510_write(codec, WM8510_POWER1, 0x1ff);
533 wm8510_write(codec, WM8510_POWER2, 0x1ff);
534 wm8510_write(codec, WM8510_POWER3, 0x1ff);
535 break;
536 case SND_SOC_BIAS_PREPARE:
537 case SND_SOC_BIAS_STANDBY:
538 break;
539 case SND_SOC_BIAS_OFF:
540 /* everything off, dac mute, inactive */
541 wm8510_write(codec, WM8510_POWER1, 0x0);
542 wm8510_write(codec, WM8510_POWER2, 0x0);
543 wm8510_write(codec, WM8510_POWER3, 0x0);
544 break;
545 }
546 codec->bias_level = level;
547 return 0;
548}
549
550#define WM8510_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
551 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
552 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
553
554#define WM8510_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
555 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
556
557struct snd_soc_dai wm8510_dai = {
558 .name = "WM8510 HiFi",
559 .playback = {
560 .stream_name = "Playback",
561 .channels_min = 2,
562 .channels_max = 2,
563 .rates = WM8510_RATES,
564 .formats = WM8510_FORMATS,},
565 .capture = {
566 .stream_name = "Capture",
567 .channels_min = 2,
568 .channels_max = 2,
569 .rates = WM8510_RATES,
570 .formats = WM8510_FORMATS,},
571 .ops = {
572 .hw_params = wm8510_pcm_hw_params,
573 },
574 .dai_ops = {
575 .digital_mute = wm8510_mute,
576 .set_fmt = wm8510_set_dai_fmt,
577 .set_clkdiv = wm8510_set_dai_clkdiv,
578 .set_pll = wm8510_set_dai_pll,
579 },
580};
581EXPORT_SYMBOL_GPL(wm8510_dai);
582
583static int wm8510_suspend(struct platform_device *pdev, pm_message_t state)
584{
585 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
586 struct snd_soc_codec *codec = socdev->codec;
587
588 wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
589 return 0;
590}
591
592static int wm8510_resume(struct platform_device *pdev)
593{
594 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
595 struct snd_soc_codec *codec = socdev->codec;
596 int i;
597 u8 data[2];
598 u16 *cache = codec->reg_cache;
599
600 /* Sync reg_cache with the hardware */
601 for (i = 0; i < ARRAY_SIZE(wm8510_reg); i++) {
602 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
603 data[1] = cache[i] & 0x00ff;
604 codec->hw_write(codec->control_data, data, 2);
605 }
606 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
607 wm8510_set_bias_level(codec, codec->suspend_bias_level);
608 return 0;
609}
610
611/*
612 * initialise the WM8510 driver
613 * register the mixer and dsp interfaces with the kernel
614 */
615static int wm8510_init(struct snd_soc_device *socdev)
616{
617 struct snd_soc_codec *codec = socdev->codec;
618 int ret = 0;
619
620 codec->name = "WM8510";
621 codec->owner = THIS_MODULE;
622 codec->read = wm8510_read_reg_cache;
623 codec->write = wm8510_write;
624 codec->set_bias_level = wm8510_set_bias_level;
625 codec->dai = &wm8510_dai;
626 codec->num_dai = 1;
627 codec->reg_cache_size = ARRAY_SIZE(wm8510_reg);
628 codec->reg_cache = kmemdup(wm8510_reg, sizeof(wm8510_reg), GFP_KERNEL);
629
630 if (codec->reg_cache == NULL)
631 return -ENOMEM;
632
633 wm8510_reset(codec);
634
635 /* register pcms */
636 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
637 if (ret < 0) {
638 printk(KERN_ERR "wm8510: failed to create pcms\n");
639 goto pcm_err;
640 }
641
642 /* power on device */
643 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
644 wm8510_add_controls(codec);
645 wm8510_add_widgets(codec);
646 ret = snd_soc_register_card(socdev);
647 if (ret < 0) {
648 printk(KERN_ERR "wm8510: failed to register card\n");
649 goto card_err;
650 }
651 return ret;
652
653card_err:
654 snd_soc_free_pcms(socdev);
655 snd_soc_dapm_free(socdev);
656pcm_err:
657 kfree(codec->reg_cache);
658 return ret;
659}
660
661static struct snd_soc_device *wm8510_socdev;
662
663#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
664
665/*
666 * WM8510 2 wire address is 0x1a
667 */
668#define I2C_DRIVERID_WM8510 0xfefe /* liam - need a proper id */
669
670static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
671
672/* Magic definition of all other variables and things */
673I2C_CLIENT_INSMOD;
674
675static struct i2c_driver wm8510_i2c_driver;
676static struct i2c_client client_template;
677
678/* If the i2c layer weren't so broken, we could pass this kind of data
679 around */
680
681static int wm8510_codec_probe(struct i2c_adapter *adap, int addr, int kind)
682{
683 struct snd_soc_device *socdev = wm8510_socdev;
684 struct wm8510_setup_data *setup = socdev->codec_data;
685 struct snd_soc_codec *codec = socdev->codec;
686 struct i2c_client *i2c;
687 int ret;
688
689 if (addr != setup->i2c_address)
690 return -ENODEV;
691
692 client_template.adapter = adap;
693 client_template.addr = addr;
694
695 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
696 if (i2c == NULL) {
697 kfree(codec);
698 return -ENOMEM;
699 }
700 i2c_set_clientdata(i2c, codec);
701 codec->control_data = i2c;
702
703 ret = i2c_attach_client(i2c);
704 if (ret < 0) {
705 pr_err("failed to attach codec at addr %x\n", addr);
706 goto err;
707 }
708
709 ret = wm8510_init(socdev);
710 if (ret < 0) {
711 pr_err("failed to initialise WM8510\n");
712 goto err;
713 }
714 return ret;
715
716err:
717 kfree(codec);
718 kfree(i2c);
719 return ret;
720}
721
722static int wm8510_i2c_detach(struct i2c_client *client)
723{
724 struct snd_soc_codec *codec = i2c_get_clientdata(client);
725 i2c_detach_client(client);
726 kfree(codec->reg_cache);
727 kfree(client);
728 return 0;
729}
730
731static int wm8510_i2c_attach(struct i2c_adapter *adap)
732{
733 return i2c_probe(adap, &addr_data, wm8510_codec_probe);
734}
735
736/* corgi i2c codec control layer */
737static struct i2c_driver wm8510_i2c_driver = {
738 .driver = {
739 .name = "WM8510 I2C Codec",
740 .owner = THIS_MODULE,
741 },
742 .id = I2C_DRIVERID_WM8510,
743 .attach_adapter = wm8510_i2c_attach,
744 .detach_client = wm8510_i2c_detach,
745 .command = NULL,
746};
747
748static struct i2c_client client_template = {
749 .name = "WM8510",
750 .driver = &wm8510_i2c_driver,
751};
752#endif
753
754static int wm8510_probe(struct platform_device *pdev)
755{
756 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
757 struct wm8510_setup_data *setup;
758 struct snd_soc_codec *codec;
759 int ret = 0;
760
761 pr_info("WM8510 Audio Codec %s", WM8510_VERSION);
762
763 setup = socdev->codec_data;
764 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
765 if (codec == NULL)
766 return -ENOMEM;
767
768 socdev->codec = codec;
769 mutex_init(&codec->mutex);
770 INIT_LIST_HEAD(&codec->dapm_widgets);
771 INIT_LIST_HEAD(&codec->dapm_paths);
772
773 wm8510_socdev = socdev;
774#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
775 if (setup->i2c_address) {
776 normal_i2c[0] = setup->i2c_address;
777 codec->hw_write = (hw_write_t)i2c_master_send;
778 ret = i2c_add_driver(&wm8510_i2c_driver);
779 if (ret != 0)
780 printk(KERN_ERR "can't add i2c driver");
781 }
782#else
783 /* Add other interfaces here */
784#endif
785 return ret;
786}
787
788/* power down chip */
789static int wm8510_remove(struct platform_device *pdev)
790{
791 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
792 struct snd_soc_codec *codec = socdev->codec;
793
794 if (codec->control_data)
795 wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
796
797 snd_soc_free_pcms(socdev);
798 snd_soc_dapm_free(socdev);
799#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
800 i2c_del_driver(&wm8510_i2c_driver);
801#endif
802 kfree(codec);
803
804 return 0;
805}
806
807struct snd_soc_codec_device soc_codec_dev_wm8510 = {
808 .probe = wm8510_probe,
809 .remove = wm8510_remove,
810 .suspend = wm8510_suspend,
811 .resume = wm8510_resume,
812};
813EXPORT_SYMBOL_GPL(soc_codec_dev_wm8510);
814
815MODULE_DESCRIPTION("ASoC WM8510 driver");
816MODULE_AUTHOR("Liam Girdwood");
817MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8510.h b/sound/soc/codecs/wm8510.h
new file mode 100644
index 000000000000..f5d2e42eb3f4
--- /dev/null
+++ b/sound/soc/codecs/wm8510.h
@@ -0,0 +1,103 @@
1/*
2 * wm8510.h -- WM8510 Soc Audio driver
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _WM8510_H
10#define _WM8510_H
11
12/* WM8510 register space */
13
14#define WM8510_RESET 0x0
15#define WM8510_POWER1 0x1
16#define WM8510_POWER2 0x2
17#define WM8510_POWER3 0x3
18#define WM8510_IFACE 0x4
19#define WM8510_COMP 0x5
20#define WM8510_CLOCK 0x6
21#define WM8510_ADD 0x7
22#define WM8510_GPIO 0x8
23#define WM8510_DAC 0xa
24#define WM8510_DACVOL 0xb
25#define WM8510_ADC 0xe
26#define WM8510_ADCVOL 0xf
27#define WM8510_EQ1 0x12
28#define WM8510_EQ2 0x13
29#define WM8510_EQ3 0x14
30#define WM8510_EQ4 0x15
31#define WM8510_EQ5 0x16
32#define WM8510_DACLIM1 0x18
33#define WM8510_DACLIM2 0x19
34#define WM8510_NOTCH1 0x1b
35#define WM8510_NOTCH2 0x1c
36#define WM8510_NOTCH3 0x1d
37#define WM8510_NOTCH4 0x1e
38#define WM8510_ALC1 0x20
39#define WM8510_ALC2 0x21
40#define WM8510_ALC3 0x22
41#define WM8510_NGATE 0x23
42#define WM8510_PLLN 0x24
43#define WM8510_PLLK1 0x25
44#define WM8510_PLLK2 0x26
45#define WM8510_PLLK3 0x27
46#define WM8510_ATTEN 0x28
47#define WM8510_INPUT 0x2c
48#define WM8510_INPPGA 0x2d
49#define WM8510_ADCBOOST 0x2f
50#define WM8510_OUTPUT 0x31
51#define WM8510_SPKMIX 0x32
52#define WM8510_SPKVOL 0x36
53#define WM8510_MONOMIX 0x38
54
55#define WM8510_CACHEREGNUM 57
56
57/* Clock divider Id's */
58#define WM8510_OPCLKDIV 0
59#define WM8510_MCLKDIV 1
60#define WM8510_ADCCLK 2
61#define WM8510_DACCLK 3
62#define WM8510_BCLKDIV 4
63
64/* DAC clock dividers */
65#define WM8510_DACCLK_F2 (1 << 3)
66#define WM8510_DACCLK_F4 (0 << 3)
67
68/* ADC clock dividers */
69#define WM8510_ADCCLK_F2 (1 << 3)
70#define WM8510_ADCCLK_F4 (0 << 3)
71
72/* PLL Out dividers */
73#define WM8510_OPCLKDIV_1 (0 << 4)
74#define WM8510_OPCLKDIV_2 (1 << 4)
75#define WM8510_OPCLKDIV_3 (2 << 4)
76#define WM8510_OPCLKDIV_4 (3 << 4)
77
78/* BCLK clock dividers */
79#define WM8510_BCLKDIV_1 (0 << 2)
80#define WM8510_BCLKDIV_2 (1 << 2)
81#define WM8510_BCLKDIV_4 (2 << 2)
82#define WM8510_BCLKDIV_8 (3 << 2)
83#define WM8510_BCLKDIV_16 (4 << 2)
84#define WM8510_BCLKDIV_32 (5 << 2)
85
86/* MCLK clock dividers */
87#define WM8510_MCLKDIV_1 (0 << 5)
88#define WM8510_MCLKDIV_1_5 (1 << 5)
89#define WM8510_MCLKDIV_2 (2 << 5)
90#define WM8510_MCLKDIV_3 (3 << 5)
91#define WM8510_MCLKDIV_4 (4 << 5)
92#define WM8510_MCLKDIV_6 (5 << 5)
93#define WM8510_MCLKDIV_8 (6 << 5)
94#define WM8510_MCLKDIV_12 (7 << 5)
95
96struct wm8510_setup_data {
97 unsigned short i2c_address;
98};
99
100extern struct snd_soc_dai wm8510_dai;
101extern struct snd_soc_codec_device soc_codec_dev_wm8510;
102
103#endif
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 0cf9265fca8f..369d39c3f745 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -31,25 +31,6 @@
31#define AUDIO_NAME "wm8731" 31#define AUDIO_NAME "wm8731"
32#define WM8731_VERSION "0.13" 32#define WM8731_VERSION "0.13"
33 33
34/*
35 * Debug
36 */
37
38#define WM8731_DEBUG 0
39
40#ifdef WM8731_DEBUG
41#define dbg(format, arg...) \
42 printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg)
43#else
44#define dbg(format, arg...) do {} while (0)
45#endif
46#define err(format, arg...) \
47 printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
48#define info(format, arg...) \
49 printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
50#define warn(format, arg...) \
51 printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
52
53struct snd_soc_codec_device soc_codec_dev_wm8731; 34struct snd_soc_codec_device soc_codec_dev_wm8731;
54 35
55/* codec private data */ 36/* codec private data */
@@ -193,7 +174,7 @@ SND_SOC_DAPM_INPUT("RLINEIN"),
193SND_SOC_DAPM_INPUT("LLINEIN"), 174SND_SOC_DAPM_INPUT("LLINEIN"),
194}; 175};
195 176
196static const char *intercon[][3] = { 177static const struct snd_soc_dapm_route intercon[] = {
197 /* output mixer */ 178 /* output mixer */
198 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 179 {"Output Mixer", "Line Bypass Switch", "Line Input"},
199 {"Output Mixer", "HiFi Playback Switch", "DAC"}, 180 {"Output Mixer", "HiFi Playback Switch", "DAC"},
@@ -214,22 +195,14 @@ static const char *intercon[][3] = {
214 {"Line Input", NULL, "LLINEIN"}, 195 {"Line Input", NULL, "LLINEIN"},
215 {"Line Input", NULL, "RLINEIN"}, 196 {"Line Input", NULL, "RLINEIN"},
216 {"Mic Bias", NULL, "MICIN"}, 197 {"Mic Bias", NULL, "MICIN"},
217
218 /* terminator */
219 {NULL, NULL, NULL},
220}; 198};
221 199
222static int wm8731_add_widgets(struct snd_soc_codec *codec) 200static int wm8731_add_widgets(struct snd_soc_codec *codec)
223{ 201{
224 int i; 202 snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets,
225 203 ARRAY_SIZE(wm8731_dapm_widgets));
226 for (i = 0; i < ARRAY_SIZE(wm8731_dapm_widgets); i++)
227 snd_soc_dapm_new_control(codec, &wm8731_dapm_widgets[i]);
228 204
229 /* set up audio path interconnects */ 205 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
230 for (i = 0; intercon[i][0] != NULL; i++)
231 snd_soc_dapm_connect_input(codec, intercon[i][0],
232 intercon[i][1], intercon[i][2]);
233 206
234 snd_soc_dapm_new_widgets(codec); 207 snd_soc_dapm_new_widgets(codec);
235 return 0; 208 return 0;
@@ -345,7 +318,7 @@ static void wm8731_shutdown(struct snd_pcm_substream *substream)
345 } 318 }
346} 319}
347 320
348static int wm8731_mute(struct snd_soc_codec_dai *dai, int mute) 321static int wm8731_mute(struct snd_soc_dai *dai, int mute)
349{ 322{
350 struct snd_soc_codec *codec = dai->codec; 323 struct snd_soc_codec *codec = dai->codec;
351 u16 mute_reg = wm8731_read_reg_cache(codec, WM8731_APDIGI) & 0xfff7; 324 u16 mute_reg = wm8731_read_reg_cache(codec, WM8731_APDIGI) & 0xfff7;
@@ -357,7 +330,7 @@ static int wm8731_mute(struct snd_soc_codec_dai *dai, int mute)
357 return 0; 330 return 0;
358} 331}
359 332
360static int wm8731_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, 333static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
361 int clk_id, unsigned int freq, int dir) 334 int clk_id, unsigned int freq, int dir)
362{ 335{
363 struct snd_soc_codec *codec = codec_dai->codec; 336 struct snd_soc_codec *codec = codec_dai->codec;
@@ -376,7 +349,7 @@ static int wm8731_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
376} 349}
377 350
378 351
379static int wm8731_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, 352static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
380 unsigned int fmt) 353 unsigned int fmt)
381{ 354{
382 struct snd_soc_codec *codec = codec_dai->codec; 355 struct snd_soc_codec *codec = codec_dai->codec;
@@ -435,29 +408,29 @@ static int wm8731_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
435 return 0; 408 return 0;
436} 409}
437 410
438static int wm8731_dapm_event(struct snd_soc_codec *codec, int event) 411static int wm8731_set_bias_level(struct snd_soc_codec *codec,
412 enum snd_soc_bias_level level)
439{ 413{
440 u16 reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff7f; 414 u16 reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff7f;
441 415
442 switch (event) { 416 switch (level) {
443 case SNDRV_CTL_POWER_D0: /* full On */ 417 case SND_SOC_BIAS_ON:
444 /* vref/mid, osc on, dac unmute */ 418 /* vref/mid, osc on, dac unmute */
445 wm8731_write(codec, WM8731_PWR, reg); 419 wm8731_write(codec, WM8731_PWR, reg);
446 break; 420 break;
447 case SNDRV_CTL_POWER_D1: /* partial On */ 421 case SND_SOC_BIAS_PREPARE:
448 case SNDRV_CTL_POWER_D2: /* partial On */
449 break; 422 break;
450 case SNDRV_CTL_POWER_D3hot: /* Off, with power */ 423 case SND_SOC_BIAS_STANDBY:
451 /* everything off except vref/vmid, */ 424 /* everything off except vref/vmid, */
452 wm8731_write(codec, WM8731_PWR, reg | 0x0040); 425 wm8731_write(codec, WM8731_PWR, reg | 0x0040);
453 break; 426 break;
454 case SNDRV_CTL_POWER_D3cold: /* Off, without power */ 427 case SND_SOC_BIAS_OFF:
455 /* everything off, dac mute, inactive */ 428 /* everything off, dac mute, inactive */
456 wm8731_write(codec, WM8731_ACTIVE, 0x0); 429 wm8731_write(codec, WM8731_ACTIVE, 0x0);
457 wm8731_write(codec, WM8731_PWR, 0xffff); 430 wm8731_write(codec, WM8731_PWR, 0xffff);
458 break; 431 break;
459 } 432 }
460 codec->dapm_state = event; 433 codec->bias_level = level;
461 return 0; 434 return 0;
462} 435}
463 436
@@ -470,7 +443,7 @@ static int wm8731_dapm_event(struct snd_soc_codec *codec, int event)
470#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 443#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
471 SNDRV_PCM_FMTBIT_S24_LE) 444 SNDRV_PCM_FMTBIT_S24_LE)
472 445
473struct snd_soc_codec_dai wm8731_dai = { 446struct snd_soc_dai wm8731_dai = {
474 .name = "WM8731", 447 .name = "WM8731",
475 .playback = { 448 .playback = {
476 .stream_name = "Playback", 449 .stream_name = "Playback",
@@ -503,7 +476,7 @@ static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
503 struct snd_soc_codec *codec = socdev->codec; 476 struct snd_soc_codec *codec = socdev->codec;
504 477
505 wm8731_write(codec, WM8731_ACTIVE, 0x0); 478 wm8731_write(codec, WM8731_ACTIVE, 0x0);
506 wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3cold); 479 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
507 return 0; 480 return 0;
508} 481}
509 482
@@ -521,8 +494,8 @@ static int wm8731_resume(struct platform_device *pdev)
521 data[1] = cache[i] & 0x00ff; 494 data[1] = cache[i] & 0x00ff;
522 codec->hw_write(codec->control_data, data, 2); 495 codec->hw_write(codec->control_data, data, 2);
523 } 496 }
524 wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3hot); 497 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
525 wm8731_dapm_event(codec, codec->suspend_dapm_state); 498 wm8731_set_bias_level(codec, codec->suspend_bias_level);
526 return 0; 499 return 0;
527} 500}
528 501
@@ -539,10 +512,10 @@ static int wm8731_init(struct snd_soc_device *socdev)
539 codec->owner = THIS_MODULE; 512 codec->owner = THIS_MODULE;
540 codec->read = wm8731_read_reg_cache; 513 codec->read = wm8731_read_reg_cache;
541 codec->write = wm8731_write; 514 codec->write = wm8731_write;
542 codec->dapm_event = wm8731_dapm_event; 515 codec->set_bias_level = wm8731_set_bias_level;
543 codec->dai = &wm8731_dai; 516 codec->dai = &wm8731_dai;
544 codec->num_dai = 1; 517 codec->num_dai = 1;
545 codec->reg_cache_size = sizeof(wm8731_reg); 518 codec->reg_cache_size = ARRAY_SIZE(wm8731_reg);
546 codec->reg_cache = kmemdup(wm8731_reg, sizeof(wm8731_reg), GFP_KERNEL); 519 codec->reg_cache = kmemdup(wm8731_reg, sizeof(wm8731_reg), GFP_KERNEL);
547 if (codec->reg_cache == NULL) 520 if (codec->reg_cache == NULL)
548 return -ENOMEM; 521 return -ENOMEM;
@@ -557,7 +530,7 @@ static int wm8731_init(struct snd_soc_device *socdev)
557 } 530 }
558 531
559 /* power on device */ 532 /* power on device */
560 wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3hot); 533 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
561 534
562 /* set the update bits */ 535 /* set the update bits */
563 reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V); 536 reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V);
@@ -632,13 +605,13 @@ static int wm8731_codec_probe(struct i2c_adapter *adap, int addr, int kind)
632 605
633 ret = i2c_attach_client(i2c); 606 ret = i2c_attach_client(i2c);
634 if (ret < 0) { 607 if (ret < 0) {
635 err("failed to attach codec at addr %x\n", addr); 608 pr_err("failed to attach codec at addr %x\n", addr);
636 goto err; 609 goto err;
637 } 610 }
638 611
639 ret = wm8731_init(socdev); 612 ret = wm8731_init(socdev);
640 if (ret < 0) { 613 if (ret < 0) {
641 err("failed to initialise WM8731\n"); 614 pr_err("failed to initialise WM8731\n");
642 goto err; 615 goto err;
643 } 616 }
644 return ret; 617 return ret;
@@ -689,7 +662,7 @@ static int wm8731_probe(struct platform_device *pdev)
689 struct wm8731_priv *wm8731; 662 struct wm8731_priv *wm8731;
690 int ret = 0; 663 int ret = 0;
691 664
692 info("WM8731 Audio Codec %s", WM8731_VERSION); 665 pr_info("WM8731 Audio Codec %s", WM8731_VERSION);
693 666
694 setup = socdev->codec_data; 667 setup = socdev->codec_data;
695 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 668 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
@@ -730,7 +703,7 @@ static int wm8731_remove(struct platform_device *pdev)
730 struct snd_soc_codec *codec = socdev->codec; 703 struct snd_soc_codec *codec = socdev->codec;
731 704
732 if (codec->control_data) 705 if (codec->control_data)
733 wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3cold); 706 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
734 707
735 snd_soc_free_pcms(socdev); 708 snd_soc_free_pcms(socdev);
736 snd_soc_dapm_free(socdev); 709 snd_soc_dapm_free(socdev);
diff --git a/sound/soc/codecs/wm8731.h b/sound/soc/codecs/wm8731.h
index 5bcab6a7afb4..99f2e3c60e33 100644
--- a/sound/soc/codecs/wm8731.h
+++ b/sound/soc/codecs/wm8731.h
@@ -38,7 +38,7 @@ struct wm8731_setup_data {
38 unsigned short i2c_address; 38 unsigned short i2c_address;
39}; 39};
40 40
41extern struct snd_soc_codec_dai wm8731_dai; 41extern struct snd_soc_dai wm8731_dai;
42extern struct snd_soc_codec_device soc_codec_dev_wm8731; 42extern struct snd_soc_codec_device soc_codec_dev_wm8731;
43 43
44#endif 44#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 16cd5d4d5ad9..e23cb09f0d14 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -31,25 +31,6 @@
31#define AUDIO_NAME "WM8750" 31#define AUDIO_NAME "WM8750"
32#define WM8750_VERSION "0.12" 32#define WM8750_VERSION "0.12"
33 33
34/*
35 * Debug
36 */
37
38#define WM8750_DEBUG 0
39
40#ifdef WM8750_DEBUG
41#define dbg(format, arg...) \
42 printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg)
43#else
44#define dbg(format, arg...) do {} while (0)
45#endif
46#define err(format, arg...) \
47 printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
48#define info(format, arg...) \
49 printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
50#define warn(format, arg...) \
51 printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
52
53/* codec private data */ 34/* codec private data */
54struct wm8750_priv { 35struct wm8750_priv {
55 unsigned int sysclk; 36 unsigned int sysclk;
@@ -378,7 +359,7 @@ static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
378 SND_SOC_DAPM_INPUT("RINPUT3"), 359 SND_SOC_DAPM_INPUT("RINPUT3"),
379}; 360};
380 361
381static const char *audio_map[][3] = { 362static const struct snd_soc_dapm_route audio_map[] = {
382 /* left mixer */ 363 /* left mixer */
383 {"Left Mixer", "Playback Switch", "Left DAC"}, 364 {"Left Mixer", "Playback Switch", "Left DAC"},
384 {"Left Mixer", "Left Bypass Switch", "Left Line Mux"}, 365 {"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
@@ -470,22 +451,14 @@ static const char *audio_map[][3] = {
470 /* ADC */ 451 /* ADC */
471 {"Left ADC", NULL, "Left ADC Mux"}, 452 {"Left ADC", NULL, "Left ADC Mux"},
472 {"Right ADC", NULL, "Right ADC Mux"}, 453 {"Right ADC", NULL, "Right ADC Mux"},
473
474 /* terminator */
475 {NULL, NULL, NULL},
476}; 454};
477 455
478static int wm8750_add_widgets(struct snd_soc_codec *codec) 456static int wm8750_add_widgets(struct snd_soc_codec *codec)
479{ 457{
480 int i; 458 snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets,
481 459 ARRAY_SIZE(wm8750_dapm_widgets));
482 for (i = 0; i < ARRAY_SIZE(wm8750_dapm_widgets); i++)
483 snd_soc_dapm_new_control(codec, &wm8750_dapm_widgets[i]);
484 460
485 /* set up audio path audio_mapnects */ 461 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
486 for (i = 0; audio_map[i][0] != NULL; i++)
487 snd_soc_dapm_connect_input(codec, audio_map[i][0],
488 audio_map[i][1], audio_map[i][2]);
489 462
490 snd_soc_dapm_new_widgets(codec); 463 snd_soc_dapm_new_widgets(codec);
491 return 0; 464 return 0;
@@ -563,7 +536,7 @@ static inline int get_coeff(int mclk, int rate)
563 return -EINVAL; 536 return -EINVAL;
564} 537}
565 538
566static int wm8750_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, 539static int wm8750_set_dai_sysclk(struct snd_soc_dai *codec_dai,
567 int clk_id, unsigned int freq, int dir) 540 int clk_id, unsigned int freq, int dir)
568{ 541{
569 struct snd_soc_codec *codec = codec_dai->codec; 542 struct snd_soc_codec *codec = codec_dai->codec;
@@ -581,7 +554,7 @@ static int wm8750_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
581 return -EINVAL; 554 return -EINVAL;
582} 555}
583 556
584static int wm8750_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, 557static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
585 unsigned int fmt) 558 unsigned int fmt)
586{ 559{
587 struct snd_soc_codec *codec = codec_dai->codec; 560 struct snd_soc_codec *codec = codec_dai->codec;
@@ -674,7 +647,7 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
674 return 0; 647 return 0;
675} 648}
676 649
677static int wm8750_mute(struct snd_soc_codec_dai *dai, int mute) 650static int wm8750_mute(struct snd_soc_dai *dai, int mute)
678{ 651{
679 struct snd_soc_codec *codec = dai->codec; 652 struct snd_soc_codec *codec = dai->codec;
680 u16 mute_reg = wm8750_read_reg_cache(codec, WM8750_ADCDAC) & 0xfff7; 653 u16 mute_reg = wm8750_read_reg_cache(codec, WM8750_ADCDAC) & 0xfff7;
@@ -686,29 +659,29 @@ static int wm8750_mute(struct snd_soc_codec_dai *dai, int mute)
686 return 0; 659 return 0;
687} 660}
688 661
689static int wm8750_dapm_event(struct snd_soc_codec *codec, int event) 662static int wm8750_set_bias_level(struct snd_soc_codec *codec,
663 enum snd_soc_bias_level level)
690{ 664{
691 u16 pwr_reg = wm8750_read_reg_cache(codec, WM8750_PWR1) & 0xfe3e; 665 u16 pwr_reg = wm8750_read_reg_cache(codec, WM8750_PWR1) & 0xfe3e;
692 666
693 switch (event) { 667 switch (level) {
694 case SNDRV_CTL_POWER_D0: /* full On */ 668 case SND_SOC_BIAS_ON:
695 /* set vmid to 50k and unmute dac */ 669 /* set vmid to 50k and unmute dac */
696 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x00c0); 670 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
697 break; 671 break;
698 case SNDRV_CTL_POWER_D1: /* partial On */ 672 case SND_SOC_BIAS_PREPARE:
699 case SNDRV_CTL_POWER_D2: /* partial On */
700 /* set vmid to 5k for quick power up */ 673 /* set vmid to 5k for quick power up */
701 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); 674 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
702 break; 675 break;
703 case SNDRV_CTL_POWER_D3hot: /* Off, with power */ 676 case SND_SOC_BIAS_STANDBY:
704 /* mute dac and set vmid to 500k, enable VREF */ 677 /* mute dac and set vmid to 500k, enable VREF */
705 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x0141); 678 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
706 break; 679 break;
707 case SNDRV_CTL_POWER_D3cold: /* Off, without power */ 680 case SND_SOC_BIAS_OFF:
708 wm8750_write(codec, WM8750_PWR1, 0x0001); 681 wm8750_write(codec, WM8750_PWR1, 0x0001);
709 break; 682 break;
710 } 683 }
711 codec->dapm_state = event; 684 codec->bias_level = level;
712 return 0; 685 return 0;
713} 686}
714 687
@@ -719,7 +692,7 @@ static int wm8750_dapm_event(struct snd_soc_codec *codec, int event)
719#define WM8750_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 692#define WM8750_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
720 SNDRV_PCM_FMTBIT_S24_LE) 693 SNDRV_PCM_FMTBIT_S24_LE)
721 694
722struct snd_soc_codec_dai wm8750_dai = { 695struct snd_soc_dai wm8750_dai = {
723 .name = "WM8750", 696 .name = "WM8750",
724 .playback = { 697 .playback = {
725 .stream_name = "Playback", 698 .stream_name = "Playback",
@@ -748,7 +721,7 @@ static void wm8750_work(struct work_struct *work)
748{ 721{
749 struct snd_soc_codec *codec = 722 struct snd_soc_codec *codec =
750 container_of(work, struct snd_soc_codec, delayed_work.work); 723 container_of(work, struct snd_soc_codec, delayed_work.work);
751 wm8750_dapm_event(codec, codec->dapm_state); 724 wm8750_set_bias_level(codec, codec->bias_level);
752} 725}
753 726
754static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) 727static int wm8750_suspend(struct platform_device *pdev, pm_message_t state)
@@ -756,7 +729,7 @@ static int wm8750_suspend(struct platform_device *pdev, pm_message_t state)
756 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 729 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
757 struct snd_soc_codec *codec = socdev->codec; 730 struct snd_soc_codec *codec = socdev->codec;
758 731
759 wm8750_dapm_event(codec, SNDRV_CTL_POWER_D3cold); 732 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
760 return 0; 733 return 0;
761} 734}
762 735
@@ -777,12 +750,12 @@ static int wm8750_resume(struct platform_device *pdev)
777 codec->hw_write(codec->control_data, data, 2); 750 codec->hw_write(codec->control_data, data, 2);
778 } 751 }
779 752
780 wm8750_dapm_event(codec, SNDRV_CTL_POWER_D3hot); 753 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
781 754
782 /* charge wm8750 caps */ 755 /* charge wm8750 caps */
783 if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) { 756 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
784 wm8750_dapm_event(codec, SNDRV_CTL_POWER_D2); 757 wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
785 codec->dapm_state = SNDRV_CTL_POWER_D0; 758 codec->bias_level = SND_SOC_BIAS_ON;
786 schedule_delayed_work(&codec->delayed_work, 759 schedule_delayed_work(&codec->delayed_work,
787 msecs_to_jiffies(1000)); 760 msecs_to_jiffies(1000));
788 } 761 }
@@ -803,10 +776,10 @@ static int wm8750_init(struct snd_soc_device *socdev)
803 codec->owner = THIS_MODULE; 776 codec->owner = THIS_MODULE;
804 codec->read = wm8750_read_reg_cache; 777 codec->read = wm8750_read_reg_cache;
805 codec->write = wm8750_write; 778 codec->write = wm8750_write;
806 codec->dapm_event = wm8750_dapm_event; 779 codec->set_bias_level = wm8750_set_bias_level;
807 codec->dai = &wm8750_dai; 780 codec->dai = &wm8750_dai;
808 codec->num_dai = 1; 781 codec->num_dai = 1;
809 codec->reg_cache_size = sizeof(wm8750_reg); 782 codec->reg_cache_size = ARRAY_SIZE(wm8750_reg);
810 codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KERNEL); 783 codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KERNEL);
811 if (codec->reg_cache == NULL) 784 if (codec->reg_cache == NULL)
812 return -ENOMEM; 785 return -ENOMEM;
@@ -821,8 +794,8 @@ static int wm8750_init(struct snd_soc_device *socdev)
821 } 794 }
822 795
823 /* charge output caps */ 796 /* charge output caps */
824 wm8750_dapm_event(codec, SNDRV_CTL_POWER_D2); 797 wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
825 codec->dapm_state = SNDRV_CTL_POWER_D3hot; 798 codec->bias_level = SND_SOC_BIAS_STANDBY;
826 schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000)); 799 schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000));
827 800
828 /* set the update bits */ 801 /* set the update bits */
@@ -904,13 +877,13 @@ static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind)
904 877
905 ret = i2c_attach_client(i2c); 878 ret = i2c_attach_client(i2c);
906 if (ret < 0) { 879 if (ret < 0) {
907 err("failed to attach codec at addr %x\n", addr); 880 pr_err("failed to attach codec at addr %x\n", addr);
908 goto err; 881 goto err;
909 } 882 }
910 883
911 ret = wm8750_init(socdev); 884 ret = wm8750_init(socdev);
912 if (ret < 0) { 885 if (ret < 0) {
913 err("failed to initialise WM8750\n"); 886 pr_err("failed to initialise WM8750\n");
914 goto err; 887 goto err;
915 } 888 }
916 return ret; 889 return ret;
@@ -961,7 +934,7 @@ static int wm8750_probe(struct platform_device *pdev)
961 struct wm8750_priv *wm8750; 934 struct wm8750_priv *wm8750;
962 int ret = 0; 935 int ret = 0;
963 936
964 info("WM8750 Audio Codec %s", WM8750_VERSION); 937 pr_info("WM8750 Audio Codec %s", WM8750_VERSION);
965 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 938 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
966 if (codec == NULL) 939 if (codec == NULL)
967 return -ENOMEM; 940 return -ENOMEM;
@@ -1021,7 +994,7 @@ static int wm8750_remove(struct platform_device *pdev)
1021 struct snd_soc_codec *codec = socdev->codec; 994 struct snd_soc_codec *codec = socdev->codec;
1022 995
1023 if (codec->control_data) 996 if (codec->control_data)
1024 wm8750_dapm_event(codec, SNDRV_CTL_POWER_D3cold); 997 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
1025 run_delayed_work(&codec->delayed_work); 998 run_delayed_work(&codec->delayed_work);
1026 snd_soc_free_pcms(socdev); 999 snd_soc_free_pcms(socdev);
1027 snd_soc_dapm_free(socdev); 1000 snd_soc_dapm_free(socdev);
diff --git a/sound/soc/codecs/wm8750.h b/sound/soc/codecs/wm8750.h
index a97a54a6348e..8ef30e628b21 100644
--- a/sound/soc/codecs/wm8750.h
+++ b/sound/soc/codecs/wm8750.h
@@ -61,7 +61,7 @@ struct wm8750_setup_data {
61 unsigned short i2c_address; 61 unsigned short i2c_address;
62}; 62};
63 63
64extern struct snd_soc_codec_dai wm8750_dai; 64extern struct snd_soc_dai wm8750_dai;
65extern struct snd_soc_codec_device soc_codec_dev_wm8750; 65extern struct snd_soc_codec_device soc_codec_dev_wm8750;
66 66
67#endif 67#endif
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index fb41826c4c4c..8604809f0c36 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -55,25 +55,6 @@
55#define AUDIO_NAME "wm8753" 55#define AUDIO_NAME "wm8753"
56#define WM8753_VERSION "0.16" 56#define WM8753_VERSION "0.16"
57 57
58/*
59 * Debug
60 */
61
62#define WM8753_DEBUG 0
63
64#ifdef WM8753_DEBUG
65#define dbg(format, arg...) \
66 printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg)
67#else
68#define dbg(format, arg...) do {} while (0)
69#endif
70#define err(format, arg...) \
71 printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
72#define info(format, arg...) \
73 printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
74#define warn(format, arg...) \
75 printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
76
77static int caps_charge = 2000; 58static int caps_charge = 2000;
78module_param(caps_charge, int, 0); 59module_param(caps_charge, int, 0);
79MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)"); 60MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
@@ -260,28 +241,50 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
260 return 1; 241 return 1;
261} 242}
262 243
263static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600); 244static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 300, 0);
245static const DECLARE_TLV_DB_SCALE(mic_preamp_tlv, 1200, 600, 0);
246static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
247static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
248static const unsigned int out_tlv[] = {
249 TLV_DB_RANGE_HEAD(2),
250 /* 0000000 - 0101111 = "Analogue mute" */
251 0, 48, TLV_DB_SCALE_ITEM(-25500, 0, 0),
252 48, 127, TLV_DB_SCALE_ITEM(-7300, 100, 0),
253};
254static const DECLARE_TLV_DB_SCALE(mix_tlv, -1500, 300, 0);
255static const DECLARE_TLV_DB_SCALE(voice_mix_tlv, -1200, 300, 0);
256static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0);
264 257
265static const struct snd_kcontrol_new wm8753_snd_controls[] = { 258static const struct snd_kcontrol_new wm8753_snd_controls[] = {
266SOC_DOUBLE_R("PCM Volume", WM8753_LDAC, WM8753_RDAC, 0, 255, 0), 259SOC_DOUBLE_R_TLV("PCM Volume", WM8753_LDAC, WM8753_RDAC, 0, 255, 0, dac_tlv),
267 260
268SOC_DOUBLE_R("ADC Capture Volume", WM8753_LADC, WM8753_RADC, 0, 255, 0), 261SOC_DOUBLE_R_TLV("ADC Capture Volume", WM8753_LADC, WM8753_RADC, 0, 255, 0,
269 262 adc_tlv),
270SOC_DOUBLE_R("Headphone Playback Volume", WM8753_LOUT1V, WM8753_ROUT1V, 0, 127, 0), 263
271SOC_DOUBLE_R("Speaker Playback Volume", WM8753_LOUT2V, WM8753_ROUT2V, 0, 127, 0), 264SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8753_LOUT1V, WM8753_ROUT1V,
272 265 0, 127, 0, out_tlv),
273SOC_SINGLE("Mono Playback Volume", WM8753_MOUTV, 0, 127, 0), 266SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8753_LOUT2V, WM8753_ROUT2V, 0,
274 267 127, 0, out_tlv),
275SOC_DOUBLE_R("Bypass Playback Volume", WM8753_LOUTM1, WM8753_ROUTM1, 4, 7, 1), 268
276SOC_DOUBLE_R("Sidetone Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 4, 7, 1), 269SOC_SINGLE_TLV("Mono Playback Volume", WM8753_MOUTV, 0, 127, 0, out_tlv),
277SOC_DOUBLE_R("Voice Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 0, 7, 1), 270
278 271SOC_DOUBLE_R_TLV("Bypass Playback Volume", WM8753_LOUTM1, WM8753_ROUTM1, 4, 7,
279SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8753_LOUT1V, WM8753_ROUT1V, 7, 1, 0), 272 1, mix_tlv),
280SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8753_LOUT2V, WM8753_ROUT2V, 7, 1, 0), 273SOC_DOUBLE_R_TLV("Sidetone Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 4,
281 274 7, 1, mix_tlv),
282SOC_SINGLE("Mono Bypass Playback Volume", WM8753_MOUTM1, 4, 7, 1), 275SOC_DOUBLE_R_TLV("Voice Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 0, 7,
283SOC_SINGLE("Mono Sidetone Playback Volume", WM8753_MOUTM2, 4, 7, 1), 276 1, voice_mix_tlv),
284SOC_SINGLE("Mono Voice Playback Volume", WM8753_MOUTM2, 0, 7, 1), 277
278SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8753_LOUT1V, WM8753_ROUT1V, 7,
279 1, 0),
280SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8753_LOUT2V, WM8753_ROUT2V, 7,
281 1, 0),
282
283SOC_SINGLE_TLV("Mono Bypass Playback Volume", WM8753_MOUTM1, 4, 7, 1, mix_tlv),
284SOC_SINGLE_TLV("Mono Sidetone Playback Volume", WM8753_MOUTM2, 4, 7, 1,
285 mix_tlv),
286SOC_SINGLE_TLV("Mono Voice Playback Volume", WM8753_MOUTM2, 0, 7, 1,
287 voice_mix_tlv),
285SOC_SINGLE("Mono Playback ZC Switch", WM8753_MOUTV, 7, 1, 0), 288SOC_SINGLE("Mono Playback ZC Switch", WM8753_MOUTV, 7, 1, 0),
286 289
287SOC_ENUM("Bass Boost", wm8753_enum[0]), 290SOC_ENUM("Bass Boost", wm8753_enum[0]),
@@ -291,10 +294,13 @@ SOC_SINGLE("Bass Volume", WM8753_BASS, 0, 15, 1),
291SOC_SINGLE("Treble Volume", WM8753_TREBLE, 0, 15, 1), 294SOC_SINGLE("Treble Volume", WM8753_TREBLE, 0, 15, 1),
292SOC_ENUM("Treble Cut-off", wm8753_enum[2]), 295SOC_ENUM("Treble Cut-off", wm8753_enum[2]),
293 296
294SOC_DOUBLE_TLV("Sidetone Capture Volume", WM8753_RECMIX1, 0, 4, 7, 1, rec_mix_tlv), 297SOC_DOUBLE_TLV("Sidetone Capture Volume", WM8753_RECMIX1, 0, 4, 7, 1,
295SOC_SINGLE_TLV("Voice Sidetone Capture Volume", WM8753_RECMIX2, 0, 7, 1, rec_mix_tlv), 298 rec_mix_tlv),
299SOC_SINGLE_TLV("Voice Sidetone Capture Volume", WM8753_RECMIX2, 0, 7, 1,
300 rec_mix_tlv),
296 301
297SOC_DOUBLE_R("Capture Volume", WM8753_LINVOL, WM8753_RINVOL, 0, 63, 0), 302SOC_DOUBLE_R_TLV("Capture Volume", WM8753_LINVOL, WM8753_RINVOL, 0, 63, 0,
303 pga_tlv),
298SOC_DOUBLE_R("Capture ZC Switch", WM8753_LINVOL, WM8753_RINVOL, 6, 1, 0), 304SOC_DOUBLE_R("Capture ZC Switch", WM8753_LINVOL, WM8753_RINVOL, 6, 1, 0),
299SOC_DOUBLE_R("Capture Switch", WM8753_LINVOL, WM8753_RINVOL, 7, 1, 1), 305SOC_DOUBLE_R("Capture Switch", WM8753_LINVOL, WM8753_RINVOL, 7, 1, 1),
300 306
@@ -326,8 +332,8 @@ SOC_ENUM("De-emphasis", wm8753_enum[8]),
326SOC_ENUM("Playback Mono Mix", wm8753_enum[9]), 332SOC_ENUM("Playback Mono Mix", wm8753_enum[9]),
327SOC_ENUM("Playback Phase", wm8753_enum[10]), 333SOC_ENUM("Playback Phase", wm8753_enum[10]),
328 334
329SOC_SINGLE("Mic2 Capture Volume", WM8753_INCTL1, 7, 3, 0), 335SOC_SINGLE_TLV("Mic2 Capture Volume", WM8753_INCTL1, 7, 3, 0, mic_preamp_tlv),
330SOC_SINGLE("Mic1 Capture Volume", WM8753_INCTL1, 5, 3, 0), 336SOC_SINGLE_TLV("Mic1 Capture Volume", WM8753_INCTL1, 5, 3, 0, mic_preamp_tlv),
331 337
332SOC_ENUM_EXT("DAI Mode", wm8753_enum[26], wm8753_get_dai, wm8753_set_dai), 338SOC_ENUM_EXT("DAI Mode", wm8753_enum[26], wm8753_get_dai, wm8753_set_dai),
333 339
@@ -523,7 +529,7 @@ SND_SOC_DAPM_INPUT("MIC2"),
523SND_SOC_DAPM_VMID("VREF"), 529SND_SOC_DAPM_VMID("VREF"),
524}; 530};
525 531
526static const char *audio_map[][3] = { 532static const struct snd_soc_dapm_route audio_map[] = {
527 /* left mixer */ 533 /* left mixer */
528 {"Left Mixer", "Left Playback Switch", "Left DAC"}, 534 {"Left Mixer", "Left Playback Switch", "Left DAC"},
529 {"Left Mixer", "Voice Playback Switch", "Voice DAC"}, 535 {"Left Mixer", "Voice Playback Switch", "Voice DAC"},
@@ -674,23 +680,14 @@ static const char *audio_map[][3] = {
674 680
675 /* ACOP */ 681 /* ACOP */
676 {"ACOP", NULL, "ALC Mixer"}, 682 {"ACOP", NULL, "ALC Mixer"},
677
678 /* terminator */
679 {NULL, NULL, NULL},
680}; 683};
681 684
682static int wm8753_add_widgets(struct snd_soc_codec *codec) 685static int wm8753_add_widgets(struct snd_soc_codec *codec)
683{ 686{
684 int i; 687 snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets,
688 ARRAY_SIZE(wm8753_dapm_widgets));
685 689
686 for (i = 0; i < ARRAY_SIZE(wm8753_dapm_widgets); i++) 690 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
687 snd_soc_dapm_new_control(codec, &wm8753_dapm_widgets[i]);
688
689 /* set up the WM8753 audio map */
690 for (i = 0; audio_map[i][0] != NULL; i++) {
691 snd_soc_dapm_connect_input(codec, audio_map[i][0],
692 audio_map[i][1], audio_map[i][2]);
693 }
694 691
695 snd_soc_dapm_new_widgets(codec); 692 snd_soc_dapm_new_widgets(codec);
696 return 0; 693 return 0;
@@ -743,7 +740,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
743 pll_div->k = K; 740 pll_div->k = K;
744} 741}
745 742
746static int wm8753_set_dai_pll(struct snd_soc_codec_dai *codec_dai, 743static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai,
747 int pll_id, unsigned int freq_in, unsigned int freq_out) 744 int pll_id, unsigned int freq_in, unsigned int freq_out)
748{ 745{
749 u16 reg, enable; 746 u16 reg, enable;
@@ -866,7 +863,7 @@ static int get_coeff(int mclk, int rate)
866/* 863/*
867 * Clock after PLL and dividers 864 * Clock after PLL and dividers
868 */ 865 */
869static int wm8753_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, 866static int wm8753_set_dai_sysclk(struct snd_soc_dai *codec_dai,
870 int clk_id, unsigned int freq, int dir) 867 int clk_id, unsigned int freq, int dir)
871{ 868{
872 struct snd_soc_codec *codec = codec_dai->codec; 869 struct snd_soc_codec *codec = codec_dai->codec;
@@ -893,7 +890,7 @@ static int wm8753_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
893/* 890/*
894 * Set's ADC and Voice DAC format. 891 * Set's ADC and Voice DAC format.
895 */ 892 */
896static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, 893static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
897 unsigned int fmt) 894 unsigned int fmt)
898{ 895{
899 struct snd_soc_codec *codec = codec_dai->codec; 896 struct snd_soc_codec *codec = codec_dai->codec;
@@ -963,7 +960,7 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
963/* 960/*
964 * Set's PCM dai fmt and BCLK. 961 * Set's PCM dai fmt and BCLK.
965 */ 962 */
966static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, 963static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
967 unsigned int fmt) 964 unsigned int fmt)
968{ 965{
969 struct snd_soc_codec *codec = codec_dai->codec; 966 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1029,7 +1026,7 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
1029 return 0; 1026 return 0;
1030} 1027}
1031 1028
1032static int wm8753_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai, 1029static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1033 int div_id, int div) 1030 int div_id, int div)
1034{ 1031{
1035 struct snd_soc_codec *codec = codec_dai->codec; 1032 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1057,7 +1054,7 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai,
1057/* 1054/*
1058 * Set's HiFi DAC format. 1055 * Set's HiFi DAC format.
1059 */ 1056 */
1060static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, 1057static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
1061 unsigned int fmt) 1058 unsigned int fmt)
1062{ 1059{
1063 struct snd_soc_codec *codec = codec_dai->codec; 1060 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1090,7 +1087,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
1090/* 1087/*
1091 * Set's I2S DAI format. 1088 * Set's I2S DAI format.
1092 */ 1089 */
1093static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, 1090static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1094 unsigned int fmt) 1091 unsigned int fmt)
1095{ 1092{
1096 struct snd_soc_codec *codec = codec_dai->codec; 1093 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1198,7 +1195,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1198 return 0; 1195 return 0;
1199} 1196}
1200 1197
1201static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, 1198static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai,
1202 unsigned int fmt) 1199 unsigned int fmt)
1203{ 1200{
1204 struct snd_soc_codec *codec = codec_dai->codec; 1201 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1213,7 +1210,7 @@ static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
1213 return wm8753_pcm_set_dai_fmt(codec_dai, fmt); 1210 return wm8753_pcm_set_dai_fmt(codec_dai, fmt);
1214} 1211}
1215 1212
1216static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, 1213static int wm8753_mode1h_set_dai_fmt(struct snd_soc_dai *codec_dai,
1217 unsigned int fmt) 1214 unsigned int fmt)
1218{ 1215{
1219 if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) 1216 if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
@@ -1221,7 +1218,7 @@ static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
1221 return wm8753_i2s_set_dai_fmt(codec_dai, fmt); 1218 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1222} 1219}
1223 1220
1224static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, 1221static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai,
1225 unsigned int fmt) 1222 unsigned int fmt)
1226{ 1223{
1227 struct snd_soc_codec *codec = codec_dai->codec; 1224 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1236,7 +1233,7 @@ static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
1236 return wm8753_i2s_set_dai_fmt(codec_dai, fmt); 1233 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1237} 1234}
1238 1235
1239static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, 1236static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
1240 unsigned int fmt) 1237 unsigned int fmt)
1241{ 1238{
1242 struct snd_soc_codec *codec = codec_dai->codec; 1239 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1253,7 +1250,7 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
1253 return wm8753_i2s_set_dai_fmt(codec_dai, fmt); 1250 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1254} 1251}
1255 1252
1256static int wm8753_mute(struct snd_soc_codec_dai *dai, int mute) 1253static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1257{ 1254{
1258 struct snd_soc_codec *codec = dai->codec; 1255 struct snd_soc_codec *codec = dai->codec;
1259 u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7; 1256 u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7;
@@ -1274,29 +1271,29 @@ static int wm8753_mute(struct snd_soc_codec_dai *dai, int mute)
1274 return 0; 1271 return 0;
1275} 1272}
1276 1273
1277static int wm8753_dapm_event(struct snd_soc_codec *codec, int event) 1274static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1275 enum snd_soc_bias_level level)
1278{ 1276{
1279 u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e; 1277 u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e;
1280 1278
1281 switch (event) { 1279 switch (level) {
1282 case SNDRV_CTL_POWER_D0: /* full On */ 1280 case SND_SOC_BIAS_ON:
1283 /* set vmid to 50k and unmute dac */ 1281 /* set vmid to 50k and unmute dac */
1284 wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); 1282 wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
1285 break; 1283 break;
1286 case SNDRV_CTL_POWER_D1: /* partial On */ 1284 case SND_SOC_BIAS_PREPARE:
1287 case SNDRV_CTL_POWER_D2: /* partial On */
1288 /* set vmid to 5k for quick power up */ 1285 /* set vmid to 5k for quick power up */
1289 wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1); 1286 wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
1290 break; 1287 break;
1291 case SNDRV_CTL_POWER_D3hot: /* Off, with power */ 1288 case SND_SOC_BIAS_STANDBY:
1292 /* mute dac and set vmid to 500k, enable VREF */ 1289 /* mute dac and set vmid to 500k, enable VREF */
1293 wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141); 1290 wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
1294 break; 1291 break;
1295 case SNDRV_CTL_POWER_D3cold: /* Off, without power */ 1292 case SND_SOC_BIAS_OFF:
1296 wm8753_write(codec, WM8753_PWR1, 0x0001); 1293 wm8753_write(codec, WM8753_PWR1, 0x0001);
1297 break; 1294 break;
1298 } 1295 }
1299 codec->dapm_state = event; 1296 codec->bias_level = level;
1300 return 0; 1297 return 0;
1301} 1298}
1302 1299
@@ -1319,7 +1316,7 @@ static int wm8753_dapm_event(struct snd_soc_codec *codec, int event)
1319 * 3. Voice disabled - HIFI over HIFI 1316 * 3. Voice disabled - HIFI over HIFI
1320 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture 1317 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
1321 */ 1318 */
1322static const struct snd_soc_codec_dai wm8753_all_dai[] = { 1319static const struct snd_soc_dai wm8753_all_dai[] = {
1323/* DAI HiFi mode 1 */ 1320/* DAI HiFi mode 1 */
1324{ .name = "WM8753 HiFi", 1321{ .name = "WM8753 HiFi",
1325 .id = 1, 1322 .id = 1,
@@ -1459,7 +1456,7 @@ static const struct snd_soc_codec_dai wm8753_all_dai[] = {
1459}, 1456},
1460}; 1457};
1461 1458
1462struct snd_soc_codec_dai wm8753_dai[2]; 1459struct snd_soc_dai wm8753_dai[2];
1463EXPORT_SYMBOL_GPL(wm8753_dai); 1460EXPORT_SYMBOL_GPL(wm8753_dai);
1464 1461
1465static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode) 1462static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode)
@@ -1500,7 +1497,7 @@ static void wm8753_work(struct work_struct *work)
1500{ 1497{
1501 struct snd_soc_codec *codec = 1498 struct snd_soc_codec *codec =
1502 container_of(work, struct snd_soc_codec, delayed_work.work); 1499 container_of(work, struct snd_soc_codec, delayed_work.work);
1503 wm8753_dapm_event(codec, codec->dapm_state); 1500 wm8753_set_bias_level(codec, codec->bias_level);
1504} 1501}
1505 1502
1506static int wm8753_suspend(struct platform_device *pdev, pm_message_t state) 1503static int wm8753_suspend(struct platform_device *pdev, pm_message_t state)
@@ -1512,7 +1509,7 @@ static int wm8753_suspend(struct platform_device *pdev, pm_message_t state)
1512 if (!codec->card) 1509 if (!codec->card)
1513 return 0; 1510 return 0;
1514 1511
1515 wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3cold); 1512 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1516 return 0; 1513 return 0;
1517} 1514}
1518 1515
@@ -1537,12 +1534,12 @@ static int wm8753_resume(struct platform_device *pdev)
1537 codec->hw_write(codec->control_data, data, 2); 1534 codec->hw_write(codec->control_data, data, 2);
1538 } 1535 }
1539 1536
1540 wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3hot); 1537 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1541 1538
1542 /* charge wm8753 caps */ 1539 /* charge wm8753 caps */
1543 if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) { 1540 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
1544 wm8753_dapm_event(codec, SNDRV_CTL_POWER_D2); 1541 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1545 codec->dapm_state = SNDRV_CTL_POWER_D0; 1542 codec->bias_level = SND_SOC_BIAS_ON;
1546 schedule_delayed_work(&codec->delayed_work, 1543 schedule_delayed_work(&codec->delayed_work,
1547 msecs_to_jiffies(caps_charge)); 1544 msecs_to_jiffies(caps_charge));
1548 } 1545 }
@@ -1563,10 +1560,10 @@ static int wm8753_init(struct snd_soc_device *socdev)
1563 codec->owner = THIS_MODULE; 1560 codec->owner = THIS_MODULE;
1564 codec->read = wm8753_read_reg_cache; 1561 codec->read = wm8753_read_reg_cache;
1565 codec->write = wm8753_write; 1562 codec->write = wm8753_write;
1566 codec->dapm_event = wm8753_dapm_event; 1563 codec->set_bias_level = wm8753_set_bias_level;
1567 codec->dai = wm8753_dai; 1564 codec->dai = wm8753_dai;
1568 codec->num_dai = 2; 1565 codec->num_dai = 2;
1569 codec->reg_cache_size = sizeof(wm8753_reg); 1566 codec->reg_cache_size = ARRAY_SIZE(wm8753_reg);
1570 codec->reg_cache = kmemdup(wm8753_reg, sizeof(wm8753_reg), GFP_KERNEL); 1567 codec->reg_cache = kmemdup(wm8753_reg, sizeof(wm8753_reg), GFP_KERNEL);
1571 1568
1572 if (codec->reg_cache == NULL) 1569 if (codec->reg_cache == NULL)
@@ -1584,8 +1581,8 @@ static int wm8753_init(struct snd_soc_device *socdev)
1584 } 1581 }
1585 1582
1586 /* charge output caps */ 1583 /* charge output caps */
1587 wm8753_dapm_event(codec, SNDRV_CTL_POWER_D2); 1584 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1588 codec->dapm_state = SNDRV_CTL_POWER_D3hot; 1585 codec->bias_level = SND_SOC_BIAS_STANDBY;
1589 schedule_delayed_work(&codec->delayed_work, 1586 schedule_delayed_work(&codec->delayed_work,
1590 msecs_to_jiffies(caps_charge)); 1587 msecs_to_jiffies(caps_charge));
1591 1588
@@ -1673,13 +1670,13 @@ static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind)
1673 1670
1674 ret = i2c_attach_client(i2c); 1671 ret = i2c_attach_client(i2c);
1675 if (ret < 0) { 1672 if (ret < 0) {
1676 err("failed to attach codec at addr %x\n", addr); 1673 pr_err("failed to attach codec at addr %x\n", addr);
1677 goto err; 1674 goto err;
1678 } 1675 }
1679 1676
1680 ret = wm8753_init(socdev); 1677 ret = wm8753_init(socdev);
1681 if (ret < 0) { 1678 if (ret < 0) {
1682 err("failed to initialise WM8753\n"); 1679 pr_err("failed to initialise WM8753\n");
1683 goto err; 1680 goto err;
1684 } 1681 }
1685 1682
@@ -1731,7 +1728,7 @@ static int wm8753_probe(struct platform_device *pdev)
1731 struct wm8753_priv *wm8753; 1728 struct wm8753_priv *wm8753;
1732 int ret = 0; 1729 int ret = 0;
1733 1730
1734 info("WM8753 Audio Codec %s", WM8753_VERSION); 1731 pr_info("WM8753 Audio Codec %s", WM8753_VERSION);
1735 1732
1736 setup = socdev->codec_data; 1733 setup = socdev->codec_data;
1737 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 1734 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
@@ -1792,7 +1789,7 @@ static int wm8753_remove(struct platform_device *pdev)
1792 struct snd_soc_codec *codec = socdev->codec; 1789 struct snd_soc_codec *codec = socdev->codec;
1793 1790
1794 if (codec->control_data) 1791 if (codec->control_data)
1795 wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3cold); 1792 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1796 run_delayed_work(&codec->delayed_work); 1793 run_delayed_work(&codec->delayed_work);
1797 snd_soc_free_pcms(socdev); 1794 snd_soc_free_pcms(socdev);
1798 snd_soc_dapm_free(socdev); 1795 snd_soc_dapm_free(socdev);
diff --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h
index 95e2a1f53169..44f5f1ff0cc7 100644
--- a/sound/soc/codecs/wm8753.h
+++ b/sound/soc/codecs/wm8753.h
@@ -120,7 +120,7 @@ struct wm8753_setup_data {
120#define WM8753_DAI_HIFI 0 120#define WM8753_DAI_HIFI 0
121#define WM8753_DAI_VOICE 1 121#define WM8753_DAI_VOICE 1
122 122
123extern struct snd_soc_codec_dai wm8753_dai[2]; 123extern struct snd_soc_dai wm8753_dai[2];
124extern struct snd_soc_codec_device soc_codec_dev_wm8753; 124extern struct snd_soc_codec_device soc_codec_dev_wm8753;
125 125
126#endif 126#endif
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
new file mode 100644
index 000000000000..3ecce5168e94
--- /dev/null
+++ b/sound/soc/codecs/wm8990.c
@@ -0,0 +1,1626 @@
1/*
2 * wm8990.c -- WM8990 ALSA Soc Audio driver
3 *
4 * Copyright 2008 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood
6 * lg@opensource.wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.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/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29#include <asm/div64.h>
30
31#include "wm8990.h"
32
33#define AUDIO_NAME "wm8990"
34#define WM8990_VERSION "0.2"
35
36/* codec private data */
37struct wm8990_priv {
38 unsigned int sysclk;
39 unsigned int pcmclk;
40};
41
42/*
43 * wm8990 register cache. Note that register 0 is not included in the
44 * cache.
45 */
46static const u16 wm8990_reg[] = {
47 0x8990, /* R0 - Reset */
48 0x0000, /* R1 - Power Management (1) */
49 0x6000, /* R2 - Power Management (2) */
50 0x0000, /* R3 - Power Management (3) */
51 0x4050, /* R4 - Audio Interface (1) */
52 0x4000, /* R5 - Audio Interface (2) */
53 0x01C8, /* R6 - Clocking (1) */
54 0x0000, /* R7 - Clocking (2) */
55 0x0040, /* R8 - Audio Interface (3) */
56 0x0040, /* R9 - Audio Interface (4) */
57 0x0004, /* R10 - DAC CTRL */
58 0x00C0, /* R11 - Left DAC Digital Volume */
59 0x00C0, /* R12 - Right DAC Digital Volume */
60 0x0000, /* R13 - Digital Side Tone */
61 0x0100, /* R14 - ADC CTRL */
62 0x00C0, /* R15 - Left ADC Digital Volume */
63 0x00C0, /* R16 - Right ADC Digital Volume */
64 0x0000, /* R17 */
65 0x0000, /* R18 - GPIO CTRL 1 */
66 0x1000, /* R19 - GPIO1 & GPIO2 */
67 0x1010, /* R20 - GPIO3 & GPIO4 */
68 0x1010, /* R21 - GPIO5 & GPIO6 */
69 0x8000, /* R22 - GPIOCTRL 2 */
70 0x0800, /* R23 - GPIO_POL */
71 0x008B, /* R24 - Left Line Input 1&2 Volume */
72 0x008B, /* R25 - Left Line Input 3&4 Volume */
73 0x008B, /* R26 - Right Line Input 1&2 Volume */
74 0x008B, /* R27 - Right Line Input 3&4 Volume */
75 0x0000, /* R28 - Left Output Volume */
76 0x0000, /* R29 - Right Output Volume */
77 0x0066, /* R30 - Line Outputs Volume */
78 0x0022, /* R31 - Out3/4 Volume */
79 0x0079, /* R32 - Left OPGA Volume */
80 0x0079, /* R33 - Right OPGA Volume */
81 0x0003, /* R34 - Speaker Volume */
82 0x0003, /* R35 - ClassD1 */
83 0x0000, /* R36 */
84 0x0100, /* R37 - ClassD3 */
85 0x0000, /* R38 */
86 0x0000, /* R39 - Input Mixer1 */
87 0x0000, /* R40 - Input Mixer2 */
88 0x0000, /* R41 - Input Mixer3 */
89 0x0000, /* R42 - Input Mixer4 */
90 0x0000, /* R43 - Input Mixer5 */
91 0x0000, /* R44 - Input Mixer6 */
92 0x0000, /* R45 - Output Mixer1 */
93 0x0000, /* R46 - Output Mixer2 */
94 0x0000, /* R47 - Output Mixer3 */
95 0x0000, /* R48 - Output Mixer4 */
96 0x0000, /* R49 - Output Mixer5 */
97 0x0000, /* R50 - Output Mixer6 */
98 0x0180, /* R51 - Out3/4 Mixer */
99 0x0000, /* R52 - Line Mixer1 */
100 0x0000, /* R53 - Line Mixer2 */
101 0x0000, /* R54 - Speaker Mixer */
102 0x0000, /* R55 - Additional Control */
103 0x0000, /* R56 - AntiPOP1 */
104 0x0000, /* R57 - AntiPOP2 */
105 0x0000, /* R58 - MICBIAS */
106 0x0000, /* R59 */
107 0x0008, /* R60 - PLL1 */
108 0x0031, /* R61 - PLL2 */
109 0x0026, /* R62 - PLL3 */
110};
111
112/*
113 * read wm8990 register cache
114 */
115static inline unsigned int wm8990_read_reg_cache(struct snd_soc_codec *codec,
116 unsigned int reg)
117{
118 u16 *cache = codec->reg_cache;
119 BUG_ON(reg > (ARRAY_SIZE(wm8990_reg)) - 1);
120 return cache[reg];
121}
122
123/*
124 * write wm8990 register cache
125 */
126static inline void wm8990_write_reg_cache(struct snd_soc_codec *codec,
127 unsigned int reg, unsigned int value)
128{
129 u16 *cache = codec->reg_cache;
130 BUG_ON(reg > (ARRAY_SIZE(wm8990_reg)) - 1);
131
132 /* Reset register is uncached */
133 if (reg == 0)
134 return;
135
136 cache[reg] = value;
137}
138
139/*
140 * write to the wm8990 register space
141 */
142static int wm8990_write(struct snd_soc_codec *codec, unsigned int reg,
143 unsigned int value)
144{
145 u8 data[3];
146
147 data[0] = reg & 0xFF;
148 data[1] = (value >> 8) & 0xFF;
149 data[2] = value & 0xFF;
150
151 wm8990_write_reg_cache(codec, reg, value);
152
153 if (codec->hw_write(codec->control_data, data, 3) == 2)
154 return 0;
155 else
156 return -EIO;
157}
158
159#define wm8990_reset(c) wm8990_write(c, WM8990_RESET, 0)
160
161static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600);
162
163static const DECLARE_TLV_DB_LINEAR(in_pga_tlv, -1650, 3000);
164
165static const DECLARE_TLV_DB_LINEAR(out_mix_tlv, 0, -2100);
166
167static const DECLARE_TLV_DB_LINEAR(out_pga_tlv, -7300, 600);
168
169static const DECLARE_TLV_DB_LINEAR(out_omix_tlv, -600, 0);
170
171static const DECLARE_TLV_DB_LINEAR(out_dac_tlv, -7163, 0);
172
173static const DECLARE_TLV_DB_LINEAR(in_adc_tlv, -7163, 1763);
174
175static const DECLARE_TLV_DB_LINEAR(out_sidetone_tlv, -3600, 0);
176
177static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
178 struct snd_ctl_elem_value *ucontrol)
179{
180 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
181 int reg = kcontrol->private_value & 0xff;
182 int ret;
183 u16 val;
184
185 ret = snd_soc_put_volsw(kcontrol, ucontrol);
186 if (ret < 0)
187 return ret;
188
189 /* now hit the volume update bits (always bit 8) */
190 val = wm8990_read_reg_cache(codec, reg);
191 return wm8990_write(codec, reg, val | 0x0100);
192}
193
194#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
195 tlv_array) {\
196 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
197 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
198 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
199 .tlv.p = (tlv_array), \
200 .info = snd_soc_info_volsw, \
201 .get = snd_soc_get_volsw, .put = wm899x_outpga_put_volsw_vu, \
202 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
203
204
205static const char *wm8990_digital_sidetone[] =
206 {"None", "Left ADC", "Right ADC", "Reserved"};
207
208static const struct soc_enum wm8990_left_digital_sidetone_enum =
209SOC_ENUM_SINGLE(WM8990_DIGITAL_SIDE_TONE,
210 WM8990_ADC_TO_DACL_SHIFT,
211 WM8990_ADC_TO_DACL_MASK,
212 wm8990_digital_sidetone);
213
214static const struct soc_enum wm8990_right_digital_sidetone_enum =
215SOC_ENUM_SINGLE(WM8990_DIGITAL_SIDE_TONE,
216 WM8990_ADC_TO_DACR_SHIFT,
217 WM8990_ADC_TO_DACR_MASK,
218 wm8990_digital_sidetone);
219
220static const char *wm8990_adcmode[] =
221 {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"};
222
223static const struct soc_enum wm8990_right_adcmode_enum =
224SOC_ENUM_SINGLE(WM8990_ADC_CTRL,
225 WM8990_ADC_HPF_CUT_SHIFT,
226 WM8990_ADC_HPF_CUT_MASK,
227 wm8990_adcmode);
228
229static const struct snd_kcontrol_new wm8990_snd_controls[] = {
230/* INMIXL */
231SOC_SINGLE("LIN12 PGA Boost", WM8990_INPUT_MIXER3, WM8990_L12MNBST_BIT, 1, 0),
232SOC_SINGLE("LIN34 PGA Boost", WM8990_INPUT_MIXER3, WM8990_L34MNBST_BIT, 1, 0),
233/* INMIXR */
234SOC_SINGLE("RIN12 PGA Boost", WM8990_INPUT_MIXER3, WM8990_R12MNBST_BIT, 1, 0),
235SOC_SINGLE("RIN34 PGA Boost", WM8990_INPUT_MIXER3, WM8990_R34MNBST_BIT, 1, 0),
236
237/* LOMIX */
238SOC_SINGLE_TLV("LOMIX LIN3 Bypass Volume", WM8990_OUTPUT_MIXER3,
239 WM8990_LLI3LOVOL_SHIFT, WM8990_LLI3LOVOL_MASK, 1, out_mix_tlv),
240SOC_SINGLE_TLV("LOMIX RIN12 PGA Bypass Volume", WM8990_OUTPUT_MIXER3,
241 WM8990_LR12LOVOL_SHIFT, WM8990_LR12LOVOL_MASK, 1, out_mix_tlv),
242SOC_SINGLE_TLV("LOMIX LIN12 PGA Bypass Volume", WM8990_OUTPUT_MIXER3,
243 WM8990_LL12LOVOL_SHIFT, WM8990_LL12LOVOL_MASK, 1, out_mix_tlv),
244SOC_SINGLE_TLV("LOMIX RIN3 Bypass Volume", WM8990_OUTPUT_MIXER5,
245 WM8990_LRI3LOVOL_SHIFT, WM8990_LRI3LOVOL_MASK, 1, out_mix_tlv),
246SOC_SINGLE_TLV("LOMIX AINRMUX Bypass Volume", WM8990_OUTPUT_MIXER5,
247 WM8990_LRBLOVOL_SHIFT, WM8990_LRBLOVOL_MASK, 1, out_mix_tlv),
248SOC_SINGLE_TLV("LOMIX AINLMUX Bypass Volume", WM8990_OUTPUT_MIXER5,
249 WM8990_LRBLOVOL_SHIFT, WM8990_LRBLOVOL_MASK, 1, out_mix_tlv),
250
251/* ROMIX */
252SOC_SINGLE_TLV("ROMIX RIN3 Bypass Volume", WM8990_OUTPUT_MIXER4,
253 WM8990_RRI3ROVOL_SHIFT, WM8990_RRI3ROVOL_MASK, 1, out_mix_tlv),
254SOC_SINGLE_TLV("ROMIX LIN12 PGA Bypass Volume", WM8990_OUTPUT_MIXER4,
255 WM8990_RL12ROVOL_SHIFT, WM8990_RL12ROVOL_MASK, 1, out_mix_tlv),
256SOC_SINGLE_TLV("ROMIX RIN12 PGA Bypass Volume", WM8990_OUTPUT_MIXER4,
257 WM8990_RR12ROVOL_SHIFT, WM8990_RR12ROVOL_MASK, 1, out_mix_tlv),
258SOC_SINGLE_TLV("ROMIX LIN3 Bypass Volume", WM8990_OUTPUT_MIXER6,
259 WM8990_RLI3ROVOL_SHIFT, WM8990_RLI3ROVOL_MASK, 1, out_mix_tlv),
260SOC_SINGLE_TLV("ROMIX AINLMUX Bypass Volume", WM8990_OUTPUT_MIXER6,
261 WM8990_RLBROVOL_SHIFT, WM8990_RLBROVOL_MASK, 1, out_mix_tlv),
262SOC_SINGLE_TLV("ROMIX AINRMUX Bypass Volume", WM8990_OUTPUT_MIXER6,
263 WM8990_RRBROVOL_SHIFT, WM8990_RRBROVOL_MASK, 1, out_mix_tlv),
264
265/* LOUT */
266SOC_WM899X_OUTPGA_SINGLE_R_TLV("LOUT Volume", WM8990_LEFT_OUTPUT_VOLUME,
267 WM8990_LOUTVOL_SHIFT, WM8990_LOUTVOL_MASK, 0, out_pga_tlv),
268SOC_SINGLE("LOUT ZC", WM8990_LEFT_OUTPUT_VOLUME, WM8990_LOZC_BIT, 1, 0),
269
270/* ROUT */
271SOC_WM899X_OUTPGA_SINGLE_R_TLV("ROUT Volume", WM8990_RIGHT_OUTPUT_VOLUME,
272 WM8990_ROUTVOL_SHIFT, WM8990_ROUTVOL_MASK, 0, out_pga_tlv),
273SOC_SINGLE("ROUT ZC", WM8990_RIGHT_OUTPUT_VOLUME, WM8990_ROZC_BIT, 1, 0),
274
275/* LOPGA */
276SOC_WM899X_OUTPGA_SINGLE_R_TLV("LOPGA Volume", WM8990_LEFT_OPGA_VOLUME,
277 WM8990_LOPGAVOL_SHIFT, WM8990_LOPGAVOL_MASK, 0, out_pga_tlv),
278SOC_SINGLE("LOPGA ZC Switch", WM8990_LEFT_OPGA_VOLUME,
279 WM8990_LOPGAZC_BIT, 1, 0),
280
281/* ROPGA */
282SOC_WM899X_OUTPGA_SINGLE_R_TLV("ROPGA Volume", WM8990_RIGHT_OPGA_VOLUME,
283 WM8990_ROPGAVOL_SHIFT, WM8990_ROPGAVOL_MASK, 0, out_pga_tlv),
284SOC_SINGLE("ROPGA ZC Switch", WM8990_RIGHT_OPGA_VOLUME,
285 WM8990_ROPGAZC_BIT, 1, 0),
286
287SOC_SINGLE("LON Mute Switch", WM8990_LINE_OUTPUTS_VOLUME,
288 WM8990_LONMUTE_BIT, 1, 0),
289SOC_SINGLE("LOP Mute Switch", WM8990_LINE_OUTPUTS_VOLUME,
290 WM8990_LOPMUTE_BIT, 1, 0),
291SOC_SINGLE("LOP Attenuation Switch", WM8990_LINE_OUTPUTS_VOLUME,
292 WM8990_LOATTN_BIT, 1, 0),
293SOC_SINGLE("RON Mute Switch", WM8990_LINE_OUTPUTS_VOLUME,
294 WM8990_RONMUTE_BIT, 1, 0),
295SOC_SINGLE("ROP Mute Switch", WM8990_LINE_OUTPUTS_VOLUME,
296 WM8990_ROPMUTE_BIT, 1, 0),
297SOC_SINGLE("ROP Attenuation Switch", WM8990_LINE_OUTPUTS_VOLUME,
298 WM8990_ROATTN_BIT, 1, 0),
299
300SOC_SINGLE("OUT3 Mute Switch", WM8990_OUT3_4_VOLUME,
301 WM8990_OUT3MUTE_BIT, 1, 0),
302SOC_SINGLE("OUT3 Attenuation Switch", WM8990_OUT3_4_VOLUME,
303 WM8990_OUT3ATTN_BIT, 1, 0),
304
305SOC_SINGLE("OUT4 Mute Switch", WM8990_OUT3_4_VOLUME,
306 WM8990_OUT4MUTE_BIT, 1, 0),
307SOC_SINGLE("OUT4 Attenuation Switch", WM8990_OUT3_4_VOLUME,
308 WM8990_OUT4ATTN_BIT, 1, 0),
309
310SOC_SINGLE("Speaker Mode Switch", WM8990_CLASSD1,
311 WM8990_CDMODE_BIT, 1, 0),
312
313SOC_SINGLE("Speaker Output Attenuation Volume", WM8990_SPEAKER_VOLUME,
314 WM8990_SPKVOL_SHIFT, WM8990_SPKVOL_MASK, 0),
315SOC_SINGLE("Speaker DC Boost Volume", WM8990_CLASSD3,
316 WM8990_DCGAIN_SHIFT, WM8990_DCGAIN_MASK, 0),
317SOC_SINGLE("Speaker AC Boost Volume", WM8990_CLASSD3,
318 WM8990_ACGAIN_SHIFT, WM8990_ACGAIN_MASK, 0),
319
320SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume",
321 WM8990_LEFT_DAC_DIGITAL_VOLUME,
322 WM8990_DACL_VOL_SHIFT,
323 WM8990_DACL_VOL_MASK,
324 0,
325 out_dac_tlv),
326
327SOC_WM899X_OUTPGA_SINGLE_R_TLV("Right DAC Digital Volume",
328 WM8990_RIGHT_DAC_DIGITAL_VOLUME,
329 WM8990_DACR_VOL_SHIFT,
330 WM8990_DACR_VOL_MASK,
331 0,
332 out_dac_tlv),
333
334SOC_ENUM("Left Digital Sidetone", wm8990_left_digital_sidetone_enum),
335SOC_ENUM("Right Digital Sidetone", wm8990_right_digital_sidetone_enum),
336
337SOC_SINGLE_TLV("Left Digital Sidetone Volume", WM8990_DIGITAL_SIDE_TONE,
338 WM8990_ADCL_DAC_SVOL_SHIFT, WM8990_ADCL_DAC_SVOL_MASK, 0,
339 out_sidetone_tlv),
340SOC_SINGLE_TLV("Right Digital Sidetone Volume", WM8990_DIGITAL_SIDE_TONE,
341 WM8990_ADCR_DAC_SVOL_SHIFT, WM8990_ADCR_DAC_SVOL_MASK, 0,
342 out_sidetone_tlv),
343
344SOC_SINGLE("ADC Digital High Pass Filter Switch", WM8990_ADC_CTRL,
345 WM8990_ADC_HPF_ENA_BIT, 1, 0),
346
347SOC_ENUM("ADC HPF Mode", wm8990_right_adcmode_enum),
348
349SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left ADC Digital Volume",
350 WM8990_LEFT_ADC_DIGITAL_VOLUME,
351 WM8990_ADCL_VOL_SHIFT,
352 WM8990_ADCL_VOL_MASK,
353 0,
354 in_adc_tlv),
355
356SOC_WM899X_OUTPGA_SINGLE_R_TLV("Right ADC Digital Volume",
357 WM8990_RIGHT_ADC_DIGITAL_VOLUME,
358 WM8990_ADCR_VOL_SHIFT,
359 WM8990_ADCR_VOL_MASK,
360 0,
361 in_adc_tlv),
362
363SOC_WM899X_OUTPGA_SINGLE_R_TLV("LIN12 Volume",
364 WM8990_LEFT_LINE_INPUT_1_2_VOLUME,
365 WM8990_LIN12VOL_SHIFT,
366 WM8990_LIN12VOL_MASK,
367 0,
368 in_pga_tlv),
369
370SOC_SINGLE("LIN12 ZC Switch", WM8990_LEFT_LINE_INPUT_1_2_VOLUME,
371 WM8990_LI12ZC_BIT, 1, 0),
372
373SOC_SINGLE("LIN12 Mute Switch", WM8990_LEFT_LINE_INPUT_1_2_VOLUME,
374 WM8990_LI12MUTE_BIT, 1, 0),
375
376SOC_WM899X_OUTPGA_SINGLE_R_TLV("LIN34 Volume",
377 WM8990_LEFT_LINE_INPUT_3_4_VOLUME,
378 WM8990_LIN34VOL_SHIFT,
379 WM8990_LIN34VOL_MASK,
380 0,
381 in_pga_tlv),
382
383SOC_SINGLE("LIN34 ZC Switch", WM8990_LEFT_LINE_INPUT_3_4_VOLUME,
384 WM8990_LI34ZC_BIT, 1, 0),
385
386SOC_SINGLE("LIN34 Mute Switch", WM8990_LEFT_LINE_INPUT_3_4_VOLUME,
387 WM8990_LI34MUTE_BIT, 1, 0),
388
389SOC_WM899X_OUTPGA_SINGLE_R_TLV("RIN12 Volume",
390 WM8990_RIGHT_LINE_INPUT_1_2_VOLUME,
391 WM8990_RIN12VOL_SHIFT,
392 WM8990_RIN12VOL_MASK,
393 0,
394 in_pga_tlv),
395
396SOC_SINGLE("RIN12 ZC Switch", WM8990_RIGHT_LINE_INPUT_1_2_VOLUME,
397 WM8990_RI12ZC_BIT, 1, 0),
398
399SOC_SINGLE("RIN12 Mute Switch", WM8990_RIGHT_LINE_INPUT_1_2_VOLUME,
400 WM8990_RI12MUTE_BIT, 1, 0),
401
402SOC_WM899X_OUTPGA_SINGLE_R_TLV("RIN34 Volume",
403 WM8990_RIGHT_LINE_INPUT_3_4_VOLUME,
404 WM8990_RIN34VOL_SHIFT,
405 WM8990_RIN34VOL_MASK,
406 0,
407 in_pga_tlv),
408
409SOC_SINGLE("RIN34 ZC Switch", WM8990_RIGHT_LINE_INPUT_3_4_VOLUME,
410 WM8990_RI34ZC_BIT, 1, 0),
411
412SOC_SINGLE("RIN34 Mute Switch", WM8990_RIGHT_LINE_INPUT_3_4_VOLUME,
413 WM8990_RI34MUTE_BIT, 1, 0),
414
415};
416
417/* add non dapm controls */
418static int wm8990_add_controls(struct snd_soc_codec *codec)
419{
420 int err, i;
421
422 for (i = 0; i < ARRAY_SIZE(wm8990_snd_controls); i++) {
423 err = snd_ctl_add(codec->card,
424 snd_soc_cnew(&wm8990_snd_controls[i], codec,
425 NULL));
426 if (err < 0)
427 return err;
428 }
429 return 0;
430}
431
432/*
433 * _DAPM_ Controls
434 */
435
436static int inmixer_event(struct snd_soc_dapm_widget *w,
437 struct snd_kcontrol *kcontrol, int event)
438{
439 u16 reg, fakepower;
440
441 reg = wm8990_read_reg_cache(w->codec, WM8990_POWER_MANAGEMENT_2);
442 fakepower = wm8990_read_reg_cache(w->codec, WM8990_INTDRIVBITS);
443
444 if (fakepower & ((1 << WM8990_INMIXL_PWR_BIT) |
445 (1 << WM8990_AINLMUX_PWR_BIT))) {
446 reg |= WM8990_AINL_ENA;
447 } else {
448 reg &= ~WM8990_AINL_ENA;
449 }
450
451 if (fakepower & ((1 << WM8990_INMIXR_PWR_BIT) |
452 (1 << WM8990_AINRMUX_PWR_BIT))) {
453 reg |= WM8990_AINR_ENA;
454 } else {
455 reg &= ~WM8990_AINL_ENA;
456 }
457 wm8990_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg);
458
459 return 0;
460}
461
462static int outmixer_event(struct snd_soc_dapm_widget *w,
463 struct snd_kcontrol *kcontrol, int event)
464{
465 u32 reg_shift = kcontrol->private_value & 0xfff;
466 int ret = 0;
467 u16 reg;
468
469 switch (reg_shift) {
470 case WM8990_SPEAKER_MIXER | (WM8990_LDSPK_BIT << 8) :
471 reg = wm8990_read_reg_cache(w->codec, WM8990_OUTPUT_MIXER1);
472 if (reg & WM8990_LDLO) {
473 printk(KERN_WARNING
474 "Cannot set as Output Mixer 1 LDLO Set\n");
475 ret = -1;
476 }
477 break;
478 case WM8990_SPEAKER_MIXER | (WM8990_RDSPK_BIT << 8):
479 reg = wm8990_read_reg_cache(w->codec, WM8990_OUTPUT_MIXER2);
480 if (reg & WM8990_RDRO) {
481 printk(KERN_WARNING
482 "Cannot set as Output Mixer 2 RDRO Set\n");
483 ret = -1;
484 }
485 break;
486 case WM8990_OUTPUT_MIXER1 | (WM8990_LDLO_BIT << 8):
487 reg = wm8990_read_reg_cache(w->codec, WM8990_SPEAKER_MIXER);
488 if (reg & WM8990_LDSPK) {
489 printk(KERN_WARNING
490 "Cannot set as Speaker Mixer LDSPK Set\n");
491 ret = -1;
492 }
493 break;
494 case WM8990_OUTPUT_MIXER2 | (WM8990_RDRO_BIT << 8):
495 reg = wm8990_read_reg_cache(w->codec, WM8990_SPEAKER_MIXER);
496 if (reg & WM8990_RDSPK) {
497 printk(KERN_WARNING
498 "Cannot set as Speaker Mixer RDSPK Set\n");
499 ret = -1;
500 }
501 break;
502 }
503
504 return ret;
505}
506
507/* INMIX dB values */
508static const unsigned int in_mix_tlv[] = {
509 TLV_DB_RANGE_HEAD(1),
510 0, 7, TLV_DB_LINEAR_ITEM(-1200, 600),
511};
512
513/* Left In PGA Connections */
514static const struct snd_kcontrol_new wm8990_dapm_lin12_pga_controls[] = {
515SOC_DAPM_SINGLE("LIN1 Switch", WM8990_INPUT_MIXER2, WM8990_LMN1_BIT, 1, 0),
516SOC_DAPM_SINGLE("LIN2 Switch", WM8990_INPUT_MIXER2, WM8990_LMP2_BIT, 1, 0),
517};
518
519static const struct snd_kcontrol_new wm8990_dapm_lin34_pga_controls[] = {
520SOC_DAPM_SINGLE("LIN3 Switch", WM8990_INPUT_MIXER2, WM8990_LMN3_BIT, 1, 0),
521SOC_DAPM_SINGLE("LIN4 Switch", WM8990_INPUT_MIXER2, WM8990_LMP4_BIT, 1, 0),
522};
523
524/* Right In PGA Connections */
525static const struct snd_kcontrol_new wm8990_dapm_rin12_pga_controls[] = {
526SOC_DAPM_SINGLE("RIN1 Switch", WM8990_INPUT_MIXER2, WM8990_RMN1_BIT, 1, 0),
527SOC_DAPM_SINGLE("RIN2 Switch", WM8990_INPUT_MIXER2, WM8990_RMP2_BIT, 1, 0),
528};
529
530static const struct snd_kcontrol_new wm8990_dapm_rin34_pga_controls[] = {
531SOC_DAPM_SINGLE("RIN3 Switch", WM8990_INPUT_MIXER2, WM8990_RMN3_BIT, 1, 0),
532SOC_DAPM_SINGLE("RIN4 Switch", WM8990_INPUT_MIXER2, WM8990_RMP4_BIT, 1, 0),
533};
534
535/* INMIXL */
536static const struct snd_kcontrol_new wm8990_dapm_inmixl_controls[] = {
537SOC_DAPM_SINGLE_TLV("Record Left Volume", WM8990_INPUT_MIXER3,
538 WM8990_LDBVOL_SHIFT, WM8990_LDBVOL_MASK, 0, in_mix_tlv),
539SOC_DAPM_SINGLE_TLV("LIN2 Volume", WM8990_INPUT_MIXER5, WM8990_LI2BVOL_SHIFT,
540 7, 0, in_mix_tlv),
541SOC_DAPM_SINGLE("LINPGA12 Switch", WM8990_INPUT_MIXER3, WM8990_L12MNB_BIT,
542 1, 0),
543SOC_DAPM_SINGLE("LINPGA34 Switch", WM8990_INPUT_MIXER3, WM8990_L34MNB_BIT,
544 1, 0),
545};
546
547/* INMIXR */
548static const struct snd_kcontrol_new wm8990_dapm_inmixr_controls[] = {
549SOC_DAPM_SINGLE_TLV("Record Right Volume", WM8990_INPUT_MIXER4,
550 WM8990_RDBVOL_SHIFT, WM8990_RDBVOL_MASK, 0, in_mix_tlv),
551SOC_DAPM_SINGLE_TLV("RIN2 Volume", WM8990_INPUT_MIXER6, WM8990_RI2BVOL_SHIFT,
552 7, 0, in_mix_tlv),
553SOC_DAPM_SINGLE("RINPGA12 Switch", WM8990_INPUT_MIXER3, WM8990_L12MNB_BIT,
554 1, 0),
555SOC_DAPM_SINGLE("RINPGA34 Switch", WM8990_INPUT_MIXER3, WM8990_L34MNB_BIT,
556 1, 0),
557};
558
559/* AINLMUX */
560static const char *wm8990_ainlmux[] =
561 {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"};
562
563static const struct soc_enum wm8990_ainlmux_enum =
564SOC_ENUM_SINGLE(WM8990_INPUT_MIXER1, WM8990_AINLMODE_SHIFT,
565 ARRAY_SIZE(wm8990_ainlmux), wm8990_ainlmux);
566
567static const struct snd_kcontrol_new wm8990_dapm_ainlmux_controls =
568SOC_DAPM_ENUM("Route", wm8990_ainlmux_enum);
569
570/* DIFFINL */
571
572/* AINRMUX */
573static const char *wm8990_ainrmux[] =
574 {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"};
575
576static const struct soc_enum wm8990_ainrmux_enum =
577SOC_ENUM_SINGLE(WM8990_INPUT_MIXER1, WM8990_AINRMODE_SHIFT,
578 ARRAY_SIZE(wm8990_ainrmux), wm8990_ainrmux);
579
580static const struct snd_kcontrol_new wm8990_dapm_ainrmux_controls =
581SOC_DAPM_ENUM("Route", wm8990_ainrmux_enum);
582
583/* RXVOICE */
584static const struct snd_kcontrol_new wm8990_dapm_rxvoice_controls[] = {
585SOC_DAPM_SINGLE_TLV("LIN4/RXN", WM8990_INPUT_MIXER5, WM8990_LR4BVOL_SHIFT,
586 WM8990_LR4BVOL_MASK, 0, in_mix_tlv),
587SOC_DAPM_SINGLE_TLV("RIN4/RXP", WM8990_INPUT_MIXER6, WM8990_RL4BVOL_SHIFT,
588 WM8990_RL4BVOL_MASK, 0, in_mix_tlv),
589};
590
591/* LOMIX */
592static const struct snd_kcontrol_new wm8990_dapm_lomix_controls[] = {
593SOC_DAPM_SINGLE("LOMIX Right ADC Bypass Switch", WM8990_OUTPUT_MIXER1,
594 WM8990_LRBLO_BIT, 1, 0),
595SOC_DAPM_SINGLE("LOMIX Left ADC Bypass Switch", WM8990_OUTPUT_MIXER1,
596 WM8990_LLBLO_BIT, 1, 0),
597SOC_DAPM_SINGLE("LOMIX RIN3 Bypass Switch", WM8990_OUTPUT_MIXER1,
598 WM8990_LRI3LO_BIT, 1, 0),
599SOC_DAPM_SINGLE("LOMIX LIN3 Bypass Switch", WM8990_OUTPUT_MIXER1,
600 WM8990_LLI3LO_BIT, 1, 0),
601SOC_DAPM_SINGLE("LOMIX RIN12 PGA Bypass Switch", WM8990_OUTPUT_MIXER1,
602 WM8990_LR12LO_BIT, 1, 0),
603SOC_DAPM_SINGLE("LOMIX LIN12 PGA Bypass Switch", WM8990_OUTPUT_MIXER1,
604 WM8990_LL12LO_BIT, 1, 0),
605SOC_DAPM_SINGLE("LOMIX Left DAC Switch", WM8990_OUTPUT_MIXER1,
606 WM8990_LDLO_BIT, 1, 0),
607};
608
609/* ROMIX */
610static const struct snd_kcontrol_new wm8990_dapm_romix_controls[] = {
611SOC_DAPM_SINGLE("ROMIX Left ADC Bypass Switch", WM8990_OUTPUT_MIXER2,
612 WM8990_RLBRO_BIT, 1, 0),
613SOC_DAPM_SINGLE("ROMIX Right ADC Bypass Switch", WM8990_OUTPUT_MIXER2,
614 WM8990_RRBRO_BIT, 1, 0),
615SOC_DAPM_SINGLE("ROMIX LIN3 Bypass Switch", WM8990_OUTPUT_MIXER2,
616 WM8990_RLI3RO_BIT, 1, 0),
617SOC_DAPM_SINGLE("ROMIX RIN3 Bypass Switch", WM8990_OUTPUT_MIXER2,
618 WM8990_RRI3RO_BIT, 1, 0),
619SOC_DAPM_SINGLE("ROMIX LIN12 PGA Bypass Switch", WM8990_OUTPUT_MIXER2,
620 WM8990_RL12RO_BIT, 1, 0),
621SOC_DAPM_SINGLE("ROMIX RIN12 PGA Bypass Switch", WM8990_OUTPUT_MIXER2,
622 WM8990_RR12RO_BIT, 1, 0),
623SOC_DAPM_SINGLE("ROMIX Right DAC Switch", WM8990_OUTPUT_MIXER2,
624 WM8990_RDRO_BIT, 1, 0),
625};
626
627/* LONMIX */
628static const struct snd_kcontrol_new wm8990_dapm_lonmix_controls[] = {
629SOC_DAPM_SINGLE("LONMIX Left Mixer PGA Switch", WM8990_LINE_MIXER1,
630 WM8990_LLOPGALON_BIT, 1, 0),
631SOC_DAPM_SINGLE("LONMIX Right Mixer PGA Switch", WM8990_LINE_MIXER1,
632 WM8990_LROPGALON_BIT, 1, 0),
633SOC_DAPM_SINGLE("LONMIX Inverted LOP Switch", WM8990_LINE_MIXER1,
634 WM8990_LOPLON_BIT, 1, 0),
635};
636
637/* LOPMIX */
638static const struct snd_kcontrol_new wm8990_dapm_lopmix_controls[] = {
639SOC_DAPM_SINGLE("LOPMIX Right Mic Bypass Switch", WM8990_LINE_MIXER1,
640 WM8990_LR12LOP_BIT, 1, 0),
641SOC_DAPM_SINGLE("LOPMIX Left Mic Bypass Switch", WM8990_LINE_MIXER1,
642 WM8990_LL12LOP_BIT, 1, 0),
643SOC_DAPM_SINGLE("LOPMIX Left Mixer PGA Switch", WM8990_LINE_MIXER1,
644 WM8990_LLOPGALOP_BIT, 1, 0),
645};
646
647/* RONMIX */
648static const struct snd_kcontrol_new wm8990_dapm_ronmix_controls[] = {
649SOC_DAPM_SINGLE("RONMIX Right Mixer PGA Switch", WM8990_LINE_MIXER2,
650 WM8990_RROPGARON_BIT, 1, 0),
651SOC_DAPM_SINGLE("RONMIX Left Mixer PGA Switch", WM8990_LINE_MIXER2,
652 WM8990_RLOPGARON_BIT, 1, 0),
653SOC_DAPM_SINGLE("RONMIX Inverted ROP Switch", WM8990_LINE_MIXER2,
654 WM8990_ROPRON_BIT, 1, 0),
655};
656
657/* ROPMIX */
658static const struct snd_kcontrol_new wm8990_dapm_ropmix_controls[] = {
659SOC_DAPM_SINGLE("ROPMIX Left Mic Bypass Switch", WM8990_LINE_MIXER2,
660 WM8990_RL12ROP_BIT, 1, 0),
661SOC_DAPM_SINGLE("ROPMIX Right Mic Bypass Switch", WM8990_LINE_MIXER2,
662 WM8990_RR12ROP_BIT, 1, 0),
663SOC_DAPM_SINGLE("ROPMIX Right Mixer PGA Switch", WM8990_LINE_MIXER2,
664 WM8990_RROPGAROP_BIT, 1, 0),
665};
666
667/* OUT3MIX */
668static const struct snd_kcontrol_new wm8990_dapm_out3mix_controls[] = {
669SOC_DAPM_SINGLE("OUT3MIX LIN4/RXP Bypass Switch", WM8990_OUT3_4_MIXER,
670 WM8990_LI4O3_BIT, 1, 0),
671SOC_DAPM_SINGLE("OUT3MIX Left Out PGA Switch", WM8990_OUT3_4_MIXER,
672 WM8990_LPGAO3_BIT, 1, 0),
673};
674
675/* OUT4MIX */
676static const struct snd_kcontrol_new wm8990_dapm_out4mix_controls[] = {
677SOC_DAPM_SINGLE("OUT4MIX Right Out PGA Switch", WM8990_OUT3_4_MIXER,
678 WM8990_RPGAO4_BIT, 1, 0),
679SOC_DAPM_SINGLE("OUT4MIX RIN4/RXP Bypass Switch", WM8990_OUT3_4_MIXER,
680 WM8990_RI4O4_BIT, 1, 0),
681};
682
683/* SPKMIX */
684static const struct snd_kcontrol_new wm8990_dapm_spkmix_controls[] = {
685SOC_DAPM_SINGLE("SPKMIX LIN2 Bypass Switch", WM8990_SPEAKER_MIXER,
686 WM8990_LI2SPK_BIT, 1, 0),
687SOC_DAPM_SINGLE("SPKMIX LADC Bypass Switch", WM8990_SPEAKER_MIXER,
688 WM8990_LB2SPK_BIT, 1, 0),
689SOC_DAPM_SINGLE("SPKMIX Left Mixer PGA Switch", WM8990_SPEAKER_MIXER,
690 WM8990_LOPGASPK_BIT, 1, 0),
691SOC_DAPM_SINGLE("SPKMIX Left DAC Switch", WM8990_SPEAKER_MIXER,
692 WM8990_LDSPK_BIT, 1, 0),
693SOC_DAPM_SINGLE("SPKMIX Right DAC Switch", WM8990_SPEAKER_MIXER,
694 WM8990_RDSPK_BIT, 1, 0),
695SOC_DAPM_SINGLE("SPKMIX Right Mixer PGA Switch", WM8990_SPEAKER_MIXER,
696 WM8990_ROPGASPK_BIT, 1, 0),
697SOC_DAPM_SINGLE("SPKMIX RADC Bypass Switch", WM8990_SPEAKER_MIXER,
698 WM8990_RL12ROP_BIT, 1, 0),
699SOC_DAPM_SINGLE("SPKMIX RIN2 Bypass Switch", WM8990_SPEAKER_MIXER,
700 WM8990_RI2SPK_BIT, 1, 0),
701};
702
703static const struct snd_soc_dapm_widget wm8990_dapm_widgets[] = {
704/* Input Side */
705/* Input Lines */
706SND_SOC_DAPM_INPUT("LIN1"),
707SND_SOC_DAPM_INPUT("LIN2"),
708SND_SOC_DAPM_INPUT("LIN3"),
709SND_SOC_DAPM_INPUT("LIN4/RXN"),
710SND_SOC_DAPM_INPUT("RIN3"),
711SND_SOC_DAPM_INPUT("RIN4/RXP"),
712SND_SOC_DAPM_INPUT("RIN1"),
713SND_SOC_DAPM_INPUT("RIN2"),
714SND_SOC_DAPM_INPUT("Internal ADC Source"),
715
716/* DACs */
717SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8990_POWER_MANAGEMENT_2,
718 WM8990_ADCL_ENA_BIT, 0),
719SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8990_POWER_MANAGEMENT_2,
720 WM8990_ADCR_ENA_BIT, 0),
721
722/* Input PGAs */
723SND_SOC_DAPM_MIXER("LIN12 PGA", WM8990_POWER_MANAGEMENT_2, WM8990_LIN12_ENA_BIT,
724 0, &wm8990_dapm_lin12_pga_controls[0],
725 ARRAY_SIZE(wm8990_dapm_lin12_pga_controls)),
726SND_SOC_DAPM_MIXER("LIN34 PGA", WM8990_POWER_MANAGEMENT_2, WM8990_LIN34_ENA_BIT,
727 0, &wm8990_dapm_lin34_pga_controls[0],
728 ARRAY_SIZE(wm8990_dapm_lin34_pga_controls)),
729SND_SOC_DAPM_MIXER("RIN12 PGA", WM8990_POWER_MANAGEMENT_2, WM8990_RIN12_ENA_BIT,
730 0, &wm8990_dapm_rin12_pga_controls[0],
731 ARRAY_SIZE(wm8990_dapm_rin12_pga_controls)),
732SND_SOC_DAPM_MIXER("RIN34 PGA", WM8990_POWER_MANAGEMENT_2, WM8990_RIN34_ENA_BIT,
733 0, &wm8990_dapm_rin34_pga_controls[0],
734 ARRAY_SIZE(wm8990_dapm_rin34_pga_controls)),
735
736/* INMIXL */
737SND_SOC_DAPM_MIXER_E("INMIXL", WM8990_INTDRIVBITS, WM8990_INMIXL_PWR_BIT, 0,
738 &wm8990_dapm_inmixl_controls[0],
739 ARRAY_SIZE(wm8990_dapm_inmixl_controls),
740 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
741
742/* AINLMUX */
743SND_SOC_DAPM_MUX_E("AILNMUX", WM8990_INTDRIVBITS, WM8990_AINLMUX_PWR_BIT, 0,
744 &wm8990_dapm_ainlmux_controls, inmixer_event,
745 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
746
747/* INMIXR */
748SND_SOC_DAPM_MIXER_E("INMIXR", WM8990_INTDRIVBITS, WM8990_INMIXR_PWR_BIT, 0,
749 &wm8990_dapm_inmixr_controls[0],
750 ARRAY_SIZE(wm8990_dapm_inmixr_controls),
751 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
752
753/* AINRMUX */
754SND_SOC_DAPM_MUX_E("AIRNMUX", WM8990_INTDRIVBITS, WM8990_AINRMUX_PWR_BIT, 0,
755 &wm8990_dapm_ainrmux_controls, inmixer_event,
756 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
757
758/* Output Side */
759/* DACs */
760SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8990_POWER_MANAGEMENT_3,
761 WM8990_DACL_ENA_BIT, 0),
762SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8990_POWER_MANAGEMENT_3,
763 WM8990_DACR_ENA_BIT, 0),
764
765/* LOMIX */
766SND_SOC_DAPM_MIXER_E("LOMIX", WM8990_POWER_MANAGEMENT_3, WM8990_LOMIX_ENA_BIT,
767 0, &wm8990_dapm_lomix_controls[0],
768 ARRAY_SIZE(wm8990_dapm_lomix_controls),
769 outmixer_event, SND_SOC_DAPM_PRE_REG),
770
771/* LONMIX */
772SND_SOC_DAPM_MIXER("LONMIX", WM8990_POWER_MANAGEMENT_3, WM8990_LON_ENA_BIT, 0,
773 &wm8990_dapm_lonmix_controls[0],
774 ARRAY_SIZE(wm8990_dapm_lonmix_controls)),
775
776/* LOPMIX */
777SND_SOC_DAPM_MIXER("LOPMIX", WM8990_POWER_MANAGEMENT_3, WM8990_LOP_ENA_BIT, 0,
778 &wm8990_dapm_lopmix_controls[0],
779 ARRAY_SIZE(wm8990_dapm_lopmix_controls)),
780
781/* OUT3MIX */
782SND_SOC_DAPM_MIXER("OUT3MIX", WM8990_POWER_MANAGEMENT_1, WM8990_OUT3_ENA_BIT, 0,
783 &wm8990_dapm_out3mix_controls[0],
784 ARRAY_SIZE(wm8990_dapm_out3mix_controls)),
785
786/* SPKMIX */
787SND_SOC_DAPM_MIXER_E("SPKMIX", WM8990_POWER_MANAGEMENT_1, WM8990_SPK_ENA_BIT, 0,
788 &wm8990_dapm_spkmix_controls[0],
789 ARRAY_SIZE(wm8990_dapm_spkmix_controls), outmixer_event,
790 SND_SOC_DAPM_PRE_REG),
791
792/* OUT4MIX */
793SND_SOC_DAPM_MIXER("OUT4MIX", WM8990_POWER_MANAGEMENT_1, WM8990_OUT4_ENA_BIT, 0,
794 &wm8990_dapm_out4mix_controls[0],
795 ARRAY_SIZE(wm8990_dapm_out4mix_controls)),
796
797/* ROPMIX */
798SND_SOC_DAPM_MIXER("ROPMIX", WM8990_POWER_MANAGEMENT_3, WM8990_ROP_ENA_BIT, 0,
799 &wm8990_dapm_ropmix_controls[0],
800 ARRAY_SIZE(wm8990_dapm_ropmix_controls)),
801
802/* RONMIX */
803SND_SOC_DAPM_MIXER("RONMIX", WM8990_POWER_MANAGEMENT_3, WM8990_RON_ENA_BIT, 0,
804 &wm8990_dapm_ronmix_controls[0],
805 ARRAY_SIZE(wm8990_dapm_ronmix_controls)),
806
807/* ROMIX */
808SND_SOC_DAPM_MIXER_E("ROMIX", WM8990_POWER_MANAGEMENT_3, WM8990_ROMIX_ENA_BIT,
809 0, &wm8990_dapm_romix_controls[0],
810 ARRAY_SIZE(wm8990_dapm_romix_controls),
811 outmixer_event, SND_SOC_DAPM_PRE_REG),
812
813/* LOUT PGA */
814SND_SOC_DAPM_PGA("LOUT PGA", WM8990_POWER_MANAGEMENT_1, WM8990_LOUT_ENA_BIT, 0,
815 NULL, 0),
816
817/* ROUT PGA */
818SND_SOC_DAPM_PGA("ROUT PGA", WM8990_POWER_MANAGEMENT_1, WM8990_ROUT_ENA_BIT, 0,
819 NULL, 0),
820
821/* LOPGA */
822SND_SOC_DAPM_PGA("LOPGA", WM8990_POWER_MANAGEMENT_3, WM8990_LOPGA_ENA_BIT, 0,
823 NULL, 0),
824
825/* ROPGA */
826SND_SOC_DAPM_PGA("ROPGA", WM8990_POWER_MANAGEMENT_3, WM8990_ROPGA_ENA_BIT, 0,
827 NULL, 0),
828
829/* MICBIAS */
830SND_SOC_DAPM_MICBIAS("MICBIAS", WM8990_POWER_MANAGEMENT_1,
831 WM8990_MICBIAS_ENA_BIT, 0),
832
833SND_SOC_DAPM_OUTPUT("LON"),
834SND_SOC_DAPM_OUTPUT("LOP"),
835SND_SOC_DAPM_OUTPUT("OUT3"),
836SND_SOC_DAPM_OUTPUT("LOUT"),
837SND_SOC_DAPM_OUTPUT("SPKN"),
838SND_SOC_DAPM_OUTPUT("SPKP"),
839SND_SOC_DAPM_OUTPUT("ROUT"),
840SND_SOC_DAPM_OUTPUT("OUT4"),
841SND_SOC_DAPM_OUTPUT("ROP"),
842SND_SOC_DAPM_OUTPUT("RON"),
843
844SND_SOC_DAPM_OUTPUT("Internal DAC Sink"),
845};
846
847static const struct snd_soc_dapm_route audio_map[] = {
848 /* Make DACs turn on when playing even if not mixed into any outputs */
849 {"Internal DAC Sink", NULL, "Left DAC"},
850 {"Internal DAC Sink", NULL, "Right DAC"},
851
852 /* Make ADCs turn on when recording even if not mixed from any inputs */
853 {"Left ADC", NULL, "Internal ADC Source"},
854 {"Right ADC", NULL, "Internal ADC Source"},
855
856 /* Input Side */
857 /* LIN12 PGA */
858 {"LIN12 PGA", "LIN1 Switch", "LIN1"},
859 {"LIN12 PGA", "LIN2 Switch", "LIN2"},
860 /* LIN34 PGA */
861 {"LIN34 PGA", "LIN3 Switch", "LIN3"},
862 {"LIN34 PGA", "LIN4 Switch", "LIN4"},
863 /* INMIXL */
864 {"INMIXL", "Record Left Volume", "LOMIX"},
865 {"INMIXL", "LIN2 Volume", "LIN2"},
866 {"INMIXL", "LINPGA12 Switch", "LIN12 PGA"},
867 {"INMIXL", "LINPGA34 Switch", "LIN34 PGA"},
868 /* AILNMUX */
869 {"AILNMUX", "INMIXL Mix", "INMIXL"},
870 {"AILNMUX", "DIFFINL Mix", "LIN12PGA"},
871 {"AILNMUX", "DIFFINL Mix", "LIN34PGA"},
872 {"AILNMUX", "RXVOICE Mix", "LIN4/RXN"},
873 {"AILNMUX", "RXVOICE Mix", "RIN4/RXP"},
874 /* ADC */
875 {"Left ADC", NULL, "AILNMUX"},
876
877 /* RIN12 PGA */
878 {"RIN12 PGA", "RIN1 Switch", "RIN1"},
879 {"RIN12 PGA", "RIN2 Switch", "RIN2"},
880 /* RIN34 PGA */
881 {"RIN34 PGA", "RIN3 Switch", "RIN3"},
882 {"RIN34 PGA", "RIN4 Switch", "RIN4"},
883 /* INMIXL */
884 {"INMIXR", "Record Right Volume", "ROMIX"},
885 {"INMIXR", "RIN2 Volume", "RIN2"},
886 {"INMIXR", "RINPGA12 Switch", "RIN12 PGA"},
887 {"INMIXR", "RINPGA34 Switch", "RIN34 PGA"},
888 /* AIRNMUX */
889 {"AIRNMUX", "INMIXR Mix", "INMIXR"},
890 {"AIRNMUX", "DIFFINR Mix", "RIN12PGA"},
891 {"AIRNMUX", "DIFFINR Mix", "RIN34PGA"},
892 {"AIRNMUX", "RXVOICE Mix", "RIN4/RXN"},
893 {"AIRNMUX", "RXVOICE Mix", "RIN4/RXP"},
894 /* ADC */
895 {"Right ADC", NULL, "AIRNMUX"},
896
897 /* LOMIX */
898 {"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"},
899 {"LOMIX", "LOMIX LIN3 Bypass Switch", "LIN3"},
900 {"LOMIX", "LOMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
901 {"LOMIX", "LOMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
902 {"LOMIX", "LOMIX Right ADC Bypass Switch", "AINRMUX"},
903 {"LOMIX", "LOMIX Left ADC Bypass Switch", "AINLMUX"},
904 {"LOMIX", "LOMIX Left DAC Switch", "Left DAC"},
905
906 /* ROMIX */
907 {"ROMIX", "ROMIX RIN3 Bypass Switch", "RIN3"},
908 {"ROMIX", "ROMIX LIN3 Bypass Switch", "LIN3"},
909 {"ROMIX", "ROMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
910 {"ROMIX", "ROMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
911 {"ROMIX", "ROMIX Right ADC Bypass Switch", "AINRMUX"},
912 {"ROMIX", "ROMIX Left ADC Bypass Switch", "AINLMUX"},
913 {"ROMIX", "ROMIX Right DAC Switch", "Right DAC"},
914
915 /* SPKMIX */
916 {"SPKMIX", "SPKMIX LIN2 Bypass Switch", "LIN2"},
917 {"SPKMIX", "SPKMIX RIN2 Bypass Switch", "RIN2"},
918 {"SPKMIX", "SPKMIX LADC Bypass Switch", "AINLMUX"},
919 {"SPKMIX", "SPKMIX RADC Bypass Switch", "AINRMUX"},
920 {"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"},
921 {"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"},
922 {"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"},
923 {"SPKMIX", "SPKMIX Left DAC Switch", "Right DAC"},
924
925 /* LONMIX */
926 {"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"},
927 {"LONMIX", "LONMIX Right Mixer PGA Switch", "ROPGA"},
928 {"LONMIX", "LONMIX Inverted LOP Switch", "LOPMIX"},
929
930 /* LOPMIX */
931 {"LOPMIX", "LOPMIX Right Mic Bypass Switch", "RIN12 PGA"},
932 {"LOPMIX", "LOPMIX Left Mic Bypass Switch", "LIN12 PGA"},
933 {"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"},
934
935 /* OUT3MIX */
936 {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXP"},
937 {"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"},
938
939 /* OUT4MIX */
940 {"OUT4MIX", "OUT4MIX Right Out PGA Switch", "ROPGA"},
941 {"OUT4MIX", "OUT4MIX RIN4/RXP Bypass Switch", "RIN4/RXP"},
942
943 /* RONMIX */
944 {"RONMIX", "RONMIX Right Mixer PGA Switch", "ROPGA"},
945 {"RONMIX", "RONMIX Left Mixer PGA Switch", "LOPGA"},
946 {"RONMIX", "RONMIX Inverted ROP Switch", "ROPMIX"},
947
948 /* ROPMIX */
949 {"ROPMIX", "ROPMIX Left Mic Bypass Switch", "LIN12 PGA"},
950 {"ROPMIX", "ROPMIX Right Mic Bypass Switch", "RIN12 PGA"},
951 {"ROPMIX", "ROPMIX Right Mixer PGA Switch", "ROPGA"},
952
953 /* Out Mixer PGAs */
954 {"LOPGA", NULL, "LOMIX"},
955 {"ROPGA", NULL, "ROMIX"},
956
957 {"LOUT PGA", NULL, "LOMIX"},
958 {"ROUT PGA", NULL, "ROMIX"},
959
960 /* Output Pins */
961 {"LON", NULL, "LONMIX"},
962 {"LOP", NULL, "LOPMIX"},
963 {"OUT", NULL, "OUT3MIX"},
964 {"LOUT", NULL, "LOUT PGA"},
965 {"SPKN", NULL, "SPKMIX"},
966 {"ROUT", NULL, "ROUT PGA"},
967 {"OUT4", NULL, "OUT4MIX"},
968 {"ROP", NULL, "ROPMIX"},
969 {"RON", NULL, "RONMIX"},
970};
971
972static int wm8990_add_widgets(struct snd_soc_codec *codec)
973{
974 snd_soc_dapm_new_controls(codec, wm8990_dapm_widgets,
975 ARRAY_SIZE(wm8990_dapm_widgets));
976
977 /* set up the WM8990 audio map */
978 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
979
980 snd_soc_dapm_new_widgets(codec);
981 return 0;
982}
983
984/* PLL divisors */
985struct _pll_div {
986 u32 div2;
987 u32 n;
988 u32 k;
989};
990
991/* The size in bits of the pll divide multiplied by 10
992 * to allow rounding later */
993#define FIXED_PLL_SIZE ((1 << 16) * 10)
994
995static void pll_factors(struct _pll_div *pll_div, unsigned int target,
996 unsigned int source)
997{
998 u64 Kpart;
999 unsigned int K, Ndiv, Nmod;
1000
1001
1002 Ndiv = target / source;
1003 if (Ndiv < 6) {
1004 source >>= 1;
1005 pll_div->div2 = 1;
1006 Ndiv = target / source;
1007 } else
1008 pll_div->div2 = 0;
1009
1010 if ((Ndiv < 6) || (Ndiv > 12))
1011 printk(KERN_WARNING
1012 "WM8990 N value outwith recommended range! N = %d\n", Ndiv);
1013
1014 pll_div->n = Ndiv;
1015 Nmod = target % source;
1016 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
1017
1018 do_div(Kpart, source);
1019
1020 K = Kpart & 0xFFFFFFFF;
1021
1022 /* Check if we need to round */
1023 if ((K % 10) >= 5)
1024 K += 5;
1025
1026 /* Move down to proper range now rounding is done */
1027 K /= 10;
1028
1029 pll_div->k = K;
1030}
1031
1032static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai,
1033 int pll_id, unsigned int freq_in, unsigned int freq_out)
1034{
1035 u16 reg;
1036 struct snd_soc_codec *codec = codec_dai->codec;
1037 struct _pll_div pll_div;
1038
1039 if (freq_in && freq_out) {
1040 pll_factors(&pll_div, freq_out * 4, freq_in);
1041
1042 /* Turn on PLL */
1043 reg = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_2);
1044 reg |= WM8990_PLL_ENA;
1045 wm8990_write(codec, WM8990_POWER_MANAGEMENT_2, reg);
1046
1047 /* sysclk comes from PLL */
1048 reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2);
1049 wm8990_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC);
1050
1051 /* set up N , fractional mode and pre-divisor if neccessary */
1052 wm8990_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM |
1053 (pll_div.div2?WM8990_PRESCALE:0));
1054 wm8990_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8));
1055 wm8990_write(codec, WM8990_PLL3, (u8)(pll_div.k & 0xFF));
1056 } else {
1057 /* Turn on PLL */
1058 reg = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_2);
1059 reg &= ~WM8990_PLL_ENA;
1060 wm8990_write(codec, WM8990_POWER_MANAGEMENT_2, reg);
1061 }
1062 return 0;
1063}
1064
1065/*
1066 * Clock after PLL and dividers
1067 */
1068static int wm8990_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1069 int clk_id, unsigned int freq, int dir)
1070{
1071 struct snd_soc_codec *codec = codec_dai->codec;
1072 struct wm8990_priv *wm8990 = codec->private_data;
1073
1074 wm8990->sysclk = freq;
1075 return 0;
1076}
1077
1078/*
1079 * Set's ADC and Voice DAC format.
1080 */
1081static int wm8990_set_dai_fmt(struct snd_soc_dai *codec_dai,
1082 unsigned int fmt)
1083{
1084 struct snd_soc_codec *codec = codec_dai->codec;
1085 u16 audio1, audio3;
1086
1087 audio1 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_1);
1088 audio3 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_3);
1089
1090 /* set master/slave audio interface */
1091 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1092 case SND_SOC_DAIFMT_CBS_CFS:
1093 audio3 &= ~WM8990_AIF_MSTR1;
1094 break;
1095 case SND_SOC_DAIFMT_CBM_CFM:
1096 audio3 |= WM8990_AIF_MSTR1;
1097 break;
1098 default:
1099 return -EINVAL;
1100 }
1101
1102 audio1 &= ~WM8990_AIF_FMT_MASK;
1103
1104 /* interface format */
1105 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1106 case SND_SOC_DAIFMT_I2S:
1107 audio1 |= WM8990_AIF_TMF_I2S;
1108 audio1 &= ~WM8990_AIF_LRCLK_INV;
1109 break;
1110 case SND_SOC_DAIFMT_RIGHT_J:
1111 audio1 |= WM8990_AIF_TMF_RIGHTJ;
1112 audio1 &= ~WM8990_AIF_LRCLK_INV;
1113 break;
1114 case SND_SOC_DAIFMT_LEFT_J:
1115 audio1 |= WM8990_AIF_TMF_LEFTJ;
1116 audio1 &= ~WM8990_AIF_LRCLK_INV;
1117 break;
1118 case SND_SOC_DAIFMT_DSP_A:
1119 audio1 |= WM8990_AIF_TMF_DSP;
1120 audio1 &= ~WM8990_AIF_LRCLK_INV;
1121 break;
1122 case SND_SOC_DAIFMT_DSP_B:
1123 audio1 |= WM8990_AIF_TMF_DSP | WM8990_AIF_LRCLK_INV;
1124 break;
1125 default:
1126 return -EINVAL;
1127 }
1128
1129 wm8990_write(codec, WM8990_AUDIO_INTERFACE_1, audio1);
1130 wm8990_write(codec, WM8990_AUDIO_INTERFACE_3, audio3);
1131 return 0;
1132}
1133
1134static int wm8990_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1135 int div_id, int div)
1136{
1137 struct snd_soc_codec *codec = codec_dai->codec;
1138 u16 reg;
1139
1140 switch (div_id) {
1141 case WM8990_MCLK_DIV:
1142 reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2) &
1143 ~WM8990_MCLK_DIV_MASK;
1144 wm8990_write(codec, WM8990_CLOCKING_2, reg | div);
1145 break;
1146 case WM8990_DACCLK_DIV:
1147 reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2) &
1148 ~WM8990_DAC_CLKDIV_MASK;
1149 wm8990_write(codec, WM8990_CLOCKING_2, reg | div);
1150 break;
1151 case WM8990_ADCCLK_DIV:
1152 reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2) &
1153 ~WM8990_ADC_CLKDIV_MASK;
1154 wm8990_write(codec, WM8990_CLOCKING_2, reg | div);
1155 break;
1156 case WM8990_BCLK_DIV:
1157 reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_1) &
1158 ~WM8990_BCLK_DIV_MASK;
1159 wm8990_write(codec, WM8990_CLOCKING_1, reg | div);
1160 break;
1161 default:
1162 return -EINVAL;
1163 }
1164
1165 return 0;
1166}
1167
1168/*
1169 * Set PCM DAI bit size and sample rate.
1170 */
1171static int wm8990_hw_params(struct snd_pcm_substream *substream,
1172 struct snd_pcm_hw_params *params)
1173{
1174 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1175 struct snd_soc_device *socdev = rtd->socdev;
1176 struct snd_soc_codec *codec = socdev->codec;
1177 u16 audio1 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_1);
1178
1179 audio1 &= ~WM8990_AIF_WL_MASK;
1180 /* bit size */
1181 switch (params_format(params)) {
1182 case SNDRV_PCM_FORMAT_S16_LE:
1183 break;
1184 case SNDRV_PCM_FORMAT_S20_3LE:
1185 audio1 |= WM8990_AIF_WL_20BITS;
1186 break;
1187 case SNDRV_PCM_FORMAT_S24_LE:
1188 audio1 |= WM8990_AIF_WL_24BITS;
1189 break;
1190 case SNDRV_PCM_FORMAT_S32_LE:
1191 audio1 |= WM8990_AIF_WL_32BITS;
1192 break;
1193 }
1194
1195 wm8990_write(codec, WM8990_AUDIO_INTERFACE_1, audio1);
1196 return 0;
1197}
1198
1199static int wm8990_mute(struct snd_soc_dai *dai, int mute)
1200{
1201 struct snd_soc_codec *codec = dai->codec;
1202 u16 val;
1203
1204 val = wm8990_read_reg_cache(codec, WM8990_DAC_CTRL) & ~WM8990_DAC_MUTE;
1205
1206 if (mute)
1207 wm8990_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE);
1208 else
1209 wm8990_write(codec, WM8990_DAC_CTRL, val);
1210
1211 return 0;
1212}
1213
1214static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1215 enum snd_soc_bias_level level)
1216{
1217 u16 val;
1218
1219 switch (level) {
1220 case SND_SOC_BIAS_ON:
1221 break;
1222 case SND_SOC_BIAS_PREPARE:
1223 break;
1224 case SND_SOC_BIAS_STANDBY:
1225 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1226 /* Enable all output discharge bits */
1227 wm8990_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
1228 WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
1229 WM8990_DIS_OUT4 | WM8990_DIS_LOUT |
1230 WM8990_DIS_ROUT);
1231
1232 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
1233 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
1234 WM8990_BUFDCOPEN | WM8990_POBCTRL |
1235 WM8990_VMIDTOG);
1236
1237 /* Delay to allow output caps to discharge */
1238 msleep(msecs_to_jiffies(300));
1239
1240 /* Disable VMIDTOG */
1241 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
1242 WM8990_BUFDCOPEN | WM8990_POBCTRL);
1243
1244 /* disable all output discharge bits */
1245 wm8990_write(codec, WM8990_ANTIPOP1, 0);
1246
1247 /* Enable outputs */
1248 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1b00);
1249
1250 msleep(msecs_to_jiffies(50));
1251
1252 /* Enable VMID at 2x50k */
1253 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f02);
1254
1255 msleep(msecs_to_jiffies(100));
1256
1257 /* Enable VREF */
1258 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
1259
1260 msleep(msecs_to_jiffies(600));
1261
1262 /* Enable BUFIOEN */
1263 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
1264 WM8990_BUFDCOPEN | WM8990_POBCTRL |
1265 WM8990_BUFIOEN);
1266
1267 /* Disable outputs */
1268 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x3);
1269
1270 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1271 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN);
1272 } else {
1273 /* ON -> standby */
1274
1275 }
1276 break;
1277
1278 case SND_SOC_BIAS_OFF:
1279 /* Enable POBCTRL and SOFT_ST */
1280 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
1281 WM8990_POBCTRL | WM8990_BUFIOEN);
1282
1283 /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
1284 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
1285 WM8990_BUFDCOPEN | WM8990_POBCTRL |
1286 WM8990_BUFIOEN);
1287
1288 /* mute DAC */
1289 val = wm8990_read_reg_cache(codec, WM8990_DAC_CTRL);
1290 wm8990_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE);
1291
1292 /* Enable any disabled outputs */
1293 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
1294
1295 /* Disable VMID */
1296 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f01);
1297
1298 msleep(msecs_to_jiffies(300));
1299
1300 /* Enable all output discharge bits */
1301 wm8990_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
1302 WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
1303 WM8990_DIS_OUT4 | WM8990_DIS_LOUT |
1304 WM8990_DIS_ROUT);
1305
1306 /* Disable VREF */
1307 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x0);
1308
1309 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1310 wm8990_write(codec, WM8990_ANTIPOP2, 0x0);
1311 break;
1312 }
1313
1314 codec->bias_level = level;
1315 return 0;
1316}
1317
1318#define WM8990_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
1319 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
1320 SNDRV_PCM_RATE_48000)
1321
1322#define WM8990_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1323 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1324
1325/*
1326 * The WM8990 supports 2 different and mutually exclusive DAI
1327 * configurations.
1328 *
1329 * 1. ADC/DAC on Primary Interface
1330 * 2. ADC on Primary Interface/DAC on secondary
1331 */
1332struct snd_soc_dai wm8990_dai = {
1333/* ADC/DAC on primary */
1334 .name = "WM8990 ADC/DAC Primary",
1335 .id = 1,
1336 .playback = {
1337 .stream_name = "Playback",
1338 .channels_min = 1,
1339 .channels_max = 2,
1340 .rates = WM8990_RATES,
1341 .formats = WM8990_FORMATS,},
1342 .capture = {
1343 .stream_name = "Capture",
1344 .channels_min = 1,
1345 .channels_max = 2,
1346 .rates = WM8990_RATES,
1347 .formats = WM8990_FORMATS,},
1348 .ops = {
1349 .hw_params = wm8990_hw_params,},
1350 .dai_ops = {
1351 .digital_mute = wm8990_mute,
1352 .set_fmt = wm8990_set_dai_fmt,
1353 .set_clkdiv = wm8990_set_dai_clkdiv,
1354 .set_pll = wm8990_set_dai_pll,
1355 .set_sysclk = wm8990_set_dai_sysclk,
1356 },
1357};
1358EXPORT_SYMBOL_GPL(wm8990_dai);
1359
1360static int wm8990_suspend(struct platform_device *pdev, pm_message_t state)
1361{
1362 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1363 struct snd_soc_codec *codec = socdev->codec;
1364
1365 /* we only need to suspend if we are a valid card */
1366 if (!codec->card)
1367 return 0;
1368
1369 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
1370 return 0;
1371}
1372
1373static int wm8990_resume(struct platform_device *pdev)
1374{
1375 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1376 struct snd_soc_codec *codec = socdev->codec;
1377 int i;
1378 u8 data[2];
1379 u16 *cache = codec->reg_cache;
1380
1381 /* we only need to resume if we are a valid card */
1382 if (!codec->card)
1383 return 0;
1384
1385 /* Sync reg_cache with the hardware */
1386 for (i = 0; i < ARRAY_SIZE(wm8990_reg); i++) {
1387 if (i + 1 == WM8990_RESET)
1388 continue;
1389 data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001);
1390 data[1] = cache[i] & 0x00ff;
1391 codec->hw_write(codec->control_data, data, 2);
1392 }
1393
1394 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1395 return 0;
1396}
1397
1398/*
1399 * initialise the WM8990 driver
1400 * register the mixer and dsp interfaces with the kernel
1401 */
1402static int wm8990_init(struct snd_soc_device *socdev)
1403{
1404 struct snd_soc_codec *codec = socdev->codec;
1405 u16 reg;
1406 int ret = 0;
1407
1408 codec->name = "WM8990";
1409 codec->owner = THIS_MODULE;
1410 codec->read = wm8990_read_reg_cache;
1411 codec->write = wm8990_write;
1412 codec->set_bias_level = wm8990_set_bias_level;
1413 codec->dai = &wm8990_dai;
1414 codec->num_dai = 2;
1415 codec->reg_cache_size = ARRAY_SIZE(wm8990_reg);
1416 codec->reg_cache = kmemdup(wm8990_reg, sizeof(wm8990_reg), GFP_KERNEL);
1417
1418 if (codec->reg_cache == NULL)
1419 return -ENOMEM;
1420
1421 wm8990_reset(codec);
1422
1423 /* register pcms */
1424 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1425 if (ret < 0) {
1426 printk(KERN_ERR "wm8990: failed to create pcms\n");
1427 goto pcm_err;
1428 }
1429
1430 /* charge output caps */
1431 codec->bias_level = SND_SOC_BIAS_OFF;
1432 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1433
1434 reg = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_4);
1435 wm8990_write(codec, WM8990_AUDIO_INTERFACE_4, reg | WM8990_ALRCGPIO1);
1436
1437 reg = wm8990_read_reg_cache(codec, WM8990_GPIO1_GPIO2) &
1438 ~WM8990_GPIO1_SEL_MASK;
1439 wm8990_write(codec, WM8990_GPIO1_GPIO2, reg | 1);
1440
1441 reg = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_2);
1442 wm8990_write(codec, WM8990_POWER_MANAGEMENT_2, reg | WM8990_OPCLK_ENA);
1443
1444 wm8990_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1445 wm8990_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1446
1447 wm8990_add_controls(codec);
1448 wm8990_add_widgets(codec);
1449 ret = snd_soc_register_card(socdev);
1450 if (ret < 0) {
1451 printk(KERN_ERR "wm8990: failed to register card\n");
1452 goto card_err;
1453 }
1454 return ret;
1455
1456card_err:
1457 snd_soc_free_pcms(socdev);
1458 snd_soc_dapm_free(socdev);
1459pcm_err:
1460 kfree(codec->reg_cache);
1461 return ret;
1462}
1463
1464/* If the i2c layer weren't so broken, we could pass this kind of data
1465 around */
1466static struct snd_soc_device *wm8990_socdev;
1467
1468#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1469
1470/*
1471 * WM891 2 wire address is determined by GPIO5
1472 * state during powerup.
1473 * low = 0x34
1474 * high = 0x36
1475 */
1476static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
1477
1478/* Magic definition of all other variables and things */
1479I2C_CLIENT_INSMOD;
1480
1481static struct i2c_driver wm8990_i2c_driver;
1482static struct i2c_client client_template;
1483
1484static int wm8990_codec_probe(struct i2c_adapter *adap, int addr, int kind)
1485{
1486 struct snd_soc_device *socdev = wm8990_socdev;
1487 struct wm8990_setup_data *setup = socdev->codec_data;
1488 struct snd_soc_codec *codec = socdev->codec;
1489 struct i2c_client *i2c;
1490 int ret;
1491
1492 if (addr != setup->i2c_address)
1493 return -ENODEV;
1494
1495 client_template.adapter = adap;
1496 client_template.addr = addr;
1497
1498 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1499 if (i2c == NULL) {
1500 kfree(codec);
1501 return -ENOMEM;
1502 }
1503 i2c_set_clientdata(i2c, codec);
1504 codec->control_data = i2c;
1505
1506 ret = i2c_attach_client(i2c);
1507 if (ret < 0) {
1508 pr_err("failed to attach codec at addr %x\n", addr);
1509 goto err;
1510 }
1511
1512 ret = wm8990_init(socdev);
1513 if (ret < 0) {
1514 pr_err("failed to initialise WM8990\n");
1515 goto err;
1516 }
1517 return ret;
1518
1519err:
1520 kfree(codec);
1521 kfree(i2c);
1522 return ret;
1523}
1524
1525static int wm8990_i2c_detach(struct i2c_client *client)
1526{
1527 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1528 i2c_detach_client(client);
1529 kfree(codec->reg_cache);
1530 kfree(client);
1531 return 0;
1532}
1533
1534static int wm8990_i2c_attach(struct i2c_adapter *adap)
1535{
1536 return i2c_probe(adap, &addr_data, wm8990_codec_probe);
1537}
1538
1539static struct i2c_driver wm8990_i2c_driver = {
1540 .driver = {
1541 .name = "WM8990 I2C Codec",
1542 .owner = THIS_MODULE,
1543 },
1544 .attach_adapter = wm8990_i2c_attach,
1545 .detach_client = wm8990_i2c_detach,
1546 .command = NULL,
1547};
1548
1549static struct i2c_client client_template = {
1550 .name = "WM8990",
1551 .driver = &wm8990_i2c_driver,
1552};
1553#endif
1554
1555static int wm8990_probe(struct platform_device *pdev)
1556{
1557 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1558 struct wm8990_setup_data *setup;
1559 struct snd_soc_codec *codec;
1560 struct wm8990_priv *wm8990;
1561 int ret = 0;
1562
1563 pr_info("WM8990 Audio Codec %s\n", WM8990_VERSION);
1564
1565 setup = socdev->codec_data;
1566 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1567 if (codec == NULL)
1568 return -ENOMEM;
1569
1570 wm8990 = kzalloc(sizeof(struct wm8990_priv), GFP_KERNEL);
1571 if (wm8990 == NULL) {
1572 kfree(codec);
1573 return -ENOMEM;
1574 }
1575
1576 codec->private_data = wm8990;
1577 socdev->codec = codec;
1578 mutex_init(&codec->mutex);
1579 INIT_LIST_HEAD(&codec->dapm_widgets);
1580 INIT_LIST_HEAD(&codec->dapm_paths);
1581 wm8990_socdev = socdev;
1582
1583#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1584 if (setup->i2c_address) {
1585 normal_i2c[0] = setup->i2c_address;
1586 codec->hw_write = (hw_write_t)i2c_master_send;
1587 ret = i2c_add_driver(&wm8990_i2c_driver);
1588 if (ret != 0)
1589 printk(KERN_ERR "can't add i2c driver");
1590 }
1591#else
1592 /* Add other interfaces here */
1593#endif
1594 return ret;
1595}
1596
1597/* power down chip */
1598static int wm8990_remove(struct platform_device *pdev)
1599{
1600 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1601 struct snd_soc_codec *codec = socdev->codec;
1602
1603 if (codec->control_data)
1604 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
1605 snd_soc_free_pcms(socdev);
1606 snd_soc_dapm_free(socdev);
1607#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1608 i2c_del_driver(&wm8990_i2c_driver);
1609#endif
1610 kfree(codec->private_data);
1611 kfree(codec);
1612
1613 return 0;
1614}
1615
1616struct snd_soc_codec_device soc_codec_dev_wm8990 = {
1617 .probe = wm8990_probe,
1618 .remove = wm8990_remove,
1619 .suspend = wm8990_suspend,
1620 .resume = wm8990_resume,
1621};
1622EXPORT_SYMBOL_GPL(soc_codec_dev_wm8990);
1623
1624MODULE_DESCRIPTION("ASoC WM8990 driver");
1625MODULE_AUTHOR("Liam Girdwood");
1626MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h
new file mode 100644
index 000000000000..6bea57485283
--- /dev/null
+++ b/sound/soc/codecs/wm8990.h
@@ -0,0 +1,832 @@
1/*
2 * wm8990.h -- audio driver for WM8990
3 *
4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#ifndef __WM8990REGISTERDEFS_H__
16#define __WM8990REGISTERDEFS_H__
17
18/*
19 * Register values.
20 */
21#define WM8990_RESET 0x00
22#define WM8990_POWER_MANAGEMENT_1 0x01
23#define WM8990_POWER_MANAGEMENT_2 0x02
24#define WM8990_POWER_MANAGEMENT_3 0x03
25#define WM8990_AUDIO_INTERFACE_1 0x04
26#define WM8990_AUDIO_INTERFACE_2 0x05
27#define WM8990_CLOCKING_1 0x06
28#define WM8990_CLOCKING_2 0x07
29#define WM8990_AUDIO_INTERFACE_3 0x08
30#define WM8990_AUDIO_INTERFACE_4 0x09
31#define WM8990_DAC_CTRL 0x0A
32#define WM8990_LEFT_DAC_DIGITAL_VOLUME 0x0B
33#define WM8990_RIGHT_DAC_DIGITAL_VOLUME 0x0C
34#define WM8990_DIGITAL_SIDE_TONE 0x0D
35#define WM8990_ADC_CTRL 0x0E
36#define WM8990_LEFT_ADC_DIGITAL_VOLUME 0x0F
37#define WM8990_RIGHT_ADC_DIGITAL_VOLUME 0x10
38#define WM8990_GPIO_CTRL_1 0x12
39#define WM8990_GPIO1_GPIO2 0x13
40#define WM8990_GPIO3_GPIO4 0x14
41#define WM8990_GPIO5_GPIO6 0x15
42#define WM8990_GPIOCTRL_2 0x16
43#define WM8990_GPIO_POL 0x17
44#define WM8990_LEFT_LINE_INPUT_1_2_VOLUME 0x18
45#define WM8990_LEFT_LINE_INPUT_3_4_VOLUME 0x19
46#define WM8990_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A
47#define WM8990_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B
48#define WM8990_LEFT_OUTPUT_VOLUME 0x1C
49#define WM8990_RIGHT_OUTPUT_VOLUME 0x1D
50#define WM8990_LINE_OUTPUTS_VOLUME 0x1E
51#define WM8990_OUT3_4_VOLUME 0x1F
52#define WM8990_LEFT_OPGA_VOLUME 0x20
53#define WM8990_RIGHT_OPGA_VOLUME 0x21
54#define WM8990_SPEAKER_VOLUME 0x22
55#define WM8990_CLASSD1 0x23
56#define WM8990_CLASSD3 0x25
57#define WM8990_INPUT_MIXER1 0x27
58#define WM8990_INPUT_MIXER2 0x28
59#define WM8990_INPUT_MIXER3 0x29
60#define WM8990_INPUT_MIXER4 0x2A
61#define WM8990_INPUT_MIXER5 0x2B
62#define WM8990_INPUT_MIXER6 0x2C
63#define WM8990_OUTPUT_MIXER1 0x2D
64#define WM8990_OUTPUT_MIXER2 0x2E
65#define WM8990_OUTPUT_MIXER3 0x2F
66#define WM8990_OUTPUT_MIXER4 0x30
67#define WM8990_OUTPUT_MIXER5 0x31
68#define WM8990_OUTPUT_MIXER6 0x32
69#define WM8990_OUT3_4_MIXER 0x33
70#define WM8990_LINE_MIXER1 0x34
71#define WM8990_LINE_MIXER2 0x35
72#define WM8990_SPEAKER_MIXER 0x36
73#define WM8990_ADDITIONAL_CONTROL 0x37
74#define WM8990_ANTIPOP1 0x38
75#define WM8990_ANTIPOP2 0x39
76#define WM8990_MICBIAS 0x3A
77#define WM8990_PLL1 0x3C
78#define WM8990_PLL2 0x3D
79#define WM8990_PLL3 0x3E
80#define WM8990_INTDRIVBITS 0x3F
81
82#define WM8990_REGISTER_COUNT 60
83#define WM8990_MAX_REGISTER 0x3F
84
85/*
86 * Field Definitions.
87 */
88
89/*
90 * R0 (0x00) - Reset
91 */
92#define WM8990_SW_RESET_CHIP_ID_MASK 0xFFFF /* SW_RESET_CHIP_ID */
93
94/*
95 * R1 (0x01) - Power Management (1)
96 */
97#define WM8990_SPK_ENA 0x1000 /* SPK_ENA */
98#define WM8990_SPK_ENA_BIT 12
99#define WM8990_OUT3_ENA 0x0800 /* OUT3_ENA */
100#define WM8990_OUT3_ENA_BIT 11
101#define WM8990_OUT4_ENA 0x0400 /* OUT4_ENA */
102#define WM8990_OUT4_ENA_BIT 10
103#define WM8990_LOUT_ENA 0x0200 /* LOUT_ENA */
104#define WM8990_LOUT_ENA_BIT 9
105#define WM8990_ROUT_ENA 0x0100 /* ROUT_ENA */
106#define WM8990_ROUT_ENA_BIT 8
107#define WM8990_MICBIAS_ENA 0x0010 /* MICBIAS_ENA */
108#define WM8990_MICBIAS_ENA_BIT 4
109#define WM8990_VMID_MODE_MASK 0x0006 /* VMID_MODE - [2:1] */
110#define WM8990_VREF_ENA 0x0001 /* VREF_ENA */
111#define WM8990_VREF_ENA_BIT 0
112
113/*
114 * R2 (0x02) - Power Management (2)
115 */
116#define WM8990_PLL_ENA 0x8000 /* PLL_ENA */
117#define WM8990_PLL_ENA_BIT 15
118#define WM8990_TSHUT_ENA 0x4000 /* TSHUT_ENA */
119#define WM8990_TSHUT_ENA_BIT 14
120#define WM8990_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
121#define WM8990_TSHUT_OPDIS_BIT 13
122#define WM8990_OPCLK_ENA 0x0800 /* OPCLK_ENA */
123#define WM8990_OPCLK_ENA_BIT 11
124#define WM8990_AINL_ENA 0x0200 /* AINL_ENA */
125#define WM8990_AINL_ENA_BIT 9
126#define WM8990_AINR_ENA 0x0100 /* AINR_ENA */
127#define WM8990_AINR_ENA_BIT 8
128#define WM8990_LIN34_ENA 0x0080 /* LIN34_ENA */
129#define WM8990_LIN34_ENA_BIT 7
130#define WM8990_LIN12_ENA 0x0040 /* LIN12_ENA */
131#define WM8990_LIN12_ENA_BIT 6
132#define WM8990_RIN34_ENA 0x0020 /* RIN34_ENA */
133#define WM8990_RIN34_ENA_BIT 5
134#define WM8990_RIN12_ENA 0x0010 /* RIN12_ENA */
135#define WM8990_RIN12_ENA_BIT 4
136#define WM8990_ADCL_ENA 0x0002 /* ADCL_ENA */
137#define WM8990_ADCL_ENA_BIT 1
138#define WM8990_ADCR_ENA 0x0001 /* ADCR_ENA */
139#define WM8990_ADCR_ENA_BIT 0
140
141/*
142 * R3 (0x03) - Power Management (3)
143 */
144#define WM8990_LON_ENA 0x2000 /* LON_ENA */
145#define WM8990_LON_ENA_BIT 13
146#define WM8990_LOP_ENA 0x1000 /* LOP_ENA */
147#define WM8990_LOP_ENA_BIT 12
148#define WM8990_RON_ENA 0x0800 /* RON_ENA */
149#define WM8990_RON_ENA_BIT 11
150#define WM8990_ROP_ENA 0x0400 /* ROP_ENA */
151#define WM8990_ROP_ENA_BIT 10
152#define WM8990_LOPGA_ENA 0x0080 /* LOPGA_ENA */
153#define WM8990_LOPGA_ENA_BIT 7
154#define WM8990_ROPGA_ENA 0x0040 /* ROPGA_ENA */
155#define WM8990_ROPGA_ENA_BIT 6
156#define WM8990_LOMIX_ENA 0x0020 /* LOMIX_ENA */
157#define WM8990_LOMIX_ENA_BIT 5
158#define WM8990_ROMIX_ENA 0x0010 /* ROMIX_ENA */
159#define WM8990_ROMIX_ENA_BIT 4
160#define WM8990_DACL_ENA 0x0002 /* DACL_ENA */
161#define WM8990_DACL_ENA_BIT 1
162#define WM8990_DACR_ENA 0x0001 /* DACR_ENA */
163#define WM8990_DACR_ENA_BIT 0
164
165/*
166 * R4 (0x04) - Audio Interface (1)
167 */
168#define WM8990_AIFADCL_SRC 0x8000 /* AIFADCL_SRC */
169#define WM8990_AIFADCR_SRC 0x4000 /* AIFADCR_SRC */
170#define WM8990_AIFADC_TDM 0x2000 /* AIFADC_TDM */
171#define WM8990_AIFADC_TDM_CHAN 0x1000 /* AIFADC_TDM_CHAN */
172#define WM8990_AIF_BCLK_INV 0x0100 /* AIF_BCLK_INV */
173#define WM8990_AIF_LRCLK_INV 0x0080 /* AIF_LRCLK_INV */
174#define WM8990_AIF_WL_MASK 0x0060 /* AIF_WL - [6:5] */
175#define WM8990_AIF_WL_16BITS (0 << 5)
176#define WM8990_AIF_WL_20BITS (1 << 5)
177#define WM8990_AIF_WL_24BITS (2 << 5)
178#define WM8990_AIF_WL_32BITS (3 << 5)
179#define WM8990_AIF_FMT_MASK 0x0018 /* AIF_FMT - [4:3] */
180#define WM8990_AIF_TMF_RIGHTJ (0 << 3)
181#define WM8990_AIF_TMF_LEFTJ (1 << 3)
182#define WM8990_AIF_TMF_I2S (2 << 3)
183#define WM8990_AIF_TMF_DSP (3 << 3)
184
185/*
186 * R5 (0x05) - Audio Interface (2)
187 */
188#define WM8990_DACL_SRC 0x8000 /* DACL_SRC */
189#define WM8990_DACR_SRC 0x4000 /* DACR_SRC */
190#define WM8990_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
191#define WM8990_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
192#define WM8990_DAC_BOOST_MASK 0x0C00 /* DAC_BOOST */
193#define WM8990_DAC_COMP 0x0010 /* DAC_COMP */
194#define WM8990_DAC_COMPMODE 0x0008 /* DAC_COMPMODE */
195#define WM8990_ADC_COMP 0x0004 /* ADC_COMP */
196#define WM8990_ADC_COMPMODE 0x0002 /* ADC_COMPMODE */
197#define WM8990_LOOPBACK 0x0001 /* LOOPBACK */
198
199/*
200 * R6 (0x06) - Clocking (1)
201 */
202#define WM8990_TOCLK_RATE 0x8000 /* TOCLK_RATE */
203#define WM8990_TOCLK_ENA 0x4000 /* TOCLK_ENA */
204#define WM8990_OPCLKDIV_MASK 0x1E00 /* OPCLKDIV - [12:9] */
205#define WM8990_DCLKDIV_MASK 0x01C0 /* DCLKDIV - [8:6] */
206#define WM8990_BCLK_DIV_MASK 0x001E /* BCLK_DIV - [4:1] */
207#define WM8990_BCLK_DIV_1 (0x0 << 1)
208#define WM8990_BCLK_DIV_1_5 (0x1 << 1)
209#define WM8990_BCLK_DIV_2 (0x2 << 1)
210#define WM8990_BCLK_DIV_3 (0x3 << 1)
211#define WM8990_BCLK_DIV_4 (0x4 << 1)
212#define WM8990_BCLK_DIV_5_5 (0x5 << 1)
213#define WM8990_BCLK_DIV_6 (0x6 << 1)
214#define WM8990_BCLK_DIV_8 (0x7 << 1)
215#define WM8990_BCLK_DIV_11 (0x8 << 1)
216#define WM8990_BCLK_DIV_12 (0x9 << 1)
217#define WM8990_BCLK_DIV_16 (0xA << 1)
218#define WM8990_BCLK_DIV_22 (0xB << 1)
219#define WM8990_BCLK_DIV_24 (0xC << 1)
220#define WM8990_BCLK_DIV_32 (0xD << 1)
221#define WM8990_BCLK_DIV_44 (0xE << 1)
222#define WM8990_BCLK_DIV_48 (0xF << 1)
223
224/*
225 * R7 (0x07) - Clocking (2)
226 */
227#define WM8990_MCLK_SRC 0x8000 /* MCLK_SRC */
228#define WM8990_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */
229#define WM8990_CLK_FORCE 0x2000 /* CLK_FORCE */
230#define WM8990_MCLK_DIV_MASK 0x1800 /* MCLK_DIV - [12:11] */
231#define WM8990_MCLK_DIV_1 (0 << 11)
232#define WM8990_MCLK_DIV_2 (2 << 11)
233#define WM8990_MCLK_INV 0x0400 /* MCLK_INV */
234#define WM8990_ADC_CLKDIV_MASK 0x00E0 /* ADC_CLKDIV */
235#define WM8990_ADC_CLKDIV_1 (0 << 5)
236#define WM8990_ADC_CLKDIV_1_5 (1 << 5)
237#define WM8990_ADC_CLKDIV_2 (2 << 5)
238#define WM8990_ADC_CLKDIV_3 (3 << 5)
239#define WM8990_ADC_CLKDIV_4 (4 << 5)
240#define WM8990_ADC_CLKDIV_5_5 (5 << 5)
241#define WM8990_ADC_CLKDIV_6 (6 << 5)
242#define WM8990_DAC_CLKDIV_MASK 0x001C /* DAC_CLKDIV - [4:2] */
243#define WM8990_DAC_CLKDIV_1 (0 << 2)
244#define WM8990_DAC_CLKDIV_1_5 (1 << 2)
245#define WM8990_DAC_CLKDIV_2 (2 << 2)
246#define WM8990_DAC_CLKDIV_3 (3 << 2)
247#define WM8990_DAC_CLKDIV_4 (4 << 2)
248#define WM8990_DAC_CLKDIV_5_5 (5 << 2)
249#define WM8990_DAC_CLKDIV_6 (6 << 2)
250
251/*
252 * R8 (0x08) - Audio Interface (3)
253 */
254#define WM8990_AIF_MSTR1 0x8000 /* AIF_MSTR1 */
255#define WM8990_AIF_MSTR2 0x4000 /* AIF_MSTR2 */
256#define WM8990_AIF_SEL 0x2000 /* AIF_SEL */
257#define WM8990_ADCLRC_DIR 0x0800 /* ADCLRC_DIR */
258#define WM8990_ADCLRC_RATE_MASK 0x07FF /* ADCLRC_RATE */
259
260/*
261 * R9 (0x09) - Audio Interface (4)
262 */
263#define WM8990_ALRCGPIO1 0x8000 /* ALRCGPIO1 */
264#define WM8990_ALRCBGPIO6 0x4000 /* ALRCBGPIO6 */
265#define WM8990_AIF_TRIS 0x2000 /* AIF_TRIS */
266#define WM8990_DACLRC_DIR 0x0800 /* DACLRC_DIR */
267#define WM8990_DACLRC_RATE_MASK 0x07FF /* DACLRC_RATE */
268
269/*
270 * R10 (0x0A) - DAC CTRL
271 */
272#define WM8990_AIF_LRCLKRATE 0x0400 /* AIF_LRCLKRATE */
273#define WM8990_DAC_MONO 0x0200 /* DAC_MONO */
274#define WM8990_DAC_SB_FILT 0x0100 /* DAC_SB_FILT */
275#define WM8990_DAC_MUTERATE 0x0080 /* DAC_MUTERATE */
276#define WM8990_DAC_MUTEMODE 0x0040 /* DAC_MUTEMODE */
277#define WM8990_DEEMP_MASK 0x0030 /* DEEMP - [5:4] */
278#define WM8990_DAC_MUTE 0x0004 /* DAC_MUTE */
279#define WM8990_DACL_DATINV 0x0002 /* DACL_DATINV */
280#define WM8990_DACR_DATINV 0x0001 /* DACR_DATINV */
281
282/*
283 * R11 (0x0B) - Left DAC Digital Volume
284 */
285#define WM8990_DAC_VU 0x0100 /* DAC_VU */
286#define WM8990_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
287#define WM8990_DACL_VOL_SHIFT 0
288/*
289 * R12 (0x0C) - Right DAC Digital Volume
290 */
291#define WM8990_DAC_VU 0x0100 /* DAC_VU */
292#define WM8990_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
293#define WM8990_DACR_VOL_SHIFT 0
294/*
295 * R13 (0x0D) - Digital Side Tone
296 */
297#define WM8990_ADCL_DAC_SVOL_MASK 0x0F /* ADCL_DAC_SVOL */
298#define WM8990_ADCL_DAC_SVOL_SHIFT 9
299#define WM8990_ADCR_DAC_SVOL_MASK 0x0F /* ADCR_DAC_SVOL */
300#define WM8990_ADCR_DAC_SVOL_SHIFT 5
301#define WM8990_ADC_TO_DACL_MASK 0x03 /* ADC_TO_DACL - [3:2] */
302#define WM8990_ADC_TO_DACL_SHIFT 2
303#define WM8990_ADC_TO_DACR_MASK 0x03 /* ADC_TO_DACR - [1:0] */
304#define WM8990_ADC_TO_DACR_SHIFT 0
305
306/*
307 * R14 (0x0E) - ADC CTRL
308 */
309#define WM8990_ADC_HPF_ENA 0x0100 /* ADC_HPF_ENA */
310#define WM8990_ADC_HPF_ENA_BIT 8
311#define WM8990_ADC_HPF_CUT_MASK 0x03 /* ADC_HPF_CUT - [6:5] */
312#define WM8990_ADC_HPF_CUT_SHIFT 5
313#define WM8990_ADCL_DATINV 0x0002 /* ADCL_DATINV */
314#define WM8990_ADCL_DATINV_BIT 1
315#define WM8990_ADCR_DATINV 0x0001 /* ADCR_DATINV */
316#define WM8990_ADCR_DATINV_BIT 0
317
318/*
319 * R15 (0x0F) - Left ADC Digital Volume
320 */
321#define WM8990_ADC_VU 0x0100 /* ADC_VU */
322#define WM8990_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
323#define WM8990_ADCL_VOL_SHIFT 0
324
325/*
326 * R16 (0x10) - Right ADC Digital Volume
327 */
328#define WM8990_ADC_VU 0x0100 /* ADC_VU */
329#define WM8990_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
330#define WM8990_ADCR_VOL_SHIFT 0
331
332/*
333 * R18 (0x12) - GPIO CTRL 1
334 */
335#define WM8990_IRQ 0x1000 /* IRQ */
336#define WM8990_TEMPOK 0x0800 /* TEMPOK */
337#define WM8990_MICSHRT 0x0400 /* MICSHRT */
338#define WM8990_MICDET 0x0200 /* MICDET */
339#define WM8990_PLL_LCK 0x0100 /* PLL_LCK */
340#define WM8990_GPI8_STATUS 0x0080 /* GPI8_STATUS */
341#define WM8990_GPI7_STATUS 0x0040 /* GPI7_STATUS */
342#define WM8990_GPIO6_STATUS 0x0020 /* GPIO6_STATUS */
343#define WM8990_GPIO5_STATUS 0x0010 /* GPIO5_STATUS */
344#define WM8990_GPIO4_STATUS 0x0008 /* GPIO4_STATUS */
345#define WM8990_GPIO3_STATUS 0x0004 /* GPIO3_STATUS */
346#define WM8990_GPIO2_STATUS 0x0002 /* GPIO2_STATUS */
347#define WM8990_GPIO1_STATUS 0x0001 /* GPIO1_STATUS */
348
349/*
350 * R19 (0x13) - GPIO1 & GPIO2
351 */
352#define WM8990_GPIO2_DEB_ENA 0x8000 /* GPIO2_DEB_ENA */
353#define WM8990_GPIO2_IRQ_ENA 0x4000 /* GPIO2_IRQ_ENA */
354#define WM8990_GPIO2_PU 0x2000 /* GPIO2_PU */
355#define WM8990_GPIO2_PD 0x1000 /* GPIO2_PD */
356#define WM8990_GPIO2_SEL_MASK 0x0F00 /* GPIO2_SEL - [11:8] */
357#define WM8990_GPIO1_DEB_ENA 0x0080 /* GPIO1_DEB_ENA */
358#define WM8990_GPIO1_IRQ_ENA 0x0040 /* GPIO1_IRQ_ENA */
359#define WM8990_GPIO1_PU 0x0020 /* GPIO1_PU */
360#define WM8990_GPIO1_PD 0x0010 /* GPIO1_PD */
361#define WM8990_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
362
363/*
364 * R20 (0x14) - GPIO3 & GPIO4
365 */
366#define WM8990_GPIO4_DEB_ENA 0x8000 /* GPIO4_DEB_ENA */
367#define WM8990_GPIO4_IRQ_ENA 0x4000 /* GPIO4_IRQ_ENA */
368#define WM8990_GPIO4_PU 0x2000 /* GPIO4_PU */
369#define WM8990_GPIO4_PD 0x1000 /* GPIO4_PD */
370#define WM8990_GPIO4_SEL_MASK 0x0F00 /* GPIO4_SEL - [11:8] */
371#define WM8990_GPIO3_DEB_ENA 0x0080 /* GPIO3_DEB_ENA */
372#define WM8990_GPIO3_IRQ_ENA 0x0040 /* GPIO3_IRQ_ENA */
373#define WM8990_GPIO3_PU 0x0020 /* GPIO3_PU */
374#define WM8990_GPIO3_PD 0x0010 /* GPIO3_PD */
375#define WM8990_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */
376
377/*
378 * R21 (0x15) - GPIO5 & GPIO6
379 */
380#define WM8990_GPIO6_DEB_ENA 0x8000 /* GPIO6_DEB_ENA */
381#define WM8990_GPIO6_IRQ_ENA 0x4000 /* GPIO6_IRQ_ENA */
382#define WM8990_GPIO6_PU 0x2000 /* GPIO6_PU */
383#define WM8990_GPIO6_PD 0x1000 /* GPIO6_PD */
384#define WM8990_GPIO6_SEL_MASK 0x0F00 /* GPIO6_SEL - [11:8] */
385#define WM8990_GPIO5_DEB_ENA 0x0080 /* GPIO5_DEB_ENA */
386#define WM8990_GPIO5_IRQ_ENA 0x0040 /* GPIO5_IRQ_ENA */
387#define WM8990_GPIO5_PU 0x0020 /* GPIO5_PU */
388#define WM8990_GPIO5_PD 0x0010 /* GPIO5_PD */
389#define WM8990_GPIO5_SEL_MASK 0x000F /* GPIO5_SEL - [3:0] */
390
391/*
392 * R22 (0x16) - GPIOCTRL 2
393 */
394#define WM8990_RD_3W_ENA 0x8000 /* RD_3W_ENA */
395#define WM8990_MODE_3W4W 0x4000 /* MODE_3W4W */
396#define WM8990_TEMPOK_IRQ_ENA 0x0800 /* TEMPOK_IRQ_ENA */
397#define WM8990_MICSHRT_IRQ_ENA 0x0400 /* MICSHRT_IRQ_ENA */
398#define WM8990_MICDET_IRQ_ENA 0x0200 /* MICDET_IRQ_ENA */
399#define WM8990_PLL_LCK_IRQ_ENA 0x0100 /* PLL_LCK_IRQ_ENA */
400#define WM8990_GPI8_DEB_ENA 0x0080 /* GPI8_DEB_ENA */
401#define WM8990_GPI8_IRQ_ENA 0x0040 /* GPI8_IRQ_ENA */
402#define WM8990_GPI8_ENA 0x0010 /* GPI8_ENA */
403#define WM8990_GPI7_DEB_ENA 0x0008 /* GPI7_DEB_ENA */
404#define WM8990_GPI7_IRQ_ENA 0x0004 /* GPI7_IRQ_ENA */
405#define WM8990_GPI7_ENA 0x0001 /* GPI7_ENA */
406
407/*
408 * R23 (0x17) - GPIO_POL
409 */
410#define WM8990_IRQ_INV 0x1000 /* IRQ_INV */
411#define WM8990_TEMPOK_POL 0x0800 /* TEMPOK_POL */
412#define WM8990_MICSHRT_POL 0x0400 /* MICSHRT_POL */
413#define WM8990_MICDET_POL 0x0200 /* MICDET_POL */
414#define WM8990_PLL_LCK_POL 0x0100 /* PLL_LCK_POL */
415#define WM8990_GPI8_POL 0x0080 /* GPI8_POL */
416#define WM8990_GPI7_POL 0x0040 /* GPI7_POL */
417#define WM8990_GPIO6_POL 0x0020 /* GPIO6_POL */
418#define WM8990_GPIO5_POL 0x0010 /* GPIO5_POL */
419#define WM8990_GPIO4_POL 0x0008 /* GPIO4_POL */
420#define WM8990_GPIO3_POL 0x0004 /* GPIO3_POL */
421#define WM8990_GPIO2_POL 0x0002 /* GPIO2_POL */
422#define WM8990_GPIO1_POL 0x0001 /* GPIO1_POL */
423
424/*
425 * R24 (0x18) - Left Line Input 1&2 Volume
426 */
427#define WM8990_IPVU 0x0100 /* IPVU */
428#define WM8990_LI12MUTE 0x0080 /* LI12MUTE */
429#define WM8990_LI12MUTE_BIT 7
430#define WM8990_LI12ZC 0x0040 /* LI12ZC */
431#define WM8990_LI12ZC_BIT 6
432#define WM8990_LIN12VOL_MASK 0x001F /* LIN12VOL - [4:0] */
433#define WM8990_LIN12VOL_SHIFT 0
434/*
435 * R25 (0x19) - Left Line Input 3&4 Volume
436 */
437#define WM8990_IPVU 0x0100 /* IPVU */
438#define WM8990_LI34MUTE 0x0080 /* LI34MUTE */
439#define WM8990_LI34MUTE_BIT 7
440#define WM8990_LI34ZC 0x0040 /* LI34ZC */
441#define WM8990_LI34ZC_BIT 6
442#define WM8990_LIN34VOL_MASK 0x001F /* LIN34VOL - [4:0] */
443#define WM8990_LIN34VOL_SHIFT 0
444
445/*
446 * R26 (0x1A) - Right Line Input 1&2 Volume
447 */
448#define WM8990_IPVU 0x0100 /* IPVU */
449#define WM8990_RI12MUTE 0x0080 /* RI12MUTE */
450#define WM8990_RI12MUTE_BIT 7
451#define WM8990_RI12ZC 0x0040 /* RI12ZC */
452#define WM8990_RI12ZC_BIT 6
453#define WM8990_RIN12VOL_MASK 0x001F /* RIN12VOL - [4:0] */
454#define WM8990_RIN12VOL_SHIFT 0
455
456/*
457 * R27 (0x1B) - Right Line Input 3&4 Volume
458 */
459#define WM8990_IPVU 0x0100 /* IPVU */
460#define WM8990_RI34MUTE 0x0080 /* RI34MUTE */
461#define WM8990_RI34MUTE_BIT 7
462#define WM8990_RI34ZC 0x0040 /* RI34ZC */
463#define WM8990_RI34ZC_BIT 6
464#define WM8990_RIN34VOL_MASK 0x001F /* RIN34VOL - [4:0] */
465#define WM8990_RIN34VOL_SHIFT 0
466
467/*
468 * R28 (0x1C) - Left Output Volume
469 */
470#define WM8990_OPVU 0x0100 /* OPVU */
471#define WM8990_LOZC 0x0080 /* LOZC */
472#define WM8990_LOZC_BIT 7
473#define WM8990_LOUTVOL_MASK 0x007F /* LOUTVOL - [6:0] */
474#define WM8990_LOUTVOL_SHIFT 0
475/*
476 * R29 (0x1D) - Right Output Volume
477 */
478#define WM8990_OPVU 0x0100 /* OPVU */
479#define WM8990_ROZC 0x0080 /* ROZC */
480#define WM8990_ROZC_BIT 7
481#define WM8990_ROUTVOL_MASK 0x007F /* ROUTVOL - [6:0] */
482#define WM8990_ROUTVOL_SHIFT 0
483/*
484 * R30 (0x1E) - Line Outputs Volume
485 */
486#define WM8990_LONMUTE 0x0040 /* LONMUTE */
487#define WM8990_LONMUTE_BIT 6
488#define WM8990_LOPMUTE 0x0020 /* LOPMUTE */
489#define WM8990_LOPMUTE_BIT 5
490#define WM8990_LOATTN 0x0010 /* LOATTN */
491#define WM8990_LOATTN_BIT 4
492#define WM8990_RONMUTE 0x0004 /* RONMUTE */
493#define WM8990_RONMUTE_BIT 2
494#define WM8990_ROPMUTE 0x0002 /* ROPMUTE */
495#define WM8990_ROPMUTE_BIT 1
496#define WM8990_ROATTN 0x0001 /* ROATTN */
497#define WM8990_ROATTN_BIT 0
498
499/*
500 * R31 (0x1F) - Out3/4 Volume
501 */
502#define WM8990_OUT3MUTE 0x0020 /* OUT3MUTE */
503#define WM8990_OUT3MUTE_BIT 5
504#define WM8990_OUT3ATTN 0x0010 /* OUT3ATTN */
505#define WM8990_OUT3ATTN_BIT 4
506#define WM8990_OUT4MUTE 0x0002 /* OUT4MUTE */
507#define WM8990_OUT4MUTE_BIT 1
508#define WM8990_OUT4ATTN 0x0001 /* OUT4ATTN */
509#define WM8990_OUT4ATTN_BIT 0
510
511/*
512 * R32 (0x20) - Left OPGA Volume
513 */
514#define WM8990_OPVU 0x0100 /* OPVU */
515#define WM8990_LOPGAZC 0x0080 /* LOPGAZC */
516#define WM8990_LOPGAZC_BIT 7
517#define WM8990_LOPGAVOL_MASK 0x007F /* LOPGAVOL - [6:0] */
518#define WM8990_LOPGAVOL_SHIFT 0
519
520/*
521 * R33 (0x21) - Right OPGA Volume
522 */
523#define WM8990_OPVU 0x0100 /* OPVU */
524#define WM8990_ROPGAZC 0x0080 /* ROPGAZC */
525#define WM8990_ROPGAZC_BIT 7
526#define WM8990_ROPGAVOL_MASK 0x007F /* ROPGAVOL - [6:0] */
527#define WM8990_ROPGAVOL_SHIFT 0
528/*
529 * R34 (0x22) - Speaker Volume
530 */
531#define WM8990_SPKVOL_MASK 0x0003 /* SPKVOL - [1:0] */
532#define WM8990_SPKVOL_SHIFT 0
533
534/*
535 * R35 (0x23) - ClassD1
536 */
537#define WM8990_CDMODE 0x0100 /* CDMODE */
538#define WM8990_CDMODE_BIT 8
539
540/*
541 * R37 (0x25) - ClassD3
542 */
543#define WM8990_DCGAIN_MASK 0x0007 /* DCGAIN - [5:3] */
544#define WM8990_DCGAIN_SHIFT 3
545#define WM8990_ACGAIN_MASK 0x0007 /* ACGAIN - [2:0] */
546#define WM8990_ACGAIN_SHIFT 0
547/*
548 * R39 (0x27) - Input Mixer1
549 */
550#define WM8990_AINLMODE_MASK 0x000C /* AINLMODE - [3:2] */
551#define WM8990_AINLMODE_SHIFT 2
552#define WM8990_AINRMODE_MASK 0x0003 /* AINRMODE - [1:0] */
553#define WM8990_AINRMODE_SHIFT 0
554
555/*
556 * R40 (0x28) - Input Mixer2
557 */
558#define WM8990_LMP4 0x0080 /* LMP4 */
559#define WM8990_LMP4_BIT 7 /* LMP4 */
560#define WM8990_LMN3 0x0040 /* LMN3 */
561#define WM8990_LMN3_BIT 6 /* LMN3 */
562#define WM8990_LMP2 0x0020 /* LMP2 */
563#define WM8990_LMP2_BIT 5 /* LMP2 */
564#define WM8990_LMN1 0x0010 /* LMN1 */
565#define WM8990_LMN1_BIT 4 /* LMN1 */
566#define WM8990_RMP4 0x0008 /* RMP4 */
567#define WM8990_RMP4_BIT 3 /* RMP4 */
568#define WM8990_RMN3 0x0004 /* RMN3 */
569#define WM8990_RMN3_BIT 2 /* RMN3 */
570#define WM8990_RMP2 0x0002 /* RMP2 */
571#define WM8990_RMP2_BIT 1 /* RMP2 */
572#define WM8990_RMN1 0x0001 /* RMN1 */
573#define WM8990_RMN1_BIT 0 /* RMN1 */
574
575/*
576 * R41 (0x29) - Input Mixer3
577 */
578#define WM8990_L34MNB 0x0100 /* L34MNB */
579#define WM8990_L34MNB_BIT 8
580#define WM8990_L34MNBST 0x0080 /* L34MNBST */
581#define WM8990_L34MNBST_BIT 7
582#define WM8990_L12MNB 0x0020 /* L12MNB */
583#define WM8990_L12MNB_BIT 5
584#define WM8990_L12MNBST 0x0010 /* L12MNBST */
585#define WM8990_L12MNBST_BIT 4
586#define WM8990_LDBVOL_MASK 0x0007 /* LDBVOL - [2:0] */
587#define WM8990_LDBVOL_SHIFT 0
588
589/*
590 * R42 (0x2A) - Input Mixer4
591 */
592#define WM8990_R34MNB 0x0100 /* R34MNB */
593#define WM8990_R34MNB_BIT 8
594#define WM8990_R34MNBST 0x0080 /* R34MNBST */
595#define WM8990_R34MNBST_BIT 7
596#define WM8990_R12MNB 0x0020 /* R12MNB */
597#define WM8990_R12MNB_BIT 5
598#define WM8990_R12MNBST 0x0010 /* R12MNBST */
599#define WM8990_R12MNBST_BIT 4
600#define WM8990_RDBVOL_MASK 0x0007 /* RDBVOL - [2:0] */
601#define WM8990_RDBVOL_SHIFT 0
602
603/*
604 * R43 (0x2B) - Input Mixer5
605 */
606#define WM8990_LI2BVOL_MASK 0x07 /* LI2BVOL - [8:6] */
607#define WM8990_LI2BVOL_SHIFT 6
608#define WM8990_LR4BVOL_MASK 0x07 /* LR4BVOL - [5:3] */
609#define WM8990_LR4BVOL_SHIFT 3
610#define WM8990_LL4BVOL_MASK 0x07 /* LL4BVOL - [2:0] */
611#define WM8990_LL4BVOL_SHIFT 0
612
613/*
614 * R44 (0x2C) - Input Mixer6
615 */
616#define WM8990_RI2BVOL_MASK 0x07 /* RI2BVOL - [8:6] */
617#define WM8990_RI2BVOL_SHIFT 6
618#define WM8990_RL4BVOL_MASK 0x07 /* RL4BVOL - [5:3] */
619#define WM8990_RL4BVOL_SHIFT 3
620#define WM8990_RR4BVOL_MASK 0x07 /* RR4BVOL - [2:0] */
621#define WM8990_RR4BVOL_SHIFT 0
622
623/*
624 * R45 (0x2D) - Output Mixer1
625 */
626#define WM8990_LRBLO 0x0080 /* LRBLO */
627#define WM8990_LRBLO_BIT 7
628#define WM8990_LLBLO 0x0040 /* LLBLO */
629#define WM8990_LLBLO_BIT 6
630#define WM8990_LRI3LO 0x0020 /* LRI3LO */
631#define WM8990_LRI3LO_BIT 5
632#define WM8990_LLI3LO 0x0010 /* LLI3LO */
633#define WM8990_LLI3LO_BIT 4
634#define WM8990_LR12LO 0x0008 /* LR12LO */
635#define WM8990_LR12LO_BIT 3
636#define WM8990_LL12LO 0x0004 /* LL12LO */
637#define WM8990_LL12LO_BIT 2
638#define WM8990_LDLO 0x0001 /* LDLO */
639#define WM8990_LDLO_BIT 0
640
641/*
642 * R46 (0x2E) - Output Mixer2
643 */
644#define WM8990_RLBRO 0x0080 /* RLBRO */
645#define WM8990_RLBRO_BIT 7
646#define WM8990_RRBRO 0x0040 /* RRBRO */
647#define WM8990_RRBRO_BIT 6
648#define WM8990_RLI3RO 0x0020 /* RLI3RO */
649#define WM8990_RLI3RO_BIT 5
650#define WM8990_RRI3RO 0x0010 /* RRI3RO */
651#define WM8990_RRI3RO_BIT 4
652#define WM8990_RL12RO 0x0008 /* RL12RO */
653#define WM8990_RL12RO_BIT 3
654#define WM8990_RR12RO 0x0004 /* RR12RO */
655#define WM8990_RR12RO_BIT 2
656#define WM8990_RDRO 0x0001 /* RDRO */
657#define WM8990_RDRO_BIT 0
658
659/*
660 * R47 (0x2F) - Output Mixer3
661 */
662#define WM8990_LLI3LOVOL_MASK 0x07 /* LLI3LOVOL - [8:6] */
663#define WM8990_LLI3LOVOL_SHIFT 6
664#define WM8990_LR12LOVOL_MASK 0x07 /* LR12LOVOL - [5:3] */
665#define WM8990_LR12LOVOL_SHIFT 3
666#define WM8990_LL12LOVOL_MASK 0x07 /* LL12LOVOL - [2:0] */
667#define WM8990_LL12LOVOL_SHIFT 0
668
669/*
670 * R48 (0x30) - Output Mixer4
671 */
672#define WM8990_RRI3ROVOL_MASK 0x07 /* RRI3ROVOL - [8:6] */
673#define WM8990_RRI3ROVOL_SHIFT 6
674#define WM8990_RL12ROVOL_MASK 0x07 /* RL12ROVOL - [5:3] */
675#define WM8990_RL12ROVOL_SHIFT 3
676#define WM8990_RR12ROVOL_MASK 0x07 /* RR12ROVOL - [2:0] */
677#define WM8990_RR12ROVOL_SHIFT 0
678
679/*
680 * R49 (0x31) - Output Mixer5
681 */
682#define WM8990_LRI3LOVOL_MASK 0x07 /* LRI3LOVOL - [8:6] */
683#define WM8990_LRI3LOVOL_SHIFT 6
684#define WM8990_LRBLOVOL_MASK 0x07 /* LRBLOVOL - [5:3] */
685#define WM8990_LRBLOVOL_SHIFT 3
686#define WM8990_LLBLOVOL_MASK 0x07 /* LLBLOVOL - [2:0] */
687#define WM8990_LLBLOVOL_SHIFT 0
688
689/*
690 * R50 (0x32) - Output Mixer6
691 */
692#define WM8990_RLI3ROVOL_MASK 0x07 /* RLI3ROVOL - [8:6] */
693#define WM8990_RLI3ROVOL_SHIFT 6
694#define WM8990_RLBROVOL_MASK 0x07 /* RLBROVOL - [5:3] */
695#define WM8990_RLBROVOL_SHIFT 3
696#define WM8990_RRBROVOL_MASK 0x07 /* RRBROVOL - [2:0] */
697#define WM8990_RRBROVOL_SHIFT 0
698
699/*
700 * R51 (0x33) - Out3/4 Mixer
701 */
702#define WM8990_VSEL_MASK 0x0180 /* VSEL - [8:7] */
703#define WM8990_LI4O3 0x0020 /* LI4O3 */
704#define WM8990_LI4O3_BIT 5
705#define WM8990_LPGAO3 0x0010 /* LPGAO3 */
706#define WM8990_LPGAO3_BIT 4
707#define WM8990_RI4O4 0x0002 /* RI4O4 */
708#define WM8990_RI4O4_BIT 1
709#define WM8990_RPGAO4 0x0001 /* RPGAO4 */
710#define WM8990_RPGAO4_BIT 0
711/*
712 * R52 (0x34) - Line Mixer1
713 */
714#define WM8990_LLOPGALON 0x0040 /* LLOPGALON */
715#define WM8990_LLOPGALON_BIT 6
716#define WM8990_LROPGALON 0x0020 /* LROPGALON */
717#define WM8990_LROPGALON_BIT 5
718#define WM8990_LOPLON 0x0010 /* LOPLON */
719#define WM8990_LOPLON_BIT 4
720#define WM8990_LR12LOP 0x0004 /* LR12LOP */
721#define WM8990_LR12LOP_BIT 2
722#define WM8990_LL12LOP 0x0002 /* LL12LOP */
723#define WM8990_LL12LOP_BIT 1
724#define WM8990_LLOPGALOP 0x0001 /* LLOPGALOP */
725#define WM8990_LLOPGALOP_BIT 0
726/*
727 * R53 (0x35) - Line Mixer2
728 */
729#define WM8990_RROPGARON 0x0040 /* RROPGARON */
730#define WM8990_RROPGARON_BIT 6
731#define WM8990_RLOPGARON 0x0020 /* RLOPGARON */
732#define WM8990_RLOPGARON_BIT 5
733#define WM8990_ROPRON 0x0010 /* ROPRON */
734#define WM8990_ROPRON_BIT 4
735#define WM8990_RL12ROP 0x0004 /* RL12ROP */
736#define WM8990_RL12ROP_BIT 2
737#define WM8990_RR12ROP 0x0002 /* RR12ROP */
738#define WM8990_RR12ROP_BIT 1
739#define WM8990_RROPGAROP 0x0001 /* RROPGAROP */
740#define WM8990_RROPGAROP_BIT 0
741
742/*
743 * R54 (0x36) - Speaker Mixer
744 */
745#define WM8990_LB2SPK 0x0080 /* LB2SPK */
746#define WM8990_LB2SPK_BIT 7
747#define WM8990_RB2SPK 0x0040 /* RB2SPK */
748#define WM8990_RB2SPK_BIT 6
749#define WM8990_LI2SPK 0x0020 /* LI2SPK */
750#define WM8990_LI2SPK_BIT 5
751#define WM8990_RI2SPK 0x0010 /* RI2SPK */
752#define WM8990_RI2SPK_BIT 4
753#define WM8990_LOPGASPK 0x0008 /* LOPGASPK */
754#define WM8990_LOPGASPK_BIT 3
755#define WM8990_ROPGASPK 0x0004 /* ROPGASPK */
756#define WM8990_ROPGASPK_BIT 2
757#define WM8990_LDSPK 0x0002 /* LDSPK */
758#define WM8990_LDSPK_BIT 1
759#define WM8990_RDSPK 0x0001 /* RDSPK */
760#define WM8990_RDSPK_BIT 0
761
762/*
763 * R55 (0x37) - Additional Control
764 */
765#define WM8990_VROI 0x0001 /* VROI */
766
767/*
768 * R56 (0x38) - AntiPOP1
769 */
770#define WM8990_DIS_LLINE 0x0020 /* DIS_LLINE */
771#define WM8990_DIS_RLINE 0x0010 /* DIS_RLINE */
772#define WM8990_DIS_OUT3 0x0008 /* DIS_OUT3 */
773#define WM8990_DIS_OUT4 0x0004 /* DIS_OUT4 */
774#define WM8990_DIS_LOUT 0x0002 /* DIS_LOUT */
775#define WM8990_DIS_ROUT 0x0001 /* DIS_ROUT */
776
777/*
778 * R57 (0x39) - AntiPOP2
779 */
780#define WM8990_SOFTST 0x0040 /* SOFTST */
781#define WM8990_BUFIOEN 0x0008 /* BUFIOEN */
782#define WM8990_BUFDCOPEN 0x0004 /* BUFDCOPEN */
783#define WM8990_POBCTRL 0x0002 /* POBCTRL */
784#define WM8990_VMIDTOG 0x0001 /* VMIDTOG */
785
786/*
787 * R58 (0x3A) - MICBIAS
788 */
789#define WM8990_MCDSCTH_MASK 0x00C0 /* MCDSCTH - [7:6] */
790#define WM8990_MCDTHR_MASK 0x0038 /* MCDTHR - [5:3] */
791#define WM8990_MCD 0x0004 /* MCD */
792#define WM8990_MBSEL 0x0001 /* MBSEL */
793
794/*
795 * R60 (0x3C) - PLL1
796 */
797#define WM8990_SDM 0x0080 /* SDM */
798#define WM8990_PRESCALE 0x0040 /* PRESCALE */
799#define WM8990_PLLN_MASK 0x000F /* PLLN - [3:0] */
800
801/*
802 * R61 (0x3D) - PLL2
803 */
804#define WM8990_PLLK1_MASK 0x00FF /* PLLK1 - [7:0] */
805
806/*
807 * R62 (0x3E) - PLL3
808 */
809#define WM8990_PLLK2_MASK 0x00FF /* PLLK2 - [7:0] */
810
811/*
812 * R63 (0x3F) - Internal Driver Bits
813 */
814#define WM8990_INMIXL_PWR_BIT 0
815#define WM8990_AINLMUX_PWR_BIT 1
816#define WM8990_INMIXR_PWR_BIT 2
817#define WM8990_AINRMUX_PWR_BIT 3
818
819struct wm8990_setup_data {
820 unsigned short i2c_address;
821};
822
823#define WM8990_MCLK_DIV 0
824#define WM8990_DACCLK_DIV 1
825#define WM8990_ADCCLK_DIV 2
826#define WM8990_BCLK_DIV 3
827
828extern struct snd_soc_dai wm8990_dai;
829extern struct snd_soc_codec_device soc_codec_dev_wm8990;
830
831#endif /* __WM8990REGISTERDEFS_H__ */
832/*------------------------------ END OF FILE ---------------------------------*/
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 76c1e2d33e7d..9fc8edd82225 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -9,9 +9,6 @@
9 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your 10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
12 *
13 * Revision history
14 * 4th Feb 2006 Initial version.
15 */ 12 */
16 13
17#include <linux/init.h> 14#include <linux/init.h>
@@ -25,6 +22,7 @@
25#include <sound/initval.h> 22#include <sound/initval.h>
26#include <sound/soc.h> 23#include <sound/soc.h>
27#include <sound/soc-dapm.h> 24#include <sound/soc-dapm.h>
25#include "wm9712.h"
28 26
29#define WM9712_VERSION "0.4" 27#define WM9712_VERSION "0.4"
30 28
@@ -351,7 +349,7 @@ SND_SOC_DAPM_INPUT("MIC1"),
351SND_SOC_DAPM_INPUT("MIC2"), 349SND_SOC_DAPM_INPUT("MIC2"),
352}; 350};
353 351
354static const char *audio_map[][3] = { 352static const struct snd_soc_dapm_route audio_map[] = {
355 /* virtual mixer - mixes left & right channels for spk and mono */ 353 /* virtual mixer - mixes left & right channels for spk and mono */
356 {"AC97 Mixer", NULL, "Left DAC"}, 354 {"AC97 Mixer", NULL, "Left DAC"},
357 {"AC97 Mixer", NULL, "Right DAC"}, 355 {"AC97 Mixer", NULL, "Right DAC"},
@@ -446,21 +444,14 @@ static const char *audio_map[][3] = {
446 {"Speaker PGA", NULL, "Speaker Mux"}, 444 {"Speaker PGA", NULL, "Speaker Mux"},
447 {"LOUT2", NULL, "Speaker PGA"}, 445 {"LOUT2", NULL, "Speaker PGA"},
448 {"ROUT2", NULL, "Speaker PGA"}, 446 {"ROUT2", NULL, "Speaker PGA"},
449
450 {NULL, NULL, NULL},
451}; 447};
452 448
453static int wm9712_add_widgets(struct snd_soc_codec *codec) 449static int wm9712_add_widgets(struct snd_soc_codec *codec)
454{ 450{
455 int i; 451 snd_soc_dapm_new_controls(codec, wm9712_dapm_widgets,
456 452 ARRAY_SIZE(wm9712_dapm_widgets));
457 for (i = 0; i < ARRAY_SIZE(wm9712_dapm_widgets); i++)
458 snd_soc_dapm_new_control(codec, &wm9712_dapm_widgets[i]);
459 453
460 /* set up audio path connects */ 454 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
461 for (i = 0; audio_map[i][0] != NULL; i++)
462 snd_soc_dapm_connect_input(codec, audio_map[i][0],
463 audio_map[i][1], audio_map[i][2]);
464 455
465 snd_soc_dapm_new_widgets(codec); 456 snd_soc_dapm_new_widgets(codec);
466 return 0; 457 return 0;
@@ -541,7 +532,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream)
541 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\ 532 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\
542 SNDRV_PCM_RATE_48000) 533 SNDRV_PCM_RATE_48000)
543 534
544struct snd_soc_codec_dai wm9712_dai[] = { 535struct snd_soc_dai wm9712_dai[] = {
545{ 536{
546 .name = "AC97 HiFi", 537 .name = "AC97 HiFi",
547 .type = SND_SOC_DAI_AC97_BUS, 538 .type = SND_SOC_DAI_AC97_BUS,
@@ -574,23 +565,23 @@ struct snd_soc_codec_dai wm9712_dai[] = {
574}; 565};
575EXPORT_SYMBOL_GPL(wm9712_dai); 566EXPORT_SYMBOL_GPL(wm9712_dai);
576 567
577static int wm9712_dapm_event(struct snd_soc_codec *codec, int event) 568static int wm9712_set_bias_level(struct snd_soc_codec *codec,
569 enum snd_soc_bias_level level)
578{ 570{
579 switch (event) { 571 switch (level) {
580 case SNDRV_CTL_POWER_D0: /* full On */ 572 case SND_SOC_BIAS_ON:
581 case SNDRV_CTL_POWER_D1: /* partial On */ 573 case SND_SOC_BIAS_PREPARE:
582 case SNDRV_CTL_POWER_D2: /* partial On */
583 break; 574 break;
584 case SNDRV_CTL_POWER_D3hot: /* Off, with power */ 575 case SND_SOC_BIAS_STANDBY:
585 ac97_write(codec, AC97_POWERDOWN, 0x0000); 576 ac97_write(codec, AC97_POWERDOWN, 0x0000);
586 break; 577 break;
587 case SNDRV_CTL_POWER_D3cold: /* Off, without power */ 578 case SND_SOC_BIAS_OFF:
588 /* disable everything including AC link */ 579 /* disable everything including AC link */
589 ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff); 580 ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
590 ac97_write(codec, AC97_POWERDOWN, 0xffff); 581 ac97_write(codec, AC97_POWERDOWN, 0xffff);
591 break; 582 break;
592 } 583 }
593 codec->dapm_state = event; 584 codec->bias_level = level;
594 return 0; 585 return 0;
595} 586}
596 587
@@ -598,12 +589,12 @@ static int wm9712_reset(struct snd_soc_codec *codec, int try_warm)
598{ 589{
599 if (try_warm && soc_ac97_ops.warm_reset) { 590 if (try_warm && soc_ac97_ops.warm_reset) {
600 soc_ac97_ops.warm_reset(codec->ac97); 591 soc_ac97_ops.warm_reset(codec->ac97);
601 if (!(ac97_read(codec, 0) & 0x8000)) 592 if (ac97_read(codec, 0) == wm9712_reg[0])
602 return 1; 593 return 1;
603 } 594 }
604 595
605 soc_ac97_ops.reset(codec->ac97); 596 soc_ac97_ops.reset(codec->ac97);
606 if (ac97_read(codec, 0) & 0x8000) 597 if (ac97_read(codec, 0) != wm9712_reg[0])
607 goto err; 598 goto err;
608 return 0; 599 return 0;
609 600
@@ -618,7 +609,7 @@ static int wm9712_soc_suspend(struct platform_device *pdev,
618 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 609 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
619 struct snd_soc_codec *codec = socdev->codec; 610 struct snd_soc_codec *codec = socdev->codec;
620 611
621 wm9712_dapm_event(codec, SNDRV_CTL_POWER_D3cold); 612 wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF);
622 return 0; 613 return 0;
623} 614}
624 615
@@ -635,7 +626,7 @@ static int wm9712_soc_resume(struct platform_device *pdev)
635 return ret; 626 return ret;
636 } 627 }
637 628
638 wm9712_dapm_event(codec, SNDRV_CTL_POWER_D3hot); 629 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
639 630
640 if (ret == 0) { 631 if (ret == 0) {
641 /* Sync reg_cache with the hardware after cold reset */ 632 /* Sync reg_cache with the hardware after cold reset */
@@ -647,8 +638,8 @@ static int wm9712_soc_resume(struct platform_device *pdev)
647 } 638 }
648 } 639 }
649 640
650 if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) 641 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
651 wm9712_dapm_event(codec, SNDRV_CTL_POWER_D0); 642 wm9712_set_bias_level(codec, SND_SOC_BIAS_ON);
652 643
653 return ret; 644 return ret;
654} 645}
@@ -682,7 +673,7 @@ static int wm9712_soc_probe(struct platform_device *pdev)
682 codec->num_dai = ARRAY_SIZE(wm9712_dai); 673 codec->num_dai = ARRAY_SIZE(wm9712_dai);
683 codec->write = ac97_write; 674 codec->write = ac97_write;
684 codec->read = ac97_read; 675 codec->read = ac97_read;
685 codec->dapm_event = wm9712_dapm_event; 676 codec->set_bias_level = wm9712_set_bias_level;
686 INIT_LIST_HEAD(&codec->dapm_widgets); 677 INIT_LIST_HEAD(&codec->dapm_widgets);
687 INIT_LIST_HEAD(&codec->dapm_paths); 678 INIT_LIST_HEAD(&codec->dapm_paths);
688 679
@@ -706,7 +697,7 @@ static int wm9712_soc_probe(struct platform_device *pdev)
706 /* set alc mux to none */ 697 /* set alc mux to none */
707 ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); 698 ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000);
708 699
709 wm9712_dapm_event(codec, SNDRV_CTL_POWER_D3hot); 700 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
710 wm9712_add_controls(codec); 701 wm9712_add_controls(codec);
711 wm9712_add_widgets(codec); 702 wm9712_add_widgets(codec);
712 ret = snd_soc_register_card(socdev); 703 ret = snd_soc_register_card(socdev);
diff --git a/sound/soc/codecs/wm9712.h b/sound/soc/codecs/wm9712.h
index 719105d61e65..d29e8a18ca6d 100644
--- a/sound/soc/codecs/wm9712.h
+++ b/sound/soc/codecs/wm9712.h
@@ -8,7 +8,7 @@
8#define WM9712_DAI_AC97_HIFI 0 8#define WM9712_DAI_AC97_HIFI 0
9#define WM9712_DAI_AC97_AUX 1 9#define WM9712_DAI_AC97_AUX 1
10 10
11extern struct snd_soc_codec_dai wm9712_dai[2]; 11extern struct snd_soc_dai wm9712_dai[2];
12extern struct snd_soc_codec_device soc_codec_dev_wm9712; 12extern struct snd_soc_codec_device soc_codec_dev_wm9712;
13 13
14#endif 14#endif
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 1f241161445c..38d1fe0971fc 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -10,9 +10,6 @@
10 * Free Software Foundation; either version 2 of the License, or (at your 10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
12 * 12 *
13 * Revision history
14 * 4th Feb 2006 Initial version.
15 *
16 * Features:- 13 * Features:-
17 * 14 *
18 * o Support for AC97 Codec, Voice DAC and Aux DAC 15 * o Support for AC97 Codec, Voice DAC and Aux DAC
@@ -456,7 +453,7 @@ SND_SOC_DAPM_INPUT("MIC2B"),
456SND_SOC_DAPM_VMID("VMID"), 453SND_SOC_DAPM_VMID("VMID"),
457}; 454};
458 455
459static const char *audio_map[][3] = { 456static const struct snd_soc_dapm_route audio_map[] = {
460 /* left HP mixer */ 457 /* left HP mixer */
461 {"Left HP Mixer", "PC Beep Playback Switch", "PCBEEP"}, 458 {"Left HP Mixer", "PC Beep Playback Switch", "PCBEEP"},
462 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"}, 459 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"},
@@ -607,21 +604,14 @@ static const char *audio_map[][3] = {
607 {"Capture Mono Mux", "Stereo", "Capture Mixer"}, 604 {"Capture Mono Mux", "Stereo", "Capture Mixer"},
608 {"Capture Mono Mux", "Left", "Left Capture Source"}, 605 {"Capture Mono Mux", "Left", "Left Capture Source"},
609 {"Capture Mono Mux", "Right", "Right Capture Source"}, 606 {"Capture Mono Mux", "Right", "Right Capture Source"},
610
611 {NULL, NULL, NULL},
612}; 607};
613 608
614static int wm9713_add_widgets(struct snd_soc_codec *codec) 609static int wm9713_add_widgets(struct snd_soc_codec *codec)
615{ 610{
616 int i; 611 snd_soc_dapm_new_controls(codec, wm9713_dapm_widgets,
617 612 ARRAY_SIZE(wm9713_dapm_widgets));
618 for (i = 0; i < ARRAY_SIZE(wm9713_dapm_widgets); i++)
619 snd_soc_dapm_new_control(codec, &wm9713_dapm_widgets[i]);
620 613
621 /* set up audio path audio_mapnects */ 614 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
622 for (i = 0; audio_map[i][0] != NULL; i++)
623 snd_soc_dapm_connect_input(codec, audio_map[i][0],
624 audio_map[i][1], audio_map[i][2]);
625 615
626 snd_soc_dapm_new_widgets(codec); 616 snd_soc_dapm_new_widgets(codec);
627 return 0; 617 return 0;
@@ -799,7 +789,7 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
799 return 0; 789 return 0;
800} 790}
801 791
802static int wm9713_set_dai_pll(struct snd_soc_codec_dai *codec_dai, 792static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai,
803 int pll_id, unsigned int freq_in, unsigned int freq_out) 793 int pll_id, unsigned int freq_in, unsigned int freq_out)
804{ 794{
805 struct snd_soc_codec *codec = codec_dai->codec; 795 struct snd_soc_codec *codec = codec_dai->codec;
@@ -810,7 +800,7 @@ static int wm9713_set_dai_pll(struct snd_soc_codec_dai *codec_dai,
810 * Tristate the PCM DAI lines, tristate can be disabled by calling 800 * Tristate the PCM DAI lines, tristate can be disabled by calling
811 * wm9713_set_dai_fmt() 801 * wm9713_set_dai_fmt()
812 */ 802 */
813static int wm9713_set_dai_tristate(struct snd_soc_codec_dai *codec_dai, 803static int wm9713_set_dai_tristate(struct snd_soc_dai *codec_dai,
814 int tristate) 804 int tristate)
815{ 805{
816 struct snd_soc_codec *codec = codec_dai->codec; 806 struct snd_soc_codec *codec = codec_dai->codec;
@@ -826,7 +816,7 @@ static int wm9713_set_dai_tristate(struct snd_soc_codec_dai *codec_dai,
826 * Configure WM9713 clock dividers. 816 * Configure WM9713 clock dividers.
827 * Voice DAC needs 256 FS 817 * Voice DAC needs 256 FS
828 */ 818 */
829static int wm9713_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai, 819static int wm9713_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
830 int div_id, int div) 820 int div_id, int div)
831{ 821{
832 struct snd_soc_codec *codec = codec_dai->codec; 822 struct snd_soc_codec *codec = codec_dai->codec;
@@ -868,7 +858,7 @@ static int wm9713_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai,
868 return 0; 858 return 0;
869} 859}
870 860
871static int wm9713_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, 861static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai,
872 unsigned int fmt) 862 unsigned int fmt)
873{ 863{
874 struct snd_soc_codec *codec = codec_dai->codec; 864 struct snd_soc_codec *codec = codec_dai->codec;
@@ -886,7 +876,7 @@ static int wm9713_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
886 gpio |= 0x0018; 876 gpio |= 0x0018;
887 break; 877 break;
888 case SND_SOC_DAIFMT_CBS_CFS: 878 case SND_SOC_DAIFMT_CBS_CFS:
889 reg |= 0x0200; 879 reg |= 0x2000;
890 gpio |= 0x001a; 880 gpio |= 0x001a;
891 break; 881 break;
892 case SND_SOC_DAIFMT_CBS_CFM: 882 case SND_SOC_DAIFMT_CBS_CFM:
@@ -1011,15 +1001,24 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream)
1011 return ac97_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate); 1001 return ac97_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate);
1012} 1002}
1013 1003
1014#define WM9713_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 1004#define WM9713_RATES (SNDRV_PCM_RATE_8000 | \
1015 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\ 1005 SNDRV_PCM_RATE_11025 | \
1016 SNDRV_PCM_RATE_48000) 1006 SNDRV_PCM_RATE_22050 | \
1007 SNDRV_PCM_RATE_44100 | \
1008 SNDRV_PCM_RATE_48000)
1009
1010#define WM9713_PCM_RATES (SNDRV_PCM_RATE_8000 | \
1011 SNDRV_PCM_RATE_11025 | \
1012 SNDRV_PCM_RATE_16000 | \
1013 SNDRV_PCM_RATE_22050 | \
1014 SNDRV_PCM_RATE_44100 | \
1015 SNDRV_PCM_RATE_48000)
1017 1016
1018#define WM9713_PCM_FORMATS \ 1017#define WM9713_PCM_FORMATS \
1019 (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ 1018 (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \
1020 SNDRV_PCM_FORMAT_S24_LE) 1019 SNDRV_PCM_FORMAT_S24_LE)
1021 1020
1022struct snd_soc_codec_dai wm9713_dai[] = { 1021struct snd_soc_dai wm9713_dai[] = {
1023{ 1022{
1024 .name = "AC97 HiFi", 1023 .name = "AC97 HiFi",
1025 .type = SND_SOC_DAI_AC97_BUS, 1024 .type = SND_SOC_DAI_AC97_BUS,
@@ -1061,13 +1060,13 @@ struct snd_soc_codec_dai wm9713_dai[] = {
1061 .stream_name = "Voice Playback", 1060 .stream_name = "Voice Playback",
1062 .channels_min = 1, 1061 .channels_min = 1,
1063 .channels_max = 1, 1062 .channels_max = 1,
1064 .rates = WM9713_RATES, 1063 .rates = WM9713_PCM_RATES,
1065 .formats = WM9713_PCM_FORMATS,}, 1064 .formats = WM9713_PCM_FORMATS,},
1066 .capture = { 1065 .capture = {
1067 .stream_name = "Voice Capture", 1066 .stream_name = "Voice Capture",
1068 .channels_min = 1, 1067 .channels_min = 1,
1069 .channels_max = 2, 1068 .channels_max = 2,
1070 .rates = WM9713_RATES, 1069 .rates = WM9713_PCM_RATES,
1071 .formats = WM9713_PCM_FORMATS,}, 1070 .formats = WM9713_PCM_FORMATS,},
1072 .ops = { 1071 .ops = {
1073 .hw_params = wm9713_pcm_hw_params, 1072 .hw_params = wm9713_pcm_hw_params,
@@ -1086,44 +1085,44 @@ int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
1086{ 1085{
1087 if (try_warm && soc_ac97_ops.warm_reset) { 1086 if (try_warm && soc_ac97_ops.warm_reset) {
1088 soc_ac97_ops.warm_reset(codec->ac97); 1087 soc_ac97_ops.warm_reset(codec->ac97);
1089 if (!(ac97_read(codec, 0) & 0x8000)) 1088 if (ac97_read(codec, 0) == wm9713_reg[0])
1090 return 1; 1089 return 1;
1091 } 1090 }
1092 1091
1093 soc_ac97_ops.reset(codec->ac97); 1092 soc_ac97_ops.reset(codec->ac97);
1094 if (ac97_read(codec, 0) & 0x8000) 1093 if (ac97_read(codec, 0) != wm9713_reg[0])
1095 return -EIO; 1094 return -EIO;
1096 return 0; 1095 return 0;
1097} 1096}
1098EXPORT_SYMBOL_GPL(wm9713_reset); 1097EXPORT_SYMBOL_GPL(wm9713_reset);
1099 1098
1100static int wm9713_dapm_event(struct snd_soc_codec *codec, int event) 1099static int wm9713_set_bias_level(struct snd_soc_codec *codec,
1100 enum snd_soc_bias_level level)
1101{ 1101{
1102 u16 reg; 1102 u16 reg;
1103 1103
1104 switch (event) { 1104 switch (level) {
1105 case SNDRV_CTL_POWER_D0: /* full On */ 1105 case SND_SOC_BIAS_ON:
1106 /* enable thermal shutdown */ 1106 /* enable thermal shutdown */
1107 reg = ac97_read(codec, AC97_EXTENDED_MID) & 0x1bff; 1107 reg = ac97_read(codec, AC97_EXTENDED_MID) & 0x1bff;
1108 ac97_write(codec, AC97_EXTENDED_MID, reg); 1108 ac97_write(codec, AC97_EXTENDED_MID, reg);
1109 break; 1109 break;
1110 case SNDRV_CTL_POWER_D1: /* partial On */ 1110 case SND_SOC_BIAS_PREPARE:
1111 case SNDRV_CTL_POWER_D2: /* partial On */
1112 break; 1111 break;
1113 case SNDRV_CTL_POWER_D3hot: /* Off, with power */ 1112 case SND_SOC_BIAS_STANDBY:
1114 /* enable master bias and vmid */ 1113 /* enable master bias and vmid */
1115 reg = ac97_read(codec, AC97_EXTENDED_MID) & 0x3bff; 1114 reg = ac97_read(codec, AC97_EXTENDED_MID) & 0x3bff;
1116 ac97_write(codec, AC97_EXTENDED_MID, reg); 1115 ac97_write(codec, AC97_EXTENDED_MID, reg);
1117 ac97_write(codec, AC97_POWERDOWN, 0x0000); 1116 ac97_write(codec, AC97_POWERDOWN, 0x0000);
1118 break; 1117 break;
1119 case SNDRV_CTL_POWER_D3cold: /* Off, without power */ 1118 case SND_SOC_BIAS_OFF:
1120 /* disable everything including AC link */ 1119 /* disable everything including AC link */
1121 ac97_write(codec, AC97_EXTENDED_MID, 0xffff); 1120 ac97_write(codec, AC97_EXTENDED_MID, 0xffff);
1122 ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff); 1121 ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
1123 ac97_write(codec, AC97_POWERDOWN, 0xffff); 1122 ac97_write(codec, AC97_POWERDOWN, 0xffff);
1124 break; 1123 break;
1125 } 1124 }
1126 codec->dapm_state = event; 1125 codec->bias_level = level;
1127 return 0; 1126 return 0;
1128} 1127}
1129 1128
@@ -1160,7 +1159,7 @@ static int wm9713_soc_resume(struct platform_device *pdev)
1160 return ret; 1159 return ret;
1161 } 1160 }
1162 1161
1163 wm9713_dapm_event(codec, SNDRV_CTL_POWER_D3hot); 1162 wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1164 1163
1165 /* do we need to re-start the PLL ? */ 1164 /* do we need to re-start the PLL ? */
1166 if (wm9713->pll_out) 1165 if (wm9713->pll_out)
@@ -1176,8 +1175,8 @@ static int wm9713_soc_resume(struct platform_device *pdev)
1176 } 1175 }
1177 } 1176 }
1178 1177
1179 if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) 1178 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
1180 wm9713_dapm_event(codec, SNDRV_CTL_POWER_D0); 1179 wm9713_set_bias_level(codec, SND_SOC_BIAS_ON);
1181 1180
1182 return ret; 1181 return ret;
1183} 1182}
@@ -1216,7 +1215,7 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1216 codec->num_dai = ARRAY_SIZE(wm9713_dai); 1215 codec->num_dai = ARRAY_SIZE(wm9713_dai);
1217 codec->write = ac97_write; 1216 codec->write = ac97_write;
1218 codec->read = ac97_read; 1217 codec->read = ac97_read;
1219 codec->dapm_event = wm9713_dapm_event; 1218 codec->set_bias_level = wm9713_set_bias_level;
1220 INIT_LIST_HEAD(&codec->dapm_widgets); 1219 INIT_LIST_HEAD(&codec->dapm_widgets);
1221 INIT_LIST_HEAD(&codec->dapm_paths); 1220 INIT_LIST_HEAD(&codec->dapm_paths);
1222 1221
@@ -1238,7 +1237,7 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1238 goto reset_err; 1237 goto reset_err;
1239 } 1238 }
1240 1239
1241 wm9713_dapm_event(codec, SNDRV_CTL_POWER_D3hot); 1240 wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1242 1241
1243 /* unmute the adc - move to kcontrol */ 1242 /* unmute the adc - move to kcontrol */
1244 reg = ac97_read(codec, AC97_CD) & 0x7fff; 1243 reg = ac97_read(codec, AC97_CD) & 0x7fff;
diff --git a/sound/soc/codecs/wm9713.h b/sound/soc/codecs/wm9713.h
index d357b6c8134b..63b8d81756e3 100644
--- a/sound/soc/codecs/wm9713.h
+++ b/sound/soc/codecs/wm9713.h
@@ -46,7 +46,7 @@
46#define WM9713_DAI_PCM_VOICE 2 46#define WM9713_DAI_PCM_VOICE 2
47 47
48extern struct snd_soc_codec_device soc_codec_dev_wm9713; 48extern struct snd_soc_codec_device soc_codec_dev_wm9713;
49extern struct snd_soc_codec_dai wm9713_dai[3]; 49extern struct snd_soc_dai wm9713_dai[3];
50 50
51int wm9713_reset(struct snd_soc_codec *codec, int try_warm); 51int wm9713_reset(struct snd_soc_codec *codec, int try_warm);
52 52
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 20680c551aab..8f7e33834902 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -1,6 +1,6 @@
1config SND_DAVINCI_SOC 1config SND_DAVINCI_SOC
2 tristate "SoC Audio for the TI DAVINCI chip" 2 tristate "SoC Audio for the TI DAVINCI chip"
3 depends on ARCH_DAVINCI && SND_SOC 3 depends on ARCH_DAVINCI
4 help 4 help
5 Say Y or M if you want to add support for codecs attached to 5 Say Y or M if you want to add support for codecs attached to
6 the DAVINCI AC97 or I2S interface. You will also need 6 the DAVINCI AC97 or I2S interface. You will also need
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index fcd165240333..5e2c306399ed 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -33,24 +33,24 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
33 struct snd_pcm_hw_params *params) 33 struct snd_pcm_hw_params *params)
34{ 34{
35 struct snd_soc_pcm_runtime *rtd = substream->private_data; 35 struct snd_soc_pcm_runtime *rtd = substream->private_data;
36 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; 36 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
37 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 37 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
38 int ret = 0; 38 int ret = 0;
39 39
40 /* set codec DAI configuration */ 40 /* set codec DAI configuration */
41 ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 41 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
42 SND_SOC_DAIFMT_CBM_CFM); 42 SND_SOC_DAIFMT_CBM_CFM);
43 if (ret < 0) 43 if (ret < 0)
44 return ret; 44 return ret;
45 45
46 /* set cpu DAI configuration */ 46 /* set cpu DAI configuration */
47 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM | 47 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM |
48 SND_SOC_DAIFMT_IB_NF); 48 SND_SOC_DAIFMT_IB_NF);
49 if (ret < 0) 49 if (ret < 0)
50 return ret; 50 return ret;
51 51
52 /* set the codec system clock */ 52 /* set the codec system clock */
53 ret = codec_dai->dai_ops.set_sysclk(codec_dai, 0, EVM_CODEC_CLOCK, 53 ret = snd_soc_dai_set_sysclk(codec_dai, 0, EVM_CODEC_CLOCK,
54 SND_SOC_CLOCK_OUT); 54 SND_SOC_CLOCK_OUT);
55 if (ret < 0) 55 if (ret < 0)
56 return ret; 56 return ret;
@@ -71,7 +71,7 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
71}; 71};
72 72
73/* davinci-evm machine audio_mapnections to the codec pins */ 73/* davinci-evm machine audio_mapnections to the codec pins */
74static const char *audio_map[][3] = { 74static const struct snd_soc_dapm_route audio_map[] = {
75 /* Headphone connected to HPLOUT, HPROUT */ 75 /* Headphone connected to HPLOUT, HPROUT */
76 {"Headphone Jack", NULL, "HPLOUT"}, 76 {"Headphone Jack", NULL, "HPLOUT"},
77 {"Headphone Jack", NULL, "HPROUT"}, 77 {"Headphone Jack", NULL, "HPROUT"},
@@ -90,36 +90,30 @@ static const char *audio_map[][3] = {
90 {"LINE2L", NULL, "Line In"}, 90 {"LINE2L", NULL, "Line In"},
91 {"LINE1R", NULL, "Line In"}, 91 {"LINE1R", NULL, "Line In"},
92 {"LINE2R", NULL, "Line In"}, 92 {"LINE2R", NULL, "Line In"},
93
94 {NULL, NULL, NULL},
95}; 93};
96 94
97/* Logic for a aic3x as connected on a davinci-evm */ 95/* Logic for a aic3x as connected on a davinci-evm */
98static int evm_aic3x_init(struct snd_soc_codec *codec) 96static int evm_aic3x_init(struct snd_soc_codec *codec)
99{ 97{
100 int i;
101
102 /* Add davinci-evm specific widgets */ 98 /* Add davinci-evm specific widgets */
103 for (i = 0; i < ARRAY_SIZE(aic3x_dapm_widgets); i++) 99 snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets,
104 snd_soc_dapm_new_control(codec, &aic3x_dapm_widgets[i]); 100 ARRAY_SIZE(aic3x_dapm_widgets));
105 101
106 /* Set up davinci-evm specific audio path audio_map */ 102 /* Set up davinci-evm specific audio path audio_map */
107 for (i = 0; audio_map[i][0] != NULL; i++) 103 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
108 snd_soc_dapm_connect_input(codec, audio_map[i][0],
109 audio_map[i][1], audio_map[i][2]);
110 104
111 /* not connected */ 105 /* not connected */
112 snd_soc_dapm_set_endpoint(codec, "MONO_LOUT", 0); 106 snd_soc_dapm_disable_pin(codec, "MONO_LOUT");
113 snd_soc_dapm_set_endpoint(codec, "HPLCOM", 0); 107 snd_soc_dapm_disable_pin(codec, "HPLCOM");
114 snd_soc_dapm_set_endpoint(codec, "HPRCOM", 0); 108 snd_soc_dapm_disable_pin(codec, "HPRCOM");
115 109
116 /* always connected */ 110 /* always connected */
117 snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 1); 111 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
118 snd_soc_dapm_set_endpoint(codec, "Line Out", 1); 112 snd_soc_dapm_enable_pin(codec, "Line Out");
119 snd_soc_dapm_set_endpoint(codec, "Mic Jack", 1); 113 snd_soc_dapm_enable_pin(codec, "Mic Jack");
120 snd_soc_dapm_set_endpoint(codec, "Line In", 1); 114 snd_soc_dapm_enable_pin(codec, "Line In");
121 115
122 snd_soc_dapm_sync_endpoints(codec); 116 snd_soc_dapm_sync(codec);
123 117
124 return 0; 118 return 0;
125} 119}
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index c421774b33ee..5ebf1ff71c4c 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -147,7 +147,7 @@ static void davinci_mcbsp_stop(struct snd_pcm_substream *substream)
147static int davinci_i2s_startup(struct snd_pcm_substream *substream) 147static int davinci_i2s_startup(struct snd_pcm_substream *substream)
148{ 148{
149 struct snd_soc_pcm_runtime *rtd = substream->private_data; 149 struct snd_soc_pcm_runtime *rtd = substream->private_data;
150 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 150 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
151 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data; 151 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
152 152
153 cpu_dai->dma_data = dev->dma_params[substream->stream]; 153 cpu_dai->dma_data = dev->dma_params[substream->stream];
@@ -155,7 +155,7 @@ static int davinci_i2s_startup(struct snd_pcm_substream *substream)
155 return 0; 155 return 0;
156} 156}
157 157
158static int davinci_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, 158static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
159 unsigned int fmt) 159 unsigned int fmt)
160{ 160{
161 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 161 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
@@ -295,11 +295,12 @@ static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
295 return ret; 295 return ret;
296} 296}
297 297
298static int davinci_i2s_probe(struct platform_device *pdev) 298static int davinci_i2s_probe(struct platform_device *pdev,
299 struct snd_soc_dai *dai)
299{ 300{
300 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 301 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
301 struct snd_soc_machine *machine = socdev->machine; 302 struct snd_soc_machine *machine = socdev->machine;
302 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai; 303 struct snd_soc_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai;
303 struct davinci_mcbsp_dev *dev; 304 struct davinci_mcbsp_dev *dev;
304 struct resource *mem, *ioarea; 305 struct resource *mem, *ioarea;
305 struct evm_snd_platform_data *pdata; 306 struct evm_snd_platform_data *pdata;
@@ -356,11 +357,12 @@ err_release_region:
356 return ret; 357 return ret;
357} 358}
358 359
359static void davinci_i2s_remove(struct platform_device *pdev) 360static void davinci_i2s_remove(struct platform_device *pdev,
361 struct snd_soc_dai *dai)
360{ 362{
361 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 363 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
362 struct snd_soc_machine *machine = socdev->machine; 364 struct snd_soc_machine *machine = socdev->machine;
363 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai; 365 struct snd_soc_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai;
364 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 366 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
365 struct resource *mem; 367 struct resource *mem;
366 368
@@ -376,7 +378,7 @@ static void davinci_i2s_remove(struct platform_device *pdev)
376 378
377#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 379#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
378 380
379struct snd_soc_cpu_dai davinci_i2s_dai = { 381struct snd_soc_dai davinci_i2s_dai = {
380 .name = "davinci-i2s", 382 .name = "davinci-i2s",
381 .id = 0, 383 .id = 0,
382 .type = SND_SOC_DAI_I2S, 384 .type = SND_SOC_DAI_I2S,
diff --git a/sound/soc/davinci/davinci-i2s.h b/sound/soc/davinci/davinci-i2s.h
index 9592d17db320..c5b091807eec 100644
--- a/sound/soc/davinci/davinci-i2s.h
+++ b/sound/soc/davinci/davinci-i2s.h
@@ -12,6 +12,6 @@
12#ifndef _DAVINCI_I2S_H 12#ifndef _DAVINCI_I2S_H
13#define _DAVINCI_I2S_H 13#define _DAVINCI_I2S_H
14 14
15extern struct snd_soc_cpu_dai davinci_i2s_dai; 15extern struct snd_soc_dai davinci_i2s_dai;
16 16
17#endif 17#endif
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 6a76927c9971..6a5e56a782bb 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -350,7 +350,7 @@ static void davinci_pcm_free(struct snd_pcm *pcm)
350static u64 davinci_pcm_dmamask = 0xffffffff; 350static u64 davinci_pcm_dmamask = 0xffffffff;
351 351
352static int davinci_pcm_new(struct snd_card *card, 352static int davinci_pcm_new(struct snd_card *card,
353 struct snd_soc_codec_dai *dai, struct snd_pcm *pcm) 353 struct snd_soc_dai *dai, struct snd_pcm *pcm)
354{ 354{
355 int ret; 355 int ret;
356 356
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 257101f44e9e..3368ace60977 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -1,8 +1,6 @@
1menu "ALSA SoC audio for Freescale SOCs"
2
3config SND_SOC_MPC8610 1config SND_SOC_MPC8610
4 bool "ALSA SoC support for the MPC8610 SOC" 2 bool "ALSA SoC support for the MPC8610 SOC"
5 depends on SND_SOC && MPC8610_HPCD 3 depends on MPC8610_HPCD
6 default y if MPC8610 4 default y if MPC8610
7 help 5 help
8 Say Y if you want to add support for codecs attached to the SSI 6 Say Y if you want to add support for codecs attached to the SSI
@@ -16,5 +14,3 @@ config SND_SOC_MPC8610_HPCD
16 default y if MPC8610_HPCD 14 default y if MPC8610_HPCD
17 help 15 help
18 Say Y if you want to enable audio on the Freescale MPC8610 HPCD. 16 Say Y if you want to enable audio on the Freescale MPC8610 HPCD.
19
20endmenu
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index 78de7168d2ba..da2bc5902864 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -282,7 +282,7 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
282 * once for each .dai_link in the machine driver's snd_soc_machine 282 * once for each .dai_link in the machine driver's snd_soc_machine
283 * structure. 283 * structure.
284 */ 284 */
285static int fsl_dma_new(struct snd_card *card, struct snd_soc_codec_dai *dai, 285static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
286 struct snd_pcm *pcm) 286 struct snd_pcm *pcm)
287{ 287{
288 static u64 fsl_dma_dmamask = DMA_BIT_MASK(32); 288 static u64 fsl_dma_dmamask = DMA_BIT_MASK(32);
diff --git a/sound/soc/fsl/fsl_dma.h b/sound/soc/fsl/fsl_dma.h
index 430a6ce8b0d0..385d4a42603c 100644
--- a/sound/soc/fsl/fsl_dma.h
+++ b/sound/soc/fsl/fsl_dma.h
@@ -126,7 +126,7 @@ struct fsl_dma_link_descriptor {
126 u8 res[4]; /* Reserved */ 126 u8 res[4]; /* Reserved */
127} __attribute__ ((aligned(32), packed)); 127} __attribute__ ((aligned(32), packed));
128 128
129/* DMA information needed to create a snd_soc_cpu_dai object 129/* DMA information needed to create a snd_soc_dai object
130 * 130 *
131 * ssi_stx_phys: bus address of SSI STX register to use 131 * ssi_stx_phys: bus address of SSI STX register to use
132 * ssi_srx_phys: bus address of SSI SRX register to use 132 * ssi_srx_phys: bus address of SSI SRX register to use
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index f588545698f3..71bff33f5528 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -82,7 +82,7 @@ struct fsl_ssi_private {
82 struct device *dev; 82 struct device *dev;
83 unsigned int playback; 83 unsigned int playback;
84 unsigned int capture; 84 unsigned int capture;
85 struct snd_soc_cpu_dai cpu_dai; 85 struct snd_soc_dai cpu_dai;
86 struct device_attribute dev_attr; 86 struct device_attribute dev_attr;
87 87
88 struct { 88 struct {
@@ -479,7 +479,7 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream)
479 * @freq: the frequency of the given clock ID, currently ignored 479 * @freq: the frequency of the given clock ID, currently ignored
480 * @dir: SND_SOC_CLOCK_IN (clock slave) or SND_SOC_CLOCK_OUT (clock master) 480 * @dir: SND_SOC_CLOCK_IN (clock slave) or SND_SOC_CLOCK_OUT (clock master)
481 */ 481 */
482static int fsl_ssi_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, 482static int fsl_ssi_set_sysclk(struct snd_soc_dai *cpu_dai,
483 int clk_id, unsigned int freq, int dir) 483 int clk_id, unsigned int freq, int dir)
484{ 484{
485 485
@@ -497,7 +497,7 @@ static int fsl_ssi_set_sysclk(struct snd_soc_cpu_dai *cpu_dai,
497 * 497 *
498 * @format: one of SND_SOC_DAIFMT_xxx 498 * @format: one of SND_SOC_DAIFMT_xxx
499 */ 499 */
500static int fsl_ssi_set_fmt(struct snd_soc_cpu_dai *cpu_dai, unsigned int format) 500static int fsl_ssi_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
501{ 501{
502 return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL; 502 return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL;
503} 503}
@@ -505,7 +505,7 @@ static int fsl_ssi_set_fmt(struct snd_soc_cpu_dai *cpu_dai, unsigned int format)
505/** 505/**
506 * fsl_ssi_dai_template: template CPU DAI for the SSI 506 * fsl_ssi_dai_template: template CPU DAI for the SSI
507 */ 507 */
508static struct snd_soc_cpu_dai fsl_ssi_dai_template = { 508static struct snd_soc_dai fsl_ssi_dai_template = {
509 .playback = { 509 .playback = {
510 /* The SSI does not support monaural audio. */ 510 /* The SSI does not support monaural audio. */
511 .channels_min = 2, 511 .channels_min = 2,
@@ -569,15 +569,15 @@ static ssize_t fsl_sysfs_ssi_show(struct device *dev,
569} 569}
570 570
571/** 571/**
572 * fsl_ssi_create_dai: create a snd_soc_cpu_dai structure 572 * fsl_ssi_create_dai: create a snd_soc_dai structure
573 * 573 *
574 * This function is called by the machine driver to create a snd_soc_cpu_dai 574 * This function is called by the machine driver to create a snd_soc_dai
575 * structure. The function creates an ssi_private object, which contains 575 * structure. The function creates an ssi_private object, which contains
576 * the snd_soc_cpu_dai. It also creates the sysfs statistics device. 576 * the snd_soc_dai. It also creates the sysfs statistics device.
577 */ 577 */
578struct snd_soc_cpu_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info) 578struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info)
579{ 579{
580 struct snd_soc_cpu_dai *fsl_ssi_dai; 580 struct snd_soc_dai *fsl_ssi_dai;
581 struct fsl_ssi_private *ssi_private; 581 struct fsl_ssi_private *ssi_private;
582 int ret = 0; 582 int ret = 0;
583 struct device_attribute *dev_attr; 583 struct device_attribute *dev_attr;
@@ -588,7 +588,7 @@ struct snd_soc_cpu_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info)
588 return NULL; 588 return NULL;
589 } 589 }
590 memcpy(&ssi_private->cpu_dai, &fsl_ssi_dai_template, 590 memcpy(&ssi_private->cpu_dai, &fsl_ssi_dai_template,
591 sizeof(struct snd_soc_cpu_dai)); 591 sizeof(struct snd_soc_dai));
592 592
593 fsl_ssi_dai = &ssi_private->cpu_dai; 593 fsl_ssi_dai = &ssi_private->cpu_dai;
594 dev_attr = &ssi_private->dev_attr; 594 dev_attr = &ssi_private->dev_attr;
@@ -623,11 +623,11 @@ struct snd_soc_cpu_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info)
623EXPORT_SYMBOL_GPL(fsl_ssi_create_dai); 623EXPORT_SYMBOL_GPL(fsl_ssi_create_dai);
624 624
625/** 625/**
626 * fsl_ssi_destroy_dai: destroy the snd_soc_cpu_dai object 626 * fsl_ssi_destroy_dai: destroy the snd_soc_dai object
627 * 627 *
628 * This function undoes the operations of fsl_ssi_create_dai() 628 * This function undoes the operations of fsl_ssi_create_dai()
629 */ 629 */
630void fsl_ssi_destroy_dai(struct snd_soc_cpu_dai *fsl_ssi_dai) 630void fsl_ssi_destroy_dai(struct snd_soc_dai *fsl_ssi_dai)
631{ 631{
632 struct fsl_ssi_private *ssi_private = 632 struct fsl_ssi_private *ssi_private =
633 container_of(fsl_ssi_dai, struct fsl_ssi_private, cpu_dai); 633 container_of(fsl_ssi_dai, struct fsl_ssi_private, cpu_dai);
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h
index c5ce88e15651..83b44d700e33 100644
--- a/sound/soc/fsl/fsl_ssi.h
+++ b/sound/soc/fsl/fsl_ssi.h
@@ -217,8 +217,8 @@ struct fsl_ssi_info {
217 struct device *dev; 217 struct device *dev;
218}; 218};
219 219
220struct snd_soc_cpu_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info); 220struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info);
221void fsl_ssi_destroy_dai(struct snd_soc_cpu_dai *fsl_ssi_dai); 221void fsl_ssi_destroy_dai(struct snd_soc_dai *fsl_ssi_dai);
222 222
223#endif 223#endif
224 224
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index a00aac7a71f1..4bdc9d8fc90e 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -58,9 +58,9 @@ static int mpc8610_hpcd_machine_probe(struct platform_device *sound_device)
58 sound_device->dev.platform_data; 58 sound_device->dev.platform_data;
59 59
60 /* Program the signal routing between the SSI and the DMA */ 60 /* Program the signal routing between the SSI and the DMA */
61 guts_set_dmacr(machine_data->guts, machine_data->dma_id + 1, 61 guts_set_dmacr(machine_data->guts, machine_data->dma_id,
62 machine_data->dma_channel_id[0], CCSR_GUTS_DMACR_DEV_SSI); 62 machine_data->dma_channel_id[0], CCSR_GUTS_DMACR_DEV_SSI);
63 guts_set_dmacr(machine_data->guts, machine_data->dma_id + 1, 63 guts_set_dmacr(machine_data->guts, machine_data->dma_id,
64 machine_data->dma_channel_id[1], CCSR_GUTS_DMACR_DEV_SSI); 64 machine_data->dma_channel_id[1], CCSR_GUTS_DMACR_DEV_SSI);
65 65
66 guts_set_pmuxcr_dma(machine_data->guts, machine_data->dma_id, 66 guts_set_pmuxcr_dma(machine_data->guts, machine_data->dma_id,
@@ -96,62 +96,52 @@ static int mpc8610_hpcd_machine_probe(struct platform_device *sound_device)
96static int mpc8610_hpcd_startup(struct snd_pcm_substream *substream) 96static int mpc8610_hpcd_startup(struct snd_pcm_substream *substream)
97{ 97{
98 struct snd_soc_pcm_runtime *rtd = substream->private_data; 98 struct snd_soc_pcm_runtime *rtd = substream->private_data;
99 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; 99 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
100 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 100 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
101 struct mpc8610_hpcd_data *machine_data = 101 struct mpc8610_hpcd_data *machine_data =
102 rtd->socdev->dev->platform_data; 102 rtd->socdev->dev->platform_data;
103 int ret = 0; 103 int ret = 0;
104 104
105 /* Tell the CPU driver what the serial protocol is. */ 105 /* Tell the CPU driver what the serial protocol is. */
106 if (cpu_dai->dai_ops.set_fmt) { 106 ret = snd_soc_dai_set_fmt(cpu_dai, machine_data->dai_format);
107 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, 107 if (ret < 0) {
108 machine_data->dai_format); 108 dev_err(substream->pcm->card->dev,
109 if (ret < 0) { 109 "could not set CPU driver audio format\n");
110 dev_err(substream->pcm->card->dev, 110 return ret;
111 "could not set CPU driver audio format\n");
112 return ret;
113 }
114 } 111 }
115 112
116 /* Tell the codec driver what the serial protocol is. */ 113 /* Tell the codec driver what the serial protocol is. */
117 if (codec_dai->dai_ops.set_fmt) { 114 ret = snd_soc_dai_set_fmt(codec_dai, machine_data->dai_format);
118 ret = codec_dai->dai_ops.set_fmt(codec_dai, 115 if (ret < 0) {
119 machine_data->dai_format); 116 dev_err(substream->pcm->card->dev,
120 if (ret < 0) { 117 "could not set codec driver audio format\n");
121 dev_err(substream->pcm->card->dev, 118 return ret;
122 "could not set codec driver audio format\n");
123 return ret;
124 }
125 } 119 }
126 120
127 /* 121 /*
128 * Tell the CPU driver what the clock frequency is, and whether it's a 122 * Tell the CPU driver what the clock frequency is, and whether it's a
129 * slave or master. 123 * slave or master.
130 */ 124 */
131 if (cpu_dai->dai_ops.set_sysclk) { 125 ret = snd_soc_dai_set_sysclk(cpu_dai, 0,
132 ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, 0, 126 machine_data->clk_frequency,
133 machine_data->clk_frequency, 127 machine_data->cpu_clk_direction);
134 machine_data->cpu_clk_direction); 128 if (ret < 0) {
135 if (ret < 0) { 129 dev_err(substream->pcm->card->dev,
136 dev_err(substream->pcm->card->dev, 130 "could not set CPU driver clock parameters\n");
137 "could not set CPU driver clock parameters\n"); 131 return ret;
138 return ret;
139 }
140 } 132 }
141 133
142 /* 134 /*
143 * Tell the codec driver what the MCLK frequency is, and whether it's 135 * Tell the codec driver what the MCLK frequency is, and whether it's
144 * a slave or master. 136 * a slave or master.
145 */ 137 */
146 if (codec_dai->dai_ops.set_sysclk) { 138 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
147 ret = codec_dai->dai_ops.set_sysclk(codec_dai, 0, 139 machine_data->clk_frequency,
148 machine_data->clk_frequency, 140 machine_data->codec_clk_direction);
149 machine_data->codec_clk_direction); 141 if (ret < 0) {
150 if (ret < 0) { 142 dev_err(substream->pcm->card->dev,
151 dev_err(substream->pcm->card->dev, 143 "could not set codec driver clock params\n");
152 "could not set codec driver clock params\n"); 144 return ret;
153 return ret;
154 }
155 } 145 }
156 146
157 return 0; 147 return 0;
@@ -170,9 +160,9 @@ int mpc8610_hpcd_machine_remove(struct platform_device *sound_device)
170 160
171 /* Restore the signal routing */ 161 /* Restore the signal routing */
172 162
173 guts_set_dmacr(machine_data->guts, machine_data->dma_id + 1, 163 guts_set_dmacr(machine_data->guts, machine_data->dma_id,
174 machine_data->dma_channel_id[0], 0); 164 machine_data->dma_channel_id[0], 0);
175 guts_set_dmacr(machine_data->guts, machine_data->dma_id + 1, 165 guts_set_dmacr(machine_data->guts, machine_data->dma_id,
176 machine_data->dma_channel_id[1], 0); 166 machine_data->dma_channel_id[1], 0);
177 167
178 switch (machine_data->ssi_id) { 168 switch (machine_data->ssi_id) {
@@ -182,7 +172,7 @@ int mpc8610_hpcd_machine_remove(struct platform_device *sound_device)
182 break; 172 break;
183 case 1: 173 case 1:
184 clrsetbits_be32(&machine_data->guts->pmuxcr, 174 clrsetbits_be32(&machine_data->guts->pmuxcr,
185 CCSR_GUTS_PMUXCR_SSI2_MASK, CCSR_GUTS_PMUXCR_SSI1_LA); 175 CCSR_GUTS_PMUXCR_SSI2_MASK, CCSR_GUTS_PMUXCR_SSI2_LA);
186 break; 176 break;
187 } 177 }
188 178
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 0230d83e8e5e..aea27e70043c 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -1,5 +1,3 @@
1menu "SoC Audio for the Texas Instruments OMAP"
2
3config SND_OMAP_SOC 1config SND_OMAP_SOC
4 tristate "SoC Audio for the Texas Instruments OMAP chips" 2 tristate "SoC Audio for the Texas Instruments OMAP chips"
5 depends on ARCH_OMAP && SND_SOC 3 depends on ARCH_OMAP && SND_SOC
@@ -15,5 +13,3 @@ config SND_OMAP_SOC_N810
15 select SND_SOC_TLV320AIC3X 13 select SND_SOC_TLV320AIC3X
16 help 14 help
17 Say Y if you want to add support for SoC audio on Nokia N810. 15 Say Y if you want to add support for SoC audio on Nokia N810.
18
19endmenu
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 6533563a6011..02cec96859b8 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -30,15 +30,15 @@
30 30
31#include <asm/mach-types.h> 31#include <asm/mach-types.h>
32#include <asm/arch/hardware.h> 32#include <asm/arch/hardware.h>
33#include <asm/arch/gpio.h> 33#include <linux/gpio.h>
34#include <asm/arch/mcbsp.h> 34#include <asm/arch/mcbsp.h>
35 35
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h" 37#include "omap-pcm.h"
38#include "../codecs/tlv320aic3x.h" 38#include "../codecs/tlv320aic3x.h"
39 39
40#define RX44_HEADSET_AMP_GPIO 10 40#define N810_HEADSET_AMP_GPIO 10
41#define RX44_SPEAKER_AMP_GPIO 101 41#define N810_SPEAKER_AMP_GPIO 101
42 42
43static struct clk *sys_clkout2; 43static struct clk *sys_clkout2;
44static struct clk *sys_clkout2_src; 44static struct clk *sys_clkout2_src;
@@ -46,13 +46,26 @@ static struct clk *func96m_clk;
46 46
47static int n810_spk_func; 47static int n810_spk_func;
48static int n810_jack_func; 48static int n810_jack_func;
49static int n810_dmic_func;
49 50
50static void n810_ext_control(struct snd_soc_codec *codec) 51static void n810_ext_control(struct snd_soc_codec *codec)
51{ 52{
52 snd_soc_dapm_set_endpoint(codec, "Ext Spk", n810_spk_func); 53 if (n810_spk_func)
53 snd_soc_dapm_set_endpoint(codec, "Headphone Jack", n810_jack_func); 54 snd_soc_dapm_enable_pin(codec, "Ext Spk");
55 else
56 snd_soc_dapm_disable_pin(codec, "Ext Spk");
57
58 if (n810_jack_func)
59 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
60 else
61 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
54 62
55 snd_soc_dapm_sync_endpoints(codec); 63 if (n810_dmic_func)
64 snd_soc_dapm_enable_pin(codec, "DMic");
65 else
66 snd_soc_dapm_disable_pin(codec, "DMic");
67
68 snd_soc_dapm_sync(codec);
56} 69}
57 70
58static int n810_startup(struct snd_pcm_substream *substream) 71static int n810_startup(struct snd_pcm_substream *substream)
@@ -73,12 +86,12 @@ static int n810_hw_params(struct snd_pcm_substream *substream,
73 struct snd_pcm_hw_params *params) 86 struct snd_pcm_hw_params *params)
74{ 87{
75 struct snd_soc_pcm_runtime *rtd = substream->private_data; 88 struct snd_soc_pcm_runtime *rtd = substream->private_data;
76 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; 89 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
77 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 90 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
78 int err; 91 int err;
79 92
80 /* Set codec DAI configuration */ 93 /* Set codec DAI configuration */
81 err = codec_dai->dai_ops.set_fmt(codec_dai, 94 err = snd_soc_dai_set_fmt(codec_dai,
82 SND_SOC_DAIFMT_I2S | 95 SND_SOC_DAIFMT_I2S |
83 SND_SOC_DAIFMT_NB_NF | 96 SND_SOC_DAIFMT_NB_NF |
84 SND_SOC_DAIFMT_CBM_CFM); 97 SND_SOC_DAIFMT_CBM_CFM);
@@ -86,7 +99,7 @@ static int n810_hw_params(struct snd_pcm_substream *substream,
86 return err; 99 return err;
87 100
88 /* Set cpu DAI configuration */ 101 /* Set cpu DAI configuration */
89 err = cpu_dai->dai_ops.set_fmt(cpu_dai, 102 err = snd_soc_dai_set_fmt(cpu_dai,
90 SND_SOC_DAIFMT_I2S | 103 SND_SOC_DAIFMT_I2S |
91 SND_SOC_DAIFMT_NB_NF | 104 SND_SOC_DAIFMT_NB_NF |
92 SND_SOC_DAIFMT_CBM_CFM); 105 SND_SOC_DAIFMT_CBM_CFM);
@@ -94,7 +107,7 @@ static int n810_hw_params(struct snd_pcm_substream *substream,
94 return err; 107 return err;
95 108
96 /* Set the codec system clock for DAC and ADC */ 109 /* Set the codec system clock for DAC and ADC */
97 err = codec_dai->dai_ops.set_sysclk(codec_dai, 0, 12000000, 110 err = snd_soc_dai_set_sysclk(codec_dai, 0, 12000000,
98 SND_SOC_CLOCK_IN); 111 SND_SOC_CLOCK_IN);
99 112
100 return err; 113 return err;
@@ -150,13 +163,35 @@ static int n810_set_jack(struct snd_kcontrol *kcontrol,
150 return 1; 163 return 1;
151} 164}
152 165
166static int n810_get_input(struct snd_kcontrol *kcontrol,
167 struct snd_ctl_elem_value *ucontrol)
168{
169 ucontrol->value.integer.value[0] = n810_dmic_func;
170
171 return 0;
172}
173
174static int n810_set_input(struct snd_kcontrol *kcontrol,
175 struct snd_ctl_elem_value *ucontrol)
176{
177 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
178
179 if (n810_dmic_func == ucontrol->value.integer.value[0])
180 return 0;
181
182 n810_dmic_func = ucontrol->value.integer.value[0];
183 n810_ext_control(codec);
184
185 return 1;
186}
187
153static int n810_spk_event(struct snd_soc_dapm_widget *w, 188static int n810_spk_event(struct snd_soc_dapm_widget *w,
154 struct snd_kcontrol *k, int event) 189 struct snd_kcontrol *k, int event)
155{ 190{
156 if (SND_SOC_DAPM_EVENT_ON(event)) 191 if (SND_SOC_DAPM_EVENT_ON(event))
157 omap_set_gpio_dataout(RX44_SPEAKER_AMP_GPIO, 1); 192 gpio_set_value(N810_SPEAKER_AMP_GPIO, 1);
158 else 193 else
159 omap_set_gpio_dataout(RX44_SPEAKER_AMP_GPIO, 0); 194 gpio_set_value(N810_SPEAKER_AMP_GPIO, 0);
160 195
161 return 0; 196 return 0;
162} 197}
@@ -165,9 +200,9 @@ static int n810_jack_event(struct snd_soc_dapm_widget *w,
165 struct snd_kcontrol *k, int event) 200 struct snd_kcontrol *k, int event)
166{ 201{
167 if (SND_SOC_DAPM_EVENT_ON(event)) 202 if (SND_SOC_DAPM_EVENT_ON(event))
168 omap_set_gpio_dataout(RX44_HEADSET_AMP_GPIO, 1); 203 gpio_set_value(N810_HEADSET_AMP_GPIO, 1);
169 else 204 else
170 omap_set_gpio_dataout(RX44_HEADSET_AMP_GPIO, 0); 205 gpio_set_value(N810_HEADSET_AMP_GPIO, 0);
171 206
172 return 0; 207 return 0;
173} 208}
@@ -175,21 +210,27 @@ static int n810_jack_event(struct snd_soc_dapm_widget *w,
175static const struct snd_soc_dapm_widget aic33_dapm_widgets[] = { 210static const struct snd_soc_dapm_widget aic33_dapm_widgets[] = {
176 SND_SOC_DAPM_SPK("Ext Spk", n810_spk_event), 211 SND_SOC_DAPM_SPK("Ext Spk", n810_spk_event),
177 SND_SOC_DAPM_HP("Headphone Jack", n810_jack_event), 212 SND_SOC_DAPM_HP("Headphone Jack", n810_jack_event),
213 SND_SOC_DAPM_MIC("DMic", NULL),
178}; 214};
179 215
180static const char *audio_map[][3] = { 216static const struct snd_soc_dapm_route audio_map[] = {
181 {"Headphone Jack", NULL, "HPLOUT"}, 217 {"Headphone Jack", NULL, "HPLOUT"},
182 {"Headphone Jack", NULL, "HPROUT"}, 218 {"Headphone Jack", NULL, "HPROUT"},
183 219
184 {"Ext Spk", NULL, "LLOUT"}, 220 {"Ext Spk", NULL, "LLOUT"},
185 {"Ext Spk", NULL, "RLOUT"}, 221 {"Ext Spk", NULL, "RLOUT"},
222
223 {"DMic Rate 64", NULL, "Mic Bias 2V"},
224 {"Mic Bias 2V", NULL, "DMic"},
186}; 225};
187 226
188static const char *spk_function[] = {"Off", "On"}; 227static const char *spk_function[] = {"Off", "On"};
189static const char *jack_function[] = {"Off", "Headphone"}; 228static const char *jack_function[] = {"Off", "Headphone"};
229static const char *input_function[] = {"ADC", "Digital Mic"};
190static const struct soc_enum n810_enum[] = { 230static const struct soc_enum n810_enum[] = {
191 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function), 231 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
192 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(jack_function), jack_function), 232 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(jack_function), jack_function),
233 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(input_function), input_function),
193}; 234};
194 235
195static const struct snd_kcontrol_new aic33_n810_controls[] = { 236static const struct snd_kcontrol_new aic33_n810_controls[] = {
@@ -197,6 +238,8 @@ static const struct snd_kcontrol_new aic33_n810_controls[] = {
197 n810_get_spk, n810_set_spk), 238 n810_get_spk, n810_set_spk),
198 SOC_ENUM_EXT("Jack Function", n810_enum[1], 239 SOC_ENUM_EXT("Jack Function", n810_enum[1],
199 n810_get_jack, n810_set_jack), 240 n810_get_jack, n810_set_jack),
241 SOC_ENUM_EXT("Input Select", n810_enum[2],
242 n810_get_input, n810_set_input),
200}; 243};
201 244
202static int n810_aic33_init(struct snd_soc_codec *codec) 245static int n810_aic33_init(struct snd_soc_codec *codec)
@@ -204,9 +247,9 @@ static int n810_aic33_init(struct snd_soc_codec *codec)
204 int i, err; 247 int i, err;
205 248
206 /* Not connected */ 249 /* Not connected */
207 snd_soc_dapm_set_endpoint(codec, "MONO_LOUT", 0); 250 snd_soc_dapm_disable_pin(codec, "MONO_LOUT");
208 snd_soc_dapm_set_endpoint(codec, "HPLCOM", 0); 251 snd_soc_dapm_disable_pin(codec, "HPLCOM");
209 snd_soc_dapm_set_endpoint(codec, "HPRCOM", 0); 252 snd_soc_dapm_disable_pin(codec, "HPRCOM");
210 253
211 /* Add N810 specific controls */ 254 /* Add N810 specific controls */
212 for (i = 0; i < ARRAY_SIZE(aic33_n810_controls); i++) { 255 for (i = 0; i < ARRAY_SIZE(aic33_n810_controls); i++) {
@@ -217,15 +260,13 @@ static int n810_aic33_init(struct snd_soc_codec *codec)
217 } 260 }
218 261
219 /* Add N810 specific widgets */ 262 /* Add N810 specific widgets */
220 for (i = 0; i < ARRAY_SIZE(aic33_dapm_widgets); i++) 263 snd_soc_dapm_new_controls(codec, aic33_dapm_widgets,
221 snd_soc_dapm_new_control(codec, &aic33_dapm_widgets[i]); 264 ARRAY_SIZE(aic33_dapm_widgets));
222 265
223 /* Set up N810 specific audio path audio_map */ 266 /* Set up N810 specific audio path audio_map */
224 for (i = 0; i < ARRAY_SIZE(audio_map); i++) 267 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
225 snd_soc_dapm_connect_input(codec, audio_map[i][0],
226 audio_map[i][1], audio_map[i][2]);
227 268
228 snd_soc_dapm_sync_endpoints(codec); 269 snd_soc_dapm_sync(codec);
229 270
230 return 0; 271 return 0;
231} 272}
@@ -250,6 +291,8 @@ static struct snd_soc_machine snd_soc_machine_n810 = {
250/* Audio private data */ 291/* Audio private data */
251static struct aic3x_setup_data n810_aic33_setup = { 292static struct aic3x_setup_data n810_aic33_setup = {
252 .i2c_address = 0x18, 293 .i2c_address = 0x18,
294 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
295 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,
253}; 296};
254 297
255/* Audio subsystem */ 298/* Audio subsystem */
@@ -267,7 +310,7 @@ static int __init n810_soc_init(void)
267 int err; 310 int err;
268 struct device *dev; 311 struct device *dev;
269 312
270 if (!machine_is_nokia_n810()) 313 if (!(machine_is_nokia_n810() || machine_is_nokia_n810_wimax()))
271 return -ENODEV; 314 return -ENODEV;
272 315
273 n810_snd_device = platform_device_alloc("soc-audio", -1); 316 n810_snd_device = platform_device_alloc("soc-audio", -1);
@@ -305,12 +348,12 @@ static int __init n810_soc_init(void)
305 clk_set_parent(sys_clkout2_src, func96m_clk); 348 clk_set_parent(sys_clkout2_src, func96m_clk);
306 clk_set_rate(sys_clkout2, 12000000); 349 clk_set_rate(sys_clkout2, 12000000);
307 350
308 if (omap_request_gpio(RX44_HEADSET_AMP_GPIO) < 0) 351 if (gpio_request(N810_HEADSET_AMP_GPIO, "hs_amp") < 0)
309 BUG(); 352 BUG();
310 if (omap_request_gpio(RX44_SPEAKER_AMP_GPIO) < 0) 353 if (gpio_request(N810_SPEAKER_AMP_GPIO, "spk_amp") < 0)
311 BUG(); 354 BUG();
312 omap_set_gpio_direction(RX44_HEADSET_AMP_GPIO, 0); 355 gpio_direction_output(N810_HEADSET_AMP_GPIO, 0);
313 omap_set_gpio_direction(RX44_SPEAKER_AMP_GPIO, 0); 356 gpio_direction_output(N810_SPEAKER_AMP_GPIO, 0);
314 357
315 return 0; 358 return 0;
316err2: 359err2:
@@ -325,6 +368,9 @@ err1:
325 368
326static void __exit n810_soc_exit(void) 369static void __exit n810_soc_exit(void)
327{ 370{
371 gpio_free(N810_SPEAKER_AMP_GPIO);
372 gpio_free(N810_HEADSET_AMP_GPIO);
373
328 platform_device_unregister(n810_snd_device); 374 platform_device_unregister(n810_snd_device);
329} 375}
330 376
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 40d87e6d0de8..00b0c9d73cd4 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -103,7 +103,7 @@ static const unsigned long omap2420_mcbsp_port[][2] = {};
103static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream) 103static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream)
104{ 104{
105 struct snd_soc_pcm_runtime *rtd = substream->private_data; 105 struct snd_soc_pcm_runtime *rtd = substream->private_data;
106 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 106 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
107 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 107 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
108 int err = 0; 108 int err = 0;
109 109
@@ -116,7 +116,7 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream)
116static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream) 116static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream)
117{ 117{
118 struct snd_soc_pcm_runtime *rtd = substream->private_data; 118 struct snd_soc_pcm_runtime *rtd = substream->private_data;
119 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 119 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
120 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 120 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
121 121
122 if (!cpu_dai->active) { 122 if (!cpu_dai->active) {
@@ -128,7 +128,7 @@ static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream)
128static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd) 128static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd)
129{ 129{
130 struct snd_soc_pcm_runtime *rtd = substream->private_data; 130 struct snd_soc_pcm_runtime *rtd = substream->private_data;
131 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 131 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
132 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 132 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
133 int err = 0; 133 int err = 0;
134 134
@@ -157,7 +157,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
157 struct snd_pcm_hw_params *params) 157 struct snd_pcm_hw_params *params)
158{ 158{
159 struct snd_soc_pcm_runtime *rtd = substream->private_data; 159 struct snd_soc_pcm_runtime *rtd = substream->private_data;
160 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 160 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
161 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 161 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
162 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 162 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
163 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; 163 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id;
@@ -223,7 +223,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
223 * This must be called before _set_clkdiv and _set_sysclk since McBSP register 223 * This must be called before _set_clkdiv and _set_sysclk since McBSP register
224 * cache is initialized here 224 * cache is initialized here
225 */ 225 */
226static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, 226static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
227 unsigned int fmt) 227 unsigned int fmt)
228{ 228{
229 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 229 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
@@ -292,7 +292,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai,
292 return 0; 292 return 0;
293} 293}
294 294
295static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_cpu_dai *cpu_dai, 295static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
296 int div_id, int div) 296 int div_id, int div)
297{ 297{
298 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 298 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
@@ -347,7 +347,7 @@ static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data,
347 return 0; 347 return 0;
348} 348}
349 349
350static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, 350static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
351 int clk_id, unsigned int freq, 351 int clk_id, unsigned int freq,
352 int dir) 352 int dir)
353{ 353{
@@ -376,7 +376,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
376 return err; 376 return err;
377} 377}
378 378
379struct snd_soc_cpu_dai omap_mcbsp_dai[NUM_LINKS] = { 379struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS] = {
380{ 380{
381 .name = "omap-mcbsp-dai", 381 .name = "omap-mcbsp-dai",
382 .id = 0, 382 .id = 0,
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index 9965fd4b0427..ed8afb550671 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -44,6 +44,6 @@ enum omap_mcbsp_div {
44 */ 44 */
45#define NUM_LINKS 1 45#define NUM_LINKS 1
46 46
47extern struct snd_soc_cpu_dai omap_mcbsp_dai[NUM_LINKS]; 47extern struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS];
48 48
49#endif 49#endif
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 62370202c649..e092f3d836d0 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -316,7 +316,7 @@ static void omap_pcm_free_dma_buffers(struct snd_pcm *pcm)
316 } 316 }
317} 317}
318 318
319int omap_pcm_new(struct snd_card *card, struct snd_soc_codec_dai *dai, 319int omap_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
320 struct snd_pcm *pcm) 320 struct snd_pcm *pcm)
321{ 321{
322 int ret = 0; 322 int ret = 0;
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 484f883459e0..12f6ac99b04c 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -1,6 +1,6 @@
1config SND_PXA2XX_SOC 1config SND_PXA2XX_SOC
2 tristate "SoC Audio for the Intel PXA2xx chip" 2 tristate "SoC Audio for the Intel PXA2xx chip"
3 depends on ARCH_PXA && SND_SOC 3 depends on ARCH_PXA
4 help 4 help
5 Say Y or M if you want to add support for codecs attached to 5 Say Y or M if you want to add support for codecs attached to
6 the PXA2xx AC97, I2S or SSP interface. You will also need 6 the PXA2xx AC97, I2S or SSP interface. You will also need
@@ -62,3 +62,12 @@ config SND_PXA2XX_SOC_E800
62 help 62 help
63 Say Y if you want to add support for SoC audio on the 63 Say Y if you want to add support for SoC audio on the
64 Toshiba e800 PDA 64 Toshiba e800 PDA
65
66config SND_PXA2XX_SOC_EM_X270
67 tristate "SoC Audio support for CompuLab EM-x270"
68 depends on SND_PXA2XX_SOC && MACH_EM_X270
69 select SND_PXA2XX_SOC_AC97
70 select SND_SOC_WM9712
71 help
72 Say Y if you want to add support for SoC audio on
73 CompuLab EM-x270.
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 04e5646f75ba..5bc8edf9dca9 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -13,10 +13,11 @@ snd-soc-poodle-objs := poodle.o
13snd-soc-tosa-objs := tosa.o 13snd-soc-tosa-objs := tosa.o
14snd-soc-e800-objs := e800_wm9712.o 14snd-soc-e800-objs := e800_wm9712.o
15snd-soc-spitz-objs := spitz.o 15snd-soc-spitz-objs := spitz.o
16snd-soc-em-x270-objs := em-x270.o
16 17
17obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o 18obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
18obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o 19obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
19obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o 20obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o
20obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o 21obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o
21obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o 22obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o
22 23obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 7f32a1167572..c0294464a23a 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -11,10 +11,6 @@
11 * under the terms of the GNU General Public License as published by the 11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your 12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version. 13 * option) any later version.
14 *
15 * Revision history
16 * 30th Nov 2005 Initial version.
17 *
18 */ 14 */
19 15
20#include <linux/module.h> 16#include <linux/module.h>
@@ -54,47 +50,51 @@ static int corgi_spk_func;
54 50
55static void corgi_ext_control(struct snd_soc_codec *codec) 51static void corgi_ext_control(struct snd_soc_codec *codec)
56{ 52{
57 int spk = 0, mic = 0, line = 0, hp = 0, hs = 0;
58
59 /* set up jack connection */ 53 /* set up jack connection */
60 switch (corgi_jack_func) { 54 switch (corgi_jack_func) {
61 case CORGI_HP: 55 case CORGI_HP:
62 hp = 1;
63 /* set = unmute headphone */ 56 /* set = unmute headphone */
64 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 57 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
65 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 58 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
59 snd_soc_dapm_disable_pin(codec, "Mic Jack");
60 snd_soc_dapm_disable_pin(codec, "Line Jack");
61 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
62 snd_soc_dapm_disable_pin(codec, "Headset Jack");
66 break; 63 break;
67 case CORGI_MIC: 64 case CORGI_MIC:
68 mic = 1;
69 /* reset = mute headphone */ 65 /* reset = mute headphone */
70 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 66 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
71 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 67 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
68 snd_soc_dapm_enable_pin(codec, "Mic Jack");
69 snd_soc_dapm_disable_pin(codec, "Line Jack");
70 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
71 snd_soc_dapm_disable_pin(codec, "Headset Jack");
72 break; 72 break;
73 case CORGI_LINE: 73 case CORGI_LINE:
74 line = 1;
75 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 74 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
76 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 75 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
76 snd_soc_dapm_disable_pin(codec, "Mic Jack");
77 snd_soc_dapm_enable_pin(codec, "Line Jack");
78 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
79 snd_soc_dapm_disable_pin(codec, "Headset Jack");
77 break; 80 break;
78 case CORGI_HEADSET: 81 case CORGI_HEADSET:
79 hs = 1;
80 mic = 1;
81 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 82 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
82 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 83 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
84 snd_soc_dapm_enable_pin(codec, "Mic Jack");
85 snd_soc_dapm_disable_pin(codec, "Line Jack");
86 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
87 snd_soc_dapm_enable_pin(codec, "Headset Jack");
83 break; 88 break;
84 } 89 }
85 90
86 if (corgi_spk_func == CORGI_SPK_ON) 91 if (corgi_spk_func == CORGI_SPK_ON)
87 spk = 1; 92 snd_soc_dapm_enable_pin(codec, "Ext Spk");
88 93 else
89 /* set the enpoints to their new connetion states */ 94 snd_soc_dapm_disable_pin(codec, "Ext Spk");
90 snd_soc_dapm_set_endpoint(codec, "Ext Spk", spk);
91 snd_soc_dapm_set_endpoint(codec, "Mic Jack", mic);
92 snd_soc_dapm_set_endpoint(codec, "Line Jack", line);
93 snd_soc_dapm_set_endpoint(codec, "Headphone Jack", hp);
94 snd_soc_dapm_set_endpoint(codec, "Headset Jack", hs);
95 95
96 /* signal a DAPM event */ 96 /* signal a DAPM event */
97 snd_soc_dapm_sync_endpoints(codec); 97 snd_soc_dapm_sync(codec);
98} 98}
99 99
100static int corgi_startup(struct snd_pcm_substream *substream) 100static int corgi_startup(struct snd_pcm_substream *substream)
@@ -123,8 +123,8 @@ static int corgi_hw_params(struct snd_pcm_substream *substream,
123 struct snd_pcm_hw_params *params) 123 struct snd_pcm_hw_params *params)
124{ 124{
125 struct snd_soc_pcm_runtime *rtd = substream->private_data; 125 struct snd_soc_pcm_runtime *rtd = substream->private_data;
126 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; 126 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
127 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 127 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
128 unsigned int clk = 0; 128 unsigned int clk = 0;
129 int ret = 0; 129 int ret = 0;
130 130
@@ -143,25 +143,25 @@ static int corgi_hw_params(struct snd_pcm_substream *substream,
143 } 143 }
144 144
145 /* set codec DAI configuration */ 145 /* set codec DAI configuration */
146 ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 146 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
147 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 147 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
148 if (ret < 0) 148 if (ret < 0)
149 return ret; 149 return ret;
150 150
151 /* set cpu DAI configuration */ 151 /* set cpu DAI configuration */
152 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | 152 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
153 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 153 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
154 if (ret < 0) 154 if (ret < 0)
155 return ret; 155 return ret;
156 156
157 /* set the codec system clock for DAC and ADC */ 157 /* set the codec system clock for DAC and ADC */
158 ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8731_SYSCLK, clk, 158 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK, clk,
159 SND_SOC_CLOCK_IN); 159 SND_SOC_CLOCK_IN);
160 if (ret < 0) 160 if (ret < 0)
161 return ret; 161 return ret;
162 162
163 /* set the I2S system clock as input (unused) */ 163 /* set the I2S system clock as input (unused) */
164 ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, 164 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
165 SND_SOC_CLOCK_IN); 165 SND_SOC_CLOCK_IN);
166 if (ret < 0) 166 if (ret < 0)
167 return ret; 167 return ret;
@@ -247,7 +247,7 @@ SND_SOC_DAPM_HP("Headset Jack", NULL),
247}; 247};
248 248
249/* Corgi machine audio map (connections to the codec pins) */ 249/* Corgi machine audio map (connections to the codec pins) */
250static const char *audio_map[][3] = { 250static const struct snd_soc_dapm_route audio_map[] = {
251 251
252 /* headset Jack - in = micin, out = LHPOUT*/ 252 /* headset Jack - in = micin, out = LHPOUT*/
253 {"Headset Jack", NULL, "LHPOUT"}, 253 {"Headset Jack", NULL, "LHPOUT"},
@@ -265,8 +265,6 @@ static const char *audio_map[][3] = {
265 265
266 /* Same as the above but no mic bias for line signals */ 266 /* Same as the above but no mic bias for line signals */
267 {"MICIN", NULL, "Line Jack"}, 267 {"MICIN", NULL, "Line Jack"},
268
269 {NULL, NULL, NULL},
270}; 268};
271 269
272static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset", 270static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset",
@@ -291,8 +289,8 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec)
291{ 289{
292 int i, err; 290 int i, err;
293 291
294 snd_soc_dapm_set_endpoint(codec, "LLINEIN", 0); 292 snd_soc_dapm_disable_pin(codec, "LLINEIN");
295 snd_soc_dapm_set_endpoint(codec, "RLINEIN", 0); 293 snd_soc_dapm_disable_pin(codec, "RLINEIN");
296 294
297 /* Add corgi specific controls */ 295 /* Add corgi specific controls */
298 for (i = 0; i < ARRAY_SIZE(wm8731_corgi_controls); i++) { 296 for (i = 0; i < ARRAY_SIZE(wm8731_corgi_controls); i++) {
@@ -303,15 +301,13 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec)
303 } 301 }
304 302
305 /* Add corgi specific widgets */ 303 /* Add corgi specific widgets */
306 for (i = 0; i < ARRAY_SIZE(wm8731_dapm_widgets); i++) 304 snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets,
307 snd_soc_dapm_new_control(codec, &wm8731_dapm_widgets[i]); 305 ARRAY_SIZE(wm8731_dapm_widgets));
308 306
309 /* Set up corgi specific audio path audio_map */ 307 /* Set up corgi specific audio path audio_map */
310 for (i = 0; audio_map[i][0] != NULL; i++) 308 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
311 snd_soc_dapm_connect_input(codec, audio_map[i][0],
312 audio_map[i][1], audio_map[i][2]);
313 309
314 snd_soc_dapm_sync_endpoints(codec); 310 snd_soc_dapm_sync(codec);
315 return 0; 311 return 0;
316} 312}
317 313
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
new file mode 100644
index 000000000000..02dcac39cdf6
--- /dev/null
+++ b/sound/soc/pxa/em-x270.c
@@ -0,0 +1,102 @@
1/*
2 * em-x270.c -- SoC audio for EM-X270
3 *
4 * Copyright 2007 CompuLab, Ltd.
5 *
6 * Author: Mike Rapoport <mike@compulab.co.il>
7 *
8 * Copied from tosa.c:
9 * Copyright 2005 Wolfson Microelectronics PLC.
10 * Copyright 2005 Openedhand Ltd.
11 *
12 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
13 * Richard Purdie <richard@openedhand.com>
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/device.h>
25
26#include <sound/driver.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31
32#include <asm/mach-types.h>
33#include <asm/arch/pxa-regs.h>
34#include <asm/arch/hardware.h>
35#include <asm/arch/audio.h>
36
37#include "../codecs/wm9712.h"
38#include "pxa2xx-pcm.h"
39#include "pxa2xx-ac97.h"
40
41static struct snd_soc_dai_link em_x270_dai[] = {
42 {
43 .name = "AC97",
44 .stream_name = "AC97 HiFi",
45 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
46 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],
47 },
48 {
49 .name = "AC97 Aux",
50 .stream_name = "AC97 Aux",
51 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
52 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX],
53 },
54};
55
56static struct snd_soc_machine em_x270 = {
57 .name = "EM-X270",
58 .dai_link = em_x270_dai,
59 .num_links = ARRAY_SIZE(em_x270_dai),
60};
61
62static struct snd_soc_device em_x270_snd_devdata = {
63 .machine = &em_x270,
64 .platform = &pxa2xx_soc_platform,
65 .codec_dev = &soc_codec_dev_wm9712,
66};
67
68static struct platform_device *em_x270_snd_device;
69
70static int __init em_x270_init(void)
71{
72 int ret;
73
74 if (!machine_is_em_x270())
75 return -ENODEV;
76
77 em_x270_snd_device = platform_device_alloc("soc-audio", -1);
78 if (!em_x270_snd_device)
79 return -ENOMEM;
80
81 platform_set_drvdata(em_x270_snd_device, &em_x270_snd_devdata);
82 em_x270_snd_devdata.dev = &em_x270_snd_device->dev;
83 ret = platform_device_add(em_x270_snd_device);
84
85 if (ret)
86 platform_device_put(em_x270_snd_device);
87
88 return ret;
89}
90
91static void __exit em_x270_exit(void)
92{
93 platform_device_unregister(em_x270_snd_device);
94}
95
96module_init(em_x270_init);
97module_exit(em_x270_exit);
98
99/* Module information */
100MODULE_AUTHOR("Mike Rapoport");
101MODULE_DESCRIPTION("ALSA SoC EM-X270");
102MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index 7e830b218943..65a4e9a8c39e 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -48,8 +48,6 @@ static int poodle_spk_func;
48 48
49static void poodle_ext_control(struct snd_soc_codec *codec) 49static void poodle_ext_control(struct snd_soc_codec *codec)
50{ 50{
51 int spk = 0;
52
53 /* set up jack connection */ 51 /* set up jack connection */
54 if (poodle_jack_func == POODLE_HP) { 52 if (poodle_jack_func == POODLE_HP) {
55 /* set = unmute headphone */ 53 /* set = unmute headphone */
@@ -57,23 +55,23 @@ static void poodle_ext_control(struct snd_soc_codec *codec)
57 POODLE_LOCOMO_GPIO_MUTE_L, 1); 55 POODLE_LOCOMO_GPIO_MUTE_L, 1);
58 locomo_gpio_write(&poodle_locomo_device.dev, 56 locomo_gpio_write(&poodle_locomo_device.dev,
59 POODLE_LOCOMO_GPIO_MUTE_R, 1); 57 POODLE_LOCOMO_GPIO_MUTE_R, 1);
60 snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 1); 58 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
61 } else { 59 } else {
62 locomo_gpio_write(&poodle_locomo_device.dev, 60 locomo_gpio_write(&poodle_locomo_device.dev,
63 POODLE_LOCOMO_GPIO_MUTE_L, 0); 61 POODLE_LOCOMO_GPIO_MUTE_L, 0);
64 locomo_gpio_write(&poodle_locomo_device.dev, 62 locomo_gpio_write(&poodle_locomo_device.dev,
65 POODLE_LOCOMO_GPIO_MUTE_R, 0); 63 POODLE_LOCOMO_GPIO_MUTE_R, 0);
66 snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0); 64 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
67 } 65 }
68 66
69 if (poodle_spk_func == POODLE_SPK_ON)
70 spk = 1;
71
72 /* set the enpoints to their new connetion states */ 67 /* set the enpoints to their new connetion states */
73 snd_soc_dapm_set_endpoint(codec, "Ext Spk", spk); 68 if (poodle_spk_func == POODLE_SPK_ON)
69 snd_soc_dapm_enable_pin(codec, "Ext Spk");
70 else
71 snd_soc_dapm_disable_pin(codec, "Ext Spk");
74 72
75 /* signal a DAPM event */ 73 /* signal a DAPM event */
76 snd_soc_dapm_sync_endpoints(codec); 74 snd_soc_dapm_sync(codec);
77} 75}
78 76
79static int poodle_startup(struct snd_pcm_substream *substream) 77static int poodle_startup(struct snd_pcm_substream *substream)
@@ -104,8 +102,8 @@ static int poodle_hw_params(struct snd_pcm_substream *substream,
104 struct snd_pcm_hw_params *params) 102 struct snd_pcm_hw_params *params)
105{ 103{
106 struct snd_soc_pcm_runtime *rtd = substream->private_data; 104 struct snd_soc_pcm_runtime *rtd = substream->private_data;
107 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; 105 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
108 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 106 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
109 unsigned int clk = 0; 107 unsigned int clk = 0;
110 int ret = 0; 108 int ret = 0;
111 109
@@ -124,25 +122,25 @@ static int poodle_hw_params(struct snd_pcm_substream *substream,
124 } 122 }
125 123
126 /* set codec DAI configuration */ 124 /* set codec DAI configuration */
127 ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 125 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
128 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 126 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
129 if (ret < 0) 127 if (ret < 0)
130 return ret; 128 return ret;
131 129
132 /* set cpu DAI configuration */ 130 /* set cpu DAI configuration */
133 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | 131 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
134 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 132 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
135 if (ret < 0) 133 if (ret < 0)
136 return ret; 134 return ret;
137 135
138 /* set the codec system clock for DAC and ADC */ 136 /* set the codec system clock for DAC and ADC */
139 ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8731_SYSCLK, clk, 137 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK, clk,
140 SND_SOC_CLOCK_IN); 138 SND_SOC_CLOCK_IN);
141 if (ret < 0) 139 if (ret < 0)
142 return ret; 140 return ret;
143 141
144 /* set the I2S system clock as input (unused) */ 142 /* set the I2S system clock as input (unused) */
145 ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, 143 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
146 SND_SOC_CLOCK_IN); 144 SND_SOC_CLOCK_IN);
147 if (ret < 0) 145 if (ret < 0)
148 return ret; 146 return ret;
@@ -215,8 +213,8 @@ SND_SOC_DAPM_HP("Headphone Jack", NULL),
215SND_SOC_DAPM_SPK("Ext Spk", poodle_amp_event), 213SND_SOC_DAPM_SPK("Ext Spk", poodle_amp_event),
216}; 214};
217 215
218/* Corgi machine audio_mapnections to the codec pins */ 216/* Corgi machine connections to the codec pins */
219static const char *audio_map[][3] = { 217static const struct snd_soc_dapm_route audio_map[] = {
220 218
221 /* headphone connected to LHPOUT1, RHPOUT1 */ 219 /* headphone connected to LHPOUT1, RHPOUT1 */
222 {"Headphone Jack", NULL, "LHPOUT"}, 220 {"Headphone Jack", NULL, "LHPOUT"},
@@ -225,8 +223,6 @@ static const char *audio_map[][3] = {
225 /* speaker connected to LOUT, ROUT */ 223 /* speaker connected to LOUT, ROUT */
226 {"Ext Spk", NULL, "ROUT"}, 224 {"Ext Spk", NULL, "ROUT"},
227 {"Ext Spk", NULL, "LOUT"}, 225 {"Ext Spk", NULL, "LOUT"},
228
229 {NULL, NULL, NULL},
230}; 226};
231 227
232static const char *jack_function[] = {"Off", "Headphone"}; 228static const char *jack_function[] = {"Off", "Headphone"};
@@ -250,9 +246,9 @@ static int poodle_wm8731_init(struct snd_soc_codec *codec)
250{ 246{
251 int i, err; 247 int i, err;
252 248
253 snd_soc_dapm_set_endpoint(codec, "LLINEIN", 0); 249 snd_soc_dapm_disable_pin(codec, "LLINEIN");
254 snd_soc_dapm_set_endpoint(codec, "RLINEIN", 0); 250 snd_soc_dapm_disable_pin(codec, "RLINEIN");
255 snd_soc_dapm_set_endpoint(codec, "MICIN", 1); 251 snd_soc_dapm_enable_pin(codec, "MICIN");
256 252
257 /* Add poodle specific controls */ 253 /* Add poodle specific controls */
258 for (i = 0; i < ARRAY_SIZE(wm8731_poodle_controls); i++) { 254 for (i = 0; i < ARRAY_SIZE(wm8731_poodle_controls); i++) {
@@ -263,15 +259,13 @@ static int poodle_wm8731_init(struct snd_soc_codec *codec)
263 } 259 }
264 260
265 /* Add poodle specific widgets */ 261 /* Add poodle specific widgets */
266 for (i = 0; i < ARRAY_SIZE(wm8731_dapm_widgets); i++) 262 snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets,
267 snd_soc_dapm_new_control(codec, &wm8731_dapm_widgets[i]); 263 ARRAY_SIZE(wm8731_dapm_widgets));
268 264
269 /* Set up poodle specific audio path audio_map */ 265 /* Set up poodle specific audio path audio_map */
270 for (i = 0; audio_map[i][0] != NULL; i++) 266 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
271 snd_soc_dapm_connect_input(codec, audio_map[i][0],
272 audio_map[i][1], audio_map[i][2]);
273 267
274 snd_soc_dapm_sync_endpoints(codec); 268 snd_soc_dapm_sync(codec);
275 return 0; 269 return 0;
276} 270}
277 271
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 97ec2d90547c..059af815ea0c 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -283,7 +283,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = {
283 283
284#ifdef CONFIG_PM 284#ifdef CONFIG_PM
285static int pxa2xx_ac97_suspend(struct platform_device *pdev, 285static int pxa2xx_ac97_suspend(struct platform_device *pdev,
286 struct snd_soc_cpu_dai *dai) 286 struct snd_soc_dai *dai)
287{ 287{
288 GCR |= GCR_ACLINK_OFF; 288 GCR |= GCR_ACLINK_OFF;
289 clk_disable(ac97_clk); 289 clk_disable(ac97_clk);
@@ -291,7 +291,7 @@ static int pxa2xx_ac97_suspend(struct platform_device *pdev,
291} 291}
292 292
293static int pxa2xx_ac97_resume(struct platform_device *pdev, 293static int pxa2xx_ac97_resume(struct platform_device *pdev,
294 struct snd_soc_cpu_dai *dai) 294 struct snd_soc_dai *dai)
295{ 295{
296 pxa_gpio_mode(GPIO31_SYNC_AC97_MD); 296 pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
297 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); 297 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
@@ -310,7 +310,8 @@ static int pxa2xx_ac97_resume(struct platform_device *pdev,
310#define pxa2xx_ac97_resume NULL 310#define pxa2xx_ac97_resume NULL
311#endif 311#endif
312 312
313static int pxa2xx_ac97_probe(struct platform_device *pdev) 313static int pxa2xx_ac97_probe(struct platform_device *pdev,
314 struct snd_soc_dai *dai)
314{ 315{
315 int ret; 316 int ret;
316 317
@@ -355,7 +356,8 @@ static int pxa2xx_ac97_probe(struct platform_device *pdev)
355 return ret; 356 return ret;
356} 357}
357 358
358static void pxa2xx_ac97_remove(struct platform_device *pdev) 359static void pxa2xx_ac97_remove(struct platform_device *pdev,
360 struct snd_soc_dai *dai)
359{ 361{
360 GCR |= GCR_ACLINK_OFF; 362 GCR |= GCR_ACLINK_OFF;
361 free_irq(IRQ_AC97, NULL); 363 free_irq(IRQ_AC97, NULL);
@@ -372,7 +374,7 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
372 struct snd_pcm_hw_params *params) 374 struct snd_pcm_hw_params *params)
373{ 375{
374 struct snd_soc_pcm_runtime *rtd = substream->private_data; 376 struct snd_soc_pcm_runtime *rtd = substream->private_data;
375 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 377 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
376 378
377 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 379 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
378 cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_out; 380 cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_out;
@@ -386,7 +388,7 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
386 struct snd_pcm_hw_params *params) 388 struct snd_pcm_hw_params *params)
387{ 389{
388 struct snd_soc_pcm_runtime *rtd = substream->private_data; 390 struct snd_soc_pcm_runtime *rtd = substream->private_data;
389 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 391 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
390 392
391 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 393 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
392 cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_out; 394 cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
@@ -400,7 +402,7 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
400 struct snd_pcm_hw_params *params) 402 struct snd_pcm_hw_params *params)
401{ 403{
402 struct snd_soc_pcm_runtime *rtd = substream->private_data; 404 struct snd_soc_pcm_runtime *rtd = substream->private_data;
403 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 405 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
404 406
405 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 407 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
406 return -ENODEV; 408 return -ENODEV;
@@ -418,7 +420,7 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
418 * There is only 1 physical AC97 interface for pxa2xx, but it 420 * There is only 1 physical AC97 interface for pxa2xx, but it
419 * has extra fifo's that can be used for aux DACs and ADCs. 421 * has extra fifo's that can be used for aux DACs and ADCs.
420 */ 422 */
421struct snd_soc_cpu_dai pxa_ac97_dai[] = { 423struct snd_soc_dai pxa_ac97_dai[] = {
422{ 424{
423 .name = "pxa2xx-ac97", 425 .name = "pxa2xx-ac97",
424 .id = 0, 426 .id = 0,
diff --git a/sound/soc/pxa/pxa2xx-ac97.h b/sound/soc/pxa/pxa2xx-ac97.h
index b8ccfee095c4..e390de8edcd4 100644
--- a/sound/soc/pxa/pxa2xx-ac97.h
+++ b/sound/soc/pxa/pxa2xx-ac97.h
@@ -14,7 +14,7 @@
14#define PXA2XX_DAI_AC97_AUX 1 14#define PXA2XX_DAI_AC97_AUX 1
15#define PXA2XX_DAI_AC97_MIC 2 15#define PXA2XX_DAI_AC97_MIC 2
16 16
17extern struct snd_soc_cpu_dai pxa_ac97_dai[3]; 17extern struct snd_soc_dai pxa_ac97_dai[3];
18 18
19/* platform data */ 19/* platform data */
20extern struct snd_ac97_bus_ops pxa2xx_ac97_ops; 20extern struct snd_ac97_bus_ops pxa2xx_ac97_ops;
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 425071030970..9c06553b9267 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -9,9 +9,6 @@
9 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your 10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
12 *
13 * Revision history
14 * 12th Aug 2005 Initial version.
15 */ 12 */
16 13
17#include <linux/init.h> 14#include <linux/init.h>
@@ -80,7 +77,7 @@ static struct pxa2xx_gpio gpio_bus[] = {
80static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream) 77static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream)
81{ 78{
82 struct snd_soc_pcm_runtime *rtd = substream->private_data; 79 struct snd_soc_pcm_runtime *rtd = substream->private_data;
83 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 80 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
84 81
85 if (!cpu_dai->active) { 82 if (!cpu_dai->active) {
86 SACR0 |= SACR0_RST; 83 SACR0 |= SACR0_RST;
@@ -101,7 +98,7 @@ static int pxa_i2s_wait(void)
101 return 0; 98 return 0;
102} 99}
103 100
104static int pxa2xx_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, 101static int pxa2xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
105 unsigned int fmt) 102 unsigned int fmt)
106{ 103{
107 /* interface format */ 104 /* interface format */
@@ -127,7 +124,7 @@ static int pxa2xx_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai,
127 return 0; 124 return 0;
128} 125}
129 126
130static int pxa2xx_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, 127static int pxa2xx_i2s_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
131 int clk_id, unsigned int freq, int dir) 128 int clk_id, unsigned int freq, int dir)
132{ 129{
133 if (clk_id != PXA2XX_I2S_SYSCLK) 130 if (clk_id != PXA2XX_I2S_SYSCLK)
@@ -143,7 +140,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *params) 140 struct snd_pcm_hw_params *params)
144{ 141{
145 struct snd_soc_pcm_runtime *rtd = substream->private_data; 142 struct snd_soc_pcm_runtime *rtd = substream->private_data;
146 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 143 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
147 144
148 pxa_gpio_mode(gpio_bus[pxa_i2s.master].rx); 145 pxa_gpio_mode(gpio_bus[pxa_i2s.master].rx);
149 pxa_gpio_mode(gpio_bus[pxa_i2s.master].tx); 146 pxa_gpio_mode(gpio_bus[pxa_i2s.master].tx);
@@ -240,7 +237,7 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream)
240 237
241#ifdef CONFIG_PM 238#ifdef CONFIG_PM
242static int pxa2xx_i2s_suspend(struct platform_device *dev, 239static int pxa2xx_i2s_suspend(struct platform_device *dev,
243 struct snd_soc_cpu_dai *dai) 240 struct snd_soc_dai *dai)
244{ 241{
245 if (!dai->active) 242 if (!dai->active)
246 return 0; 243 return 0;
@@ -258,7 +255,7 @@ static int pxa2xx_i2s_suspend(struct platform_device *dev,
258} 255}
259 256
260static int pxa2xx_i2s_resume(struct platform_device *pdev, 257static int pxa2xx_i2s_resume(struct platform_device *pdev,
261 struct snd_soc_cpu_dai *dai) 258 struct snd_soc_dai *dai)
262{ 259{
263 if (!dai->active) 260 if (!dai->active)
264 return 0; 261 return 0;
@@ -283,7 +280,7 @@ static int pxa2xx_i2s_resume(struct platform_device *pdev,
283 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ 280 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
284 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) 281 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
285 282
286struct snd_soc_cpu_dai pxa_i2s_dai = { 283struct snd_soc_dai pxa_i2s_dai = {
287 .name = "pxa2xx-i2s", 284 .name = "pxa2xx-i2s",
288 .id = 0, 285 .id = 0,
289 .type = SND_SOC_DAI_I2S, 286 .type = SND_SOC_DAI_I2S,
diff --git a/sound/soc/pxa/pxa2xx-i2s.h b/sound/soc/pxa/pxa2xx-i2s.h
index 4435bd9f884f..e2def441153e 100644
--- a/sound/soc/pxa/pxa2xx-i2s.h
+++ b/sound/soc/pxa/pxa2xx-i2s.h
@@ -15,6 +15,6 @@
15/* I2S clock */ 15/* I2S clock */
16#define PXA2XX_I2S_SYSCLK 0 16#define PXA2XX_I2S_SYSCLK 0
17 17
18extern struct snd_soc_cpu_dai pxa_i2s_dai; 18extern struct snd_soc_dai pxa_i2s_dai;
19 19
20#endif 20#endif
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index 01ad7bf716b7..2df03ee5819e 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -330,7 +330,7 @@ static void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
330 330
331static u64 pxa2xx_pcm_dmamask = DMA_32BIT_MASK; 331static u64 pxa2xx_pcm_dmamask = DMA_32BIT_MASK;
332 332
333int pxa2xx_pcm_new(struct snd_card *card, struct snd_soc_codec_dai *dai, 333int pxa2xx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
334 struct snd_pcm *pcm) 334 struct snd_pcm *pcm)
335{ 335{
336 int ret = 0; 336 int ret = 0;
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index d8b8372db00e..64385797da5d 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -12,9 +12,6 @@
12 * Free Software Foundation; either version 2 of the License, or (at your 12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version. 13 * option) any later version.
14 * 14 *
15 * Revision history
16 * 30th Nov 2005 Initial version.
17 *
18 */ 15 */
19 16
20#include <linux/module.h> 17#include <linux/module.h>
@@ -54,60 +51,60 @@ static int spitz_spk_func;
54static void spitz_ext_control(struct snd_soc_codec *codec) 51static void spitz_ext_control(struct snd_soc_codec *codec)
55{ 52{
56 if (spitz_spk_func == SPITZ_SPK_ON) 53 if (spitz_spk_func == SPITZ_SPK_ON)
57 snd_soc_dapm_set_endpoint(codec, "Ext Spk", 1); 54 snd_soc_dapm_enable_pin(codec, "Ext Spk");
58 else 55 else
59 snd_soc_dapm_set_endpoint(codec, "Ext Spk", 0); 56 snd_soc_dapm_disable_pin(codec, "Ext Spk");
60 57
61 /* set up jack connection */ 58 /* set up jack connection */
62 switch (spitz_jack_func) { 59 switch (spitz_jack_func) {
63 case SPITZ_HP: 60 case SPITZ_HP:
64 /* enable and unmute hp jack, disable mic bias */ 61 /* enable and unmute hp jack, disable mic bias */
65 snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0); 62 snd_soc_dapm_disable_pin(codec, "Headset Jack");
66 snd_soc_dapm_set_endpoint(codec, "Mic Jack", 0); 63 snd_soc_dapm_disable_pin(codec, "Mic Jack");
67 snd_soc_dapm_set_endpoint(codec, "Line Jack", 0); 64 snd_soc_dapm_disable_pin(codec, "Line Jack");
68 snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 1); 65 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
69 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 66 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
70 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 67 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
71 break; 68 break;
72 case SPITZ_MIC: 69 case SPITZ_MIC:
73 /* enable mic jack and bias, mute hp */ 70 /* enable mic jack and bias, mute hp */
74 snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0); 71 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
75 snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0); 72 snd_soc_dapm_disable_pin(codec, "Headset Jack");
76 snd_soc_dapm_set_endpoint(codec, "Line Jack", 0); 73 snd_soc_dapm_disable_pin(codec, "Line Jack");
77 snd_soc_dapm_set_endpoint(codec, "Mic Jack", 1); 74 snd_soc_dapm_enable_pin(codec, "Mic Jack");
78 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 75 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
79 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 76 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
80 break; 77 break;
81 case SPITZ_LINE: 78 case SPITZ_LINE:
82 /* enable line jack, disable mic bias and mute hp */ 79 /* enable line jack, disable mic bias and mute hp */
83 snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0); 80 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
84 snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0); 81 snd_soc_dapm_disable_pin(codec, "Headset Jack");
85 snd_soc_dapm_set_endpoint(codec, "Mic Jack", 0); 82 snd_soc_dapm_disable_pin(codec, "Mic Jack");
86 snd_soc_dapm_set_endpoint(codec, "Line Jack", 1); 83 snd_soc_dapm_enable_pin(codec, "Line Jack");
87 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 84 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
88 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 85 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
89 break; 86 break;
90 case SPITZ_HEADSET: 87 case SPITZ_HEADSET:
91 /* enable and unmute headset jack enable mic bias, mute L hp */ 88 /* enable and unmute headset jack enable mic bias, mute L hp */
92 snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0); 89 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
93 snd_soc_dapm_set_endpoint(codec, "Mic Jack", 1); 90 snd_soc_dapm_enable_pin(codec, "Mic Jack");
94 snd_soc_dapm_set_endpoint(codec, "Line Jack", 0); 91 snd_soc_dapm_disable_pin(codec, "Line Jack");
95 snd_soc_dapm_set_endpoint(codec, "Headset Jack", 1); 92 snd_soc_dapm_enable_pin(codec, "Headset Jack");
96 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 93 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
97 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 94 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
98 break; 95 break;
99 case SPITZ_HP_OFF: 96 case SPITZ_HP_OFF:
100 97
101 /* jack removed, everything off */ 98 /* jack removed, everything off */
102 snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0); 99 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
103 snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0); 100 snd_soc_dapm_disable_pin(codec, "Headset Jack");
104 snd_soc_dapm_set_endpoint(codec, "Mic Jack", 0); 101 snd_soc_dapm_disable_pin(codec, "Mic Jack");
105 snd_soc_dapm_set_endpoint(codec, "Line Jack", 0); 102 snd_soc_dapm_disable_pin(codec, "Line Jack");
106 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 103 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
107 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 104 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
108 break; 105 break;
109 } 106 }
110 snd_soc_dapm_sync_endpoints(codec); 107 snd_soc_dapm_sync(codec);
111} 108}
112 109
113static int spitz_startup(struct snd_pcm_substream *substream) 110static int spitz_startup(struct snd_pcm_substream *substream)
@@ -124,8 +121,8 @@ static int spitz_hw_params(struct snd_pcm_substream *substream,
124 struct snd_pcm_hw_params *params) 121 struct snd_pcm_hw_params *params)
125{ 122{
126 struct snd_soc_pcm_runtime *rtd = substream->private_data; 123 struct snd_soc_pcm_runtime *rtd = substream->private_data;
127 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; 124 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
128 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 125 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
129 unsigned int clk = 0; 126 unsigned int clk = 0;
130 int ret = 0; 127 int ret = 0;
131 128
@@ -144,25 +141,25 @@ static int spitz_hw_params(struct snd_pcm_substream *substream,
144 } 141 }
145 142
146 /* set codec DAI configuration */ 143 /* set codec DAI configuration */
147 ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 144 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
148 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 145 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
149 if (ret < 0) 146 if (ret < 0)
150 return ret; 147 return ret;
151 148
152 /* set cpu DAI configuration */ 149 /* set cpu DAI configuration */
153 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | 150 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
154 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 151 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
155 if (ret < 0) 152 if (ret < 0)
156 return ret; 153 return ret;
157 154
158 /* set the codec system clock for DAC and ADC */ 155 /* set the codec system clock for DAC and ADC */
159 ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8750_SYSCLK, clk, 156 ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
160 SND_SOC_CLOCK_IN); 157 SND_SOC_CLOCK_IN);
161 if (ret < 0) 158 if (ret < 0)
162 return ret; 159 return ret;
163 160
164 /* set the I2S system clock as input (unused) */ 161 /* set the I2S system clock as input (unused) */
165 ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, 162 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
166 SND_SOC_CLOCK_IN); 163 SND_SOC_CLOCK_IN);
167 if (ret < 0) 164 if (ret < 0)
168 return ret; 165 return ret;
@@ -250,7 +247,7 @@ static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
250}; 247};
251 248
252/* Spitz machine audio_map */ 249/* Spitz machine audio_map */
253static const char *audio_map[][3] = { 250static const struct snd_soc_dapm_route audio_map[] = {
254 251
255 /* headphone connected to LOUT1, ROUT1 */ 252 /* headphone connected to LOUT1, ROUT1 */
256 {"Headphone Jack", NULL, "LOUT1"}, 253 {"Headphone Jack", NULL, "LOUT1"},
@@ -269,8 +266,6 @@ static const char *audio_map[][3] = {
269 266
270 /* line is connected to input 1 - no bias */ 267 /* line is connected to input 1 - no bias */
271 {"LINPUT1", NULL, "Line Jack"}, 268 {"LINPUT1", NULL, "Line Jack"},
272
273 {NULL, NULL, NULL},
274}; 269};
275 270
276static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset", 271static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset",
@@ -296,13 +291,13 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec)
296 int i, err; 291 int i, err;
297 292
298 /* NC codec pins */ 293 /* NC codec pins */
299 snd_soc_dapm_set_endpoint(codec, "RINPUT1", 0); 294 snd_soc_dapm_disable_pin(codec, "RINPUT1");
300 snd_soc_dapm_set_endpoint(codec, "LINPUT2", 0); 295 snd_soc_dapm_disable_pin(codec, "LINPUT2");
301 snd_soc_dapm_set_endpoint(codec, "RINPUT2", 0); 296 snd_soc_dapm_disable_pin(codec, "RINPUT2");
302 snd_soc_dapm_set_endpoint(codec, "LINPUT3", 0); 297 snd_soc_dapm_disable_pin(codec, "LINPUT3");
303 snd_soc_dapm_set_endpoint(codec, "RINPUT3", 0); 298 snd_soc_dapm_disable_pin(codec, "RINPUT3");
304 snd_soc_dapm_set_endpoint(codec, "OUT3", 0); 299 snd_soc_dapm_disable_pin(codec, "OUT3");
305 snd_soc_dapm_set_endpoint(codec, "MONO", 0); 300 snd_soc_dapm_disable_pin(codec, "MONO");
306 301
307 /* Add spitz specific controls */ 302 /* Add spitz specific controls */
308 for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) { 303 for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) {
@@ -313,15 +308,13 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec)
313 } 308 }
314 309
315 /* Add spitz specific widgets */ 310 /* Add spitz specific widgets */
316 for (i = 0; i < ARRAY_SIZE(wm8750_dapm_widgets); i++) 311 snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets,
317 snd_soc_dapm_new_control(codec, &wm8750_dapm_widgets[i]); 312 ARRAY_SIZE(wm8750_dapm_widgets));
318 313
319 /* Set up spitz specific audio path audio_map */ 314 /* Set up spitz specific audio paths */
320 for (i = 0; audio_map[i][0] != NULL; i++) 315 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
321 snd_soc_dapm_connect_input(codec, audio_map[i][0],
322 audio_map[i][1], audio_map[i][2]);
323 316
324 snd_soc_dapm_sync_endpoints(codec); 317 snd_soc_dapm_sync(codec);
325 return 0; 318 return 0;
326} 319}
327 320
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 7346d7e5d066..b6edb61a3a30 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -12,9 +12,6 @@
12 * Free Software Foundation; either version 2 of the License, or (at your 12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version. 13 * option) any later version.
14 * 14 *
15 * Revision history
16 * 30th Nov 2005 Initial version.
17 *
18 * GPIO's 15 * GPIO's
19 * 1 - Jack Insertion 16 * 1 - Jack Insertion
20 * 5 - Hookswitch (headset answer/hang up switch) 17 * 5 - Hookswitch (headset answer/hang up switch)
@@ -55,29 +52,31 @@ static int tosa_spk_func;
55 52
56static void tosa_ext_control(struct snd_soc_codec *codec) 53static void tosa_ext_control(struct snd_soc_codec *codec)
57{ 54{
58 int spk = 0, mic_int = 0, hp = 0, hs = 0;
59
60 /* set up jack connection */ 55 /* set up jack connection */
61 switch (tosa_jack_func) { 56 switch (tosa_jack_func) {
62 case TOSA_HP: 57 case TOSA_HP:
63 hp = 1; 58 snd_soc_dapm_disable_pin(codec, "Mic (Internal)");
59 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
60 snd_soc_dapm_disable_pin(codec, "Headset Jack");
64 break; 61 break;
65 case TOSA_MIC_INT: 62 case TOSA_MIC_INT:
66 mic_int = 1; 63 snd_soc_dapm_enable_pin(codec, "Mic (Internal)");
64 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
65 snd_soc_dapm_disable_pin(codec, "Headset Jack");
67 break; 66 break;
68 case TOSA_HEADSET: 67 case TOSA_HEADSET:
69 hs = 1; 68 snd_soc_dapm_disable_pin(codec, "Mic (Internal)");
69 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
70 snd_soc_dapm_enable_pin(codec, "Headset Jack");
70 break; 71 break;
71 } 72 }
72 73
73 if (tosa_spk_func == TOSA_SPK_ON) 74 if (tosa_spk_func == TOSA_SPK_ON)
74 spk = 1; 75 snd_soc_dapm_enable_pin(codec, "Speaker");
76 else
77 snd_soc_dapm_disable_pin(codec, "Speaker");
75 78
76 snd_soc_dapm_set_endpoint(codec, "Speaker", spk); 79 snd_soc_dapm_sync(codec);
77 snd_soc_dapm_set_endpoint(codec, "Mic (Internal)", mic_int);
78 snd_soc_dapm_set_endpoint(codec, "Headphone Jack", hp);
79 snd_soc_dapm_set_endpoint(codec, "Headset Jack", hs);
80 snd_soc_dapm_sync_endpoints(codec);
81} 80}
82 81
83static int tosa_startup(struct snd_pcm_substream *substream) 82static int tosa_startup(struct snd_pcm_substream *substream)
@@ -154,7 +153,7 @@ SND_SOC_DAPM_SPK("Speaker", NULL),
154}; 153};
155 154
156/* tosa audio map */ 155/* tosa audio map */
157static const char *audio_map[][3] = { 156static const struct snd_soc_dapm_route audio_map[] = {
158 157
159 /* headphone connected to HPOUTL, HPOUTR */ 158 /* headphone connected to HPOUTL, HPOUTR */
160 {"Headphone Jack", NULL, "HPOUTL"}, 159 {"Headphone Jack", NULL, "HPOUTL"},
@@ -173,8 +172,6 @@ static const char *audio_map[][3] = {
173 {"Headset Jack", NULL, "HPOUTR"}, 172 {"Headset Jack", NULL, "HPOUTR"},
174 {"LINEINR", NULL, "Mic Bias"}, 173 {"LINEINR", NULL, "Mic Bias"},
175 {"Mic Bias", NULL, "Headset Jack"}, 174 {"Mic Bias", NULL, "Headset Jack"},
176
177 {NULL, NULL, NULL},
178}; 175};
179 176
180static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset", 177static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset",
@@ -196,8 +193,8 @@ static int tosa_ac97_init(struct snd_soc_codec *codec)
196{ 193{
197 int i, err; 194 int i, err;
198 195
199 snd_soc_dapm_set_endpoint(codec, "OUT3", 0); 196 snd_soc_dapm_disable_pin(codec, "OUT3");
200 snd_soc_dapm_set_endpoint(codec, "MONOOUT", 0); 197 snd_soc_dapm_disable_pin(codec, "MONOOUT");
201 198
202 /* add tosa specific controls */ 199 /* add tosa specific controls */
203 for (i = 0; i < ARRAY_SIZE(tosa_controls); i++) { 200 for (i = 0; i < ARRAY_SIZE(tosa_controls); i++) {
@@ -208,17 +205,13 @@ static int tosa_ac97_init(struct snd_soc_codec *codec)
208 } 205 }
209 206
210 /* add tosa specific widgets */ 207 /* add tosa specific widgets */
211 for (i = 0; i < ARRAY_SIZE(tosa_dapm_widgets); i++) { 208 snd_soc_dapm_new_controls(codec, tosa_dapm_widgets,
212 snd_soc_dapm_new_control(codec, &tosa_dapm_widgets[i]); 209 ARRAY_SIZE(tosa_dapm_widgets));
213 }
214 210
215 /* set up tosa specific audio path audio_map */ 211 /* set up tosa specific audio path audio_map */
216 for (i = 0; audio_map[i][0] != NULL; i++) { 212 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
217 snd_soc_dapm_connect_input(codec, audio_map[i][0],
218 audio_map[i][1], audio_map[i][2]);
219 }
220 213
221 snd_soc_dapm_sync_endpoints(codec); 214 snd_soc_dapm_sync(codec);
222 return 0; 215 return 0;
223} 216}
224 217
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index 1f6dbfc4caa8..b9f2353effeb 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -1,7 +1,6 @@
1config SND_S3C24XX_SOC 1config SND_S3C24XX_SOC
2 tristate "SoC Audio for the Samsung S3C24XX chips" 2 tristate "SoC Audio for the Samsung S3C24XX chips"
3 depends on ARCH_S3C2410 && SND_SOC 3 depends on ARCH_S3C2410
4 select SND_PCM
5 help 4 help
6 Say Y or M if you want to add support for codecs attached to 5 Say Y or M if you want to add support for codecs attached to
7 the S3C24XX AC97, I2S or SSP interface. You will also need 6 the S3C24XX AC97, I2S or SSP interface. You will also need
@@ -16,7 +15,6 @@ config SND_S3C2412_SOC_I2S
16config SND_S3C2443_SOC_AC97 15config SND_S3C2443_SOC_AC97
17 tristate 16 tristate
18 select AC97_BUS 17 select AC97_BUS
19 select SND_AC97_CODEC
20 select SND_SOC_AC97_BUS 18 select SND_SOC_AC97_BUS
21 19
22config SND_S3C24XX_SOC_NEO1973_WM8753 20config SND_S3C24XX_SOC_NEO1973_WM8753
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
index 0e9d1c5f2484..4d7a9aa15f1a 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -10,10 +10,6 @@
10 * Free Software Foundation; either version 2 of the License, or (at your 10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
12 * 12 *
13 * Revision history
14 * 20th Jan 2007 Initial version.
15 * 05th Feb 2007 Rename all to Neo1973
16 *
17 */ 13 */
18 14
19#include <linux/module.h> 15#include <linux/module.h>
@@ -26,6 +22,7 @@
26#include <sound/pcm.h> 22#include <sound/pcm.h>
27#include <sound/soc.h> 23#include <sound/soc.h>
28#include <sound/soc-dapm.h> 24#include <sound/soc-dapm.h>
25#include <sound/tlv.h>
29 26
30#include <asm/mach-types.h> 27#include <asm/mach-types.h>
31#include <asm/hardware/scoop.h> 28#include <asm/hardware/scoop.h>
@@ -43,6 +40,14 @@
43#include "s3c24xx-pcm.h" 40#include "s3c24xx-pcm.h"
44#include "s3c24xx-i2s.h" 41#include "s3c24xx-i2s.h"
45 42
43/* Debugging stuff */
44#define S3C24XX_SOC_NEO1973_WM8753_DEBUG 0
45#if S3C24XX_SOC_NEO1973_WM8753_DEBUG
46#define DBG(x...) printk(KERN_DEBUG "s3c24xx-soc-neo1973-wm8753: " x)
47#else
48#define DBG(x...)
49#endif
50
46/* define the scenarios */ 51/* define the scenarios */
47#define NEO_AUDIO_OFF 0 52#define NEO_AUDIO_OFF 0
48#define NEO_GSM_CALL_AUDIO_HANDSET 1 53#define NEO_GSM_CALL_AUDIO_HANDSET 1
@@ -61,12 +66,14 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
61 struct snd_pcm_hw_params *params) 66 struct snd_pcm_hw_params *params)
62{ 67{
63 struct snd_soc_pcm_runtime *rtd = substream->private_data; 68 struct snd_soc_pcm_runtime *rtd = substream->private_data;
64 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; 69 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
65 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 70 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
66 unsigned int pll_out = 0, bclk = 0; 71 unsigned int pll_out = 0, bclk = 0;
67 int ret = 0; 72 int ret = 0;
68 unsigned long iis_clkrate; 73 unsigned long iis_clkrate;
69 74
75 DBG("Entered %s\n", __func__);
76
70 iis_clkrate = s3c24xx_i2s_get_clockrate(); 77 iis_clkrate = s3c24xx_i2s_get_clockrate();
71 78
72 switch (params_rate(params)) { 79 switch (params_rate(params)) {
@@ -101,44 +108,44 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
101 } 108 }
102 109
103 /* set codec DAI configuration */ 110 /* set codec DAI configuration */
104 ret = codec_dai->dai_ops.set_fmt(codec_dai, 111 ret = snd_soc_dai_set_fmt(codec_dai,
105 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 112 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
106 SND_SOC_DAIFMT_CBM_CFM); 113 SND_SOC_DAIFMT_CBM_CFM);
107 if (ret < 0) 114 if (ret < 0)
108 return ret; 115 return ret;
109 116
110 /* set cpu DAI configuration */ 117 /* set cpu DAI configuration */
111 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, 118 ret = snd_soc_dai_set_fmt(cpu_dai,
112 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 119 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
113 SND_SOC_DAIFMT_CBM_CFM); 120 SND_SOC_DAIFMT_CBM_CFM);
114 if (ret < 0) 121 if (ret < 0)
115 return ret; 122 return ret;
116 123
117 /* set the codec system clock for DAC and ADC */ 124 /* set the codec system clock for DAC and ADC */
118 ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8753_MCLK, pll_out, 125 ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out,
119 SND_SOC_CLOCK_IN); 126 SND_SOC_CLOCK_IN);
120 if (ret < 0) 127 if (ret < 0)
121 return ret; 128 return ret;
122 129
123 /* set MCLK division for sample rate */ 130 /* set MCLK division for sample rate */
124 ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, 131 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
125 S3C2410_IISMOD_32FS); 132 S3C2410_IISMOD_32FS);
126 if (ret < 0) 133 if (ret < 0)
127 return ret; 134 return ret;
128 135
129 /* set codec BCLK division for sample rate */ 136 /* set codec BCLK division for sample rate */
130 ret = codec_dai->dai_ops.set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk); 137 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk);
131 if (ret < 0) 138 if (ret < 0)
132 return ret; 139 return ret;
133 140
134 /* set prescaler division for sample rate */ 141 /* set prescaler division for sample rate */
135 ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, 142 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
136 S3C24XX_PRESCALE(4, 4)); 143 S3C24XX_PRESCALE(4, 4));
137 if (ret < 0) 144 if (ret < 0)
138 return ret; 145 return ret;
139 146
140 /* codec PLL input is PCLK/4 */ 147 /* codec PLL input is PCLK/4 */
141 ret = codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL1, 148 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1,
142 iis_clkrate / 4, pll_out); 149 iis_clkrate / 4, pll_out);
143 if (ret < 0) 150 if (ret < 0)
144 return ret; 151 return ret;
@@ -149,10 +156,12 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
149static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) 156static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
150{ 157{
151 struct snd_soc_pcm_runtime *rtd = substream->private_data; 158 struct snd_soc_pcm_runtime *rtd = substream->private_data;
152 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; 159 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
160
161 DBG("Entered %s\n", __func__);
153 162
154 /* disable the PLL */ 163 /* disable the PLL */
155 return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL1, 0, 0); 164 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0);
156} 165}
157 166
158/* 167/*
@@ -167,11 +176,13 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
167 struct snd_pcm_hw_params *params) 176 struct snd_pcm_hw_params *params)
168{ 177{
169 struct snd_soc_pcm_runtime *rtd = substream->private_data; 178 struct snd_soc_pcm_runtime *rtd = substream->private_data;
170 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; 179 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
171 unsigned int pcmdiv = 0; 180 unsigned int pcmdiv = 0;
172 int ret = 0; 181 int ret = 0;
173 unsigned long iis_clkrate; 182 unsigned long iis_clkrate;
174 183
184 DBG("Entered %s\n", __func__);
185
175 iis_clkrate = s3c24xx_i2s_get_clockrate(); 186 iis_clkrate = s3c24xx_i2s_get_clockrate();
176 187
177 if (params_rate(params) != 8000) 188 if (params_rate(params) != 8000)
@@ -183,24 +194,24 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
183 194
184 /* todo: gg check mode (DSP_B) against CSR datasheet */ 195 /* todo: gg check mode (DSP_B) against CSR datasheet */
185 /* set codec DAI configuration */ 196 /* set codec DAI configuration */
186 ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | 197 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B |
187 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 198 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
188 if (ret < 0) 199 if (ret < 0)
189 return ret; 200 return ret;
190 201
191 /* set the codec system clock for DAC and ADC */ 202 /* set the codec system clock for DAC and ADC */
192 ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8753_PCMCLK, 12288000, 203 ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, 12288000,
193 SND_SOC_CLOCK_IN); 204 SND_SOC_CLOCK_IN);
194 if (ret < 0) 205 if (ret < 0)
195 return ret; 206 return ret;
196 207
197 /* set codec PCM division for sample rate */ 208 /* set codec PCM division for sample rate */
198 ret = codec_dai->dai_ops.set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv); 209 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv);
199 if (ret < 0) 210 if (ret < 0)
200 return ret; 211 return ret;
201 212
202 /* configue and enable PLL for 12.288MHz output */ 213 /* configue and enable PLL for 12.288MHz output */
203 ret = codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL2, 214 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2,
204 iis_clkrate / 4, 12288000); 215 iis_clkrate / 4, 12288000);
205 if (ret < 0) 216 if (ret < 0)
206 return ret; 217 return ret;
@@ -211,10 +222,12 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
211static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) 222static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
212{ 223{
213 struct snd_soc_pcm_runtime *rtd = substream->private_data; 224 struct snd_soc_pcm_runtime *rtd = substream->private_data;
214 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; 225 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
226
227 DBG("Entered %s\n", __func__);
215 228
216 /* disable the PLL */ 229 /* disable the PLL */
217 return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL2, 0, 0); 230 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0);
218} 231}
219 232
220static struct snd_soc_ops neo1973_voice_ops = { 233static struct snd_soc_ops neo1973_voice_ops = {
@@ -233,79 +246,81 @@ static int neo1973_get_scenario(struct snd_kcontrol *kcontrol,
233 246
234static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario) 247static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario)
235{ 248{
249 DBG("Entered %s\n", __func__);
250
236 switch (neo1973_scenario) { 251 switch (neo1973_scenario) {
237 case NEO_AUDIO_OFF: 252 case NEO_AUDIO_OFF:
238 snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); 253 snd_soc_dapm_disable_pin(codec, "Audio Out");
239 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); 254 snd_soc_dapm_disable_pin(codec, "GSM Line Out");
240 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); 255 snd_soc_dapm_disable_pin(codec, "GSM Line In");
241 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); 256 snd_soc_dapm_disable_pin(codec, "Headset Mic");
242 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); 257 snd_soc_dapm_disable_pin(codec, "Call Mic");
243 break; 258 break;
244 case NEO_GSM_CALL_AUDIO_HANDSET: 259 case NEO_GSM_CALL_AUDIO_HANDSET:
245 snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); 260 snd_soc_dapm_enable_pin(codec, "Audio Out");
246 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1); 261 snd_soc_dapm_enable_pin(codec, "GSM Line Out");
247 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1); 262 snd_soc_dapm_enable_pin(codec, "GSM Line In");
248 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); 263 snd_soc_dapm_disable_pin(codec, "Headset Mic");
249 snd_soc_dapm_set_endpoint(codec, "Call Mic", 1); 264 snd_soc_dapm_enable_pin(codec, "Call Mic");
250 break; 265 break;
251 case NEO_GSM_CALL_AUDIO_HEADSET: 266 case NEO_GSM_CALL_AUDIO_HEADSET:
252 snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); 267 snd_soc_dapm_enable_pin(codec, "Audio Out");
253 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1); 268 snd_soc_dapm_enable_pin(codec, "GSM Line Out");
254 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1); 269 snd_soc_dapm_enable_pin(codec, "GSM Line In");
255 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 1); 270 snd_soc_dapm_enable_pin(codec, "Headset Mic");
256 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); 271 snd_soc_dapm_disable_pin(codec, "Call Mic");
257 break; 272 break;
258 case NEO_GSM_CALL_AUDIO_BLUETOOTH: 273 case NEO_GSM_CALL_AUDIO_BLUETOOTH:
259 snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); 274 snd_soc_dapm_disable_pin(codec, "Audio Out");
260 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1); 275 snd_soc_dapm_enable_pin(codec, "GSM Line Out");
261 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1); 276 snd_soc_dapm_enable_pin(codec, "GSM Line In");
262 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); 277 snd_soc_dapm_disable_pin(codec, "Headset Mic");
263 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); 278 snd_soc_dapm_disable_pin(codec, "Call Mic");
264 break; 279 break;
265 case NEO_STEREO_TO_SPEAKERS: 280 case NEO_STEREO_TO_SPEAKERS:
266 snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); 281 snd_soc_dapm_enable_pin(codec, "Audio Out");
267 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); 282 snd_soc_dapm_disable_pin(codec, "GSM Line Out");
268 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); 283 snd_soc_dapm_disable_pin(codec, "GSM Line In");
269 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); 284 snd_soc_dapm_disable_pin(codec, "Headset Mic");
270 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); 285 snd_soc_dapm_disable_pin(codec, "Call Mic");
271 break; 286 break;
272 case NEO_STEREO_TO_HEADPHONES: 287 case NEO_STEREO_TO_HEADPHONES:
273 snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); 288 snd_soc_dapm_enable_pin(codec, "Audio Out");
274 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); 289 snd_soc_dapm_disable_pin(codec, "GSM Line Out");
275 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); 290 snd_soc_dapm_disable_pin(codec, "GSM Line In");
276 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); 291 snd_soc_dapm_disable_pin(codec, "Headset Mic");
277 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); 292 snd_soc_dapm_disable_pin(codec, "Call Mic");
278 break; 293 break;
279 case NEO_CAPTURE_HANDSET: 294 case NEO_CAPTURE_HANDSET:
280 snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); 295 snd_soc_dapm_disable_pin(codec, "Audio Out");
281 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); 296 snd_soc_dapm_disable_pin(codec, "GSM Line Out");
282 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); 297 snd_soc_dapm_disable_pin(codec, "GSM Line In");
283 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); 298 snd_soc_dapm_disable_pin(codec, "Headset Mic");
284 snd_soc_dapm_set_endpoint(codec, "Call Mic", 1); 299 snd_soc_dapm_enable_pin(codec, "Call Mic");
285 break; 300 break;
286 case NEO_CAPTURE_HEADSET: 301 case NEO_CAPTURE_HEADSET:
287 snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); 302 snd_soc_dapm_disable_pin(codec, "Audio Out");
288 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); 303 snd_soc_dapm_disable_pin(codec, "GSM Line Out");
289 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); 304 snd_soc_dapm_disable_pin(codec, "GSM Line In");
290 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 1); 305 snd_soc_dapm_enable_pin(codec, "Headset Mic");
291 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); 306 snd_soc_dapm_disable_pin(codec, "Call Mic");
292 break; 307 break;
293 case NEO_CAPTURE_BLUETOOTH: 308 case NEO_CAPTURE_BLUETOOTH:
294 snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); 309 snd_soc_dapm_disable_pin(codec, "Audio Out");
295 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); 310 snd_soc_dapm_disable_pin(codec, "GSM Line Out");
296 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); 311 snd_soc_dapm_disable_pin(codec, "GSM Line In");
297 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); 312 snd_soc_dapm_disable_pin(codec, "Headset Mic");
298 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); 313 snd_soc_dapm_disable_pin(codec, "Call Mic");
299 break; 314 break;
300 default: 315 default:
301 snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); 316 snd_soc_dapm_disable_pin(codec, "Audio Out");
302 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); 317 snd_soc_dapm_disable_pin(codec, "GSM Line Out");
303 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); 318 snd_soc_dapm_disable_pin(codec, "GSM Line In");
304 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); 319 snd_soc_dapm_disable_pin(codec, "Headset Mic");
305 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); 320 snd_soc_dapm_disable_pin(codec, "Call Mic");
306 } 321 }
307 322
308 snd_soc_dapm_sync_endpoints(codec); 323 snd_soc_dapm_sync(codec);
309 324
310 return 0; 325 return 0;
311} 326}
@@ -315,6 +330,8 @@ static int neo1973_set_scenario(struct snd_kcontrol *kcontrol,
315{ 330{
316 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 331 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
317 332
333 DBG("Entered %s\n", __func__);
334
318 if (neo1973_scenario == ucontrol->value.integer.value[0]) 335 if (neo1973_scenario == ucontrol->value.integer.value[0])
319 return 0; 336 return 0;
320 337
@@ -327,6 +344,8 @@ static u8 lm4857_regs[4] = {0x00, 0x40, 0x80, 0xC0};
327 344
328static void lm4857_write_regs(void) 345static void lm4857_write_regs(void)
329{ 346{
347 DBG("Entered %s\n", __func__);
348
330 if (i2c_master_send(i2c, lm4857_regs, 4) != 4) 349 if (i2c_master_send(i2c, lm4857_regs, 4) != 4)
331 printk(KERN_ERR "lm4857: i2c write failed\n"); 350 printk(KERN_ERR "lm4857: i2c write failed\n");
332} 351}
@@ -338,6 +357,8 @@ static int lm4857_get_reg(struct snd_kcontrol *kcontrol,
338 int shift = (kcontrol->private_value >> 8) & 0x0F; 357 int shift = (kcontrol->private_value >> 8) & 0x0F;
339 int mask = (kcontrol->private_value >> 16) & 0xFF; 358 int mask = (kcontrol->private_value >> 16) & 0xFF;
340 359
360 DBG("Entered %s\n", __func__);
361
341 ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask; 362 ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask;
342 return 0; 363 return 0;
343} 364}
@@ -364,6 +385,8 @@ static int lm4857_get_mode(struct snd_kcontrol *kcontrol,
364{ 385{
365 u8 value = lm4857_regs[LM4857_CTRL] & 0x0F; 386 u8 value = lm4857_regs[LM4857_CTRL] & 0x0F;
366 387
388 DBG("Entered %s\n", __func__);
389
367 if (value) 390 if (value)
368 value -= 5; 391 value -= 5;
369 392
@@ -376,6 +399,8 @@ static int lm4857_set_mode(struct snd_kcontrol *kcontrol,
376{ 399{
377 u8 value = ucontrol->value.integer.value[0]; 400 u8 value = ucontrol->value.integer.value[0];
378 401
402 DBG("Entered %s\n", __func__);
403
379 if (value) 404 if (value)
380 value += 5; 405 value += 5;
381 406
@@ -397,8 +422,7 @@ static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
397}; 422};
398 423
399 424
400/* example machine audio_mapnections */ 425static const struct snd_soc_dapm_route dapm_routes[] = {
401static const char *audio_map[][3] = {
402 426
403 /* Connections to the lm4857 amp */ 427 /* Connections to the lm4857 amp */
404 {"Audio Out", NULL, "LOUT1"}, 428 {"Audio Out", NULL, "LOUT1"},
@@ -421,8 +445,6 @@ static const char *audio_map[][3] = {
421 445
422 /* Connect the ALC pins */ 446 /* Connect the ALC pins */
423 {"ACIN", NULL, "ACOP"}, 447 {"ACIN", NULL, "ACOP"},
424
425 {NULL, NULL, NULL},
426}; 448};
427 449
428static const char *lm4857_mode[] = { 450static const char *lm4857_mode[] = {
@@ -453,13 +475,16 @@ static const struct soc_enum neo_scenario_enum[] = {
453 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(neo_scenarios), neo_scenarios), 475 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(neo_scenarios), neo_scenarios),
454}; 476};
455 477
478static const DECLARE_TLV_DB_SCALE(stereo_tlv, -4050, 150, 0);
479static const DECLARE_TLV_DB_SCALE(mono_tlv, -3450, 150, 0);
480
456static const struct snd_kcontrol_new wm8753_neo1973_controls[] = { 481static const struct snd_kcontrol_new wm8753_neo1973_controls[] = {
457 SOC_SINGLE_EXT("Amp Left Playback Volume", LM4857_LVOL, 0, 31, 0, 482 SOC_SINGLE_EXT_TLV("Amp Left Playback Volume", LM4857_LVOL, 0, 31, 0,
458 lm4857_get_reg, lm4857_set_reg), 483 lm4857_get_reg, lm4857_set_reg, stereo_tlv),
459 SOC_SINGLE_EXT("Amp Right Playback Volume", LM4857_RVOL, 0, 31, 0, 484 SOC_SINGLE_EXT_TLV("Amp Right Playback Volume", LM4857_RVOL, 0, 31, 0,
460 lm4857_get_reg, lm4857_set_reg), 485 lm4857_get_reg, lm4857_set_reg, stereo_tlv),
461 SOC_SINGLE_EXT("Amp Mono Playback Volume", LM4857_MVOL, 0, 31, 0, 486 SOC_SINGLE_EXT_TLV("Amp Mono Playback Volume", LM4857_MVOL, 0, 31, 0,
462 lm4857_get_reg, lm4857_set_reg), 487 lm4857_get_reg, lm4857_set_reg, mono_tlv),
463 SOC_ENUM_EXT("Amp Mode", lm4857_mode_enum[0], 488 SOC_ENUM_EXT("Amp Mode", lm4857_mode_enum[0],
464 lm4857_get_mode, lm4857_set_mode), 489 lm4857_get_mode, lm4857_set_mode),
465 SOC_ENUM_EXT("Neo Mode", neo_scenario_enum[0], 490 SOC_ENUM_EXT("Neo Mode", neo_scenario_enum[0],
@@ -483,21 +508,23 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec)
483{ 508{
484 int i, err; 509 int i, err;
485 510
511 DBG("Entered %s\n", __func__);
512
486 /* set up NC codec pins */ 513 /* set up NC codec pins */
487 snd_soc_dapm_set_endpoint(codec, "LOUT2", 0); 514 snd_soc_dapm_disable_pin(codec, "LOUT2");
488 snd_soc_dapm_set_endpoint(codec, "ROUT2", 0); 515 snd_soc_dapm_disable_pin(codec, "ROUT2");
489 snd_soc_dapm_set_endpoint(codec, "OUT3", 0); 516 snd_soc_dapm_disable_pin(codec, "OUT3");
490 snd_soc_dapm_set_endpoint(codec, "OUT4", 0); 517 snd_soc_dapm_disable_pin(codec, "OUT4");
491 snd_soc_dapm_set_endpoint(codec, "LINE1", 0); 518 snd_soc_dapm_disable_pin(codec, "LINE1");
492 snd_soc_dapm_set_endpoint(codec, "LINE2", 0); 519 snd_soc_dapm_disable_pin(codec, "LINE2");
493 520
494 521
495 /* set endpoints to default mode */ 522 /* set endpoints to default mode */
496 set_scenario_endpoints(codec, NEO_AUDIO_OFF); 523 set_scenario_endpoints(codec, NEO_AUDIO_OFF);
497 524
498 /* Add neo1973 specific widgets */ 525 /* Add neo1973 specific widgets */
499 for (i = 0; i < ARRAY_SIZE(wm8753_dapm_widgets); i++) 526 snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets,
500 snd_soc_dapm_new_control(codec, &wm8753_dapm_widgets[i]); 527 ARRAY_SIZE(wm8753_dapm_widgets));
501 528
502 /* add neo1973 specific controls */ 529 /* add neo1973 specific controls */
503 for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_controls); i++) { 530 for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_controls); i++) {
@@ -508,20 +535,18 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec)
508 return err; 535 return err;
509 } 536 }
510 537
511 /* set up neo1973 specific audio path audio_mapnects */ 538 /* set up neo1973 specific audio routes */
512 for (i = 0; audio_map[i][0] != NULL; i++) { 539 err = snd_soc_dapm_add_routes(codec, dapm_routes,
513 snd_soc_dapm_connect_input(codec, audio_map[i][0], 540 ARRAY_SIZE(dapm_routes));
514 audio_map[i][1], audio_map[i][2]);
515 }
516 541
517 snd_soc_dapm_sync_endpoints(codec); 542 snd_soc_dapm_sync(codec);
518 return 0; 543 return 0;
519} 544}
520 545
521/* 546/*
522 * BT Codec DAI 547 * BT Codec DAI
523 */ 548 */
524static struct snd_soc_cpu_dai bt_dai = { 549static struct snd_soc_dai bt_dai = {
525 .name = "Bluetooth", 550 .name = "Bluetooth",
526 .id = 0, 551 .id = 0,
527 .type = SND_SOC_DAI_PCM, 552 .type = SND_SOC_DAI_PCM,
@@ -583,6 +608,8 @@ static int lm4857_amp_probe(struct i2c_adapter *adap, int addr, int kind)
583{ 608{
584 int ret; 609 int ret;
585 610
611 DBG("Entered %s\n", __func__);
612
586 client_template.adapter = adap; 613 client_template.adapter = adap;
587 client_template.addr = addr; 614 client_template.addr = addr;
588 615
@@ -606,6 +633,8 @@ exit_err:
606 633
607static int lm4857_i2c_detach(struct i2c_client *client) 634static int lm4857_i2c_detach(struct i2c_client *client)
608{ 635{
636 DBG("Entered %s\n", __func__);
637
609 i2c_detach_client(client); 638 i2c_detach_client(client);
610 kfree(client); 639 kfree(client);
611 return 0; 640 return 0;
@@ -613,6 +642,8 @@ static int lm4857_i2c_detach(struct i2c_client *client)
613 642
614static int lm4857_i2c_attach(struct i2c_adapter *adap) 643static int lm4857_i2c_attach(struct i2c_adapter *adap)
615{ 644{
645 DBG("Entered %s\n", __func__);
646
616 return i2c_probe(adap, &addr_data, lm4857_amp_probe); 647 return i2c_probe(adap, &addr_data, lm4857_amp_probe);
617} 648}
618 649
@@ -620,6 +651,8 @@ static u8 lm4857_state;
620 651
621static int lm4857_suspend(struct i2c_client *dev, pm_message_t state) 652static int lm4857_suspend(struct i2c_client *dev, pm_message_t state)
622{ 653{
654 DBG("Entered %s\n", __func__);
655
623 dev_dbg(&dev->dev, "lm4857_suspend\n"); 656 dev_dbg(&dev->dev, "lm4857_suspend\n");
624 lm4857_state = lm4857_regs[LM4857_CTRL] & 0xf; 657 lm4857_state = lm4857_regs[LM4857_CTRL] & 0xf;
625 if (lm4857_state) { 658 if (lm4857_state) {
@@ -631,6 +664,8 @@ static int lm4857_suspend(struct i2c_client *dev, pm_message_t state)
631 664
632static int lm4857_resume(struct i2c_client *dev) 665static int lm4857_resume(struct i2c_client *dev)
633{ 666{
667 DBG("Entered %s\n", __func__);
668
634 if (lm4857_state) { 669 if (lm4857_state) {
635 lm4857_regs[LM4857_CTRL] |= (lm4857_state & 0x0f); 670 lm4857_regs[LM4857_CTRL] |= (lm4857_state & 0x0f);
636 lm4857_write_regs(); 671 lm4857_write_regs();
@@ -640,6 +675,8 @@ static int lm4857_resume(struct i2c_client *dev)
640 675
641static void lm4857_shutdown(struct i2c_client *dev) 676static void lm4857_shutdown(struct i2c_client *dev)
642{ 677{
678 DBG("Entered %s\n", __func__);
679
643 dev_dbg(&dev->dev, "lm4857_shutdown\n"); 680 dev_dbg(&dev->dev, "lm4857_shutdown\n");
644 lm4857_regs[LM4857_CTRL] &= 0xf0; 681 lm4857_regs[LM4857_CTRL] &= 0xf0;
645 lm4857_write_regs(); 682 lm4857_write_regs();
@@ -671,6 +708,8 @@ static int __init neo1973_init(void)
671{ 708{
672 int ret; 709 int ret;
673 710
711 DBG("Entered %s\n", __func__);
712
674 neo1973_snd_device = platform_device_alloc("soc-audio", -1); 713 neo1973_snd_device = platform_device_alloc("soc-audio", -1);
675 if (!neo1973_snd_device) 714 if (!neo1973_snd_device)
676 return -ENOMEM; 715 return -ENOMEM;
@@ -691,6 +730,8 @@ static int __init neo1973_init(void)
691 730
692static void __exit neo1973_exit(void) 731static void __exit neo1973_exit(void)
693{ 732{
733 DBG("Entered %s\n", __func__);
734
694 i2c_del_driver(&lm4857_i2c_driver); 735 i2c_del_driver(&lm4857_i2c_driver);
695 platform_device_unregister(neo1973_snd_device); 736 platform_device_unregister(neo1973_snd_device);
696} 737}
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c
index c4a46dd589b3..ee4676ed1283 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c
@@ -295,7 +295,7 @@ static inline int s3c2412_snd_is_clkmaster(void)
295/* 295/*
296 * Set S3C2412 I2S DAI format 296 * Set S3C2412 I2S DAI format
297 */ 297 */
298static int s3c2412_i2s_set_fmt(struct snd_soc_cpu_dai *cpu_dai, 298static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
299 unsigned int fmt) 299 unsigned int fmt)
300{ 300{
301 u32 iismod; 301 u32 iismod;
@@ -500,7 +500,7 @@ EXPORT_SYMBOL_GPL(s3c2412_iis_calc_rate);
500/* 500/*
501 * Set S3C2412 Clock source 501 * Set S3C2412 Clock source
502 */ 502 */
503static int s3c2412_i2s_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, 503static int s3c2412_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
504 int clk_id, unsigned int freq, int dir) 504 int clk_id, unsigned int freq, int dir)
505{ 505{
506 u32 iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD); 506 u32 iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD);
@@ -528,7 +528,7 @@ static int s3c2412_i2s_set_sysclk(struct snd_soc_cpu_dai *cpu_dai,
528/* 528/*
529 * Set S3C2412 Clock dividers 529 * Set S3C2412 Clock dividers
530 */ 530 */
531static int s3c2412_i2s_set_clkdiv(struct snd_soc_cpu_dai *cpu_dai, 531static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
532 int div_id, int div) 532 int div_id, int div)
533{ 533{
534 struct s3c2412_i2s_info *i2s = &s3c2412_i2s; 534 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
@@ -601,7 +601,8 @@ struct clk *s3c2412_get_iisclk(void)
601EXPORT_SYMBOL_GPL(s3c2412_get_iisclk); 601EXPORT_SYMBOL_GPL(s3c2412_get_iisclk);
602 602
603 603
604static int s3c2412_i2s_probe(struct platform_device *pdev) 604static int s3c2412_i2s_probe(struct platform_device *pdev,
605 struct snd_soc_dai *dai)
605{ 606{
606 DBG("Entered %s\n", __func__); 607 DBG("Entered %s\n", __func__);
607 608
@@ -647,7 +648,7 @@ static int s3c2412_i2s_probe(struct platform_device *pdev)
647 648
648#ifdef CONFIG_PM 649#ifdef CONFIG_PM
649static int s3c2412_i2s_suspend(struct platform_device *dev, 650static int s3c2412_i2s_suspend(struct platform_device *dev,
650 struct snd_soc_cpu_dai *dai) 651 struct snd_soc_dai *dai)
651{ 652{
652 struct s3c2412_i2s_info *i2s = &s3c2412_i2s; 653 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
653 u32 iismod; 654 u32 iismod;
@@ -675,7 +676,7 @@ static int s3c2412_i2s_suspend(struct platform_device *dev,
675} 676}
676 677
677static int s3c2412_i2s_resume(struct platform_device *pdev, 678static int s3c2412_i2s_resume(struct platform_device *pdev,
678 struct snd_soc_cpu_dai *dai) 679 struct snd_soc_dai *dai)
679{ 680{
680 struct s3c2412_i2s_info *i2s = &s3c2412_i2s; 681 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
681 682
@@ -707,7 +708,7 @@ static int s3c2412_i2s_resume(struct platform_device *pdev,
707 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ 708 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
708 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 709 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
709 710
710struct snd_soc_cpu_dai s3c2412_i2s_dai = { 711struct snd_soc_dai s3c2412_i2s_dai = {
711 .name = "s3c2412-i2s", 712 .name = "s3c2412-i2s",
712 .id = 0, 713 .id = 0,
713 .type = SND_SOC_DAI_I2S, 714 .type = SND_SOC_DAI_I2S,
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.h b/sound/soc/s3c24xx/s3c2412-i2s.h
index 27f48e1ffa86..aac08a25e541 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.h
+++ b/sound/soc/s3c24xx/s3c2412-i2s.h
@@ -24,7 +24,7 @@
24 24
25extern struct clk *s3c2412_get_iisclk(void); 25extern struct clk *s3c2412_get_iisclk(void);
26 26
27extern struct snd_soc_cpu_dai s3c2412_i2s_dai; 27extern struct snd_soc_dai s3c2412_i2s_dai;
28 28
29struct s3c2412_rate_calc { 29struct s3c2412_rate_calc {
30 unsigned int clk_div; /* for prescaler */ 30 unsigned int clk_div; /* for prescaler */
diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c
index e81d9a6c83da..783349b7fede 100644
--- a/sound/soc/s3c24xx/s3c2443-ac97.c
+++ b/sound/soc/s3c24xx/s3c2443-ac97.c
@@ -10,9 +10,6 @@
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 *
14 * Revision history
15 * 21st Mar 2007 Initial Version
16 */ 13 */
17 14
18#include <linux/init.h> 15#include <linux/init.h>
@@ -212,7 +209,8 @@ static struct s3c24xx_pcm_dma_params s3c2443_ac97_mic_mono_in = {
212 .dma_size = 4, 209 .dma_size = 4,
213}; 210};
214 211
215static int s3c2443_ac97_probe(struct platform_device *pdev) 212static int s3c2443_ac97_probe(struct platform_device *pdev,
213 struct snd_soc_dai *dai)
216{ 214{
217 int ret; 215 int ret;
218 u32 ac_glbctrl; 216 u32 ac_glbctrl;
@@ -263,7 +261,8 @@ static int s3c2443_ac97_probe(struct platform_device *pdev)
263 return ret; 261 return ret;
264} 262}
265 263
266static void s3c2443_ac97_remove(struct platform_device *pdev) 264static void s3c2443_ac97_remove(struct platform_device *pdev,
265 struct snd_soc_dai *dai)
267{ 266{
268 free_irq(IRQ_S3C244x_AC97, NULL); 267 free_irq(IRQ_S3C244x_AC97, NULL);
269 clk_disable(s3c24xx_ac97.ac97_clk); 268 clk_disable(s3c24xx_ac97.ac97_clk);
@@ -275,7 +274,7 @@ static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
275 struct snd_pcm_hw_params *params) 274 struct snd_pcm_hw_params *params)
276{ 275{
277 struct snd_soc_pcm_runtime *rtd = substream->private_data; 276 struct snd_soc_pcm_runtime *rtd = substream->private_data;
278 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 277 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
279 278
280 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 279 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
281 cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_out; 280 cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_out;
@@ -317,7 +316,7 @@ static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
317 struct snd_pcm_hw_params *params) 316 struct snd_pcm_hw_params *params)
318{ 317{
319 struct snd_soc_pcm_runtime *rtd = substream->private_data; 318 struct snd_soc_pcm_runtime *rtd = substream->private_data;
320 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; 319 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
321 320
322 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 321 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
323 return -ENODEV; 322 return -ENODEV;
@@ -353,7 +352,7 @@ static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream,
353 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ 352 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
354 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) 353 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
355 354
356struct snd_soc_cpu_dai s3c2443_ac97_dai[] = { 355struct snd_soc_dai s3c2443_ac97_dai[] = {
357{ 356{
358 .name = "s3c2443-ac97", 357 .name = "s3c2443-ac97",
359 .id = 0, 358 .id = 0,
diff --git a/sound/soc/s3c24xx/s3c24xx-ac97.h b/sound/soc/s3c24xx/s3c24xx-ac97.h
index bf03e8ed16c3..a96dcadf28b4 100644
--- a/sound/soc/s3c24xx/s3c24xx-ac97.h
+++ b/sound/soc/s3c24xx/s3c24xx-ac97.h
@@ -26,6 +26,6 @@
26#define IRQ_S3C244x_AC97 IRQ_S3C2443_AC97 26#define IRQ_S3C244x_AC97 IRQ_S3C2443_AC97
27#endif 27#endif
28 28
29extern struct snd_soc_cpu_dai s3c2443_ac97_dai[]; 29extern struct snd_soc_dai s3c2443_ac97_dai[];
30 30
31#endif /*S3C24XXAC97_H_*/ 31#endif /*S3C24XXAC97_H_*/
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index 1ed6afd45459..397524282b57 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -12,11 +12,6 @@
12 * under the terms of the GNU General Public License as published by the 12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your 13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version. 14 * option) any later version.
15 *
16 *
17 * Revision history
18 * 11th Dec 2006 Merged with Simtec driver
19 * 10th Nov 2006 Initial version.
20 */ 15 */
21 16
22#include <linux/init.h> 17#include <linux/init.h>
@@ -180,7 +175,7 @@ static void s3c24xx_snd_rxctrl(int on)
180static int s3c24xx_snd_lrsync(void) 175static int s3c24xx_snd_lrsync(void)
181{ 176{
182 u32 iiscon; 177 u32 iiscon;
183 unsigned long timeout = jiffies + msecs_to_jiffies(5); 178 int timeout = 50; /* 5ms */
184 179
185 DBG("Entered %s\n", __func__); 180 DBG("Entered %s\n", __func__);
186 181
@@ -189,8 +184,9 @@ static int s3c24xx_snd_lrsync(void)
189 if (iiscon & S3C2410_IISCON_LRINDEX) 184 if (iiscon & S3C2410_IISCON_LRINDEX)
190 break; 185 break;
191 186
192 if (time_after(jiffies, timeout)) 187 if (!timeout--)
193 return -ETIMEDOUT; 188 return -ETIMEDOUT;
189 udelay(100);
194 } 190 }
195 191
196 return 0; 192 return 0;
@@ -209,7 +205,7 @@ static inline int s3c24xx_snd_is_clkmaster(void)
209/* 205/*
210 * Set S3C24xx I2S DAI format 206 * Set S3C24xx I2S DAI format
211 */ 207 */
212static int s3c24xx_i2s_set_fmt(struct snd_soc_cpu_dai *cpu_dai, 208static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
213 unsigned int fmt) 209 unsigned int fmt)
214{ 210{
215 u32 iismod; 211 u32 iismod;
@@ -317,7 +313,7 @@ exit_err:
317/* 313/*
318 * Set S3C24xx Clock source 314 * Set S3C24xx Clock source
319 */ 315 */
320static int s3c24xx_i2s_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, 316static int s3c24xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
321 int clk_id, unsigned int freq, int dir) 317 int clk_id, unsigned int freq, int dir)
322{ 318{
323 u32 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); 319 u32 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
@@ -343,7 +339,7 @@ static int s3c24xx_i2s_set_sysclk(struct snd_soc_cpu_dai *cpu_dai,
343/* 339/*
344 * Set S3C24xx Clock dividers 340 * Set S3C24xx Clock dividers
345 */ 341 */
346static int s3c24xx_i2s_set_clkdiv(struct snd_soc_cpu_dai *cpu_dai, 342static int s3c24xx_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
347 int div_id, int div) 343 int div_id, int div)
348{ 344{
349 u32 reg; 345 u32 reg;
@@ -381,7 +377,8 @@ u32 s3c24xx_i2s_get_clockrate(void)
381} 377}
382EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate); 378EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate);
383 379
384static int s3c24xx_i2s_probe(struct platform_device *pdev) 380static int s3c24xx_i2s_probe(struct platform_device *pdev,
381 struct snd_soc_dai *dai)
385{ 382{
386 DBG("Entered %s\n", __func__); 383 DBG("Entered %s\n", __func__);
387 384
@@ -414,7 +411,7 @@ static int s3c24xx_i2s_probe(struct platform_device *pdev)
414 411
415#ifdef CONFIG_PM 412#ifdef CONFIG_PM
416static int s3c24xx_i2s_suspend(struct platform_device *pdev, 413static int s3c24xx_i2s_suspend(struct platform_device *pdev,
417 struct snd_soc_cpu_dai *cpu_dai) 414 struct snd_soc_dai *cpu_dai)
418{ 415{
419 DBG("Entered %s\n", __func__); 416 DBG("Entered %s\n", __func__);
420 417
@@ -429,7 +426,7 @@ static int s3c24xx_i2s_suspend(struct platform_device *pdev,
429} 426}
430 427
431static int s3c24xx_i2s_resume(struct platform_device *pdev, 428static int s3c24xx_i2s_resume(struct platform_device *pdev,
432 struct snd_soc_cpu_dai *cpu_dai) 429 struct snd_soc_dai *cpu_dai)
433{ 430{
434 DBG("Entered %s\n", __func__); 431 DBG("Entered %s\n", __func__);
435 clk_enable(s3c24xx_i2s.iis_clk); 432 clk_enable(s3c24xx_i2s.iis_clk);
@@ -452,7 +449,7 @@ static int s3c24xx_i2s_resume(struct platform_device *pdev,
452 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ 449 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
453 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 450 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
454 451
455struct snd_soc_cpu_dai s3c24xx_i2s_dai = { 452struct snd_soc_dai s3c24xx_i2s_dai = {
456 .name = "s3c24xx-i2s", 453 .name = "s3c24xx-i2s",
457 .id = 0, 454 .id = 0,
458 .type = SND_SOC_DAI_I2S, 455 .type = SND_SOC_DAI_I2S,
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.h b/sound/soc/s3c24xx/s3c24xx-i2s.h
index 537b4ecce8a3..726d91cf4e1c 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.h
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.h
@@ -32,6 +32,6 @@
32 32
33u32 s3c24xx_i2s_get_clockrate(void); 33u32 s3c24xx_i2s_get_clockrate(void);
34 34
35extern struct snd_soc_cpu_dai s3c24xx_i2s_dai; 35extern struct snd_soc_dai s3c24xx_i2s_dai;
36 36
37#endif /*S3C24XXI2S_H_*/ 37#endif /*S3C24XXI2S_H_*/
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
index 7806ae614617..cef79b34dc6f 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
@@ -12,10 +12,6 @@
12 * under the terms of the GNU General Public License as published by the 12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your 13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version. 14 * option) any later version.
15 *
16 * Revision history
17 * 11th Dec 2006 Merged with Simtec driver
18 * 10th Nov 2006 Initial version.
19 */ 15 */
20 16
21#include <linux/module.h> 17#include <linux/module.h>
@@ -433,7 +429,7 @@ static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
433static u64 s3c24xx_pcm_dmamask = DMA_32BIT_MASK; 429static u64 s3c24xx_pcm_dmamask = DMA_32BIT_MASK;
434 430
435static int s3c24xx_pcm_new(struct snd_card *card, 431static int s3c24xx_pcm_new(struct snd_card *card,
436 struct snd_soc_codec_dai *dai, struct snd_pcm *pcm) 432 struct snd_soc_dai *dai, struct snd_pcm *pcm)
437{ 433{
438 int ret = 0; 434 int ret = 0;
439 435
diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c
index b4a56302b9ab..8515d6ff03f2 100644
--- a/sound/soc/s3c24xx/smdk2443_wm9710.c
+++ b/sound/soc/s3c24xx/smdk2443_wm9710.c
@@ -10,9 +10,6 @@
10 * Free Software Foundation; either version 2 of the License, or (at your 10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
12 * 12 *
13 * Revision history
14 * 8th Mar 2007 Initial version.
15 *
16 */ 13 */
17 14
18#include <linux/module.h> 15#include <linux/module.h>
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 4c1e013381c9..54bd604012af 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -3,7 +3,7 @@ menu "SoC Audio support for SuperH"
3 3
4config SND_SOC_PCM_SH7760 4config SND_SOC_PCM_SH7760
5 tristate "SoC Audio support for Renesas SH7760" 5 tristate "SoC Audio support for Renesas SH7760"
6 depends on CPU_SUBTYPE_SH7760 && SND_SOC && SH_DMABRG 6 depends on CPU_SUBTYPE_SH7760 && SH_DMABRG
7 help 7 help
8 Enable this option for SH7760 AC97/I2S audio support. 8 Enable this option for SH7760 AC97/I2S audio support.
9 9
@@ -13,10 +13,9 @@ config SND_SOC_PCM_SH7760
13## 13##
14 14
15config SND_SOC_SH4_HAC 15config SND_SOC_SH4_HAC
16 tristate
16 select AC97_BUS 17 select AC97_BUS
17 select SND_SOC_AC97_BUS 18 select SND_SOC_AC97_BUS
18 select SND_AC97_CODEC
19 tristate
20 19
21config SND_SOC_SH4_SSI 20config SND_SOC_SH4_SSI
22 tristate 21 tristate
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
index 7a3ce80d6727..9faa12622d09 100644
--- a/sound/soc/sh/dma-sh7760.c
+++ b/sound/soc/sh/dma-sh7760.c
@@ -326,7 +326,7 @@ static void camelot_pcm_free(struct snd_pcm *pcm)
326} 326}
327 327
328static int camelot_pcm_new(struct snd_card *card, 328static int camelot_pcm_new(struct snd_card *card,
329 struct snd_soc_codec_dai *dai, 329 struct snd_soc_dai *dai,
330 struct snd_pcm *pcm) 330 struct snd_pcm *pcm)
331{ 331{
332 /* dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel 332 /* dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
index b7b676b3d671..df7bc345c320 100644
--- a/sound/soc/sh/hac.c
+++ b/sound/soc/sh/hac.c
@@ -266,7 +266,7 @@ static int hac_hw_params(struct snd_pcm_substream *substream,
266#define AC97_FMTS \ 266#define AC97_FMTS \
267 SNDRV_PCM_FMTBIT_S16_LE 267 SNDRV_PCM_FMTBIT_S16_LE
268 268
269struct snd_soc_cpu_dai sh4_hac_dai[] = { 269struct snd_soc_dai sh4_hac_dai[] = {
270{ 270{
271 .name = "HAC0", 271 .name = "HAC0",
272 .id = 0, 272 .id = 0,
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c
index 2f91de84c5c7..92bfaf4774a7 100644
--- a/sound/soc/sh/sh7760-ac97.c
+++ b/sound/soc/sh/sh7760-ac97.c
@@ -20,12 +20,12 @@
20#define IPSEL 0xFE400034 20#define IPSEL 0xFE400034
21 21
22/* platform specific structs can be declared here */ 22/* platform specific structs can be declared here */
23extern struct snd_soc_cpu_dai sh4_hac_dai[2]; 23extern struct snd_soc_dai sh4_hac_dai[2];
24extern struct snd_soc_platform sh7760_soc_platform; 24extern struct snd_soc_platform sh7760_soc_platform;
25 25
26static int machine_init(struct snd_soc_codec *codec) 26static int machine_init(struct snd_soc_codec *codec)
27{ 27{
28 snd_soc_dapm_sync_endpoints(codec); 28 snd_soc_dapm_sync(codec);
29 return 0; 29 return 0;
30} 30}
31 31
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c
index 3388bc3d62d1..55c3464163ab 100644
--- a/sound/soc/sh/ssi.c
+++ b/sound/soc/sh/ssi.c
@@ -208,7 +208,7 @@ static int ssi_hw_params(struct snd_pcm_substream *substream,
208 return 0; 208 return 0;
209} 209}
210 210
211static int ssi_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, int clk_id, 211static int ssi_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,
212 unsigned int freq, int dir) 212 unsigned int freq, int dir)
213{ 213{
214 struct ssi_priv *ssi = &ssi_cpu_data[cpu_dai->id]; 214 struct ssi_priv *ssi = &ssi_cpu_data[cpu_dai->id];
@@ -222,7 +222,7 @@ static int ssi_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, int clk_id,
222 * This divider is used to generate the SSI_SCK (I2S bitclock) from the 222 * This divider is used to generate the SSI_SCK (I2S bitclock) from the
223 * clock at the HAC_BIT_CLK ("oversampling clock") pin. 223 * clock at the HAC_BIT_CLK ("oversampling clock") pin.
224 */ 224 */
225static int ssi_set_clkdiv(struct snd_soc_cpu_dai *dai, int did, int div) 225static int ssi_set_clkdiv(struct snd_soc_dai *dai, int did, int div)
226{ 226{
227 struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; 227 struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
228 unsigned long ssicr; 228 unsigned long ssicr;
@@ -245,7 +245,7 @@ static int ssi_set_clkdiv(struct snd_soc_cpu_dai *dai, int did, int div)
245 return 0; 245 return 0;
246} 246}
247 247
248static int ssi_set_fmt(struct snd_soc_cpu_dai *dai, unsigned int fmt) 248static int ssi_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
249{ 249{
250 struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; 250 struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
251 unsigned long ssicr = SSIREG(SSICR); 251 unsigned long ssicr = SSIREG(SSICR);
@@ -332,7 +332,7 @@ static int ssi_set_fmt(struct snd_soc_cpu_dai *dai, unsigned int fmt)
332 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \ 332 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \
333 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) 333 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE)
334 334
335struct snd_soc_cpu_dai sh4_ssi_dai[] = { 335struct snd_soc_dai sh4_ssi_dai[] = {
336{ 336{
337 .name = "SSI0", 337 .name = "SSI0",
338 .id = 0, 338 .id = 0,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index e148db940cfc..83f1190293a8 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -14,10 +14,6 @@
14 * Free Software Foundation; either version 2 of the License, or (at your 14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. 15 * option) any later version.
16 * 16 *
17 * Revision history
18 * 12th Aug 2005 Initial version.
19 * 25th Oct 2005 Working Codec, Interface and Platform registration.
20 *
21 * TODO: 17 * TODO:
22 * o Add hw rules to enforce rates, etc. 18 * o Add hw rules to enforce rates, etc.
23 * o More testing with other codecs/machines. 19 * o More testing with other codecs/machines.
@@ -112,9 +108,9 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
112} 108}
113#endif 109#endif
114 110
115static inline const char* get_dai_name(int type) 111static inline const char *get_dai_name(int type)
116{ 112{
117 switch(type) { 113 switch (type) {
118 case SND_SOC_DAI_AC97_BUS: 114 case SND_SOC_DAI_AC97_BUS:
119 case SND_SOC_DAI_AC97: 115 case SND_SOC_DAI_AC97:
120 return "AC97"; 116 return "AC97";
@@ -138,8 +134,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
138 struct snd_pcm_runtime *runtime = substream->runtime; 134 struct snd_pcm_runtime *runtime = substream->runtime;
139 struct snd_soc_dai_link *machine = rtd->dai; 135 struct snd_soc_dai_link *machine = rtd->dai;
140 struct snd_soc_platform *platform = socdev->platform; 136 struct snd_soc_platform *platform = socdev->platform;
141 struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; 137 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
142 struct snd_soc_codec_dai *codec_dai = machine->codec_dai; 138 struct snd_soc_dai *codec_dai = machine->codec_dai;
143 int ret = 0; 139 int ret = 0;
144 140
145 mutex_lock(&pcm_mutex); 141 mutex_lock(&pcm_mutex);
@@ -182,9 +178,11 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
182 /* Check that the codec and cpu DAI's are compatible */ 178 /* Check that the codec and cpu DAI's are compatible */
183 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 179 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
184 runtime->hw.rate_min = 180 runtime->hw.rate_min =
185 max(codec_dai->playback.rate_min, cpu_dai->playback.rate_min); 181 max(codec_dai->playback.rate_min,
182 cpu_dai->playback.rate_min);
186 runtime->hw.rate_max = 183 runtime->hw.rate_max =
187 min(codec_dai->playback.rate_max, cpu_dai->playback.rate_max); 184 min(codec_dai->playback.rate_max,
185 cpu_dai->playback.rate_max);
188 runtime->hw.channels_min = 186 runtime->hw.channels_min =
189 max(codec_dai->playback.channels_min, 187 max(codec_dai->playback.channels_min,
190 cpu_dai->playback.channels_min); 188 cpu_dai->playback.channels_min);
@@ -197,9 +195,11 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
197 codec_dai->playback.rates & cpu_dai->playback.rates; 195 codec_dai->playback.rates & cpu_dai->playback.rates;
198 } else { 196 } else {
199 runtime->hw.rate_min = 197 runtime->hw.rate_min =
200 max(codec_dai->capture.rate_min, cpu_dai->capture.rate_min); 198 max(codec_dai->capture.rate_min,
199 cpu_dai->capture.rate_min);
201 runtime->hw.rate_max = 200 runtime->hw.rate_max =
202 min(codec_dai->capture.rate_max, cpu_dai->capture.rate_max); 201 min(codec_dai->capture.rate_max,
202 cpu_dai->capture.rate_max);
203 runtime->hw.channels_min = 203 runtime->hw.channels_min =
204 max(codec_dai->capture.channels_min, 204 max(codec_dai->capture.channels_min,
205 cpu_dai->capture.channels_min); 205 cpu_dai->capture.channels_min);
@@ -229,7 +229,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
229 goto machine_err; 229 goto machine_err;
230 } 230 }
231 231
232 dbg("asoc: %s <-> %s info:\n",codec_dai->name, cpu_dai->name); 232 dbg("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name);
233 dbg("asoc: rate mask 0x%x\n", runtime->hw.rates); 233 dbg("asoc: rate mask 0x%x\n", runtime->hw.rates);
234 dbg("asoc: min ch %d max ch %d\n", runtime->hw.channels_min, 234 dbg("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
235 runtime->hw.channels_max); 235 runtime->hw.channels_max);
@@ -272,11 +272,11 @@ static void close_delayed_work(struct work_struct *work)
272 struct snd_soc_device *socdev = 272 struct snd_soc_device *socdev =
273 container_of(work, struct snd_soc_device, delayed_work.work); 273 container_of(work, struct snd_soc_device, delayed_work.work);
274 struct snd_soc_codec *codec = socdev->codec; 274 struct snd_soc_codec *codec = socdev->codec;
275 struct snd_soc_codec_dai *codec_dai; 275 struct snd_soc_dai *codec_dai;
276 int i; 276 int i;
277 277
278 mutex_lock(&pcm_mutex); 278 mutex_lock(&pcm_mutex);
279 for(i = 0; i < codec->num_dai; i++) { 279 for (i = 0; i < codec->num_dai; i++) {
280 codec_dai = &codec->dai[i]; 280 codec_dai = &codec->dai[i];
281 281
282 dbg("pop wq checking: %s status: %s waiting: %s\n", 282 dbg("pop wq checking: %s status: %s waiting: %s\n",
@@ -287,12 +287,12 @@ static void close_delayed_work(struct work_struct *work)
287 /* are we waiting on this codec DAI stream */ 287 /* are we waiting on this codec DAI stream */
288 if (codec_dai->pop_wait == 1) { 288 if (codec_dai->pop_wait == 1) {
289 289
290 /* power down the codec to D1 if no longer active */ 290 /* Reduce power if no longer active */
291 if (codec->active == 0) { 291 if (codec->active == 0) {
292 dbg("pop wq D1 %s %s\n", codec->name, 292 dbg("pop wq D1 %s %s\n", codec->name,
293 codec_dai->playback.stream_name); 293 codec_dai->playback.stream_name);
294 snd_soc_dapm_device_event(socdev, 294 snd_soc_dapm_set_bias_level(socdev,
295 SNDRV_CTL_POWER_D1); 295 SND_SOC_BIAS_PREPARE);
296 } 296 }
297 297
298 codec_dai->pop_wait = 0; 298 codec_dai->pop_wait = 0;
@@ -300,12 +300,12 @@ static void close_delayed_work(struct work_struct *work)
300 codec_dai->playback.stream_name, 300 codec_dai->playback.stream_name,
301 SND_SOC_DAPM_STREAM_STOP); 301 SND_SOC_DAPM_STREAM_STOP);
302 302
303 /* power down the codec power domain if no longer active */ 303 /* Fall into standby if no longer active */
304 if (codec->active == 0) { 304 if (codec->active == 0) {
305 dbg("pop wq D3 %s %s\n", codec->name, 305 dbg("pop wq D3 %s %s\n", codec->name,
306 codec_dai->playback.stream_name); 306 codec_dai->playback.stream_name);
307 snd_soc_dapm_device_event(socdev, 307 snd_soc_dapm_set_bias_level(socdev,
308 SNDRV_CTL_POWER_D3hot); 308 SND_SOC_BIAS_STANDBY);
309 } 309 }
310 } 310 }
311 } 311 }
@@ -323,8 +323,8 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
323 struct snd_soc_device *socdev = rtd->socdev; 323 struct snd_soc_device *socdev = rtd->socdev;
324 struct snd_soc_dai_link *machine = rtd->dai; 324 struct snd_soc_dai_link *machine = rtd->dai;
325 struct snd_soc_platform *platform = socdev->platform; 325 struct snd_soc_platform *platform = socdev->platform;
326 struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; 326 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
327 struct snd_soc_codec_dai *codec_dai = machine->codec_dai; 327 struct snd_soc_dai *codec_dai = machine->codec_dai;
328 struct snd_soc_codec *codec = socdev->codec; 328 struct snd_soc_codec *codec = socdev->codec;
329 329
330 mutex_lock(&pcm_mutex); 330 mutex_lock(&pcm_mutex);
@@ -365,8 +365,8 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
365 SND_SOC_DAPM_STREAM_STOP); 365 SND_SOC_DAPM_STREAM_STOP);
366 366
367 if (codec->active == 0 && codec_dai->pop_wait == 0) 367 if (codec->active == 0 && codec_dai->pop_wait == 0)
368 snd_soc_dapm_device_event(socdev, 368 snd_soc_dapm_set_bias_level(socdev,
369 SNDRV_CTL_POWER_D3hot); 369 SND_SOC_BIAS_STANDBY);
370 } 370 }
371 371
372 mutex_unlock(&pcm_mutex); 372 mutex_unlock(&pcm_mutex);
@@ -384,8 +384,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
384 struct snd_soc_device *socdev = rtd->socdev; 384 struct snd_soc_device *socdev = rtd->socdev;
385 struct snd_soc_dai_link *machine = rtd->dai; 385 struct snd_soc_dai_link *machine = rtd->dai;
386 struct snd_soc_platform *platform = socdev->platform; 386 struct snd_soc_platform *platform = socdev->platform;
387 struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; 387 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
388 struct snd_soc_codec_dai *codec_dai = machine->codec_dai; 388 struct snd_soc_dai *codec_dai = machine->codec_dai;
389 struct snd_soc_codec *codec = socdev->codec; 389 struct snd_soc_codec *codec = socdev->codec;
390 int ret = 0; 390 int ret = 0;
391 391
@@ -434,14 +434,14 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
434 else { 434 else {
435 codec_dai->pop_wait = 0; 435 codec_dai->pop_wait = 0;
436 cancel_delayed_work(&socdev->delayed_work); 436 cancel_delayed_work(&socdev->delayed_work);
437 if (codec_dai->dai_ops.digital_mute) 437 snd_soc_dai_digital_mute(codec_dai, 0);
438 codec_dai->dai_ops.digital_mute(codec_dai, 0);
439 } 438 }
440 } else { 439 } else {
441 /* no delayed work - do we need to power up codec */ 440 /* no delayed work - do we need to power up codec */
442 if (codec->dapm_state != SNDRV_CTL_POWER_D0) { 441 if (codec->bias_level != SND_SOC_BIAS_ON) {
443 442
444 snd_soc_dapm_device_event(socdev, SNDRV_CTL_POWER_D1); 443 snd_soc_dapm_set_bias_level(socdev,
444 SND_SOC_BIAS_PREPARE);
445 445
446 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 446 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
447 snd_soc_dapm_stream_event(codec, 447 snd_soc_dapm_stream_event(codec,
@@ -452,9 +452,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
452 codec_dai->capture.stream_name, 452 codec_dai->capture.stream_name,
453 SND_SOC_DAPM_STREAM_START); 453 SND_SOC_DAPM_STREAM_START);
454 454
455 snd_soc_dapm_device_event(socdev, SNDRV_CTL_POWER_D0); 455 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON);
456 if (codec_dai->dai_ops.digital_mute) 456 snd_soc_dai_digital_mute(codec_dai, 0);
457 codec_dai->dai_ops.digital_mute(codec_dai, 0);
458 457
459 } else { 458 } else {
460 /* codec already powered - power on widgets */ 459 /* codec already powered - power on widgets */
@@ -466,8 +465,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
466 snd_soc_dapm_stream_event(codec, 465 snd_soc_dapm_stream_event(codec,
467 codec_dai->capture.stream_name, 466 codec_dai->capture.stream_name,
468 SND_SOC_DAPM_STREAM_START); 467 SND_SOC_DAPM_STREAM_START);
469 if (codec_dai->dai_ops.digital_mute) 468
470 codec_dai->dai_ops.digital_mute(codec_dai, 0); 469 snd_soc_dai_digital_mute(codec_dai, 0);
471 } 470 }
472 } 471 }
473 472
@@ -488,8 +487,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
488 struct snd_soc_device *socdev = rtd->socdev; 487 struct snd_soc_device *socdev = rtd->socdev;
489 struct snd_soc_dai_link *machine = rtd->dai; 488 struct snd_soc_dai_link *machine = rtd->dai;
490 struct snd_soc_platform *platform = socdev->platform; 489 struct snd_soc_platform *platform = socdev->platform;
491 struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; 490 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
492 struct snd_soc_codec_dai *codec_dai = machine->codec_dai; 491 struct snd_soc_dai *codec_dai = machine->codec_dai;
493 int ret = 0; 492 int ret = 0;
494 493
495 mutex_lock(&pcm_mutex); 494 mutex_lock(&pcm_mutex);
@@ -514,7 +513,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
514 if (cpu_dai->ops.hw_params) { 513 if (cpu_dai->ops.hw_params) {
515 ret = cpu_dai->ops.hw_params(substream, params); 514 ret = cpu_dai->ops.hw_params(substream, params);
516 if (ret < 0) { 515 if (ret < 0) {
517 printk(KERN_ERR "asoc: can't set interface %s hw params\n", 516 printk(KERN_ERR "asoc: interface %s hw params failed\n",
518 cpu_dai->name); 517 cpu_dai->name);
519 goto interface_err; 518 goto interface_err;
520 } 519 }
@@ -523,7 +522,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
523 if (platform->pcm_ops->hw_params) { 522 if (platform->pcm_ops->hw_params) {
524 ret = platform->pcm_ops->hw_params(substream, params); 523 ret = platform->pcm_ops->hw_params(substream, params);
525 if (ret < 0) { 524 if (ret < 0) {
526 printk(KERN_ERR "asoc: can't set platform %s hw params\n", 525 printk(KERN_ERR "asoc: platform %s hw params failed\n",
527 platform->name); 526 platform->name);
528 goto platform_err; 527 goto platform_err;
529 } 528 }
@@ -542,7 +541,7 @@ interface_err:
542 codec_dai->ops.hw_free(substream); 541 codec_dai->ops.hw_free(substream);
543 542
544codec_err: 543codec_err:
545 if(machine->ops && machine->ops->hw_free) 544 if (machine->ops && machine->ops->hw_free)
546 machine->ops->hw_free(substream); 545 machine->ops->hw_free(substream);
547 546
548 mutex_unlock(&pcm_mutex); 547 mutex_unlock(&pcm_mutex);
@@ -558,15 +557,15 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
558 struct snd_soc_device *socdev = rtd->socdev; 557 struct snd_soc_device *socdev = rtd->socdev;
559 struct snd_soc_dai_link *machine = rtd->dai; 558 struct snd_soc_dai_link *machine = rtd->dai;
560 struct snd_soc_platform *platform = socdev->platform; 559 struct snd_soc_platform *platform = socdev->platform;
561 struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; 560 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
562 struct snd_soc_codec_dai *codec_dai = machine->codec_dai; 561 struct snd_soc_dai *codec_dai = machine->codec_dai;
563 struct snd_soc_codec *codec = socdev->codec; 562 struct snd_soc_codec *codec = socdev->codec;
564 563
565 mutex_lock(&pcm_mutex); 564 mutex_lock(&pcm_mutex);
566 565
567 /* apply codec digital mute */ 566 /* apply codec digital mute */
568 if (!codec->active && codec_dai->dai_ops.digital_mute) 567 if (!codec->active)
569 codec_dai->dai_ops.digital_mute(codec_dai, 1); 568 snd_soc_dai_digital_mute(codec_dai, 1);
570 569
571 /* free any machine hw params */ 570 /* free any machine hw params */
572 if (machine->ops && machine->ops->hw_free) 571 if (machine->ops && machine->ops->hw_free)
@@ -593,8 +592,8 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
593 struct snd_soc_device *socdev = rtd->socdev; 592 struct snd_soc_device *socdev = rtd->socdev;
594 struct snd_soc_dai_link *machine = rtd->dai; 593 struct snd_soc_dai_link *machine = rtd->dai;
595 struct snd_soc_platform *platform = socdev->platform; 594 struct snd_soc_platform *platform = socdev->platform;
596 struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; 595 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
597 struct snd_soc_codec_dai *codec_dai = machine->codec_dai; 596 struct snd_soc_dai *codec_dai = machine->codec_dai;
598 int ret; 597 int ret;
599 598
600 if (codec_dai->ops.trigger) { 599 if (codec_dai->ops.trigger) {
@@ -631,16 +630,26 @@ static struct snd_pcm_ops soc_pcm_ops = {
631/* powers down audio subsystem for suspend */ 630/* powers down audio subsystem for suspend */
632static int soc_suspend(struct platform_device *pdev, pm_message_t state) 631static int soc_suspend(struct platform_device *pdev, pm_message_t state)
633{ 632{
634 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 633 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
635 struct snd_soc_machine *machine = socdev->machine; 634 struct snd_soc_machine *machine = socdev->machine;
636 struct snd_soc_platform *platform = socdev->platform; 635 struct snd_soc_platform *platform = socdev->platform;
637 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 636 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
638 struct snd_soc_codec *codec = socdev->codec; 637 struct snd_soc_codec *codec = socdev->codec;
639 int i; 638 int i;
640 639
640 /* Due to the resume being scheduled into a workqueue we could
641 * suspend before that's finished - wait for it to complete.
642 */
643 snd_power_lock(codec->card);
644 snd_power_wait(codec->card, SNDRV_CTL_POWER_D0);
645 snd_power_unlock(codec->card);
646
647 /* we're going to block userspace touching us until resume completes */
648 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D3hot);
649
641 /* mute any active DAC's */ 650 /* mute any active DAC's */
642 for(i = 0; i < machine->num_links; i++) { 651 for (i = 0; i < machine->num_links; i++) {
643 struct snd_soc_codec_dai *dai = machine->dai_link[i].codec_dai; 652 struct snd_soc_dai *dai = machine->dai_link[i].codec_dai;
644 if (dai->dai_ops.digital_mute && dai->playback.active) 653 if (dai->dai_ops.digital_mute && dai->playback.active)
645 dai->dai_ops.digital_mute(dai, 1); 654 dai->dai_ops.digital_mute(dai, 1);
646 } 655 }
@@ -652,8 +661,8 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
652 if (machine->suspend_pre) 661 if (machine->suspend_pre)
653 machine->suspend_pre(pdev, state); 662 machine->suspend_pre(pdev, state);
654 663
655 for(i = 0; i < machine->num_links; i++) { 664 for (i = 0; i < machine->num_links; i++) {
656 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; 665 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai;
657 if (cpu_dai->suspend && cpu_dai->type != SND_SOC_DAI_AC97) 666 if (cpu_dai->suspend && cpu_dai->type != SND_SOC_DAI_AC97)
658 cpu_dai->suspend(pdev, cpu_dai); 667 cpu_dai->suspend(pdev, cpu_dai);
659 if (platform->suspend) 668 if (platform->suspend)
@@ -662,9 +671,9 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
662 671
663 /* close any waiting streams and save state */ 672 /* close any waiting streams and save state */
664 run_delayed_work(&socdev->delayed_work); 673 run_delayed_work(&socdev->delayed_work);
665 codec->suspend_dapm_state = codec->dapm_state; 674 codec->suspend_bias_level = codec->bias_level;
666 675
667 for(i = 0; i < codec->num_dai; i++) { 676 for (i = 0; i < codec->num_dai; i++) {
668 char *stream = codec->dai[i].playback.stream_name; 677 char *stream = codec->dai[i].playback.stream_name;
669 if (stream != NULL) 678 if (stream != NULL)
670 snd_soc_dapm_stream_event(codec, stream, 679 snd_soc_dapm_stream_event(codec, stream,
@@ -678,8 +687,8 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
678 if (codec_dev->suspend) 687 if (codec_dev->suspend)
679 codec_dev->suspend(pdev, state); 688 codec_dev->suspend(pdev, state);
680 689
681 for(i = 0; i < machine->num_links; i++) { 690 for (i = 0; i < machine->num_links; i++) {
682 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; 691 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai;
683 if (cpu_dai->suspend && cpu_dai->type == SND_SOC_DAI_AC97) 692 if (cpu_dai->suspend && cpu_dai->type == SND_SOC_DAI_AC97)
684 cpu_dai->suspend(pdev, cpu_dai); 693 cpu_dai->suspend(pdev, cpu_dai);
685 } 694 }
@@ -690,21 +699,32 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
690 return 0; 699 return 0;
691} 700}
692 701
693/* powers up audio subsystem after a suspend */ 702/* deferred resume work, so resume can complete before we finished
694static int soc_resume(struct platform_device *pdev) 703 * setting our codec back up, which can be very slow on I2C
704 */
705static void soc_resume_deferred(struct work_struct *work)
695{ 706{
696 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 707 struct snd_soc_device *socdev = container_of(work,
697 struct snd_soc_machine *machine = socdev->machine; 708 struct snd_soc_device,
698 struct snd_soc_platform *platform = socdev->platform; 709 deferred_resume_work);
699 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 710 struct snd_soc_machine *machine = socdev->machine;
711 struct snd_soc_platform *platform = socdev->platform;
712 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
700 struct snd_soc_codec *codec = socdev->codec; 713 struct snd_soc_codec *codec = socdev->codec;
714 struct platform_device *pdev = to_platform_device(socdev->dev);
701 int i; 715 int i;
702 716
717 /* our power state is still SNDRV_CTL_POWER_D3hot from suspend time,
718 * so userspace apps are blocked from touching us
719 */
720
721 dev_info(socdev->dev, "starting resume work\n");
722
703 if (machine->resume_pre) 723 if (machine->resume_pre)
704 machine->resume_pre(pdev); 724 machine->resume_pre(pdev);
705 725
706 for(i = 0; i < machine->num_links; i++) { 726 for (i = 0; i < machine->num_links; i++) {
707 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; 727 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai;
708 if (cpu_dai->resume && cpu_dai->type == SND_SOC_DAI_AC97) 728 if (cpu_dai->resume && cpu_dai->type == SND_SOC_DAI_AC97)
709 cpu_dai->resume(pdev, cpu_dai); 729 cpu_dai->resume(pdev, cpu_dai);
710 } 730 }
@@ -712,8 +732,8 @@ static int soc_resume(struct platform_device *pdev)
712 if (codec_dev->resume) 732 if (codec_dev->resume)
713 codec_dev->resume(pdev); 733 codec_dev->resume(pdev);
714 734
715 for(i = 0; i < codec->num_dai; i++) { 735 for (i = 0; i < codec->num_dai; i++) {
716 char* stream = codec->dai[i].playback.stream_name; 736 char *stream = codec->dai[i].playback.stream_name;
717 if (stream != NULL) 737 if (stream != NULL)
718 snd_soc_dapm_stream_event(codec, stream, 738 snd_soc_dapm_stream_event(codec, stream,
719 SND_SOC_DAPM_STREAM_RESUME); 739 SND_SOC_DAPM_STREAM_RESUME);
@@ -723,15 +743,15 @@ static int soc_resume(struct platform_device *pdev)
723 SND_SOC_DAPM_STREAM_RESUME); 743 SND_SOC_DAPM_STREAM_RESUME);
724 } 744 }
725 745
726 /* unmute any active DAC's */ 746 /* unmute any active DACs */
727 for(i = 0; i < machine->num_links; i++) { 747 for (i = 0; i < machine->num_links; i++) {
728 struct snd_soc_codec_dai *dai = machine->dai_link[i].codec_dai; 748 struct snd_soc_dai *dai = machine->dai_link[i].codec_dai;
729 if (dai->dai_ops.digital_mute && dai->playback.active) 749 if (dai->dai_ops.digital_mute && dai->playback.active)
730 dai->dai_ops.digital_mute(dai, 0); 750 dai->dai_ops.digital_mute(dai, 0);
731 } 751 }
732 752
733 for(i = 0; i < machine->num_links; i++) { 753 for (i = 0; i < machine->num_links; i++) {
734 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; 754 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai;
735 if (cpu_dai->resume && cpu_dai->type != SND_SOC_DAI_AC97) 755 if (cpu_dai->resume && cpu_dai->type != SND_SOC_DAI_AC97)
736 cpu_dai->resume(pdev, cpu_dai); 756 cpu_dai->resume(pdev, cpu_dai);
737 if (platform->resume) 757 if (platform->resume)
@@ -741,6 +761,22 @@ static int soc_resume(struct platform_device *pdev)
741 if (machine->resume_post) 761 if (machine->resume_post)
742 machine->resume_post(pdev); 762 machine->resume_post(pdev);
743 763
764 dev_info(socdev->dev, "resume work completed\n");
765
766 /* userspace can access us now we are back as we were before */
767 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D0);
768}
769
770/* powers up audio subsystem after a suspend */
771static int soc_resume(struct platform_device *pdev)
772{
773 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
774
775 dev_info(socdev->dev, "scheduling resume work\n");
776
777 if (!schedule_work(&socdev->deferred_resume_work))
778 dev_err(socdev->dev, "work item may be lost\n");
779
744 return 0; 780 return 0;
745} 781}
746 782
@@ -760,33 +796,38 @@ static int soc_probe(struct platform_device *pdev)
760 796
761 if (machine->probe) { 797 if (machine->probe) {
762 ret = machine->probe(pdev); 798 ret = machine->probe(pdev);
763 if(ret < 0) 799 if (ret < 0)
764 return ret; 800 return ret;
765 } 801 }
766 802
767 for (i = 0; i < machine->num_links; i++) { 803 for (i = 0; i < machine->num_links; i++) {
768 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; 804 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai;
769 if (cpu_dai->probe) { 805 if (cpu_dai->probe) {
770 ret = cpu_dai->probe(pdev); 806 ret = cpu_dai->probe(pdev, cpu_dai);
771 if(ret < 0) 807 if (ret < 0)
772 goto cpu_dai_err; 808 goto cpu_dai_err;
773 } 809 }
774 } 810 }
775 811
776 if (codec_dev->probe) { 812 if (codec_dev->probe) {
777 ret = codec_dev->probe(pdev); 813 ret = codec_dev->probe(pdev);
778 if(ret < 0) 814 if (ret < 0)
779 goto cpu_dai_err; 815 goto cpu_dai_err;
780 } 816 }
781 817
782 if (platform->probe) { 818 if (platform->probe) {
783 ret = platform->probe(pdev); 819 ret = platform->probe(pdev);
784 if(ret < 0) 820 if (ret < 0)
785 goto platform_err; 821 goto platform_err;
786 } 822 }
787 823
788 /* DAPM stream work */ 824 /* DAPM stream work */
789 INIT_DELAYED_WORK(&socdev->delayed_work, close_delayed_work); 825 INIT_DELAYED_WORK(&socdev->delayed_work, close_delayed_work);
826#ifdef CONFIG_PM
827 /* deferred resume work */
828 INIT_WORK(&socdev->deferred_resume_work, soc_resume_deferred);
829#endif
830
790 return 0; 831 return 0;
791 832
792platform_err: 833platform_err:
@@ -795,9 +836,9 @@ platform_err:
795 836
796cpu_dai_err: 837cpu_dai_err:
797 for (i--; i >= 0; i--) { 838 for (i--; i >= 0; i--) {
798 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; 839 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai;
799 if (cpu_dai->remove) 840 if (cpu_dai->remove)
800 cpu_dai->remove(pdev); 841 cpu_dai->remove(pdev, cpu_dai);
801 } 842 }
802 843
803 if (machine->remove) 844 if (machine->remove)
@@ -824,9 +865,9 @@ static int soc_remove(struct platform_device *pdev)
824 codec_dev->remove(pdev); 865 codec_dev->remove(pdev);
825 866
826 for (i = 0; i < machine->num_links; i++) { 867 for (i = 0; i < machine->num_links; i++) {
827 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; 868 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai;
828 if (cpu_dai->remove) 869 if (cpu_dai->remove)
829 cpu_dai->remove(pdev); 870 cpu_dai->remove(pdev, cpu_dai);
830 } 871 }
831 872
832 if (machine->remove) 873 if (machine->remove)
@@ -852,8 +893,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
852 struct snd_soc_dai_link *dai_link, int num) 893 struct snd_soc_dai_link *dai_link, int num)
853{ 894{
854 struct snd_soc_codec *codec = socdev->codec; 895 struct snd_soc_codec *codec = socdev->codec;
855 struct snd_soc_codec_dai *codec_dai = dai_link->codec_dai; 896 struct snd_soc_dai *codec_dai = dai_link->codec_dai;
856 struct snd_soc_cpu_dai *cpu_dai = dai_link->cpu_dai; 897 struct snd_soc_dai *cpu_dai = dai_link->cpu_dai;
857 struct snd_soc_pcm_runtime *rtd; 898 struct snd_soc_pcm_runtime *rtd;
858 struct snd_pcm *pcm; 899 struct snd_pcm *pcm;
859 char new_name[64]; 900 char new_name[64];
@@ -868,7 +909,7 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
868 codec_dai->codec = socdev->codec; 909 codec_dai->codec = socdev->codec;
869 910
870 /* check client and interface hw capabilities */ 911 /* check client and interface hw capabilities */
871 sprintf(new_name, "%s %s-%s-%d",dai_link->stream_name, codec_dai->name, 912 sprintf(new_name, "%s %s-%s-%d", dai_link->stream_name, codec_dai->name,
872 get_dai_name(cpu_dai->type), num); 913 get_dai_name(cpu_dai->type), num);
873 914
874 if (codec_dai->playback.channels_min) 915 if (codec_dai->playback.channels_min)
@@ -879,7 +920,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
879 ret = snd_pcm_new(codec->card, new_name, codec->pcm_devs++, playback, 920 ret = snd_pcm_new(codec->card, new_name, codec->pcm_devs++, playback,
880 capture, &pcm); 921 capture, &pcm);
881 if (ret < 0) { 922 if (ret < 0) {
882 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name); 923 printk(KERN_ERR "asoc: can't create pcm for codec %s\n",
924 codec->name);
883 kfree(rtd); 925 kfree(rtd);
884 return ret; 926 return ret;
885 } 927 }
@@ -928,8 +970,9 @@ static ssize_t codec_reg_show(struct device *dev,
928 step = codec->reg_cache_step; 970 step = codec->reg_cache_step;
929 971
930 count += sprintf(buf, "%s registers\n", codec->name); 972 count += sprintf(buf, "%s registers\n", codec->name);
931 for(i = 0; i < codec->reg_cache_size; i += step) 973 for (i = 0; i < codec->reg_cache_size; i += step)
932 count += sprintf(buf + count, "%2x: %4x\n", i, codec->read(codec, i)); 974 count += sprintf(buf + count, "%2x: %4x\n", i,
975 codec->read(codec, i));
933 976
934 return count; 977 return count;
935} 978}
@@ -1072,7 +1115,7 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
1072 strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver)); 1115 strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver));
1073 1116
1074 /* create the pcms */ 1117 /* create the pcms */
1075 for(i = 0; i < machine->num_links; i++) { 1118 for (i = 0; i < machine->num_links; i++) {
1076 ret = soc_new_pcm(socdev, &machine->dai_link[i], i); 1119 ret = soc_new_pcm(socdev, &machine->dai_link[i], i);
1077 if (ret < 0) { 1120 if (ret < 0) {
1078 printk(KERN_ERR "asoc: can't create pcm %s\n", 1121 printk(KERN_ERR "asoc: can't create pcm %s\n",
@@ -1102,7 +1145,7 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
1102 struct snd_soc_machine *machine = socdev->machine; 1145 struct snd_soc_machine *machine = socdev->machine;
1103 int ret = 0, i, ac97 = 0, err = 0; 1146 int ret = 0, i, ac97 = 0, err = 0;
1104 1147
1105 for(i = 0; i < machine->num_links; i++) { 1148 for (i = 0; i < machine->num_links; i++) {
1106 if (socdev->machine->dai_link[i].init) { 1149 if (socdev->machine->dai_link[i].init) {
1107 err = socdev->machine->dai_link[i].init(codec); 1150 err = socdev->machine->dai_link[i].init(codec);
1108 if (err < 0) { 1151 if (err < 0) {
@@ -1111,7 +1154,7 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
1111 continue; 1154 continue;
1112 } 1155 }
1113 } 1156 }
1114 if (socdev->machine->dai_link[i].codec_dai->type == 1157 if (socdev->machine->dai_link[i].codec_dai->type ==
1115 SND_SOC_DAI_AC97_BUS) 1158 SND_SOC_DAI_AC97_BUS)
1116 ac97 = 1; 1159 ac97 = 1;
1117 } 1160 }
@@ -1122,7 +1165,7 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
1122 1165
1123 ret = snd_card_register(codec->card); 1166 ret = snd_card_register(codec->card);
1124 if (ret < 0) { 1167 if (ret < 0) {
1125 printk(KERN_ERR "asoc: failed to register soundcard for codec %s\n", 1168 printk(KERN_ERR "asoc: failed to register soundcard for %s\n",
1126 codec->name); 1169 codec->name);
1127 goto out; 1170 goto out;
1128 } 1171 }
@@ -1146,7 +1189,7 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
1146 1189
1147 err = device_create_file(socdev->dev, &dev_attr_codec_reg); 1190 err = device_create_file(socdev->dev, &dev_attr_codec_reg);
1148 if (err < 0) 1191 if (err < 0)
1149 printk(KERN_WARNING "asoc: failed to add codec sysfs entries\n"); 1192 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
1150 1193
1151 mutex_unlock(&codec->mutex); 1194 mutex_unlock(&codec->mutex);
1152 1195
@@ -1166,13 +1209,13 @@ void snd_soc_free_pcms(struct snd_soc_device *socdev)
1166{ 1209{
1167 struct snd_soc_codec *codec = socdev->codec; 1210 struct snd_soc_codec *codec = socdev->codec;
1168#ifdef CONFIG_SND_SOC_AC97_BUS 1211#ifdef CONFIG_SND_SOC_AC97_BUS
1169 struct snd_soc_codec_dai *codec_dai; 1212 struct snd_soc_dai *codec_dai;
1170 int i; 1213 int i;
1171#endif 1214#endif
1172 1215
1173 mutex_lock(&codec->mutex); 1216 mutex_lock(&codec->mutex);
1174#ifdef CONFIG_SND_SOC_AC97_BUS 1217#ifdef CONFIG_SND_SOC_AC97_BUS
1175 for(i = 0; i < codec->num_dai; i++) { 1218 for (i = 0; i < codec->num_dai; i++) {
1176 codec_dai = &codec->dai[i]; 1219 codec_dai = &codec->dai[i];
1177 if (codec_dai->type == SND_SOC_DAI_AC97_BUS && codec->ac97) { 1220 if (codec_dai->type == SND_SOC_DAI_AC97_BUS && codec->ac97) {
1178 soc_ac97_dev_unregister(codec); 1221 soc_ac97_dev_unregister(codec);
@@ -1282,7 +1325,8 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
1282 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) 1325 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1)
1283 ; 1326 ;
1284 val = snd_soc_read(codec, e->reg); 1327 val = snd_soc_read(codec, e->reg);
1285 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1); 1328 ucontrol->value.enumerated.item[0]
1329 = (val >> e->shift_l) & (bitmask - 1);
1286 if (e->shift_l != e->shift_r) 1330 if (e->shift_l != e->shift_r)
1287 ucontrol->value.enumerated.item[1] = 1331 ucontrol->value.enumerated.item[1] =
1288 (val >> e->shift_r) & (bitmask - 1); 1332 (val >> e->shift_r) & (bitmask - 1);
@@ -1576,7 +1620,8 @@ int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
1576 val = val << shift; 1620 val = val << shift;
1577 val2 = val2 << shift; 1621 val2 = val2 << shift;
1578 1622
1579 if ((err = snd_soc_update_bits(codec, reg, val_mask, val)) < 0) 1623 err = snd_soc_update_bits(codec, reg, val_mask, val);
1624 if (err < 0)
1580 return err; 1625 return err;
1581 1626
1582 err = snd_soc_update_bits(codec, reg2, val_mask, val2); 1627 err = snd_soc_update_bits(codec, reg2, val_mask, val2);
@@ -1584,6 +1629,204 @@ int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
1584} 1629}
1585EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r); 1630EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r);
1586 1631
1632/**
1633 * snd_soc_info_volsw_s8 - signed mixer info callback
1634 * @kcontrol: mixer control
1635 * @uinfo: control element information
1636 *
1637 * Callback to provide information about a signed mixer control.
1638 *
1639 * Returns 0 for success.
1640 */
1641int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
1642 struct snd_ctl_elem_info *uinfo)
1643{
1644 int max = (signed char)((kcontrol->private_value >> 16) & 0xff);
1645 int min = (signed char)((kcontrol->private_value >> 24) & 0xff);
1646
1647 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1648 uinfo->count = 2;
1649 uinfo->value.integer.min = 0;
1650 uinfo->value.integer.max = max-min;
1651 return 0;
1652}
1653EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8);
1654
1655/**
1656 * snd_soc_get_volsw_s8 - signed mixer get callback
1657 * @kcontrol: mixer control
1658 * @uinfo: control element information
1659 *
1660 * Callback to get the value of a signed mixer control.
1661 *
1662 * Returns 0 for success.
1663 */
1664int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
1665 struct snd_ctl_elem_value *ucontrol)
1666{
1667 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1668 int reg = kcontrol->private_value & 0xff;
1669 int min = (signed char)((kcontrol->private_value >> 24) & 0xff);
1670 int val = snd_soc_read(codec, reg);
1671
1672 ucontrol->value.integer.value[0] =
1673 ((signed char)(val & 0xff))-min;
1674 ucontrol->value.integer.value[1] =
1675 ((signed char)((val >> 8) & 0xff))-min;
1676 return 0;
1677}
1678EXPORT_SYMBOL_GPL(snd_soc_get_volsw_s8);
1679
1680/**
1681 * snd_soc_put_volsw_sgn - signed mixer put callback
1682 * @kcontrol: mixer control
1683 * @uinfo: control element information
1684 *
1685 * Callback to set the value of a signed mixer control.
1686 *
1687 * Returns 0 for success.
1688 */
1689int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
1690 struct snd_ctl_elem_value *ucontrol)
1691{
1692 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1693 int reg = kcontrol->private_value & 0xff;
1694 int min = (signed char)((kcontrol->private_value >> 24) & 0xff);
1695 unsigned short val;
1696
1697 val = (ucontrol->value.integer.value[0]+min) & 0xff;
1698 val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8;
1699
1700 return snd_soc_update_bits(codec, reg, 0xffff, val);
1701}
1702EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
1703
1704/**
1705 * snd_soc_dai_set_sysclk - configure DAI system or master clock.
1706 * @dai: DAI
1707 * @clk_id: DAI specific clock ID
1708 * @freq: new clock frequency in Hz
1709 * @dir: new clock direction - input/output.
1710 *
1711 * Configures the DAI master (MCLK) or system (SYSCLK) clocking.
1712 */
1713int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1714 unsigned int freq, int dir)
1715{
1716 if (dai->dai_ops.set_sysclk)
1717 return dai->dai_ops.set_sysclk(dai, clk_id, freq, dir);
1718 else
1719 return -EINVAL;
1720}
1721EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
1722
1723/**
1724 * snd_soc_dai_set_clkdiv - configure DAI clock dividers.
1725 * @dai: DAI
1726 * @clk_id: DAI specific clock divider ID
1727 * @div: new clock divisor.
1728 *
1729 * Configures the clock dividers. This is used to derive the best DAI bit and
1730 * frame clocks from the system or master clock. It's best to set the DAI bit
1731 * and frame clocks as low as possible to save system power.
1732 */
1733int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
1734 int div_id, int div)
1735{
1736 if (dai->dai_ops.set_clkdiv)
1737 return dai->dai_ops.set_clkdiv(dai, div_id, div);
1738 else
1739 return -EINVAL;
1740}
1741EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
1742
1743/**
1744 * snd_soc_dai_set_pll - configure DAI PLL.
1745 * @dai: DAI
1746 * @pll_id: DAI specific PLL ID
1747 * @freq_in: PLL input clock frequency in Hz
1748 * @freq_out: requested PLL output clock frequency in Hz
1749 *
1750 * Configures and enables PLL to generate output clock based on input clock.
1751 */
1752int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
1753 int pll_id, unsigned int freq_in, unsigned int freq_out)
1754{
1755 if (dai->dai_ops.set_pll)
1756 return dai->dai_ops.set_pll(dai, pll_id, freq_in, freq_out);
1757 else
1758 return -EINVAL;
1759}
1760EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
1761
1762/**
1763 * snd_soc_dai_set_fmt - configure DAI hardware audio format.
1764 * @dai: DAI
1765 * @clk_id: DAI specific clock ID
1766 * @fmt: SND_SOC_DAIFMT_ format value.
1767 *
1768 * Configures the DAI hardware format and clocking.
1769 */
1770int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1771{
1772 if (dai->dai_ops.set_fmt)
1773 return dai->dai_ops.set_fmt(dai, fmt);
1774 else
1775 return -EINVAL;
1776}
1777EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
1778
1779/**
1780 * snd_soc_dai_set_tdm_slot - configure DAI TDM.
1781 * @dai: DAI
1782 * @mask: DAI specific mask representing used slots.
1783 * @slots: Number of slots in use.
1784 *
1785 * Configures a DAI for TDM operation. Both mask and slots are codec and DAI
1786 * specific.
1787 */
1788int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
1789 unsigned int mask, int slots)
1790{
1791 if (dai->dai_ops.set_sysclk)
1792 return dai->dai_ops.set_tdm_slot(dai, mask, slots);
1793 else
1794 return -EINVAL;
1795}
1796EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
1797
1798/**
1799 * snd_soc_dai_set_tristate - configure DAI system or master clock.
1800 * @dai: DAI
1801 * @tristate: tristate enable
1802 *
1803 * Tristates the DAI so that others can use it.
1804 */
1805int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
1806{
1807 if (dai->dai_ops.set_sysclk)
1808 return dai->dai_ops.set_tristate(dai, tristate);
1809 else
1810 return -EINVAL;
1811}
1812EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
1813
1814/**
1815 * snd_soc_dai_digital_mute - configure DAI system or master clock.
1816 * @dai: DAI
1817 * @mute: mute enable
1818 *
1819 * Mutes the DAI DAC.
1820 */
1821int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute)
1822{
1823 if (dai->dai_ops.digital_mute)
1824 return dai->dai_ops.digital_mute(dai, mute);
1825 else
1826 return -EINVAL;
1827}
1828EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
1829
1587static int __devinit snd_soc_init(void) 1830static int __devinit snd_soc_init(void)
1588{ 1831{
1589 printk(KERN_INFO "ASoC version %s\n", SND_SOC_VERSION); 1832 printk(KERN_INFO "ASoC version %s\n", SND_SOC_VERSION);
@@ -1592,7 +1835,7 @@ static int __devinit snd_soc_init(void)
1592 1835
1593static void snd_soc_exit(void) 1836static void snd_soc_exit(void)
1594{ 1837{
1595 platform_driver_unregister(&soc_driver); 1838 platform_driver_unregister(&soc_driver);
1596} 1839}
1597 1840
1598module_init(snd_soc_init); 1841module_init(snd_soc_init);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index af3326c63504..2c87061c2a6b 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -10,11 +10,6 @@
10 * Free Software Foundation; either version 2 of the License, or (at your 10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
12 * 12 *
13 * Revision history
14 * 12th Aug 2005 Initial version.
15 * 25th Oct 2005 Implemented path power domain.
16 * 18th Dec 2005 Implemented machine and stream level power domain.
17 *
18 * Features: 13 * Features:
19 * o Changes power status of internal codec blocks depending on the 14 * o Changes power status of internal codec blocks depending on the
20 * dynamic configuration of codec internal audio paths and active 15 * dynamic configuration of codec internal audio paths and active
@@ -50,23 +45,10 @@
50#include <sound/initval.h> 45#include <sound/initval.h>
51 46
52/* debug */ 47/* debug */
53#define DAPM_DEBUG 0 48#ifdef DEBUG
54#if DAPM_DEBUG
55#define dump_dapm(codec, action) dbg_dump_dapm(codec, action) 49#define dump_dapm(codec, action) dbg_dump_dapm(codec, action)
56#define dbg(format, arg...) printk(format, ## arg)
57#else 50#else
58#define dump_dapm(codec, action) 51#define dump_dapm(codec, action)
59#define dbg(format, arg...)
60#endif
61
62#define POP_DEBUG 0
63#if POP_DEBUG
64#define POP_TIME 500 /* 500 msecs - change if pop debug is too fast */
65#define pop_wait(time) schedule_timeout_uninterruptible(msecs_to_jiffies(time))
66#define pop_dbg(format, arg...) printk(format, ## arg); pop_wait(POP_TIME)
67#else
68#define pop_dbg(format, arg...)
69#define pop_wait(time)
70#endif 52#endif
71 53
72/* dapm power sequences - make this per codec in the future */ 54/* dapm power sequences - make this per codec in the future */
@@ -85,6 +67,28 @@ static int dapm_status = 1;
85module_param(dapm_status, int, 0); 67module_param(dapm_status, int, 0);
86MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries"); 68MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries");
87 69
70static unsigned int pop_time;
71
72static void pop_wait(void)
73{
74 if (pop_time)
75 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time));
76}
77
78static void pop_dbg(const char *fmt, ...)
79{
80 va_list args;
81
82 va_start(args, fmt);
83
84 if (pop_time) {
85 vprintk(fmt, args);
86 pop_wait();
87 }
88
89 va_end(args);
90}
91
88/* create a new dapm widget */ 92/* create a new dapm widget */
89static inline struct snd_soc_dapm_widget *dapm_cnew_widget( 93static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
90 const struct snd_soc_dapm_widget *_widget) 94 const struct snd_soc_dapm_widget *_widget)
@@ -222,11 +226,12 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
222 change = old != new; 226 change = old != new;
223 if (change) { 227 if (change) {
224 pop_dbg("pop test %s : %s in %d ms\n", widget->name, 228 pop_dbg("pop test %s : %s in %d ms\n", widget->name,
225 widget->power ? "on" : "off", POP_TIME); 229 widget->power ? "on" : "off", pop_time);
226 snd_soc_write(codec, widget->reg, new); 230 snd_soc_write(codec, widget->reg, new);
227 pop_wait(POP_TIME); 231 pop_wait();
228 } 232 }
229 dbg("reg %x old %x new %x change %d\n", widget->reg, old, new, change); 233 pr_debug("reg %x old %x new %x change %d\n", widget->reg,
234 old, new, change);
230 return change; 235 return change;
231} 236}
232 237
@@ -448,6 +453,25 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
448} 453}
449 454
450/* 455/*
456 * Handler for generic register modifier widget.
457 */
458int dapm_reg_event(struct snd_soc_dapm_widget *w,
459 struct snd_kcontrol *kcontrol, int event)
460{
461 unsigned int val;
462
463 if (SND_SOC_DAPM_EVENT_ON(event))
464 val = w->on_val;
465 else
466 val = w->off_val;
467
468 snd_soc_update_bits(w->codec, -(w->reg + 1),
469 w->mask << w->shift, val << w->shift);
470
471 return 0;
472}
473
474/*
451 * Scan each dapm widget for complete audio path. 475 * Scan each dapm widget for complete audio path.
452 * A complete path is a route that has valid endpoints i.e.:- 476 * A complete path is a route that has valid endpoints i.e.:-
453 * 477 *
@@ -565,8 +589,8 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
565 /* call any power change event handlers */ 589 /* call any power change event handlers */
566 if (power_change) { 590 if (power_change) {
567 if (w->event) { 591 if (w->event) {
568 dbg("power %s event for %s flags %x\n", 592 pr_debug("power %s event for %s flags %x\n",
569 w->power ? "on" : "off", w->name, w->event_flags); 593 w->power ? "on" : "off", w->name, w->event_flags);
570 if (power) { 594 if (power) {
571 /* power up event */ 595 /* power up event */
572 if (w->event_flags & SND_SOC_DAPM_PRE_PMU) { 596 if (w->event_flags & SND_SOC_DAPM_PRE_PMU) {
@@ -608,7 +632,7 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
608 return ret; 632 return ret;
609} 633}
610 634
611#if DAPM_DEBUG 635#ifdef DEBUG
612static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action) 636static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
613{ 637{
614 struct snd_soc_dapm_widget *w; 638 struct snd_soc_dapm_widget *w;
@@ -693,8 +717,10 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
693 path->connect = 0; /* old connection must be powered down */ 717 path->connect = 0; /* old connection must be powered down */
694 } 718 }
695 719
696 if (found) 720 if (found) {
697 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); 721 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
722 dump_dapm(widget->codec, "mux power update");
723 }
698 724
699 return 0; 725 return 0;
700} 726}
@@ -730,8 +756,10 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
730 break; 756 break;
731 } 757 }
732 758
733 if (found) 759 if (found) {
734 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); 760 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
761 dump_dapm(widget->codec, "mixer power update");
762 }
735 763
736 return 0; 764 return 0;
737} 765}
@@ -768,21 +796,18 @@ static ssize_t dapm_widget_show(struct device *dev,
768 } 796 }
769 } 797 }
770 798
771 switch(codec->dapm_state){ 799 switch (codec->bias_level) {
772 case SNDRV_CTL_POWER_D0: 800 case SND_SOC_BIAS_ON:
773 state = "D0"; 801 state = "On";
774 break; 802 break;
775 case SNDRV_CTL_POWER_D1: 803 case SND_SOC_BIAS_PREPARE:
776 state = "D1"; 804 state = "Prepare";
777 break; 805 break;
778 case SNDRV_CTL_POWER_D2: 806 case SND_SOC_BIAS_STANDBY:
779 state = "D2"; 807 state = "Standby";
780 break; 808 break;
781 case SNDRV_CTL_POWER_D3hot: 809 case SND_SOC_BIAS_OFF:
782 state = "D3hot"; 810 state = "Off";
783 break;
784 case SNDRV_CTL_POWER_D3cold:
785 state = "D3cold";
786 break; 811 break;
787 } 812 }
788 count += sprintf(buf + count, "PM State: %s\n", state); 813 count += sprintf(buf + count, "PM State: %s\n", state);
@@ -792,20 +817,51 @@ static ssize_t dapm_widget_show(struct device *dev,
792 817
793static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL); 818static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL);
794 819
820/* pop/click delay times */
821static ssize_t dapm_pop_time_show(struct device *dev,
822 struct device_attribute *attr, char *buf)
823{
824 return sprintf(buf, "%d\n", pop_time);
825}
826
827static ssize_t dapm_pop_time_store(struct device *dev,
828 struct device_attribute *attr,
829 const char *buf, size_t count)
830
831{
832 unsigned long val;
833
834 if (strict_strtoul(buf, 10, &val) >= 0)
835 pop_time = val;
836 else
837 printk(KERN_ERR "Unable to parse pop_time setting\n");
838
839 return count;
840}
841
842static DEVICE_ATTR(dapm_pop_time, 0744, dapm_pop_time_show,
843 dapm_pop_time_store);
844
795int snd_soc_dapm_sys_add(struct device *dev) 845int snd_soc_dapm_sys_add(struct device *dev)
796{ 846{
797 int ret = 0; 847 int ret = 0;
798 848
799 if (dapm_status) 849 if (dapm_status) {
800 ret = device_create_file(dev, &dev_attr_dapm_widget); 850 ret = device_create_file(dev, &dev_attr_dapm_widget);
801 851
852 if (ret == 0)
853 ret = device_create_file(dev, &dev_attr_dapm_pop_time);
854 }
855
802 return ret; 856 return ret;
803} 857}
804 858
805static void snd_soc_dapm_sys_remove(struct device *dev) 859static void snd_soc_dapm_sys_remove(struct device *dev)
806{ 860{
807 if (dapm_status) 861 if (dapm_status) {
862 device_remove_file(dev, &dev_attr_dapm_pop_time);
808 device_remove_file(dev, &dev_attr_dapm_widget); 863 device_remove_file(dev, &dev_attr_dapm_widget);
864 }
809} 865}
810 866
811/* free all dapm widgets and resources */ 867/* free all dapm widgets and resources */
@@ -826,8 +882,25 @@ static void dapm_free_widgets(struct snd_soc_codec *codec)
826 } 882 }
827} 883}
828 884
885static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec,
886 char *pin, int status)
887{
888 struct snd_soc_dapm_widget *w;
889
890 list_for_each_entry(w, &codec->dapm_widgets, list) {
891 if (!strcmp(w->name, pin)) {
892 pr_debug("dapm: %s: pin %s\n", codec->name, pin);
893 w->connected = status;
894 return 0;
895 }
896 }
897
898 pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin);
899 return -EINVAL;
900}
901
829/** 902/**
830 * snd_soc_dapm_sync_endpoints - scan and power dapm paths 903 * snd_soc_dapm_sync - scan and power dapm paths
831 * @codec: audio codec 904 * @codec: audio codec
832 * 905 *
833 * Walks all dapm audio paths and powers widgets according to their 906 * Walks all dapm audio paths and powers widgets according to their
@@ -835,27 +908,16 @@ static void dapm_free_widgets(struct snd_soc_codec *codec)
835 * 908 *
836 * Returns 0 for success. 909 * Returns 0 for success.
837 */ 910 */
838int snd_soc_dapm_sync_endpoints(struct snd_soc_codec *codec) 911int snd_soc_dapm_sync(struct snd_soc_codec *codec)
839{ 912{
840 return dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); 913 int ret = dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP);
914 dump_dapm(codec, "sync");
915 return ret;
841} 916}
842EXPORT_SYMBOL_GPL(snd_soc_dapm_sync_endpoints); 917EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
843 918
844/** 919static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
845 * snd_soc_dapm_connect_input - connect dapm widgets 920 const char *sink, const char *control, const char *source)
846 * @codec: audio codec
847 * @sink: name of target widget
848 * @control: mixer control name
849 * @source: name of source name
850 *
851 * Connects 2 dapm widgets together via a named audio path. The sink is
852 * the widget receiving the audio signal, whilst the source is the sender
853 * of the audio signal.
854 *
855 * Returns 0 for success else error.
856 */
857int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink,
858 const char * control, const char *source)
859{ 921{
860 struct snd_soc_dapm_path *path; 922 struct snd_soc_dapm_path *path;
861 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; 923 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
@@ -957,9 +1019,64 @@ err:
957 kfree(path); 1019 kfree(path);
958 return ret; 1020 return ret;
959} 1021}
1022
1023/**
1024 * snd_soc_dapm_connect_input - connect dapm widgets
1025 * @codec: audio codec
1026 * @sink: name of target widget
1027 * @control: mixer control name
1028 * @source: name of source name
1029 *
1030 * Connects 2 dapm widgets together via a named audio path. The sink is
1031 * the widget receiving the audio signal, whilst the source is the sender
1032 * of the audio signal.
1033 *
1034 * This function has been deprecated in favour of snd_soc_dapm_add_routes().
1035 *
1036 * Returns 0 for success else error.
1037 */
1038int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink,
1039 const char *control, const char *source)
1040{
1041 return snd_soc_dapm_add_route(codec, sink, control, source);
1042}
960EXPORT_SYMBOL_GPL(snd_soc_dapm_connect_input); 1043EXPORT_SYMBOL_GPL(snd_soc_dapm_connect_input);
961 1044
962/** 1045/**
1046 * snd_soc_dapm_add_routes - Add routes between DAPM widgets
1047 * @codec: codec
1048 * @route: audio routes
1049 * @num: number of routes
1050 *
1051 * Connects 2 dapm widgets together via a named audio path. The sink is
1052 * the widget receiving the audio signal, whilst the source is the sender
1053 * of the audio signal.
1054 *
1055 * Returns 0 for success else error. On error all resources can be freed
1056 * with a call to snd_soc_card_free().
1057 */
1058int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
1059 const struct snd_soc_dapm_route *route, int num)
1060{
1061 int i, ret;
1062
1063 for (i = 0; i < num; i++) {
1064 ret = snd_soc_dapm_add_route(codec, route->sink,
1065 route->control, route->source);
1066 if (ret < 0) {
1067 printk(KERN_ERR "Failed to add route %s->%s\n",
1068 route->source,
1069 route->sink);
1070 return ret;
1071 }
1072 route++;
1073 }
1074
1075 return 0;
1076}
1077EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
1078
1079/**
963 * snd_soc_dapm_new_widgets - add new dapm widgets 1080 * snd_soc_dapm_new_widgets - add new dapm widgets
964 * @codec: audio codec 1081 * @codec: audio codec
965 * 1082 *
@@ -1234,6 +1351,33 @@ int snd_soc_dapm_new_control(struct snd_soc_codec *codec,
1234EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control); 1351EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control);
1235 1352
1236/** 1353/**
1354 * snd_soc_dapm_new_controls - create new dapm controls
1355 * @codec: audio codec
1356 * @widget: widget array
1357 * @num: number of widgets
1358 *
1359 * Creates new DAPM controls based upon the templates.
1360 *
1361 * Returns 0 for success else error.
1362 */
1363int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
1364 const struct snd_soc_dapm_widget *widget,
1365 int num)
1366{
1367 int i, ret;
1368
1369 for (i = 0; i < num; i++) {
1370 ret = snd_soc_dapm_new_control(codec, widget);
1371 if (ret < 0)
1372 return ret;
1373 widget++;
1374 }
1375 return 0;
1376}
1377EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
1378
1379
1380/**
1237 * snd_soc_dapm_stream_event - send a stream event to the dapm core 1381 * snd_soc_dapm_stream_event - send a stream event to the dapm core
1238 * @codec: audio codec 1382 * @codec: audio codec
1239 * @stream: stream name 1383 * @stream: stream name
@@ -1257,8 +1401,8 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
1257 { 1401 {
1258 if (!w->sname) 1402 if (!w->sname)
1259 continue; 1403 continue;
1260 dbg("widget %s\n %s stream %s event %d\n", w->name, w->sname, 1404 pr_debug("widget %s\n %s stream %s event %d\n",
1261 stream, event); 1405 w->name, w->sname, stream, event);
1262 if (strstr(w->sname, stream)) { 1406 if (strstr(w->sname, stream)) {
1263 switch(event) { 1407 switch(event) {
1264 case SND_SOC_DAPM_STREAM_START: 1408 case SND_SOC_DAPM_STREAM_START:
@@ -1294,53 +1438,81 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
1294EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); 1438EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
1295 1439
1296/** 1440/**
1297 * snd_soc_dapm_device_event - send a device event to the dapm core 1441 * snd_soc_dapm_set_bias_level - set the bias level for the system
1298 * @socdev: audio device 1442 * @socdev: audio device
1299 * @event: device event 1443 * @level: level to configure
1300 * 1444 *
1301 * Sends a device event to the dapm core. The core then makes any 1445 * Configure the bias (power) levels for the SoC audio device.
1302 * necessary machine or codec power changes..
1303 * 1446 *
1304 * Returns 0 for success else error. 1447 * Returns 0 for success else error.
1305 */ 1448 */
1306int snd_soc_dapm_device_event(struct snd_soc_device *socdev, int event) 1449int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
1450 enum snd_soc_bias_level level)
1307{ 1451{
1308 struct snd_soc_codec *codec = socdev->codec; 1452 struct snd_soc_codec *codec = socdev->codec;
1309 struct snd_soc_machine *machine = socdev->machine; 1453 struct snd_soc_machine *machine = socdev->machine;
1454 int ret = 0;
1310 1455
1311 if (machine->dapm_event) 1456 if (machine->set_bias_level)
1312 machine->dapm_event(machine, event); 1457 ret = machine->set_bias_level(machine, level);
1313 if (codec->dapm_event) 1458 if (ret == 0 && codec->set_bias_level)
1314 codec->dapm_event(codec, event); 1459 ret = codec->set_bias_level(codec, level);
1315 return 0; 1460
1461 return ret;
1316} 1462}
1317EXPORT_SYMBOL_GPL(snd_soc_dapm_device_event);
1318 1463
1319/** 1464/**
1320 * snd_soc_dapm_set_endpoint - set audio endpoint status 1465 * snd_soc_dapm_enable_pin - enable pin.
1466 * @snd_soc_codec: SoC codec
1467 * @pin: pin name
1468 *
1469 * Enables input/output pin and it's parents or children widgets iff there is
1470 * a valid audio route and active audio stream.
1471 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
1472 * do any widget power switching.
1473 */
1474int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, char *pin)
1475{
1476 return snd_soc_dapm_set_pin(codec, pin, 1);
1477}
1478EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
1479
1480/**
1481 * snd_soc_dapm_disable_pin - disable pin.
1482 * @codec: SoC codec
1483 * @pin: pin name
1484 *
1485 * Disables input/output pin and it's parents or children widgets.
1486 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
1487 * do any widget power switching.
1488 */
1489int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, char *pin)
1490{
1491 return snd_soc_dapm_set_pin(codec, pin, 0);
1492}
1493EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
1494
1495/**
1496 * snd_soc_dapm_get_pin_status - get audio pin status
1321 * @codec: audio codec 1497 * @codec: audio codec
1322 * @endpoint: audio signal endpoint (or start point) 1498 * @pin: audio signal pin endpoint (or start point)
1323 * @status: point status
1324 * 1499 *
1325 * Set audio endpoint status - connected or disconnected. 1500 * Get audio pin status - connected or disconnected.
1326 * 1501 *
1327 * Returns 0 for success else error. 1502 * Returns 1 for connected otherwise 0.
1328 */ 1503 */
1329int snd_soc_dapm_set_endpoint(struct snd_soc_codec *codec, 1504int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, char *pin)
1330 char *endpoint, int status)
1331{ 1505{
1332 struct snd_soc_dapm_widget *w; 1506 struct snd_soc_dapm_widget *w;
1333 1507
1334 list_for_each_entry(w, &codec->dapm_widgets, list) { 1508 list_for_each_entry(w, &codec->dapm_widgets, list) {
1335 if (!strcmp(w->name, endpoint)) { 1509 if (!strcmp(w->name, pin))
1336 w->connected = status; 1510 return w->connected;
1337 return 0;
1338 }
1339 } 1511 }
1340 1512
1341 return -ENODEV; 1513 return 0;
1342} 1514}
1343EXPORT_SYMBOL_GPL(snd_soc_dapm_set_endpoint); 1515EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
1344 1516
1345/** 1517/**
1346 * snd_soc_dapm_free - free dapm resources 1518 * snd_soc_dapm_free - free dapm resources
diff --git a/sound/sparc/Kconfig b/sound/sparc/Kconfig
index 079e22af074c..d75deba5617d 100644
--- a/sound/sparc/Kconfig
+++ b/sound/sparc/Kconfig
@@ -1,11 +1,17 @@
1# ALSA Sparc drivers 1# ALSA Sparc drivers
2 2
3menu "ALSA Sparc devices" 3menuconfig SND_SPARC
4 depends on SND!=n && SPARC 4 bool "Sparc sound devices"
5 depends on SPARC
6 default y
7 help
8 Support for sound devices specific to Sun SPARC architectures.
9
10if SND_SPARC
5 11
6config SND_SUN_AMD7930 12config SND_SUN_AMD7930
7 tristate "Sun AMD7930" 13 tristate "Sun AMD7930"
8 depends on SBUS && SND 14 depends on SBUS
9 select SND_PCM 15 select SND_PCM
10 help 16 help
11 Say Y here to include support for AMD7930 sound device on Sun. 17 Say Y here to include support for AMD7930 sound device on Sun.
@@ -15,7 +21,6 @@ config SND_SUN_AMD7930
15 21
16config SND_SUN_CS4231 22config SND_SUN_CS4231
17 tristate "Sun CS4231" 23 tristate "Sun CS4231"
18 depends on SND
19 select SND_PCM 24 select SND_PCM
20 help 25 help
21 Say Y here to include support for CS4231 sound device on Sun. 26 Say Y here to include support for CS4231 sound device on Sun.
@@ -25,7 +30,7 @@ config SND_SUN_CS4231
25 30
26config SND_SUN_DBRI 31config SND_SUN_DBRI
27 tristate "Sun DBRI" 32 tristate "Sun DBRI"
28 depends on SND && SBUS 33 depends on SBUS
29 select SND_PCM 34 select SND_PCM
30 help 35 help
31 Say Y here to include support for DBRI sound device on Sun. 36 Say Y here to include support for DBRI sound device on Sun.
@@ -33,4 +38,4 @@ config SND_SUN_DBRI
33 To compile this driver as a module, choose M here: the module 38 To compile this driver as a module, choose M here: the module
34 will be called snd-sun-dbri. 39 will be called snd-sun-dbri.
35 40
36endmenu 41endif # SND_SPARC
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 3d00e0797b11..ee2e1b4f3551 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -2490,7 +2490,7 @@ static void dbri_debug_read(struct snd_info_entry *entry,
2490} 2490}
2491#endif 2491#endif
2492 2492
2493void __devinit snd_dbri_proc(struct snd_card *card) 2493static void __devinit snd_dbri_proc(struct snd_card *card)
2494{ 2494{
2495 struct snd_dbri *dbri = card->private_data; 2495 struct snd_dbri *dbri = card->private_data;
2496 struct snd_info_entry *entry; 2496 struct snd_info_entry *entry;
diff --git a/sound/spi/Kconfig b/sound/spi/Kconfig
index 0d08c29213c8..e6485be2e6f7 100644
--- a/sound/spi/Kconfig
+++ b/sound/spi/Kconfig
@@ -1,7 +1,13 @@
1#SPI drivers 1#SPI drivers
2 2
3menu "SPI devices" 3menuconfig SND_SPI
4 depends on SND != n 4 bool "SPI sound devices"
5 depends on SPI
6 default y
7 help
8 Support for sound devices connected via the SPI bus.
9
10if SND_SPI
5 11
6config SND_AT73C213 12config SND_AT73C213
7 tristate "Atmel AT73C213 DAC driver" 13 tristate "Atmel AT73C213 DAC driver"
@@ -28,4 +34,5 @@ config SND_AT73C213_TARGET_BITRATE
28 34
29 Set to 48000 Hz by default. 35 Set to 48000 Hz by default.
30 36
31endmenu 37endif # SND_SPI
38
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 9351b8a765b9..ffcdc8f4ef66 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -1,11 +1,16 @@
1# ALSA USB drivers 1# ALSA USB drivers
2 2
3menu "USB devices" 3menuconfig SND_USB
4 depends on SND!=n && USB!=n 4 bool "USB sound devices"
5 depends on USB
6 default y
7 help
8 Support for sound devices connected via the USB bus.
9
10if SND_USB && USB
5 11
6config SND_USB_AUDIO 12config SND_USB_AUDIO
7 tristate "USB Audio/MIDI driver" 13 tristate "USB Audio/MIDI driver"
8 depends on SND && USB
9 select SND_HWDEP 14 select SND_HWDEP
10 select SND_RAWMIDI 15 select SND_RAWMIDI
11 select SND_PCM 16 select SND_PCM
@@ -18,7 +23,7 @@ config SND_USB_AUDIO
18 23
19config SND_USB_USX2Y 24config SND_USB_USX2Y
20 tristate "Tascam US-122, US-224 and US-428 USB driver" 25 tristate "Tascam US-122, US-224 and US-428 USB driver"
21 depends on SND && USB && (X86 || PPC || ALPHA) 26 depends on X86 || PPC || ALPHA
22 select SND_HWDEP 27 select SND_HWDEP
23 select SND_RAWMIDI 28 select SND_RAWMIDI
24 select SND_PCM 29 select SND_PCM
@@ -31,7 +36,6 @@ config SND_USB_USX2Y
31 36
32config SND_USB_CAIAQ 37config SND_USB_CAIAQ
33 tristate "Native Instruments USB audio devices" 38 tristate "Native Instruments USB audio devices"
34 depends on SND && USB
35 select SND_HWDEP 39 select SND_HWDEP
36 select SND_RAWMIDI 40 select SND_RAWMIDI
37 select SND_PCM 41 select SND_PCM
@@ -63,5 +67,5 @@ config SND_USB_CAIAQ_INPUT
63 * Native Instruments Kore Controller 2 67 * Native Instruments Kore Controller 2
64 * Native Instruments Audio Kontrol 1 68 * Native Instruments Audio Kontrol 1
65 69
66endmenu 70endif # SND_USB
67 71
diff --git a/sound/usb/caiaq/caiaq-audio.c b/sound/usb/caiaq/caiaq-audio.c
index 24970a5c888f..b3a603325835 100644
--- a/sound/usb/caiaq/caiaq-audio.c
+++ b/sound/usb/caiaq/caiaq-audio.c
@@ -637,6 +637,7 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev)
637 switch (dev->chip.usb_id) { 637 switch (dev->chip.usb_id) {
638 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): 638 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
639 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): 639 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
640 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_SESSIONIO):
640 dev->samplerates |= SNDRV_PCM_RATE_88200; 641 dev->samplerates |= SNDRV_PCM_RATE_88200;
641 dev->samplerates |= SNDRV_PCM_RATE_192000; 642 dev->samplerates |= SNDRV_PCM_RATE_192000;
642 break; 643 break;
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c
index a972f77bd785..83175083e50f 100644
--- a/sound/usb/caiaq/caiaq-device.c
+++ b/sound/usb/caiaq/caiaq-device.c
@@ -42,14 +42,15 @@
42#endif 42#endif
43 43
44MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 44MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
45MODULE_DESCRIPTION("caiaq USB audio, version 1.3.6"); 45MODULE_DESCRIPTION("caiaq USB audio, version 1.3.8");
46MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
47MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," 47MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
48 "{Native Instruments, RigKontrol3}," 48 "{Native Instruments, RigKontrol3},"
49 "{Native Instruments, Kore Controller}," 49 "{Native Instruments, Kore Controller},"
50 "{Native Instruments, Kore Controller 2}," 50 "{Native Instruments, Kore Controller 2},"
51 "{Native Instruments, Audio Kontrol 1}" 51 "{Native Instruments, Audio Kontrol 1},"
52 "{Native Instruments, Audio 8 DJ}}"); 52 "{Native Instruments, Audio 8 DJ},"
53 "{Native Instruments, Session I/O}}");
53 54
54static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ 55static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
55static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ 56static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
@@ -110,6 +111,11 @@ static struct usb_device_id snd_usb_id_table[] = {
110 .idVendor = USB_VID_NATIVEINSTRUMENTS, 111 .idVendor = USB_VID_NATIVEINSTRUMENTS,
111 .idProduct = USB_PID_AUDIO8DJ 112 .idProduct = USB_PID_AUDIO8DJ
112 }, 113 },
114 {
115 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
116 .idVendor = USB_VID_NATIVEINSTRUMENTS,
117 .idProduct = USB_PID_SESSIONIO
118 },
113 { /* terminator */ } 119 { /* terminator */ }
114}; 120};
115 121
diff --git a/sound/usb/caiaq/caiaq-device.h b/sound/usb/caiaq/caiaq-device.h
index 96a491379c60..f9fbdbae269d 100644
--- a/sound/usb/caiaq/caiaq-device.h
+++ b/sound/usb/caiaq/caiaq-device.h
@@ -11,6 +11,7 @@
11#define USB_PID_KORECONTROLLER2 0x4712 11#define USB_PID_KORECONTROLLER2 0x4712
12#define USB_PID_AK1 0x0815 12#define USB_PID_AK1 0x0815
13#define USB_PID_AUDIO8DJ 0x1978 13#define USB_PID_AUDIO8DJ 0x1978
14#define USB_PID_SESSIONIO 0x1915
14 15
15#define EP1_BUFSIZE 64 16#define EP1_BUFSIZE 64
16#define CAIAQ_USB_STR_LEN 0xff 17#define CAIAQ_USB_STR_LEN 0xff
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 410be4aff1ba..b8cfb7c22768 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -819,10 +819,6 @@ static const char *usb_error_string(int err)
819 return "device disabled"; 819 return "device disabled";
820 case -EHOSTUNREACH: 820 case -EHOSTUNREACH:
821 return "device suspended"; 821 return "device suspended";
822#ifndef CONFIG_USB_EHCI_SPLIT_ISO
823 case -ENOSYS:
824 return "enable CONFIG_USB_EHCI_SPLIT_ISO to play through a hub";
825#endif
826 case -EINVAL: 822 case -EINVAL:
827 case -EAGAIN: 823 case -EAGAIN:
828 case -EFBIG: 824 case -EFBIG:
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index 82a8d14c26af..9ea726c049c6 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -210,6 +210,11 @@ YAMAHA_DEVICE(0x1042, NULL),
210YAMAHA_DEVICE(0x1043, NULL), 210YAMAHA_DEVICE(0x1043, NULL),
211YAMAHA_DEVICE(0x1044, NULL), 211YAMAHA_DEVICE(0x1044, NULL),
212YAMAHA_DEVICE(0x1045, NULL), 212YAMAHA_DEVICE(0x1045, NULL),
213YAMAHA_INTERFACE(0x104e, 0, NULL),
214YAMAHA_DEVICE(0x104f, NULL),
215YAMAHA_DEVICE(0x1050, NULL),
216YAMAHA_DEVICE(0x1051, NULL),
217YAMAHA_DEVICE(0x1052, NULL),
213YAMAHA_DEVICE(0x2000, "DGP-7"), 218YAMAHA_DEVICE(0x2000, "DGP-7"),
214YAMAHA_DEVICE(0x2001, "DGP-5"), 219YAMAHA_DEVICE(0x2001, "DGP-5"),
215YAMAHA_DEVICE(0x2002, NULL), 220YAMAHA_DEVICE(0x2002, NULL),
@@ -1379,6 +1384,39 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1379 } 1384 }
1380}, 1385},
1381 1386
1387{
1388 /* Roland SonicCell */
1389 USB_DEVICE(0x0582, 0x00c2),
1390 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1391 .vendor_name = "Roland",
1392 .product_name = "SonicCell",
1393 .ifnum = QUIRK_ANY_INTERFACE,
1394 .type = QUIRK_COMPOSITE,
1395 .data = (const struct snd_usb_audio_quirk[]) {
1396 {
1397 .ifnum = 0,
1398 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1399 },
1400 {
1401 .ifnum = 1,
1402 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1403 },
1404 {
1405 .ifnum = 2,
1406 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1407 .data = & (const struct snd_usb_midi_endpoint_info) {
1408 .out_cables = 0x0001,
1409 .in_cables = 0x0001
1410 }
1411 },
1412 {
1413 .ifnum = -1
1414 }
1415 }
1416 }
1417},
1418
1419
1382/* Guillemot devices */ 1420/* Guillemot devices */
1383{ 1421{
1384 /* 1422 /*